openssh-7.5p1004075500017500001750000000000001306372320400114005ustar00djmdjmopenssh-7.5p1/.skipped-commit-ids010064400017500001750000000014471306364033700151720ustar00djmdjm321065a95a7ccebdd5fd08482a1e19afbf524e35 Update DH groups d4f699a421504df35254cf1c6f1a7c304fb907ca Remove 1k bit groups aafe246655b53b52bc32c8a24002bc262f4230f7 Remove intermediate moduli 8fa9cd1dee3c3339ae329cf20fb591db6d605120 put back SSH1 for 6.9 f31327a48dd4103333cc53315ec53fe65ed8a17a Generate new moduli edbfde98c40007b7752a4ac106095e060c25c1ef Regen moduli 052fd565e3ff2d8cec3bc957d1788f50c827f8e2 Switch to tame-based sandbox 7cf73737f357492776223da1c09179fa6ba74660 Remove moduli <2k 180d84674be1344e45a63990d60349988187c1ae Update moduli f6ae971186ba68d066cd102e57d5b0b2c211a5ee systrace is dead. 96c5054e3e1f170c6276902d5bc65bb3b87a2603 remove DEBUGLIBS from Makefile 6da9a37f74aef9f9cc639004345ad893cad582d8 Update moduli file 77bcb50e47b68c7209c7f0a5a020d73761e5143b unset REGRESS_FAIL_EARLY openssh-7.5p1/CREDITS010064400017500001750000000125651306364033700125120ustar00djmdjmTatu 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 openssh-7.5p1/INSTALL010064400017500001750000000223471306364033700125220ustar00djmdjm1. Prerequisites ---------------- A C compiler. Any C89 or better compiler should work. Where supported, configure will attempt to enable the compiler's run-time integrity checking options. Some notes about specific compilers: - clang: -ftrapv and -sanitize=integer require the compiler-rt runtime (CC=clang LDFLAGS=--rtlib=compiler-rt ./configure) You will need working installations of Zlib and libcrypto (LibreSSL / OpenSSL) Zlib 1.1.4 or 1.2.1.2 or greater (earlier 1.2.x versions have problems): http://www.gzip.org/zlib/ libcrypto (LibreSSL or OpenSSL >= 0.9.8f < 1.1.0) 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. Note that because of API changes, OpenSSL 1.1.x is not currently supported. 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.69 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 [type] -f /etc/ssh/ssh_host_key -N "" for each of the types you wish to generate (rsa, dsa or ecdsa) or ssh-keygen -A to generate keys for all supported types. 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 https://www.openssh.com/ openssh-7.5p1/LICENCE010064400017500001750000000372501306364033700124550ustar00djmdjmThis 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.5p1/Makefile.in010064400017500001750000000622471306364033700135410ustar00djmdjm# $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 utf8.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 platform-tracing.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 \ audit.o audit-bsm.o audit-linux.o platform.o \ sshpty.o sshlogin.o servconf.o serverloop.o \ auth.o auth2.o auth-options.o session.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.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 -Dumac_ctx=umac128_ctx 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/conversion/*.o rm -f regress/unittests/conversion/test_conversion 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 rm -f regress/unittests/match/*.o rm -f regress/unittests/match/test_match rm -f regress/unittests/utf8/*.o rm -f regress/unittests/utf8/test_utf8 rm -f regress/misc/kexfuzz/*.o rm -f regress/misc/kexfuzz/kexfuzz (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/conversion/*.o rm -f regress/unittests/conversion/test_conversion 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 rm -f regress/unittests/match/*.o rm -f regress/unittests/match/test_match rm -f regress/unittests/utf8/*.o rm -f regress/unittests/utf8/test_utf8 rm -f regress/unittests/misc/kexfuzz (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/conversion ] || \ mkdir -p `pwd`/regress/unittests/conversion [ -d `pwd`/regress/unittests/hostkeys ] || \ mkdir -p `pwd`/regress/unittests/hostkeys [ -d `pwd`/regress/unittests/kex ] || \ mkdir -p `pwd`/regress/unittests/kex [ -d `pwd`/regress/unittests/match ] || \ mkdir -p `pwd`/regress/unittests/match [ -d `pwd`/regress/unittests/utf8 ] || \ mkdir -p `pwd`/regress/unittests/utf8 [ -d `pwd`/regress/misc/kexfuzz ] || \ mkdir -p `pwd`/regress/misc/kexfuzz [ -f `pwd`/regress/Makefile ] || \ ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile REGRESSLIBS=libssh.a $(LIBCOMPAT) regress/modpipe$(EXEEXT): $(srcdir)/regress/modpipe.c $(REGRESSLIBS) $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/regress/modpipe.c \ $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) regress/setuid-allowed$(EXEEXT): $(srcdir)/regress/setuid-allowed.c $(REGRESSLIBS) $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/regress/setuid-allowed.c \ $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) regress/netcat$(EXEEXT): $(srcdir)/regress/netcat.c $(REGRESSLIBS) $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/regress/netcat.c \ $(LDFLAGS) -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) regress/check-perm$(EXEEXT): $(srcdir)/regress/check-perm.c $(REGRESSLIBS) $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(srcdir)/regress/check-perm.c \ $(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_CONVERSION_OBJS=\ regress/unittests/conversion/tests.o regress/unittests/conversion/test_conversion$(EXEEXT): \ ${UNITTESTS_TEST_CONVERSION_OBJS} \ regress/unittests/test_helper/libtest_helper.a libssh.a $(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_CONVERSION_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) UNITTESTS_TEST_MATCH_OBJS=\ regress/unittests/match/tests.o regress/unittests/match/test_match$(EXEEXT): \ ${UNITTESTS_TEST_MATCH_OBJS} \ regress/unittests/test_helper/libtest_helper.a libssh.a $(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_MATCH_OBJS) \ regress/unittests/test_helper/libtest_helper.a \ -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) UNITTESTS_TEST_UTF8_OBJS=\ regress/unittests/utf8/tests.o regress/unittests/utf8/test_utf8$(EXEEXT): \ ${UNITTESTS_TEST_UTF8_OBJS} \ regress/unittests/test_helper/libtest_helper.a libssh.a $(LD) -o $@ $(LDFLAGS) $(UNITTESTS_TEST_UTF8_OBJS) \ regress/unittests/test_helper/libtest_helper.a \ -lssh -lopenbsd-compat -lssh -lopenbsd-compat $(LIBS) MISC_KEX_FUZZ_OBJS=\ regress/misc/kexfuzz/kexfuzz.o regress/misc/kexfuzz/kexfuzz$(EXEEXT): ${MISC_KEX_FUZZ_OBJS} libssh.a $(LD) -o $@ $(LDFLAGS) $(MISC_KEX_FUZZ_OBJS) \ -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/conversion/test_conversion$(EXEEXT) \ regress/unittests/hostkeys/test_hostkeys$(EXEEXT) \ regress/unittests/kex/test_kex$(EXEEXT) \ regress/unittests/match/test_match$(EXEEXT) \ regress/unittests/utf8/test_utf8$(EXEEXT) \ regress/misc/kexfuzz/kexfuzz$(EXEEXT) tests interop-tests t-exec unit: regress-prep regress-binaries $(TARGETS) 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_UTF8="@TEST_SSH_UTF8@" ; \ 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_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_UTF8="$${TEST_SSH_UTF8}" \ 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.5p1/PROTOCOL010064400017500001750000000406241306364033700126530ustar00djmdjmThis 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: https://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: https://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: https://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 string reserved uint32 reserved 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.30 2016/04/08 06:35:54 djm Exp $ openssh-7.5p1/PROTOCOL.agent010064400017500001750000000444271306364033700137550ustar00djmdjmThis 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 ED25519 keys may be added using the following request byte SSH2_AGENTC_ADD_IDENTITY or SSH2_AGENTC_ADD_ID_CONSTRAINED string "ssh-ed25519" string ed25519_public_key string ed25519_private_key || ed25519_public_key string key_comment constraint[] key_constraints ED25519 certificates may be added with: byte SSH2_AGENTC_ADD_IDENTITY or SSH2_AGENTC_ADD_ID_CONSTRAINED string "ssh-ed25519-cert-v01@openssh.com" string certificate string ed25519_public_key string ed25519_private_key || ed25519_public_key string key_comment constraint[] key_constraints For both ssh-ed25519 and ssh-ed25519-cert-v01@openssh.com keys, the private key has the public key appended (for historical reasons). 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.11 2016/05/19 07:45:32 djm Exp $ openssh-7.5p1/PROTOCOL.certkeys010064400017500001750000000261471306364033700145070ustar00djmdjmThis 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-v01@openssh.com" | "ecdsa-sha2-nistp384-v01@openssh.com" | "ecdsa-sha2-nistp521-v01@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 ED25519 certificate string "ssh-ed25519-cert-v01@openssh.com" string nonce string pk 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. pk is the encoded Ed25519 public key as defined by draft-josefsson-eddsa-ed25519-03. 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. "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), and draft-josefsson-eddsa-ed25519-03 for Ed25519. 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. No critical options are defined for host certificates at present. The supported user certificate 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. No extensions are defined for host certificates at present. The supported user certificate 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.10 2016/05/03 10:27:59 djm Exp $ openssh-7.5p1/PROTOCOL.chacha20poly1305010064400017500001750000000110211306364033700154250ustar00djmdjmThis 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 first 256 bits consitute K_2 and the second 256 bits become K_1. 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.3 2016/05/03 13:10:24 djm Exp $ openssh-7.5p1/PROTOCOL.key010064400017500001750000000030031306364033700134300ustar00djmdjmThis 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.5p1/PROTOCOL.krl010064400017500001750000000120571306364033700134410ustar00djmdjmThis 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.5p1/PROTOCOL.mux010064400017500001750000000141661306364033700134650ustar00djmdjmThis 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.5p1/README010064400017500001750000000050761306364033700123510ustar00djmdjmSee https://www.openssh.com/releasenotes.html#7.5p1 for the release notes. Please read https://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 release notes 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 https://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 https://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. 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] https://www.openssh.com/ [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://man.openbsd.org/style.9 openssh-7.5p1/README.dns010064400017500001750000000031071306364033700131250ustar00djmdjmHow 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.5p1/README.platform010064400017500001750000000077171306364033700142000ustar00djmdjmThis 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. openssh-7.5p1/README.privsep010064400017500001750000000044141306364033700140330ustar00djmdjmPrivilege 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). 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 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. openssh-7.5p1/README.tun010064400017500001750000000114321306364033700131470ustar00djmdjmHow 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.5p1/TODO010064400017500001750000000050561306364033700121570ustar00djmdjmDocumentation: - 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: - 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) openssh-7.5p1/aclocal.m4010064400017500001750000000125501306364033700133240ustar00djmdjmdnl 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; long long int p = n * o; printf("%d %d %d %f %f %lld %lld %lld\n", i, j, k, l, m, n, o, p); 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; long long p = n * o; printf("%d %d %d %f %f %lld %lld %lld\n", i, j, k, l, m, n, o, p); 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.5p1/addrmatch.c010064400017500001750000000256751306364033700135730ustar00djmdjm/* $OpenBSD: addrmatch.c,v 1.13 2016/09/21 16:55:42 djm 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) { debug2("%s: inconsistent mask length for " "match network \"%.100s\"", __func__, 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.5p1/atomicio.c010064400017500001750000000106301306364033700134310ustar00djmdjm/* $OpenBSD: atomicio.c,v 1.28 2016/07/27 23:18:12 djm 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 < 0 || iovcnt > IOV_MAX) { errno = EINVAL; return 0; } /* Make a copy of the iov array because we may modify it below */ memcpy(iov, _iov, (size_t)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.5p1/atomicio.h010064400017500001750000000042141306364033700134370ustar00djmdjm/* $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.5p1/audit-bsm.c010064400017500001750000000275261306364033700135260ustar00djmdjm/* * 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.5p1/audit-linux.c010064400017500001750000000067321306364033700141000ustar00djmdjm/* * 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" #include "packet.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; if ((audit_fd = audit_open()) < 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) { struct ssh *ssh = active_state; /* XXX */ 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, ssh_remote_ipaddr(ssh), "sshd", 0); break; default: debug("%s: unhandled event %d", __func__, event); break; } } #endif /* USE_LINUX_AUDIT */ openssh-7.5p1/audit.c010064400017500001750000000133001306364033700127300ustar00djmdjm/* * 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.5p1/audit.h010064400017500001750000000044261306364033700127460ustar00djmdjm/* * 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.5p1/auth-bsdauth.c010064400017500001750000000072211306364033700142200ustar00djmdjm/* $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.5p1/auth-krb5.c010064400017500001750000000156671306364033700134460ustar00djmdjm/* $OpenBSD: auth-krb5.c,v 1.22 2016/05/04 14:22:33 markus 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 "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.5p1/auth-options.c010064400017500001750000000412351306364033700142640ustar00djmdjm/* $OpenBSD: auth-options.c,v 1.72 2016/11/30 02:57:40 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". */ #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 "packet.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) { struct ssh *ssh = active_state; /* XXX */ 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 = ssh_remote_ipaddr(ssh); const char *remote_host = auth_get_canonical_hostname( ssh, 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) { struct ssh *ssh = active_state; /* XXX */ 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 = ssh_remote_ipaddr(ssh); 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, const char **reason) { 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; *reason = "invalid certificate options"; /* 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; /* * Only permit both CA and key option forced-command if they match. * Otherwise refuse the certificate. */ if (cert_forced_command != NULL && forced_command != NULL) { if (strcmp(forced_command, cert_forced_command) == 0) { free(forced_command); forced_command = cert_forced_command; } else { *reason = "certificate and key options forced command " "do not match"; free(cert_forced_command); return -1; } } else if (cert_forced_command != NULL) forced_command = cert_forced_command; /* success */ *reason = NULL; return 0; } openssh-7.5p1/auth-options.h010064400017500001750000000024051306364033700142650ustar00djmdjm/* $OpenBSD: auth-options.h,v 1.22 2016/11/30 02:57:40 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 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 *, const char **); #endif openssh-7.5p1/auth-pam.c010064400017500001750000000772161306364033700133560ustar00djmdjm/*- * 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 #if !defined(SSHD_PAM_SERVICE) extern char *__progname; # define SSHD_PAM_SERVICE __progname #endif /* OpenGroup RFC86.0 and XSSO specify no "const" on arguments */ #ifdef PAM_SUN_CODEBASE # define sshpam_const /* Solaris, HP-UX, SunOS */ #else # define sshpam_const const /* LinuxPAM, OpenPAM, AIX */ #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); while (waitpid(cleanup_ctxt->pam_thread, &sshpam_thread_status, 0) == -1) { if (errno == EINTR) continue; return; } } 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); while (waitpid(thread, &status, 0) == -1) { if (errno == EINTR) continue; fatal("%s: waitpid: %s", __func__, strerror(errno)); } 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 int sshpam_maxtries_reached = 0; static char **sshpam_env = NULL; static Authctxt *sshpam_authctxt = NULL; static const char *sshpam_password = NULL; /* 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: 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: 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_MAXTRIES) sshpam_set_maxtries_reached(1); 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 if (sshpam_maxtries_reached) ssh_msg_send(ctxt->pam_csock, PAM_MAXTRIES, &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) { const char *pam_rhost, *pam_user, *user = authctxt->user; const char **ptr_pam_user = &pam_user; struct ssh *ssh = active_state; /* XXX */ 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 = auth_get_canonical_hostname(ssh, 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) { struct ssh *ssh = active_state; /* XXX */ 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: case PAM_MAXTRIES: if (type == PAM_ACCT_EXPIRED) sshpam_account_status = 0; if (type == PAM_MAXTRIES) sshpam_set_maxtries_reached(1); /* 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, auth_get_canonical_hostname(ssh, options.use_dns)); /* FALLTHROUGH */ default: *num = 0; **echo_on = 0; free(msg); ctxt->pam_done = -1; return (-1); } } return (-1); } /* * Returns a junk password of identical length to that the user supplied. * Used to mitigate timing attacks against crypt(3)/PAM stacks that * vary processing time in proportion to password length. */ static char * fake_password(const char *wire_password) { const char junk[] = "\b\n\r\177INCORRECT"; char *ret = NULL; size_t i, l = wire_password != NULL ? strlen(wire_password) : 0; if (l >= INT_MAX) fatal("%s: password length too long: %zu", __func__, l); ret = malloc(l + 1); if (ret == NULL) return NULL; for (i = 0; i < l; i++) ret[i] = junk[i % (sizeof(junk) - 1)]; ret[i] = '\0'; return ret; } /* 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; char *fake; 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 { fake = fake_password(*resp); buffer_put_cstring(&buffer, fake); free(fake); } 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_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); char *fake = NULL; 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 = fake = fake_password(password); 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; free(fake); if (sshpam_err == PAM_MAXTRIES) sshpam_set_maxtries_reached(1); 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; } } int sshpam_get_maxtries_reached(void) { return sshpam_maxtries_reached; } void sshpam_set_maxtries_reached(int reached) { if (reached == 0 || sshpam_maxtries_reached) return; sshpam_maxtries_reached = 1; options.password_authentication = 0; options.kbd_interactive_authentication = 0; options.challenge_response_authentication = 0; } #endif /* USE_PAM */ openssh-7.5p1/auth-pam.h010064400017500001750000000035661306364033700133600ustar00djmdjm/* * 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 void start_pam(Authctxt *); void finish_pam(void); u_int do_pam_account(void); void do_pam_session(void); 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 sshpam_get_maxtries_reached(void); void sshpam_set_maxtries_reached(int); int is_pam_session_open(void); #endif /* USE_PAM */ openssh-7.5p1/auth-passwd.c010064400017500001750000000145671306364033700141020ustar00djmdjm/* $OpenBSD: auth-passwd.c,v 1.45 2016/07/21 01:39:35 dtucker 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 */ #define MAX_PASSWORD_LEN 1024 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 if (strlen(password) > MAX_PASSWORD_LEN) return 0; #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, *salt = NULL; /* 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, or pass a * NULL and let xcrypt pick one. */ if (authctxt->valid && pw_password[0] && pw_password[1]) salt = pw_password; encrypted_password = xcrypt(password, salt); /* * Authentication is accepted if the encrypted passwords * are identical. */ return encrypted_password != NULL && strcmp(encrypted_password, pw_password) == 0; } #endif openssh-7.5p1/auth-rhosts.c010064400017500001750000000216441306364033700141150ustar00djmdjm/* $OpenBSD: auth-rhosts.c,v 1.48 2016/08/13 17:47:41 markus 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 "uidswap.h" #include "pathnames.h" #include "log.h" #include "misc.h" #include "buffer.h" /* XXX */ #include "key.h" /* XXX */ #include "servconf.h" #include "canohost.h" #include "sshkey.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_rhosts2(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; } openssh-7.5p1/auth-shadow.c010064400017500001750000000103421306364033700140510ustar00djmdjm/* * 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.5p1/auth-sia.c010064400017500001750000000061641306364033700133470ustar00djmdjm/* * 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.5p1/auth-sia.h010064400017500001750000000026331306364033700133510ustar00djmdjm/* * 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.5p1/auth-skey.c010064400017500001750000000054251306364033700135450ustar00djmdjm/* $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.5p1/auth.c010064400017500001750000000567371306364033700126100ustar00djmdjm/* $OpenBSD: auth.c,v 1.119 2016/12/15 21:29:05 dtucker Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" #include #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 #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 ssh *ssh = active_state; /* XXX */ struct stat st; const char *hostname = NULL, *ipaddr = NULL, *passwd = NULL; u_int i; int r; #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 = auth_get_canonical_hostname(ssh, options.use_dns); ipaddr = ssh_remote_ipaddr(ssh); } /* Return false if user is listed in DenyUsers */ if (options.num_deny_users > 0) { for (i = 0; i < options.num_deny_users; i++) { r = match_user(pw->pw_name, hostname, ipaddr, options.deny_users[i]); if (r < 0) { fatal("Invalid DenyUsers pattern \"%.100s\"", options.deny_users[i]); } else if (r != 0) { 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++) { r = match_user(pw->pw_name, hostname, ipaddr, options.allow_users[i]); if (r < 0) { fatal("Invalid AllowUsers pattern \"%.100s\"", options.allow_users[i]); } else if (r == 1) 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) { struct ssh *ssh = active_state; /* XXX */ 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 ssh2%s%s", authmsg, method, submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod, authctxt->valid ? "" : "invalid user ", authctxt->user, ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), 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, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); # ifdef WITH_AIXAUTHENTICATE if (authenticated) sys_auth_record_login(authctxt->user, auth_get_canonical_hostname(ssh, 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) { struct ssh *ssh = active_state; /* XXX */ error("maximum authentication attempts exceeded for " "%s%.100s from %.200s port %d ssh2", authctxt->valid ? "" : "invalid user ", authctxt->user, ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); packet_disconnect("Too many authentication failures"); /* NOTREACHED */ } /* * Check whether root logins are disallowed. */ int auth_root_allowed(const char *method) { struct ssh *ssh = active_state; /* XXX */ 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 port %d", ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); 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) { struct ssh *ssh = active_state; /* XXX */ #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 port %d", user, ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); #ifdef CUSTOM_FAILED_LOGIN record_failed_login(user, auth_get_canonical_hostname(ssh, 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); } /* * Returns the remote DNS hostname as a string. The returned string must not * be freed. NB. this will usually trigger a DNS query the first time it is * called. * This function does additional checks on the hostname to mitigate some * attacks on legacy rhosts-style authentication. * XXX is RhostsRSAAuthentication vulnerable to these? * XXX Can we remove these checks? (or if not, remove RhostsRSAAuthentication?) */ static char * remote_hostname(struct ssh *ssh) { struct sockaddr_storage from; socklen_t fromlen; struct addrinfo hints, *ai, *aitop; char name[NI_MAXHOST], ntop2[NI_MAXHOST]; const char *ntop = ssh_remote_ipaddr(ssh); /* Get IP address of client. */ fromlen = sizeof(from); memset(&from, 0, sizeof(from)); if (getpeername(ssh_packet_get_connection_in(ssh), (struct sockaddr *)&from, &fromlen) < 0) { debug("getpeername failed: %.100s", strerror(errno)); return strdup(ntop); } ipv64_normalise_mapped(&from, &fromlen); if (from.ss_family == AF_INET6) fromlen = sizeof(struct sockaddr_in6); 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 strdup(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 strdup(ntop); } /* Names are stored 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.", name, ntop); return strdup(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 == NULL) { /* Address not found for the host name. */ logit("Address %.100s maps to %.600s, but this does not " "map back to the address.", ntop, name); return strdup(ntop); } return strdup(name); } /* * 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 * auth_get_canonical_hostname(struct ssh *ssh, int use_dns) { static char *dnsname; if (!use_dns) return ssh_remote_ipaddr(ssh); else if (dnsname != NULL) return dnsname; else { dnsname = remote_hostname(ssh); return dnsname; } } openssh-7.5p1/auth.h010064400017500001750000000155601306364033700126020ustar00djmdjm/* $OpenBSD: auth.h,v 1.89 2016/08/13 17:47:41 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_rhosts2(struct passwd *, const char *, const char *, const char *); int auth_password(Authctxt *, const char *); 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_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 *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 *); const char *auth_get_canonical_hostname(struct ssh *, int); 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 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.5p1/auth2-chall.c010064400017500001750000000223521306364033700137350ustar00djmdjm/* $OpenBSD: auth2-chall.c,v 1.44 2016/05/02 08:49:03 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)); } if ((kbdintctxt->devices = sshbuf_dup_string(&b)) == NULL) fatal("%s: sshbuf_dup_string failed", __func__); 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.5p1/auth2-gss.c010064400017500001750000000200521306364033700134410ustar00djmdjm/* $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.5p1/auth2-hostbased.c010064400017500001750000000164251306364033700146320ustar00djmdjm/* $OpenBSD: auth2-hostbased.c,v 1.26 2016/03/07 19:02:43 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) { struct ssh *ssh = active_state; /* XXX */ const char *resolvedname, *ipaddr, *lookup, *reason; HostStatus host_status; int len; char *fp; if (auth_key_is_revoked(key)) return 0; resolvedname = auth_get_canonical_hostname(ssh, options.use_dns); ipaddr = ssh_remote_ipaddr(ssh); 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.5p1/auth2-kbdint.c010064400017500001750000000041751306364033700141300ustar00djmdjm/* $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.5p1/auth2-none.c010064400017500001750000000043531306364033700136120ustar00djmdjm/* $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.5p1/auth2-passwd.c010064400017500001750000000046151306364033700141550ustar00djmdjm/* $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.5p1/auth2-pubkey.c010064400017500001750000000741601306364033700141550ustar00djmdjm/* $OpenBSD: auth2-pubkey.c,v 1.62 2017/01/30 01:03:00 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, const struct sshkey_cert *cert) { char line[SSH_MAX_PUBKEY_BYTES], *cp, *ep, *line_opts; u_long linenum = 0; u_int i, found_principal = 0; while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) { /* Always consume entire input */ if (found_principal) continue; /* 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; found_principal = 1; continue; } } } return found_principal; } 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, const struct sshkey *key) { const struct sshkey_cert *cert = key->cert; FILE *f = NULL; int r, 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; char *ca_fp = NULL, *key_fp = NULL, *catext = NULL, *keytext = NULL; char serial_s[16]; 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; } if ((ca_fp = sshkey_fingerprint(cert->signature_key, options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) { error("%s: sshkey_fingerprint failed", __func__); goto out; } 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(cert->signature_key, &catext)) != 0) { error("%s: sshkey_to_base64 failed: %s", __func__, ssh_err(r)); goto out; } if ((r = sshkey_to_base64(key, &keytext)) != 0) { error("%s: sshkey_to_base64 failed: %s", __func__, ssh_err(r)); goto out; } snprintf(serial_s, sizeof(serial_s), "%llu", (unsigned long long)cert->serial); 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), "T", sshkey_ssh_name(cert->signature_key), "f", key_fp, "F", ca_fp, "k", keytext, "K", catext, "i", cert->key_id, "s", serial_s, (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); fclose(f); f = NULL; 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); free(ca_fp); free(key_fp); free(catext); free(keytext); 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]; int found_key = 0; u_long linenum = 0; Key *found; found_key = 0; found = NULL; while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) { char *cp, *key_options = NULL, *fp = NULL; const char *reason = NULL; /* Always consume entrire file */ if (found_key) continue; 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, &reason) != 0) goto fail_reason; 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; continue; } } 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)) 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, &reason) != 0) goto fail_reason; 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); fclose(f); f = NULL; 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.5p1/auth2.c010064400017500001750000000403331306364033700126530ustar00djmdjm/* $OpenBSD: auth2.c,v 1.137 2017/02/03 23:05:57 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 #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) { struct ssh *ssh = active_state; /* XXX */ 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("%s: setting up authctxt for %s", __func__, user); } else { /* Invalid user, fake password information */ 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 ssh_packet_set_log_preamble(ssh, "%suser %s", authctxt->valid ? "authenticating " : "invalid ", user); 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) { struct ssh *ssh = active_state; /* XXX */ 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; ssh_packet_set_log_preamble(ssh, "user %s", authctxt->user); } 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)); } if ((list = sshbuf_dup_string(&b)) == NULL) fatal("%s: sshbuf_dup_string failed", __func__); 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.5p1/authfd.c010064400017500001750000000436571306364033700131170ustar00djmdjm/* $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.5p1/authfd.h010064400017500001750000000062031306364033700131060ustar00djmdjm/* $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.5p1/authfile.c010064400017500001750000000345071306364033700134370ustar00djmdjm/* $OpenBSD: authfile.c,v 1.122 2016/11/25 23:24:45 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. */ #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, dontmax = 0; 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; /* * Pre-allocate the buffer used for the key contents and clamp its * maximum size. This ensures that key contents are never leaked via * implicit realloc() in the sshbuf code. */ if ((st.st_mode & S_IFREG) == 0 || st.st_size <= 0) { st.st_size = 64*1024; /* 64k should be enough for anyone :) */ dontmax = 1; } if ((r = sshbuf_allocate(blob, st.st_size)) != 0 || (dontmax && (r = sshbuf_set_max_size(blob, st.st_size)) != 0)) return r; 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; if (keyp != NULL) *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; if (keyp != NULL) *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 (keyp != NULL) *keyp = NULL; 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; if (keyp != NULL) *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; if (keyp != NULL) *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; /* success */ if (keyp != NULL) { *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; if (keyp != NULL) *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; if (keyp != NULL) { *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.5p1/authfile.h010064400017500001750000000045301306364033700134350ustar00djmdjm/* $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.5p1/bitmap.c010064400017500001750000000106411306364033700131030ustar00djmdjm/* * 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.5p1/bitmap.h010064400017500001750000000035341306364033700131130ustar00djmdjm/* * 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.5p1/blocks.c010064400017500001750000000147641306364033700131160ustar00djmdjm/* $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.5p1/bufaux.c010064400017500001750000000121551306364033700131230ustar00djmdjm/* $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.5p1/bufbn.c010064400017500001750000000047331306364033700127300ustar00djmdjm/* $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.5p1/bufec.c010064400017500001750000000036011306364033700127110ustar00djmdjm/* $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.5p1/buffer.c010064400017500001750000000051711306364033700131020ustar00djmdjm/* $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.5p1/buffer.h010064400017500001750000000070011306364033700131010ustar00djmdjm/* $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.5p1/buildpkg.sh.in010064400017500001750000000432161306364033700142310ustar00djmdjm#!/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 - https://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.5p1/canohost.c010064400017500001750000000113411306364033700134430ustar00djmdjm/* $OpenBSD: canohost.c,v 1.73 2016/03/07 19:02:43 djm 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" 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; } /* * 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("%s: getnameinfo %d failed: %s", __func__, 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("%s: gethostname: %s", __func__, strerror(errno)); host = xstrdup("UNKNOWN"); } else { host = xstrdup(myname); } return host; } /* Returns the local/remote port for the socket. */ static int get_sock_port(int sock, int local) { struct sockaddr_storage from; socklen_t fromlen; char strport[NI_MAXSERV]; int r; /* Get IP address of client. */ fromlen = sizeof(from); memset(&from, 0, sizeof(from)); if (local) { if (getsockname(sock, (struct sockaddr *)&from, &fromlen) < 0) { error("getsockname failed: %.100s", strerror(errno)); return 0; } } else { if (getpeername(sock, (struct sockaddr *)&from, &fromlen) < 0) { debug("getpeername failed: %.100s", strerror(errno)); return -1; } } /* Work around Linux IPv6 weirdness */ if (from.ss_family == AF_INET6) fromlen = sizeof(struct sockaddr_in6); /* 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("%s: getnameinfo NI_NUMERICSERV failed: %s", __func__, ssh_gai_strerror(r)); return atoi(strport); } int get_peer_port(int sock) { return get_sock_port(sock, 0); } int get_local_port(int sock) { return get_sock_port(sock, 1); } openssh-7.5p1/canohost.h010064400017500001750000000015121306364033700134470ustar00djmdjm/* $OpenBSD: canohost.h,v 1.12 2016/03/07 19:02: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". */ #ifndef _CANOHOST_H #define _CANOHOST_H char *get_peer_ipaddr(int); int get_peer_port(int); char *get_local_ipaddr(int); char *get_local_name(int); int get_local_port(int); #endif /* _CANOHOST_H */ void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); openssh-7.5p1/chacha.c010064400017500001750000000124431306364033700130400ustar00djmdjm/* 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.5p1/chacha.h010064400017500001750000000017501306364033700130440ustar00djmdjm/* $OpenBSD: chacha.h,v 1.4 2016/08/27 04:04:56 guenther Exp $ */ /* chacha-merged.c version 20080118 D. J. Bernstein Public domain. */ #ifndef CHACHA_H #define CHACHA_H #include #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.5p1/channels.c010064400017500001750000003716741306364033700134420ustar00djmdjm/* $OpenBSD: channels.c,v 1.357 2017/02/01 02:59:09 dtucker 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 #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 "ssherr.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. */ Channel *downstream; /* Downstream mux*/ } 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 /* special-case wildcard meaning allow any host */ #define FWD_PERMIT_ANY_HOST "*" /* * 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); static const char *channel_rfwd_bind_host(const char *listen_host); /* 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; } Channel * channel_by_remote_id(int remote_id) { Channel *c; u_int i; for (i = 0; i < channels_alloc; i++) { c = channels[i]; if (c != NULL && c->remote_id == remote_id) return c; } return NULL; } /* * 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: case SSH_CHANNEL_MUX_PROXY: 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 = MAXIMUM(channel_max_fd, rfd); channel_max_fd = MAXIMUM(channel_max_fd, wfd); channel_max_fd = MAXIMUM(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 = MAXIMUM(max, c->rfd); max = MAXIMUM(max, c->wfd); max = MAXIMUM(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; Channel *other; struct channel_confirm *cc; for (n = 0, i = 0; i < channels_alloc; i++) { if ((other = channels[i]) != NULL) { n++; /* detach from mux client and prepare for closing */ if (c->type == SSH_CHANNEL_MUX_CLIENT && other->type == SSH_CHANNEL_MUX_PROXY && other->mux_ctx == c) { other->mux_ctx = NULL; other->type = SSH_CHANNEL_OPEN; other->istate = CHAN_INPUT_CLOSED; other->ostate = CHAN_OUTPUT_CLOSED; } } } debug("channel %d: free: %s, nchannels %u", c->self, c->remote_name ? c->remote_name : "???", n); /* XXX more MUX cleanup: remove remote forwardings */ if (c->type == SSH_CHANNEL_MUX_CLIENT) { for (i = 0; i < (u_int)num_permitted_opens; i++) { if (permitted_opens[i].downstream != c) continue; /* cancel on the server, since mux client is gone */ debug("channel %d: cleanup remote forward for %s:%u", c->self, permitted_opens[i].listen_host, permitted_opens[i].listen_port); packet_start(SSH2_MSG_GLOBAL_REQUEST); packet_put_cstring("cancel-tcpip-forward"); packet_put_char(0); packet_put_cstring(channel_rfwd_bind_host( permitted_opens[i].listen_host)); packet_put_int(permitted_opens[i].listen_port); packet_send(); /* unregister */ 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; permitted_opens[i].downstream = NULL; } } 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: case SSH_CHANNEL_MUX_PROXY: 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_MUX_PROXY: 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_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: case SSH_CHANNEL_MUX_PROXY: case SSH_CHANNEL_MUX_CLIENT: 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_local_port(c->sock); 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, MINIMUM(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 = MAXIMUM(*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); } } } /* -- mux proxy support */ /* * When multiplexing channel messages for mux clients we have to deal * with downstream messages from the mux client and upstream messages * from the ssh server: * 1) Handling downstream messages is straightforward and happens * in channel_proxy_downstream(): * - We forward all messages (mostly) unmodified to the server. * - However, in order to route messages from upstream to the correct * downstream client, we have to replace the channel IDs used by the * mux clients with a unique channel ID because the mux clients might * use conflicting channel IDs. * - so we inspect and change both SSH2_MSG_CHANNEL_OPEN and * SSH2_MSG_CHANNEL_OPEN_CONFIRMATION messages, create a local * SSH_CHANNEL_MUX_PROXY channel and replace the mux clients ID * with the newly allocated channel ID. * 2) Upstream messages are received by matching SSH_CHANNEL_MUX_PROXY * channels and procesed by channel_proxy_upstream(). The local channel ID * is then translated back to the original mux client ID. * 3) In both cases we need to keep track of matching SSH2_MSG_CHANNEL_CLOSE * messages so we can clean up SSH_CHANNEL_MUX_PROXY channels. * 4) The SSH_CHANNEL_MUX_PROXY channels also need to closed when the * downstream mux client are removed. * 5) Handling SSH2_MSG_CHANNEL_OPEN messages from the upstream server * requires more work, because they are not addressed to a specific * channel. E.g. client_request_forwarded_tcpip() needs to figure * out whether the request is addressed to the local client or a * specific downstream client based on the listen-address/port. * 6) Agent and X11-Forwarding have a similar problem and are currenly * not supported as the matching session/channel cannot be identified * easily. */ /* * receive packets from downstream mux clients: * channel callback fired on read from mux client, creates * SSH_CHANNEL_MUX_PROXY channels and translates channel IDs * on channel creation. */ int channel_proxy_downstream(Channel *downstream) { Channel *c = NULL; struct ssh *ssh = active_state; struct sshbuf *original = NULL, *modified = NULL; const u_char *cp; char *ctype = NULL, *listen_host = NULL; u_char type; size_t have; int ret = -1, r, idx; u_int id, remote_id, listen_port; /* sshbuf_dump(&downstream->input, stderr); */ if ((r = sshbuf_get_string_direct(&downstream->input, &cp, &have)) != 0) { error("%s: malformed message: %s", __func__, ssh_err(r)); return -1; } if (have < 2) { error("%s: short message", __func__); return -1; } type = cp[1]; /* skip padlen + type */ cp += 2; have -= 2; if (ssh_packet_log_type(type)) debug3("%s: channel %u: down->up: type %u", __func__, downstream->self, type); switch (type) { case SSH2_MSG_CHANNEL_OPEN: if ((original = sshbuf_from(cp, have)) == NULL || (modified = sshbuf_new()) == NULL) { error("%s: alloc", __func__); goto out; } if ((r = sshbuf_get_cstring(original, &ctype, NULL)) != 0 || (r = sshbuf_get_u32(original, &id)) != 0) { error("%s: parse error %s", __func__, ssh_err(r)); goto out; } c = channel_new("mux proxy", SSH_CHANNEL_MUX_PROXY, -1, -1, -1, 0, 0, 0, ctype, 1); c->mux_ctx = downstream; /* point to mux client */ c->mux_downstream_id = id; /* original downstream id */ if ((r = sshbuf_put_cstring(modified, ctype)) != 0 || (r = sshbuf_put_u32(modified, c->self)) != 0 || (r = sshbuf_putb(modified, original)) != 0) { error("%s: compose error %s", __func__, ssh_err(r)); channel_free(c); goto out; } break; case SSH2_MSG_CHANNEL_OPEN_CONFIRMATION: /* * Almost the same as SSH2_MSG_CHANNEL_OPEN, except then we * need to parse 'remote_id' instead of 'ctype'. */ if ((original = sshbuf_from(cp, have)) == NULL || (modified = sshbuf_new()) == NULL) { error("%s: alloc", __func__); goto out; } if ((r = sshbuf_get_u32(original, &remote_id)) != 0 || (r = sshbuf_get_u32(original, &id)) != 0) { error("%s: parse error %s", __func__, ssh_err(r)); goto out; } c = channel_new("mux proxy", SSH_CHANNEL_MUX_PROXY, -1, -1, -1, 0, 0, 0, "mux-down-connect", 1); c->mux_ctx = downstream; /* point to mux client */ c->mux_downstream_id = id; c->remote_id = remote_id; if ((r = sshbuf_put_u32(modified, remote_id)) != 0 || (r = sshbuf_put_u32(modified, c->self)) != 0 || (r = sshbuf_putb(modified, original)) != 0) { error("%s: compose error %s", __func__, ssh_err(r)); channel_free(c); goto out; } break; case SSH2_MSG_GLOBAL_REQUEST: if ((original = sshbuf_from(cp, have)) == NULL) { error("%s: alloc", __func__); goto out; } if ((r = sshbuf_get_cstring(original, &ctype, NULL)) != 0) { error("%s: parse error %s", __func__, ssh_err(r)); goto out; } if (strcmp(ctype, "tcpip-forward") != 0) { error("%s: unsupported request %s", __func__, ctype); goto out; } if ((r = sshbuf_get_u8(original, NULL)) != 0 || (r = sshbuf_get_cstring(original, &listen_host, NULL)) != 0 || (r = sshbuf_get_u32(original, &listen_port)) != 0) { error("%s: parse error %s", __func__, ssh_err(r)); goto out; } if (listen_port > 65535) { error("%s: tcpip-forward for %s: bad port %u", __func__, listen_host, listen_port); goto out; } /* 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++; permitted_opens[idx].host_to_connect = xstrdup(""); permitted_opens[idx].port_to_connect = -1; permitted_opens[idx].listen_host = listen_host; permitted_opens[idx].listen_port = (int)listen_port; permitted_opens[idx].downstream = downstream; listen_host = NULL; break; case SSH2_MSG_CHANNEL_CLOSE: if (have < 4) break; remote_id = PEEK_U32(cp); if ((c = channel_by_remote_id(remote_id)) != NULL) { if (c->flags & CHAN_CLOSE_RCVD) channel_free(c); else c->flags |= CHAN_CLOSE_SENT; } break; } if (modified) { if ((r = sshpkt_start(ssh, type)) != 0 || (r = sshpkt_putb(ssh, modified)) != 0 || (r = sshpkt_send(ssh)) != 0) { error("%s: send %s", __func__, ssh_err(r)); goto out; } } else { if ((r = sshpkt_start(ssh, type)) != 0 || (r = sshpkt_put(ssh, cp, have)) != 0 || (r = sshpkt_send(ssh)) != 0) { error("%s: send %s", __func__, ssh_err(r)); goto out; } } ret = 0; out: free(ctype); free(listen_host); sshbuf_free(original); sshbuf_free(modified); return ret; } /* * receive packets from upstream server and de-multiplex packets * to correct downstream: * implemented as a helper for channel input handlers, * replaces local (proxy) channel ID with downstream channel ID. */ int channel_proxy_upstream(Channel *c, int type, u_int32_t seq, void *ctxt) { struct ssh *ssh = active_state; struct sshbuf *b = NULL; Channel *downstream; const u_char *cp = NULL; size_t len; int r; /* * When receiving packets from the peer we need to check whether we * need to forward the packets to the mux client. In this case we * restore the orignal channel id and keep track of CLOSE messages, * so we can cleanup the channel. */ if (c == NULL || c->type != SSH_CHANNEL_MUX_PROXY) return 0; if ((downstream = c->mux_ctx) == NULL) return 0; switch (type) { case SSH2_MSG_CHANNEL_CLOSE: case SSH2_MSG_CHANNEL_DATA: case SSH2_MSG_CHANNEL_EOF: case SSH2_MSG_CHANNEL_EXTENDED_DATA: case SSH2_MSG_CHANNEL_OPEN_CONFIRMATION: case SSH2_MSG_CHANNEL_OPEN_FAILURE: case SSH2_MSG_CHANNEL_WINDOW_ADJUST: case SSH2_MSG_CHANNEL_SUCCESS: case SSH2_MSG_CHANNEL_FAILURE: case SSH2_MSG_CHANNEL_REQUEST: break; default: debug2("%s: channel %u: unsupported type %u", __func__, c->self, type); return 0; } if ((b = sshbuf_new()) == NULL) { error("%s: alloc reply", __func__); goto out; } /* get remaining payload (after id) */ cp = sshpkt_ptr(ssh, &len); if (cp == NULL) { error("%s: no packet", __func__); goto out; } /* translate id and send to muxclient */ if ((r = sshbuf_put_u8(b, 0)) != 0 || /* padlen */ (r = sshbuf_put_u8(b, type)) != 0 || (r = sshbuf_put_u32(b, c->mux_downstream_id)) != 0 || (r = sshbuf_put(b, cp, len)) != 0 || (r = sshbuf_put_stringb(&downstream->output, b)) != 0) { error("%s: compose for muxclient %s", __func__, ssh_err(r)); goto out; } /* sshbuf_dump(b, stderr); */ if (ssh_packet_log_type(type)) debug3("%s: channel %u: up->down: type %u", __func__, c->self, type); out: /* update state */ switch (type) { case SSH2_MSG_CHANNEL_OPEN_CONFIRMATION: /* record remote_id for SSH2_MSG_CHANNEL_CLOSE */ if (cp && len > 4) c->remote_id = PEEK_U32(cp); break; case SSH2_MSG_CHANNEL_CLOSE: if (c->flags & CHAN_CLOSE_SENT) channel_free(c); else c->flags |= CHAN_CLOSE_RCVD; break; } sshbuf_free(b); return 1; } /* -- 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); if (channel_proxy_upstream(c, type, seq, ctxt)) return 0; /* 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 (channel_proxy_upstream(c, type, seq, ctxt)) return 0; 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); if (channel_proxy_upstream(c, type, seq, ctxt)) return 0; 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); if (channel_proxy_upstream(c, type, seq, ctxt)) return 0; /* * 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); if (c == NULL) packet_disconnect("Received oclose for nonexistent channel %d.", id); if (channel_proxy_upstream(c, type, seq, ctxt)) return 0; packet_check_eom(); 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); if (c == NULL) packet_disconnect("Received close confirmation for " "out-of-range channel %d.", id); if (channel_proxy_upstream(c, type, seq, ctxt)) return 0; packet_check_eom(); 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) packet_disconnect("Received open confirmation for " "unknown channel %d.", id); if (channel_proxy_upstream(c, type, seq, ctxt)) return 0; if (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) packet_disconnect("Received open failure for " "unknown channel %d.", id); if (channel_proxy_upstream(c, type, seq, ctxt)) return 0; if (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; } if (channel_proxy_upstream(c, type, seq, ctxt)) 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, NULL, NULL); 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(); 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 (channel_proxy_upstream(c, type, seq, ctxt)) return 0; packet_check_eom(); 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_local_port(sock); 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; } permitted_opens[idx].downstream = NULL; } 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, FWD_PERMIT_ANY_HOST) != 0 && 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; permitted_opens[i].downstream = 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; permitted_opens[i].downstream = 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)); } } /* * 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; permitted_opens[num_permitted_opens].downstream = NULL; 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[MAXIMUM(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, * passing back the failure reason if appropriate. */ static Channel * connect_to_reason(const char *name, int port, char *ctype, char *rname, int *reason, const char **errmsg) { 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) { if (errmsg != NULL) *errmsg = ssh_gai_strerror(gaierr); if (reason != NULL) *reason = SSH2_OPEN_CONNECT_FAILED; 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; } /* Return CONNECTING channel to remote host:port or local socket path */ static Channel * connect_to(const char *name, int port, char *ctype, char *rname) { return connect_to_reason(name, port, ctype, rname, NULL, NULL); } /* * returns either the newly connected channel or the downstream channel * that needs to deal with this connection. */ 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)) { if (permitted_opens[i].downstream) return permitted_opens[i].downstream; 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 *reason, const char **errmsg) { 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); if (reason != NULL) *reason = SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED; return NULL; } return connect_to_reason(host, port, ctype, rname, reason, errmsg); } /* 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); } #ifdef __APPLE__ static int is_path_to_xsocket(const char *display, char *path, size_t pathlen) { struct stat sbuf; if (strlcpy(path, display, pathlen) >= pathlen) { error("%s: display path too long", __func__); return 0; } if (display[0] != '/') return 0; if (stat(path, &sbuf) == 0) { return 1; } else { char *dot = strrchr(path, '.'); if (dot != NULL) { *dot = '\0'; if (stat(path, &sbuf) == 0) { return 1; } } } return 0; } #endif 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. */ #ifdef __APPLE__ /* Check if display is a path to a socket (as set by launchd). */ { char path[PATH_MAX]; if (is_path_to_xsocket(display, path, sizeof(path))) { debug("x11_connect_display: $DISPLAY is launchd"); /* Create a socket. */ sock = connect_local_xsocket_path(path); 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; 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. */ x11_saved_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); x11_saved_data[i] = value; } x11_saved_data_len = data_len; /* Generate fake data of the same length. */ x11_fake_data = xmalloc(data_len); arc4random_buf(x11_fake_data, 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.5p1/channels.h010064400017500001750000000275601306364033700134370ustar00djmdjm/* $OpenBSD: channels.h,v 1.121 2017/02/01 02:59:09 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". */ /* * 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_MUX_PROXY 20 /* proxy channel for mux-slave */ #define SSH_CHANNEL_MAX_TYPE 21 #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; int mux_downstream_id; }; #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_by_remote_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); /* mux proxy support */ int channel_proxy_downstream(Channel *mc); int channel_proxy_upstream(Channel *, int, u_int32_t, 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); Channel *channel_connect_to_port(const char *, u_short, char *, char *, int *, const 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.5p1/cipher-3des1.c010064400017500001750000000104421306364033700140150ustar00djmdjm/* $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" #ifdef WITH_SSH1 #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; } #endif /* WITH_SSH1 */ openssh-7.5p1/cipher-aes.c010064400017500001750000000110531306364033700136450ustar00djmdjm/* * 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.5p1/cipher-aesctr.c010064400017500001750000000040741306364033700143630ustar00djmdjm/* $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.5p1/cipher-aesctr.h010064400017500001750000000024631306364033700143700ustar00djmdjm/* $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.5p1/cipher-bf1.c010064400017500001750000000054631306364033700135550ustar00djmdjm/* $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_SSH1 #if defined(WITH_OPENSSL) && !defined(OPENSSL_NO_BF) #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 /* defined(WITH_OPENSSL) && !defined(OPENSSL_NO_BF) */ #endif /* WITH_SSH1 */ openssh-7.5p1/cipher-chachapoly.c010064400017500001750000000073461306364033700152220ustar00djmdjm/* * 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.8 2016/08/03 05:41:57 djm 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.5p1/cipher-chachapoly.h010064400017500001750000000031171306364033700152170ustar00djmdjm/* $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.5p1/cipher-ctr.c010064400017500001750000000071141306364033700136700ustar00djmdjm/* $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.5p1/cipher.c010064400017500001750000000443561306364033700131130ustar00djmdjm/* $OpenBSD: cipher.c,v 1.102 2016/08/03 05:41: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". * * * 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_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; }; 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 }, # ifndef OPENSSL_NO_BF { "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, 0, 0, 0, 1, evp_ssh1_bf }, # endif /* OPENSSL_NO_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 }, # ifndef OPENSSL_NO_BF { "blowfish-cbc", SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_bf_cbc }, # endif /* OPENSSL_NO_BF */ # ifndef OPENSSL_NO_CAST { "cast128-cbc", SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_cast5_cbc }, # endif /* OPENSSL_NO_CAST */ # ifndef OPENSSL_NO_RC4 { "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 }, # endif /* OPENSSL_NO_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_ctx_is_plaintext(struct sshcipher_ctx *cc) { return cc->plaintext; } u_int cipher_ctx_get_number(struct sshcipher_ctx *cc) { return cc->cipher->number; } u_int cipher_mask_ssh1(int client) { u_int mask = 0; mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */ mask |= 1 << SSH_CIPHER_BLOWFISH; if (client) { mask |= 1 << SSH_CIPHER_DES; } return mask; } 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 **ccp, const struct sshcipher *cipher, const u_char *key, u_int keylen, const u_char *iv, u_int ivlen, int do_encrypt) { struct sshcipher_ctx *cc = NULL; int ret = SSH_ERR_INTERNAL_ERROR; #ifdef WITH_OPENSSL const EVP_CIPHER *type; int klen; u_char *junk, *discard; #endif *ccp = NULL; if ((cc = calloc(sizeof(*cc), 1)) == NULL) return SSH_ERR_ALLOC_FAIL; if (cipher->number == SSH_CIPHER_DES) { if (keylen > 8) keylen = 8; } cc->plaintext = (cipher->number == SSH_CIPHER_NONE); cc->encrypt = do_encrypt; if (keylen < cipher->key_len || (iv != NULL && ivlen < cipher_ivlen(cipher))) { ret = SSH_ERR_INVALID_ARGUMENT; goto out; } cc->cipher = cipher; if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { ret = chachapoly_init(&cc->cp_ctx, key, keylen); goto out; } #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); ret = 0; goto out; } if ((cc->cipher->flags & CFLAG_NONE) != 0) { ret = 0; goto out; } ret = SSH_ERR_INVALID_ARGUMENT; goto out; #else /* WITH_OPENSSL */ type = (*cipher->evptype)(); if ((cc->evp = EVP_CIPHER_CTX_new()) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } if (EVP_CipherInit(cc->evp, type, NULL, (u_char *)iv, (do_encrypt == CIPHER_ENCRYPT)) == 0) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } 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 out; } 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 out; } } if (EVP_CipherInit(cc->evp, NULL, (u_char *)key, NULL, -1) == 0) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } 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 out; } 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; goto out; } } ret = 0; #endif /* WITH_OPENSSL */ out: if (ret == 0) { /* success */ *ccp = cc; } else { if (cc != NULL) { #ifdef WITH_OPENSSL if (cc->evp != NULL) EVP_CIPHER_CTX_free(cc->evp); #endif /* WITH_OPENSSL */ explicit_bzero(cc, sizeof(*cc)); free(cc); } } return ret; } /* * 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; } void cipher_free(struct sshcipher_ctx *cc) { if (cc == NULL) return; 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 if (cc->evp != NULL) { EVP_CIPHER_CTX_free(cc->evp); cc->evp = NULL; } #endif explicit_bzero(cc, sizeof(*cc)); free(cc); } /* * 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 **ccp, 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(ccp, 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; #ifndef OPENSSL_HAVE_EVPCTR /* XXX iv arg is const, but ssh_aes_ctr_iv isn't */ if (c->evptype == evp_aes_128_ctr) ssh_aes_ctr_iv(cc->evp, 1, (u_char *)iv, evplen); else #endif 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) { #if defined(WITH_OPENSSL) && !defined(OPENSSL_NO_RC4) 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) { #if defined(WITH_OPENSSL) && !defined(OPENSSL_NO_RC4) 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.5p1/cipher.h010064400017500001750000000104431306364033700131060ustar00djmdjm/* $OpenBSD: cipher.h,v 1.49 2016/08/03 05:41: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". * * 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; 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); void cipher_free(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_ctx_is_plaintext(struct sshcipher_ctx *); u_int cipher_ctx_get_number(struct sshcipher_ctx *); 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.5p1/cleanup.c010064400017500001750000000020131306364033700132500ustar00djmdjm/* $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.5p1/clientloop.c010064400017500001750000002306111306364033700140000ustar00djmdjm/* $OpenBSD: clientloop.c,v 1.291 2017/03/10 05:01:13 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 #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; /* Flag indicating that ssh should daemonise after authentication is complete */ extern int fork_after_authentication_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, 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_int8_t rnd[16]; u_int i; logit("Warning: No xauth data; " "using fake authentication data for X11 forwarding."); strlcpy(proto, SSH_X11_PROTO, sizeof proto); arc4random_buf(rnd, sizeof(rnd)); for (i = 0; i < sizeof(rnd); i++) { snprintf(data + 2 * i, sizeof data - 2 * i, "%02x", rnd[i]); } } 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 = MINIMUM(timeout_secs, packet_get_rekey_timeout()); set_control_persist_exit_time(); if (control_persist_exit_time > 0) { timeout_secs = MINIMUM(timeout_secs, control_persist_exit_time - now); if (timeout_secs < 0) timeout_secs = 0; } if (minwait_secs != 0) timeout_secs = MINIMUM(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("Unknown 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 recvfd 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) || fork_after_authentication_flag) { 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 = MAXIMUM(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 = MAXIMUM(max_fd, fileno(stdin)); max_fd = MAXIMUM(max_fd, fileno(stdout)); max_fd = MAXIMUM(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, u_int rwindow, u_int rmaxpack) { Channel *c = NULL; struct sshbuf *b = NULL; char *listen_address, *originator_address; u_short listen_port, originator_port; int r; /* 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); if (c != NULL && c->type == SSH_CHANNEL_MUX_CLIENT) { if ((b = sshbuf_new()) == NULL) { error("%s: alloc reply", __func__); goto out; } /* reconstruct and send to muxclient */ if ((r = sshbuf_put_u8(b, 0)) != 0 || /* padlen */ (r = sshbuf_put_u8(b, SSH2_MSG_CHANNEL_OPEN)) != 0 || (r = sshbuf_put_cstring(b, request_type)) != 0 || (r = sshbuf_put_u32(b, rchan)) != 0 || (r = sshbuf_put_u32(b, rwindow)) != 0 || (r = sshbuf_put_u32(b, rmaxpack)) != 0 || (r = sshbuf_put_cstring(b, listen_address)) != 0 || (r = sshbuf_put_u32(b, listen_port)) != 0 || (r = sshbuf_put_cstring(b, originator_address)) != 0 || (r = sshbuf_put_u32(b, originator_port)) != 0 || (r = sshbuf_put_stringb(&c->output, b)) != 0) { error("%s: compose for muxclient %s", __func__, ssh_err(r)); goto out; } } out: sshbuf_free(b); 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, rwindow, rmaxpack); } 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); } if (c != NULL && c->type == SSH_CHANNEL_MUX_CLIENT) { debug3("proxied to downstream: %s", ctype); } else 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(); c = channel_lookup(id); if (channel_proxy_upstream(c, type, seq, ctxt)) return 0; 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 == 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); } /* * Returns non-zero if the key is accepted by HostkeyAlgorithms. * Made slightly less trivial by the multiple RSA signature algorithm names. */ static int key_accepted_by_hostkeyalgs(const struct sshkey *key) { const char *ktype = sshkey_ssh_name(key); const char *hostkeyalgs = options.hostkeyalgorithms != NULL ? options.hostkeyalgorithms : KEX_DEFAULT_PK_ALG; if (key == NULL || key->type == KEY_UNSPEC) return 0; if (key->type == KEY_RSA && (match_pattern_list("rsa-sha2-256", hostkeyalgs, 0) == 1 || match_pattern_list("rsa-sha2-512", hostkeyalgs, 0) == 1)) return 1; return match_pattern_list(ktype, hostkeyalgs, 0) == 1; } /* * 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); if (!key_accepted_by_hostkeyalgs(key)) { 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.5p1/clientloop.h010064400017500001750000000070271306364033700140100ustar00djmdjm/* $OpenBSD: clientloop.h,v 1.33 2016/09/30 09:19:13 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) 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) */ #define SSHMUX_COMMAND_PROXY 8 /* Open new connection */ void muxserver_listen(void); int muxclient(const char *); void mux_exit_message(Channel *, int); void mux_tty_alloc_failed(Channel *); openssh-7.5p1/compat.c010064400017500001750000000212751306364033700131170ustar00djmdjm/* $OpenBSD: compat.c,v 1.100 2017/02/03 23:01:19 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" #include "kex.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; } char * compat_cipher_proposal(char *cipher_prop) { if (!(datafellows & SSH_BUG_BIGENDIANAES)) return cipher_prop; debug2("%s: original cipher proposal: %s", __func__, cipher_prop); if ((cipher_prop = match_filter_list(cipher_prop, "aes*")) == NULL) fatal("match_filter_list failed"); 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); if ((pkalg_prop = match_filter_list(pkalg_prop, "ssh-rsa")) == NULL) fatal("match_filter_list failed"); 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) if ((p = match_filter_list(p, "curve25519-sha256@libssh.org")) == NULL) fatal("match_filter_list failed"); if ((datafellows & SSH_OLD_DHGEX) != 0) { if ((p = match_filter_list(p, "diffie-hellman-group-exchange-sha256," "diffie-hellman-group-exchange-sha1")) == NULL) fatal("match_filter_list failed"); } debug2("%s: compat KEX proposal: %s", __func__, p); if (*p == '\0') fatal("No supported key exchange algorithms found"); return p; } openssh-7.5p1/compat.h010064400017500001750000000056341306364033700131250ustar00djmdjm/* $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.5p1/config.guess010075500017500001750000001253651306364033700140150ustar00djmdjm#! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2016 Free Software Foundation, Inc. timestamp='2016-05-15' # 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 3 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. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # 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 # # Please send patches to . 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 1992-2016 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 case "${UNAME_SYSTEM}" in Linux|GNU|GNU/*) # If the system lacks a compiler, then just pick glibc. # We could probably try harder. LIBC=gnu eval $set_cc_for_build cat <<-EOF > $dummy.c #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #else LIBC=gnu #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` ;; esac # 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=`(uname -p 2>/dev/null || \ /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 ;; earmv*) arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'` endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'` machine=${arch}${endian}-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) and ABI. case "${UNAME_MACHINE_ARCH}" in earm*) os=netbsdelf ;; 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 # Determine ABI tags. case "${UNAME_MACHINE_ARCH}" in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"` ;; 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/[-_].*//' | cut -d. -f1,2` ;; 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}${abi}" 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 ;; *:LibertyBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${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 ;; *:Sortix:*:*) echo ${UNAME_MACHINE}-unknown-sortix 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/lslpp ] ; then IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` 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 ;; *: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-${LIBC}`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 "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; aarch64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 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=gnulibc1 ; fi echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arc:Linux:*:* | arceb:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${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-${LIBC} else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi else echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf fi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; cris:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; crisv32:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; e2k:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; frv:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; hexagon:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:Linux:*:*) echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; k1om:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 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-${LIBC}"; exit; } ;; openrisc*:Linux:*:*) echo or1k-unknown-linux-${LIBC} exit ;; or32:Linux:*:* | or1k*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; padre:Linux:*:*) echo sparc-unknown-linux-${LIBC} exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-${LIBC} 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-${LIBC} ;; PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; *) echo hppa-unknown-linux-${LIBC} ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-${LIBC} exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-${LIBC} exit ;; ppc64le:Linux:*:*) echo powerpc64le-unknown-linux-${LIBC} exit ;; ppcle:Linux:*:*) echo powerpcle-unknown-linux-${LIBC} exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux-${LIBC} exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; tile*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 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 configure 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 ;; SX-ACE:SUPER-UX:*:*) echo sxace-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 eval $set_cc_for_build if test "$UNAME_PROCESSOR" = unknown ; then UNAME_PROCESSOR=powerpc fi if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then 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 case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi fi elif test "$UNAME_PROCESSOR" = i386 ; then # Avoid executing cc on OS X 10.9, as it ships with a stub # that puts up a graphical alert prompting to install # developer tools. Any system running Mac OS X 10.7 or # later (Darwin 11 and later) is required to have a 64-bit # processor. This is not true of the ARM version of Darwin # that Apple uses in portable devices. UNAME_PROCESSOR=x86_64 fi 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 ;; amd64:Isilon\ OneFS:*:*) echo x86_64-unknown-onefs exit ;; esac cat >&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.5p1/config.sub010075500017500001750000001067711306364033700134600ustar00djmdjm#! /bin/sh # Configuration validation subroutine script. # Copyright 1992-2016 Free Software Foundation, Inc. timestamp='2016-06-20' # 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 3 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. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches to . # # 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 # 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 or 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 1992-2016 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* | netbsd*-eabi* | \ 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 | arceb \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ | ba \ | be32 | be64 \ | bfin \ | c4x | c8051 | clipper \ | d10v | d30v | dlx | dsp16xx \ | e2k | epiphany \ | fido | fr30 | frv | ft32 \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | k1om \ | 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 \ | mipsisa32r6 | mipsisa32r6el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64r6 | mipsisa64r6el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 | or1k | or1knd | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ | riscv32 | riscv64 \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]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 \ | visium \ | 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 ;; leon|leon[3-9]) basic_machine=sparc-$basic_machine ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | 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-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | ba-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | c8051-* | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | e2k-* | 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-* \ | k1om-* \ | 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-* \ | mipsisa32r6-* | mipsisa32r6el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64r6-* | mipsisa64r6el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipsr5900-* | mipsr5900el-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* | nios2eb-* | nios2el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | or1k*-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ | riscv32-* | riscv64-* \ | 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-* \ | visium-* \ | 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 ;; asmjs) basic_machine=asmjs-unknown ;; 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 ;; e500v[12]) basic_machine=powerpc-unknown os=$os"spe" ;; e500v[12]-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` os=$os"spe" ;; 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 ;; leon-*|leon[3-9]-*) basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` ;; 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=i686-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 ;; moxiebox) basic_machine=moxie-unknown os=-moxiebox ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i686-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* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* | -cloudabi* | -sortix* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ | -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* \ | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ | -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* \ | -onefs* | -tirtos* | -phoenix*) # 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 ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -nacl*) ;; -ios) ;; -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 ;; c8051-*) os=-elf ;; 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.5p1/configure.ac010064400017500001750000004262601306364033700137610ustar00djmdjm# $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 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 COMMENT_OUT_RSA1="#no ssh1#" 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 COMMENT_OUT_RSA1="" 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]) AC_SUBST([COMMENT_OUT_RSA1]) 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 \ err.h \ features.h \ fcntl.h \ floatingpoint.h \ getopt.h \ glob.h \ ia.h \ iaf.h \ inttypes.h \ langinfo.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/ptrace.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 \ wchar.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([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_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 dnl Target SUSv3/POSIX.1-2001 plus BSD specifics. dnl _DEFAULT_SOURCE is the new name for _BSD_SOURCE CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_DEFAULT_SOURCE" 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_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 ;; s390x-*) seccomp_audit_arch=AUDIT_ARCH_S390X ;; s390-*) seccomp_audit_arch=AUDIT_ARCH_S390 ;; powerpc64-*) seccomp_audit_arch=AUDIT_ARCH_PPC64 ;; powerpc64le-*) seccomp_audit_arch=AUDIT_ARCH_PPC64LE ;; mips-*) seccomp_audit_arch=AUDIT_ARCH_MIPS ;; mipsel-*) seccomp_audit_arch=AUDIT_ARCH_MIPSEL ;; mips64-*) seccomp_audit_arch=AUDIT_ARCH_MIPS64 ;; mips64el-*) seccomp_audit_arch=AUDIT_ARCH_MIPSEL64 ;; 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 CPPFLAGS="$CPPFLAGS -D_OPENBSD_SOURCE" 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_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]) 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([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([setpflags]) 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([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_CHECK_DECL([VIS_ALL], , AC_DEFINE(BROKEN_STRNVIS, 1, [missing VIS_ALL]), [#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)], [ ldns="" if test "x$withval" = "xyes" ; then AC_PATH_TOOL([LDNSCONFIG], [ldns-config], [no]) if test "x$PKGCONFIG" = "xno"; then CPPFLAGS="$CPPFLAGS -I${withval}/include" LDFLAGS="$LDFLAGS -L${withval}/lib" LIBS="-lldns $LIBS" ldns=yes else LIBS="$LIBS `$LDNSCONFIG --libs`" CPPFLAGS="$CPPFLAGS `$LDNSCONFIG --cflags`" fi elif test "x$withval" != "xno" ; then CPPFLAGS="$CPPFLAGS -I${withval}/include" LDFLAGS="$LDFLAGS -L${withval}/lib" LIBS="-lldns $LIBS" ldns=yes fi # Verify that it works. if test "x$ldns" = "xyes" ; then AC_DEFINE(HAVE_LDNS, 1, [Define if you want ldns support]) 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 \ err \ errx \ 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 \ llabs \ login_getcapbool \ md5_crypt \ memmove \ memset_s \ mkdtemp \ 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 \ strcasestr \ 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 \ warn \ ]) dnl Wide character support. AC_CHECK_FUNCS([mblen mbtowc nl_langinfo wcwidth]) TEST_SSH_UTF8=${TEST_SSH_UTF8:=yes} AC_MSG_CHECKING([for utf8 locale support]) AC_RUN_IFELSE( [AC_LANG_PROGRAM([[ #include #include ]], [[ char *loc = setlocale(LC_CTYPE, "en_US.UTF-8"); if (loc != NULL) exit(0); exit(1); ]])], AC_MSG_RESULT(yes), [AC_MSG_RESULT(no) TEST_SSH_UTF8=no], AC_MSG_WARN([cross compiling: assuming yes]) ) AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[ #include ]], [[ return (isblank('a')); ]])], [AC_DEFINE([HAVE_ISBLANK], [1], [Define if you have isblank(3C).]) ]) disable_pkcs11= AC_ARG_ENABLE([pkcs11], [ --disable-pkcs11 disable PKCS#11 support code [no]], [ if test "x$enableval" = "xno" ; then disable_pkcs11=1 fi ] ) # PKCS11 depends on OpenSSL. if test "x$openssl" = "xyes" && test "x$disable_pkcs11" = "x"; 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 dnl NetBSD added an strnvis and unfortunately made it incompatible with the dnl existing one in OpenBSD and Linux's libbsd (the former having existed dnl for over ten years). Despite this incompatibility being reported during dnl development (see http://gnats.netbsd.org/44977) they still shipped it. dnl Even more unfortunately FreeBSD and later MacOS picked up this incompatible dnl implementation. Try to detect this mess, and assume the only safe option dnl if we're cross compiling. dnl dnl OpenBSD, 2001: strnvis(char *dst, const char *src, size_t dlen, int flag); dnl NetBSD: 2012, strnvis(char *dst, size_t dlen, const char *src, int flag); if test "x$ac_cv_func_strnvis" = "xyes"; then AC_MSG_CHECKING([for working strnvis]) AC_RUN_IFELSE( [AC_LANG_PROGRAM([[ #include #include #include #include static void sighandler(int sig) { _exit(1); } ]], [[ char dst[16]; signal(SIGSEGV, sighandler); if (strnvis(dst, "src", 4, 0) && strcmp(dst, "src") == 0) exit(0); exit(1) ]])], [AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no]) AC_DEFINE([BROKEN_STRNVIS], [1], [strnvis detected broken])], [AC_MSG_WARN([cross compiling: assuming broken]) AC_DEFINE([BROKEN_STRNVIS], [1], [strnvis assumed broken])] ) 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, "%08lx (%s)\n", (unsigned long)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 10000*|0*) AC_MSG_ERROR([OpenSSL >= 1.0.1 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 ] ) AC_ARG_WITH([pam-service], [ --with-pam-service=name Specify PAM service name ], [ if test "x$withval" != "xno" && \ test "x$withval" != "xyes" ; then AC_DEFINE_UNQUOTED([SSHD_PAM_SERVICE], ["$withval"], [sshd PAM service name]) 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_TOOL([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_SSH_UTF8], [$TEST_SSH_UTF8]) 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 " libldns support: $LDNS_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.5p1/contrib004075500017500001750000000000001306364033700130455ustar00djmdjmopenssh-7.5p1/contrib/Makefile010064400017500001750000000012701306364033700145610ustar00djmdjmPKG_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` gnome-ssh-askpass3: gnome-ssh-askpass2.c $(CC) $(CFLAGS) `$(PKG_CONFIG) --cflags gtk+-3.0` \ gnome-ssh-askpass2.c -o gnome-ssh-askpass3 \ `$(PKG_CONFIG) --libs gtk+-3.0 x11` clean: rm -f *.o gnome-ssh-askpass gnome-ssh-askpass[123] openssh-7.5p1/contrib/README010064400017500001750000000033601306364033700140030ustar00djmdjmOther 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.5p1/contrib/aix004075500017500001750000000000001306364033700136265ustar00djmdjmopenssh-7.5p1/contrib/aix/README010064400017500001750000000025101306364033700145600ustar00djmdjmOverview: 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.5p1/contrib/aix/buildbff.sh010075500017500001750000000224561306364033700160270ustar00djmdjm#!/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.5p1/contrib/aix/inventory.sh010075500017500001750000000031251306364033700162770ustar00djmdjm#!/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.5p1/contrib/aix/pam.conf010064400017500001750000000012741306364033700153320ustar00djmdjm# # 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.5p1/contrib/cygwin004075500017500001750000000000001306364033700143455ustar00djmdjmopenssh-7.5p1/contrib/cygwin/Makefile010064400017500001750000000061051306364033700160630ustar00djmdjmsrcdir=../.. 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.5p1/contrib/cygwin/README010064400017500001750000000060101306364033700152760ustar00djmdjmThis 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. --name -N sshd windows service name. --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.5p1/contrib/cygwin/ssh-host-config010064400017500001750000000541151306364033700173650ustar00djmdjm#!/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 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 # Try to create ssshd user account # ====================================================================== sshd_privsep() { local ret=0 if [ "${sshd_config_configured}" != "yes" ] then if ! csih_create_unprivileged_user sshd then csih_error_recoverable "Could not create user 'sshd'!" csih_error_recoverable "You will not be able to run an sshd service" csih_error_recoverable "under a privileged account successfully." csih_error_recoverable "Make sure to create a non-privileged user 'sshd'" csih_error_recoverable "manually before trying to run the service!" let ++ret 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 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 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.5p1/contrib/cygwin/ssh-user-config010064400017500001750000000177411306364033700173720ustar00djmdjm#!/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.5p1/contrib/cygwin/sshd-inetd010064400017500001750000000003001306364033700163770ustar00djmdjm# 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.5p1/contrib/findssl.sh010064400017500001750000000113711306364033700151220ustar00djmdjm#!/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.5p1/contrib/gnome-ssh-askpass1.c010064400017500001750000000125401306364033700167130ustar00djmdjm/* * 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.5p1/contrib/gnome-ssh-askpass2.c010064400017500001750000000145711306364033700167220ustar00djmdjm/* * 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 (GtkWidget *parent_window, const char *what) { GtkWidget *err; err = gtk_message_dialog_new(GTK_WINDOW(parent_window), 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_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 *parent_window, *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; /* Create an invisible parent window so that GtkDialog doesn't * complain. */ parent_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); dialog = gtk_message_dialog_new(GTK_WINDOW(parent_window), 0, GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL, "%s", message); entry = gtk_entry_new(); gtk_box_pack_start( GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), 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); /* 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_get_window(GTK_WIDGET(dialog))), 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_get_window(GTK_WIDGET(dialog)), 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_x11_get_default_xdisplay()); 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_x11_get_default_xdisplay()); gtk_widget_destroy(dialog); report_failed_grab(parent_window, 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.5p1/contrib/hpux004075500017500001750000000000001306364033700140315ustar00djmdjmopenssh-7.5p1/contrib/hpux/README010064400017500001750000000021641306364033700147700ustar00djmdjmREADME 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.5p1/contrib/hpux/egd010064400017500001750000000006051306364033700145700ustar00djmdjm# 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.5p1/contrib/hpux/egd.rc010075500017500001750000000042471306364033700152040ustar00djmdjm#!/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.5p1/contrib/hpux/sshd010064400017500001750000000001731306364033700147720ustar00djmdjm# 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.5p1/contrib/hpux/sshd.rc010075500017500001750000000036661306364033700154120ustar00djmdjm#!/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.5p1/contrib/redhat004075500017500001750000000000001306364033700143145ustar00djmdjmopenssh-7.5p1/contrib/redhat/gnome-ssh-askpass.csh010064400017500001750000000000721306364033700204310ustar00djmdjmsetenv SSH_ASKPASS /usr/libexec/openssh/gnome-ssh-askpass openssh-7.5p1/contrib/redhat/gnome-ssh-askpass.sh010064400017500001750000000001061306364033700202640ustar00djmdjmSSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass export SSH_ASKPASS openssh-7.5p1/contrib/redhat/openssh.spec010064400017500001750000000700071306364033700167270ustar00djmdjm%define ver 7.5p1 %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: https://www.openssh.com/portable.html Source0: https://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 %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.5p1/contrib/redhat/sshd.init010075500017500001750000000033461306364033700162270ustar00djmdjm#!/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.5p1/contrib/redhat/sshd.init.old010075500017500001750000000057721306364033700170110ustar00djmdjm#!/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.5p1/contrib/redhat/sshd.pam010064400017500001750000000004251306364033700160310ustar00djmdjm#%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.5p1/contrib/redhat/sshd.pam.old010064400017500001750000000006321306364033700166060ustar00djmdjm#%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.5p1/contrib/solaris004075500017500001750000000000001306364033700145215ustar00djmdjmopenssh-7.5p1/contrib/solaris/README010064400017500001750000000024461306364033700154630ustar00djmdjmThe 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.5p1/contrib/ssh-copy-id010064400017500001750000000242041306364033700152050ustar00djmdjm#!/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.5p1/contrib/ssh-copy-id.1010064400017500001750000000146311306364033700153470ustar00djmdjm.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.5p1/contrib/sshd.pam.freebsd010064400017500001750000000002671306364033700161770ustar00djmdjmsshd 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.5p1/contrib/sshd.pam.generic010064400017500001750000000006321306364033700161750ustar00djmdjm#%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.5p1/contrib/suse004075500017500001750000000000001306364033700140245ustar00djmdjmopenssh-7.5p1/contrib/suse/openssh.spec010064400017500001750000000210211306364033700164270ustar00djmdjm# 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.5p1 URL: https://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(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(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.5p1/contrib/suse/rc.config.sshd010064400017500001750000000000751306364033700166350ustar00djmdjm# # Start the Secure Shell (SSH) Daemon? # START_SSHD="yes" openssh-7.5p1/contrib/suse/rc.sshd010064400017500001750000000061421306364033700153720ustar00djmdjm#! /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.5p1/contrib/suse/sysconfig.ssh010064400017500001750000000002421306364033700166210ustar00djmdjm## Path: Network/Remote access/SSH ## Description: SSH server settings ## Type: string ## Default: "" ## ServiceRestart: sshd # # Options for sshd # SSHD_OPTS="" openssh-7.5p1/crc32.c010064400017500001750000000116611306364033700125460ustar00djmdjm/* $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.5p1/crc32.h010064400017500001750000000027031306364033700125500ustar00djmdjm/* $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.5p1/crypto_api.h010064400017500001750000000024421306364033700140050ustar00djmdjm/* $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.5p1/deattack.c010064400017500001750000000101471306364033700134100ustar00djmdjm/* $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.5p1/deattack.h010064400017500001750000000020621306364033700134120ustar00djmdjm/* $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.5p1/defines.h010064400017500001750000000533611306364033700132570ustar00djmdjm/* * 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 /* 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 /* * Cygwin doesn't really have a notion of reserved ports. It is still * is useful on the client side so for compatibility it defines as 1024 via * netinet/in.h inside an enum. We * don't actually want that restriction * so we want to set that to zero, but we can't do it direct in config.h * because it'll cause a conflicting definition the first time we include * netinet/in.h. */ #ifdef HAVE_CYGWIN #define IPPORT_RESERVED 0 #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 /* * We want functions in openbsd-compat, if enabled, to override system ones. * We no-op out the weak symbol definition rather than remove it to reduce * future sync problems. */ #define DEF_WEAK(x) /* * 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.5p1/dh.c010064400017500001750000000351101306364033700122200ustar00djmdjm/* $OpenBSD: dh.c,v 1.62 2016/12/15 21:20:41 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 #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) { logit("WARNING: could not open %s (%s), using fixed modulus", _PATH_DH_MODULI, strerror(errno)); 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_MODULI); 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_MODULI); 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 < 4) { logit("invalid public DH value (%d/%d)", bits_set, BN_num_bits(dh->p)); return 0; } return 1; } 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; if (need < 256) need = 256; /* * Pollard Rho, Big step/Little Step attacks are O(sqrt(n)), * so double requested need here. */ dh->length = MINIMUM(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); } /* rfc2409 "Second Oakley Group" (1024 bits) */ 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)); } /* rfc3526 group 14 "2048-bit MODP Group" */ 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)); } /* rfc3526 group 16 "4096-bit MODP Group" */ DH * dh_new_group16(void) { 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"; return (dh_new_group_asc(gen, group16)); } /* rfc3526 group 18 "8192-bit MODP Group" */ DH * dh_new_group18(void) { 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" "34028492" "36C3FAB4" "D27C7026" "C1D4DCB2" "602646DE" "C9751E76" "3DBA37BD" "F8FF9406" "AD9E530E" "E5DB382F" "413001AE" "B06A53ED" "9027D831" "179727B0" "865A8918" "DA3EDBEB" "CF9B14ED" "44CE6CBA" "CED4BB1B" "DB7F1447" "E6CC254B" "33205151" "2BD7AF42" "6FB8F401" "378CD2BF" "5983CA01" "C64B92EC" "F032EA15" "D1721D03" "F482D7CE" "6E74FEF6" "D55E702F" "46980C82" "B5A84031" "900B1C9E" "59E7C97F" "BEC7E8F3" "23A97A7E" "36CC88BE" "0F1D45B7" "FF585AC5" "4BD407B2" "2B4154AA" "CC8F6D7E" "BF48E1D8" "14CC5ED2" "0F8037E0" "A79715EE" "F29BE328" "06A1D58B" "B7C5DA76" "F550AA3D" "8A1FBFF0" "EB19CCB1" "A313D55C" "DA56C9EC" "2EF29632" "387FE8D7" "6E3C0468" "043E8F66" "3F4860EE" "12BF2D5B" "0B7474D6" "E694F91E" "6DBE1159" "74A3926F" "12FEE5E4" "38777CB6" "A932DF8C" "D8BEC4D0" "73B931BA" "3BC832B6" "8D9DD300" "741FA7BF" "8AFC47ED" "2576F693" "6BA42466" "3AAB639C" "5AE4F568" "3423B474" "2BF1C978" "238F16CB" "E39D652D" "E3FDB8BE" "FC848AD9" "22222E04" "A4037C07" "13EB57A8" "1A23F0C7" "3473FC64" "6CEA306B" "4BCBC886" "2F8385DD" "FA9D4B7F" "A2C087E8" "79683303" "ED5BDD3A" "062B3CF5" "B3A278A6" "6D2A13F8" "3F44F82D" "DF310EE0" "74AB6A36" "4597E899" "A0255DC1" "64F31CC5" "0846851D" "F9AB4819" "5DED7EA1" "B1D510BD" "7EE74D73" "FAF36BC3" "1ECFA268" "359046F4" "EB879F92" "4009438B" "481C6CD7" "889A002E" "D5EE382B" "C9190DA6" "FC026E47" "9558E447" "5677E9AA" "9E3050E2" "765694DF" "C81F56E8" "80B96E71" "60C980DD" "98EDD3DF" "FFFFFFFF" "FFFFFFFF"; return (dh_new_group_asc(gen, group16)); } /* Select fallback group used by DH-GEX if moduli file cannot be read. */ DH * dh_new_group_fallback(int max) { debug3("%s: requested max size %d", __func__, max); if (max < 3072) { debug3("using 2k bit group 14"); return dh_new_group14(); } else if (max < 6144) { debug3("using 4k bit group 16"); return dh_new_group16(); } debug3("using 8k bit group 18"); return dh_new_group18(); } /* * 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.5p1/dh.h010064400017500001750000000051171306364033700122310ustar00djmdjm/* $OpenBSD: dh.h,v 1.15 2016/05/02 10:26:04 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_group16(void); DH *dh_new_group18(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.5p1/digest-libc.c010064400017500001750000000136211306364033700140160ustar00djmdjm/* $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.5p1/digest-openssl.c010064400017500001750000000117511306364033700145720ustar00djmdjm/* $OpenBSD: digest-openssl.c,v 1.6 2017/03/10 02:59:51 dtucker 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 (digest == NULL || 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.5p1/digest.h010064400017500001750000000050521306364033700131130ustar00djmdjm/* $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.5p1/dispatch.c010064400017500001750000000072761306364033700134400ustar00djmdjm/* $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.5p1/dispatch.h010064400017500001750000000044631306364033700134400ustar00djmdjm/* $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.5p1/dns.c010064400017500001750000000220541306364033700124140ustar00djmdjm/* $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.5p1/dns.h010064400017500001750000000040051306364033700124150ustar00djmdjm/* $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.5p1/ed25519.c010064400017500001750000000061431306364033700126270ustar00djmdjm/* $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.5p1/entropy.h010064400017500001750000000027351306364033700133410ustar00djmdjm/* * 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. */ #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.5p1/fatal.c010064400017500001750000000032051306364033700127140ustar00djmdjm/* $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.5p1/fe25519.c010064400017500001750000000202121306364033700126220ustar00djmdjm/* $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.5p1/fe25519.h010064400017500001750000000044741306364033700126430ustar00djmdjm/* $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.5p1/fixalgorithms010075500017500001750000000006461306364033700142750ustar00djmdjm#!/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.5p1/fixpaths010075500017500001750000000007631306364033700132430ustar00djmdjm#!/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.5p1/fixprogs010075500017500001750000000031201306364033700132440ustar00djmdjm#!/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.5p1/ge25519.c010064400017500001750000000260561306364033700126370ustar00djmdjm/* $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.5p1/ge25519.h010064400017500001750000000025501306364033700126350ustar00djmdjm/* $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.5p1/ge25519_base.data010064400017500001750000005111601306364033700143130ustar00djmdjm/* $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.5p1/groupaccess.c010064400017500001750000000065501306364033700141510ustar00djmdjm/* $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.5p1/groupaccess.h010064400017500001750000000030421306364033700141470ustar00djmdjm/* $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.5p1/gss-genr.c010064400017500001750000000164711306364033700133630ustar00djmdjm/* $OpenBSD: gss-genr.c,v 1.24 2016/09/12 01:22:38 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 "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.5p1/gss-serv-krb5.c010064400017500001750000000132161306364033700142420ustar00djmdjm/* $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.5p1/gss-serv.c010064400017500001750000000241751306364033700134070ustar00djmdjm/* $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.5p1/hash.c010064400017500001750000000035121306364033700125510ustar00djmdjm/* $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.5p1/hmac.c010064400017500001750000000121201306364033700125310ustar00djmdjm/* $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.5p1/hmac.h010064400017500001750000000031761306364033700125510ustar00djmdjm/* $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.5p1/hostfile.c010064400017500001750000000545321306364033700134530ustar00djmdjm/* $OpenBSD: hostfile.c,v 1.68 2017/03/10 04:26:06 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 len; len = ssh_digest_bytes(SSH_DIGEST_SHA1); if (name_from_hostfile == NULL) { /* Create new salt */ arc4random_buf(salt, len); } 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, *lhost; lhost = xstrdup(host); lowercase(lhost); if (store_hash) { if ((hashed_host = host_hash(lhost, NULL, 0)) == NULL) { error("%s: host_hash failed", __func__); free(lhost); return 0; } fprintf(f, "%s ", hashed_host); } else if (ip != NULL) fprintf(f, "%s,%s ", lhost, ip); else { fprintf(f, "%s ", lhost); } free(lhost); 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.5p1/hostfile.h010064400017500001750000000074661306364033700134640ustar00djmdjm/* $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.5p1/includes.h010064400017500001750000000074231306364033700134460ustar00djmdjm/* $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.5p1/install-sh010075500017500001750000000127221306364033700134710ustar00djmdjm#!/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.5p1/kex.c010064400017500001750000000636611306364033700124300ustar00djmdjm/* $OpenBSD: kex.c,v 1.131 2017/03/15 07:07:39 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. */ #include "includes.h" #include #include #include #include #include #ifdef WITH_OPENSSL #include #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_SHA1, KEX_DH_GRP14_SHA1, 0, SSH_DIGEST_SHA1 }, { KEX_DH14_SHA256, KEX_DH_GRP14_SHA256, 0, SSH_DIGEST_SHA256 }, { KEX_DH16_SHA512, KEX_DH_GRP16_SHA512, 0, SSH_DIGEST_SHA512 }, { KEX_DH18_SHA512, KEX_DH_GRP18_SHA512, 0, SSH_DIGEST_SHA512 }, { 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 }, { KEX_CURVE25519_SHA256_OLD, 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, *m; 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 ((m = match_list(ret, p, NULL)) != NULL) { free(m); 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 or '-' that the * specified names should be removed. */ 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 == '+') { if ((ret = kex_names_cat(def, *list + 1)) == NULL) return SSH_ERR_ALLOC_FAIL; free(*list); *list = ret; } else if (**list == '-') { if ((ret = match_filter_list(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); } static int kex_send_ext_info(struct ssh *ssh) { int r; char *algs; if ((algs = sshkey_alg_list(0, 1, 1, ',')) == NULL) return SSH_ERR_ALLOC_FAIL; 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, algs)) != 0 || (r = sshpkt_send(ssh)) != 0) goto out; /* success */ r = 0; out: free(algs); return r; } 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); ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit); if ((r = sshpkt_get_end(ssh)) != 0) return r; if ((r = ssh_set_newkeys(ssh, MODE_IN)) != 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; ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, NULL); 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); ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit); 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) { free(name); 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) { free(name); 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 { free(name); 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); kex->ext_info_c = (ext != NULL); 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 = MAXIMUM(need, newkeys->enc.key_len); need = MAXIMUM(need, newkeys->enc.block_size); need = MAXIMUM(need, newkeys->enc.iv_len); need = MAXIMUM(need, newkeys->mac.key_len); dh_need = MAXIMUM(dh_need, cipher_seclen(newkeys->enc.cipher)); dh_need = MAXIMUM(dh_need, newkeys->enc.block_size); dh_need = MAXIMUM(dh_need, newkeys->enc.iv_len); dh_need = MAXIMUM(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.5p1/kex.h010064400017500001750000000165231306364033700124300ustar00djmdjm/* $OpenBSD: kex.h,v 1.81 2016/09/28 21:44: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 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_SHA1 "diffie-hellman-group14-sha1" #define KEX_DH14_SHA256 "diffie-hellman-group14-sha256" #define KEX_DH16_SHA512 "diffie-hellman-group16-sha512" #define KEX_DH18_SHA512 "diffie-hellman-group18-sha512" #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" #define KEX_CURVE25519_SHA256_OLD "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_GRP14_SHA256, KEX_DH_GRP16_SHA512, KEX_DH_GRP18_SHA512, 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(int, 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 u_char *, size_t, const u_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.5p1/kexc25519.c010064400017500001750000000111671306364033700131730ustar00djmdjm/* $OpenBSD: kexc25519.c,v 1.10 2016/05/02 08:49:03 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 u_char *ckexinit, size_t ckexinitlen, const u_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.5p1/kexc25519c.c010064400017500001750000000121531306364033700133320ustar00djmdjm/* $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.5p1/kexc25519s.c010064400017500001750000000120111306364033700133430ustar00djmdjm/* $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.5p1/kexdh.c010064400017500001750000000063501306364033700127340ustar00djmdjm/* $OpenBSD: kexdh.c,v 1.26 2016/05/02 10:26:04 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 "ssh2.h" #include "sshkey.h" #include "cipher.h" #include "kex.h" #include "ssherr.h" #include "sshbuf.h" #include "digest.h" int kex_dh_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, 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(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_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(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 /* WITH_OPENSSL */ openssh-7.5p1/kexdhc.c010064400017500001750000000140171306364033700130760ustar00djmdjm/* $OpenBSD: kexdhc.c,v 1.19 2016/05/02 10:26:04 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: case KEX_DH_GRP14_SHA256: kex->dh = dh_new_group14(); break; case KEX_DH_GRP16_SHA512: kex->dh = dh_new_group16(); break; case KEX_DH_GRP18_SHA512: kex->dh = dh_new_group18(); 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->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->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.5p1/kexdhs.c010064400017500001750000000140771306364033700131240ustar00djmdjm/* $OpenBSD: kexdhs.c,v 1.24 2016/05/02 10:26:04 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 "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: case KEX_DH_GRP14_SHA256: kex->dh = dh_new_group14(); break; case KEX_DH_GRP16_SHA512: kex->dh = dh_new_group16(); break; case KEX_DH_GRP18_SHA512: kex->dh = dh_new_group18(); 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->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, 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.5p1/kexecdh.c010064400017500001750000000067721306364033700132540ustar00djmdjm/* $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.5p1/kexecdhc.c010064400017500001750000000144631306364033700134130ustar00djmdjm/* $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.5p1/kexecdhs.c010064400017500001750000000140261306364033700134260ustar00djmdjm/* $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.5p1/kexgex.c010064400017500001750000000072031306364033700131220ustar00djmdjm/* $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.5p1/kexgexc.c010064400017500001750000000171551306364033700132740ustar00djmdjm/* $OpenBSD: kexgexc.c,v 1.23 2016/09/12 01:22:38 deraadt 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 "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" #include "misc.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 = MINIMUM(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.5p1/kexgexs.c010064400017500001750000000163601306364033700133110ustar00djmdjm/* $OpenBSD: kexgexs.c,v 1.30 2016/09/12 01:22:38 deraadt 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 "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" #include "misc.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 = MAXIMUM(DH_GRP_MIN, min); max = MINIMUM(DH_GRP_MAX, max); nbits = MAXIMUM(DH_GRP_MIN, nbits); nbits = MINIMUM(DH_GRP_MAX, nbits); if (kex->max < kex->min || kex->nbits < kex->min || kex->max < kex->nbits || kex->max < DH_GRP_MIN) { 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.5p1/key.c010064400017500001750000000206301306364033700124160ustar00djmdjm/* $OpenBSD: key.c,v 1.130 2016/05/02 09:36:42 djm 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, NULL)) != 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.5p1/key.h010064400017500001750000000100341306364033700124200ustar00djmdjm/* $OpenBSD: key.h,v 1.50 2016/09/12 23:31:27 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 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 **); #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.5p1/krl.c010064400017500001750000001036531306364033700124250ustar00djmdjm/* * 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.39 2017/03/10 07:18:32 dtucker Exp $ */ #include "includes.h" #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, MINIMUM(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 = MINIMUM(contig, 1ULL<<31); last_gap = MINIMUM(last_gap, 1ULL<<31); next_gap = MINIMUM(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 : MINIMUM(next_gap, 8+64)); cost_bitmap_restart += contig + (final ? 0 : MINIMUM(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_free(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: if (fd != -1) close(fd); sshbuf_free(krlbuf); ssh_krl_free(krl); if (r != 0) errno = oerrno; return r; } openssh-7.5p1/krl.h010064400017500001750000000050601306364033700124230ustar00djmdjm/* * 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.5p1/log.c010064400017500001750000000251541306364033700124150ustar00djmdjm/* $OpenBSD: log.c,v 1.49 2017/03/10 03:15:58 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) 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); } void logdie(const char *fmt,...) { va_list args; va_start(args, fmt); do_log(SYSLOG_LEVEL_INFO, fmt, args); va_end(args); cleanup_exit(255); } /* 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 && log_stderr_fd == STDERR_FILENO; } /* 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", (int)sizeof msgbuf - 3, 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.5p1/log.h010064400017500001750000000051661306364033700124230ustar00djmdjm/* $OpenBSD: log.h,v 1.21 2016/07/15 05:01:58 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 logdie(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.5p1/loginrec.c010064400017500001750000001237521306364033700134410ustar00djmdjm/* * 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.5p1/loginrec.h010064400017500001750000000111501306364033700134320ustar00djmdjm#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.5p1/logintest.c010064400017500001750000000211241306364033700136350ustar00djmdjm/* * 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.5p1/mac.c010064400017500001750000000170411306364033700123700ustar00djmdjm/* $OpenBSD: mac.c,v 1.33 2016/07/08 03:44:42 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 "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 }, #ifdef HAVE_EVP_RIPEMD160 { "hmac-ripemd160", SSH_DIGEST, SSH_DIGEST_RIPEMD160, 0, 0, 0, 0 }, { "hmac-ripemd160@openssh.com", SSH_DIGEST, SSH_DIGEST_RIPEMD160, 0, 0, 0, 0 }, #endif { "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 }, #ifdef HAVE_EVP_RIPEMD160 { "hmac-ripemd160-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_RIPEMD160, 0, 0, 0, 1 }, #endif { "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; } int mac_check(struct sshmac *mac, u_int32_t seqno, const u_char *data, size_t dlen, const u_char *theirmac, size_t mlen) { u_char ourmac[SSH_DIGEST_MAX_LENGTH]; int r; if (mac->mac_len > mlen) return SSH_ERR_INVALID_ARGUMENT; if ((r = mac_compute(mac, seqno, data, dlen, ourmac, sizeof(ourmac))) != 0) return r; if (timingsafe_bcmp(ourmac, theirmac, mac->mac_len) != 0) return SSH_ERR_MAC_INVALID; 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.5p1/mac.h010064400017500001750000000037251306364033700124010ustar00djmdjm/* $OpenBSD: mac.h,v 1.10 2016/07/08 03:44:42 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. */ #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); int mac_check(struct sshmac *, u_int32_t, const u_char *, size_t, const u_char *, size_t); void mac_clear(struct sshmac *); #endif /* SSHMAC_H */ openssh-7.5p1/match.c010064400017500001750000000206221306364033700127230ustar00djmdjm/* $OpenBSD: match.c,v 1.37 2017/03/10 04:24:55 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 #include "xmalloc.h" #include "match.h" #include "misc.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, then skip it. */ 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) { char *hostcopy = xstrdup(host); int r; lowercase(hostcopy); r = match_pattern_list(hostcopy, pattern, 1); free(hostcopy); return r; } /* * 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; if ((mip = addr_match_list(ipaddr, patterns)) == -2) return -1; /* error in ipaddr match */ else if (host == NULL || ipaddr == NULL || mip == -1) return 0; /* negative ip address match, or testing pattern */ /* 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. * If user, host and ipaddr are all NULL then validate pattern/ * Returns -1 on invalid pattern, 0 on no match, 1 on match. */ int match_user(const char *user, const char *host, const char *ipaddr, const char *pattern) { char *p, *pat; int ret; /* test mode */ if (user == NULL && host == NULL && ipaddr == NULL) { if ((p = strchr(pattern, '@')) != NULL && match_host_and_ip(NULL, NULL, p + 1) < 0) return -1; return 0; } 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; } /* * Filters a comma-separated list of strings, excluding any entry matching * the 'filter' pattern list. Caller must free returned string. */ char * match_filter_list(const char *proposal, const char *filter) { size_t len = strlen(proposal) + 1; char *fix_prop = malloc(len); char *orig_prop = strdup(proposal); char *cp, *tmp; if (fix_prop == NULL || orig_prop == NULL) { free(orig_prop); free(fix_prop); return NULL; } tmp = orig_prop; *fix_prop = '\0'; while ((cp = strsep(&tmp, ",")) != NULL) { if (match_pattern_list(cp, filter, 0) != 1) { if (*fix_prop != '\0') strlcat(fix_prop, ",", len); strlcat(fix_prop, cp, len); } } free(orig_prop); return fix_prop; } openssh-7.5p1/match.h010064400017500001750000000021461306364033700127310ustar00djmdjm/* $OpenBSD: match.h,v 1.17 2017/02/03 23:01:19 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 *); char *match_filter_list(const char *, const char *); /* addrmatch.c */ int addr_match_list(const char *, const char *); int addr_match_cidr_list(const char *, const char *); #endif openssh-7.5p1/md-sha256.c010064400017500001750000000043501306364033700132350ustar00djmdjm/* $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.5p1/md5crypt.c010064400017500001750000000100211306364033700133660ustar00djmdjm/* * ---------------------------------------------------------------------------- * "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.5p1/md5crypt.h010064400017500001750000000013501306364033700134000ustar00djmdjm/* * ---------------------------------------------------------------------------- * "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 * ---------------------------------------------------------------------------- */ #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.5p1/mdoc2man.awk010064400017500001750000000207061306364033700136720ustar00djmdjm#!/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.5p1/misc.c010064400017500001750000000653071306364033700125730ustar00djmdjm/* $OpenBSD: misc.c,v 1.109 2017/03/14 00:55:37 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); if (val < 0) { error("fcntl(%d, F_GETFL): %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); if (val < 0) { error("fcntl(%d, F_GETFL): %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, multiplier = 1; 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': multiplier = MINUTES; break; case 'h': case 'H': multiplier = HOURS; break; case 'd': case 'D': multiplier = DAYS; break; case 'w': case 'W': multiplier = WEEKS; break; default: return -1; } if (secs >= LONG_MAX / multiplier) return -1; secs *= multiplier; if (total >= LONG_MAX - secs) 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; } /* * Parse a [user@]host[:port] string. * Caller must free returned user and host. * Any of the pointer return arguments may be NULL (useful for syntax checking). * If user was not specified then *userp will be set to NULL. * If port was not specified then *portp will be -1. * Returns 0 on success, -1 on failure. */ int parse_user_host_port(const char *s, char **userp, char **hostp, int *portp) { char *sdup, *cp, *tmp; char *user = NULL, *host = NULL; int port = -1, ret = -1; if (userp != NULL) *userp = NULL; if (hostp != NULL) *hostp = NULL; if (portp != NULL) *portp = -1; if ((sdup = tmp = strdup(s)) == NULL) return -1; /* Extract optional username */ if ((cp = strchr(tmp, '@')) != NULL) { *cp = '\0'; if (*tmp == '\0') goto out; if ((user = strdup(tmp)) == NULL) goto out; tmp = cp + 1; } /* Extract mandatory hostname */ if ((cp = hpdelim(&tmp)) == NULL || *cp == '\0') goto out; host = xstrdup(cleanhostname(cp)); /* Convert and verify optional port */ if (tmp != NULL && *tmp != '\0') { if ((port = a2port(tmp)) <= 0) goto out; } /* Success */ if (userp != NULL) { *userp = user; user = NULL; } if (hostp != NULL) { *hostp = host; host = NULL; } if (portp != NULL) *portp = port; ret = 0; out: free(sdup); free(user); free(host); return ret; } /* 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 <= STDERR_FILENO) { /* Only populate closed fds. */ if (fcntl(dupfd, F_GETFL) == -1 && errno == EBADF) { if (dup2(nullfd, dupfd) == -1) { fprintf(stderr, "dup2: %s\n", strerror(errno)); exit(1); } } } if (nullfd > STDERR_FILENO) 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); } double monotime_double(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 + (double)ts.tv_nsec / 1000000000); #endif #if defined(CLOCK_MONOTONIC) if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) return (ts.tv_sec + (double)ts.tv_nsec / 1000000000); #endif debug3("clock_gettime: %s", strerror(errno)); gettime_failed = 1; } #endif /* HAVE_CLOCK_GETTIME && (CLOCK_MONOTONIC || CLOCK_BOOTTIME */ return (double)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 } /* * Compares two strings that maybe be NULL. Returns non-zero if strings * are both NULL or are identical, returns zero otherwise. */ static int strcmp_maybe_null(const char *a, const char *b) { if ((a == NULL && b != NULL) || (a != NULL && b == NULL)) return 0; if (a != NULL && strcmp(a, b) != 0) return 0; return 1; } /* * Compare two forwards, returning non-zero if they are identical or * zero otherwise. */ int forward_equals(const struct Forward *a, const struct Forward *b) { if (strcmp_maybe_null(a->listen_host, b->listen_host) == 0) return 0; if (a->listen_port != b->listen_port) return 0; if (strcmp_maybe_null(a->listen_path, b->listen_path) == 0) return 0; if (strcmp_maybe_null(a->connect_host, b->connect_host) == 0) return 0; if (a->connect_port != b->connect_port) return 0; if (strcmp_maybe_null(a->connect_path, b->connect_path) == 0) return 0; /* allocated_port and handle are not checked */ return 1; } /* returns 1 if bind to specified port by specified user is permitted */ int bind_permitted(int port, uid_t uid) { if (port < IPPORT_RESERVED && uid != 0) return 0; return 1; } /* returns 1 if process is already daemonized, 0 otherwise */ int daemonized(void) { int fd; if ((fd = open(_PATH_TTY, O_RDONLY | O_NOCTTY)) >= 0) { close(fd); return 0; /* have controlling terminal */ } if (getppid() != 1) return 0; /* parent is not init */ if (getsid(0) != getpid()) return 0; /* not session leader */ debug3("already daemonized"); return 1; } openssh-7.5p1/misc.h010064400017500001750000000114551306364033700125730ustar00djmdjm/* $OpenBSD: misc.h,v 1.61 2016/11/30 00:28:31 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 _MISC_H #define _MISC_H #include /* 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 */ }; int forward_equals(const struct Forward *, const struct Forward *); int bind_permitted(int, uid_t); int daemonized(void); /* 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 *); int parse_user_host_port(const char *, char **, char **, int *); 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); double monotime_double(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 *); #define MINIMUM(a, b) (((a) < (b)) ? (a) : (b)) #define MAXIMUM(a, b) (((a) > (b)) ? (a) : (b)) #define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y)) #endif /* _MISC_H */ openssh-7.5p1/mkinstalldirs010075500017500001750000000012631306364033700142710ustar00djmdjm#! /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.5p1/moduli010064400017500001750000020703411306364033700127040ustar00djmdjm# $OpenBSD: moduli,v 1.18 2016/08/11 01:42:11 dtucker Exp $ # Time Type Tests Tries Size Generator Modulus 20160301052556 2 6 100 2047 5 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D19F4647 20160301052601 2 6 100 2047 2 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D1A5C13B 20160301052612 2 6 100 2047 5 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D1B7A3EF 20160301052620 2 6 100 2047 2 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D1C4C33B 20160301052628 2 6 100 2047 2 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D1CFFACB 20160301052645 2 6 100 2047 2 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D1F31D8B 20160301052703 2 6 100 2047 2 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D218C293 20160301052723 2 6 100 2047 2 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D24116E3 20160301052732 2 6 100 2047 2 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D25321F3 20160301052741 2 6 100 2047 2 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D260D8E3 20160301052748 2 6 100 2047 2 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D26CD3D3 20160301052756 2 6 100 2047 2 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D2791F7B 20160301052823 2 6 100 2047 2 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D2B71133 20160301052827 2 6 100 2047 2 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D2BABBA3 20160301052832 2 6 100 2047 5 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D2BFC957 20160301052931 2 6 100 2047 5 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D3514117 20160301053017 2 6 100 2047 5 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D3BF91F7 20160301053037 2 6 100 2047 5 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D3E9113F 20160301053101 2 6 100 2047 2 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D41BFA83 20160301053129 2 6 100 2047 5 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D45A369F 20160301053217 2 6 100 2047 2 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D4CB8683 20160301053222 2 6 100 2047 2 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D4D01463 20160301053251 2 6 100 2047 2 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D50F62C3 20160301053309 2 6 100 2047 5 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D5351887 20160301053333 2 6 100 2047 2 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D568358B 20160301053350 2 6 100 2047 5 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D58AA31F 20160301053359 2 6 100 2047 2 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D5991AF3 20160301053438 2 6 100 2047 5 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D5F65E07 20160301053523 2 6 100 2047 2 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D65F37D3 20160301053556 2 6 100 2047 2 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D6AB7E73 20160301053608 2 6 100 2047 2 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D6C131CB 20160301053631 2 6 100 2047 2 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D6F18A93 20160301053647 2 6 100 2047 5 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D7132B7F 20160301053724 2 6 100 2047 2 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D76995EB 20160301053743 2 6 100 2047 2 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D793D27B 20160301053757 2 6 100 2047 2 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D7AE856B 20160301053820 2 6 100 2047 5 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D7E1810F 20160301053828 2 6 100 2047 2 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D7EC09EB 20160301053831 2 6 100 2047 2 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D7ECC2FB 20160301053958 2 6 100 2047 2 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D8B829CB 20160301054042 2 6 100 2047 2 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D91CFCF3 20160301054134 2 6 100 2047 2 F030C513D5C6694FB09539ECF9D8290608A96280EDDEB74FD66DD43CACE3A5BFD6BC4F02EF38E44F68296DA50091214D9E6C518D715D76E19CCCA0578886B93ADA36E8AFDC23B311DA04EB8AC2FF31F3B87BD27C283519DF9CFCAA9D4EF822ECD2AD5593D3819399CEF3FAF0B786071496A9BD94164F739A2D1E0DEBB798BAEF0540B4388D3762523B68E100D6EE231DD95BEB4F4472E9E2236A24E0891DF5A19222A6C69D531C9E73DEF6ADAC84D61BC4EEA36E2A9FD64902461BFAF9BF81D699E141EE77A03996DC4586D3487A0E6189696C1D67F91E91595EB584AD1DF9EF5FC64160EAC3F2D88B4FB0E20A7925FE133D71EF9E1DD018101AAF251903103B 20160301054139 2 6 100 2047 2 F030C513D5C6694FB09539ECF9D8290608A96280EDDEB74FD66DD43CACE3A5BFD6BC4F02EF38E44F68296DA50091214D9E6C518D715D76E19CCCA0578886B93ADA36E8AFDC23B311DA04EB8AC2FF31F3B87BD27C283519DF9CFCAA9D4EF822ECD2AD5593D3819399CEF3FAF0B786071496A9BD94164F739A2D1E0DEBB798BAEF0540B4388D3762523B68E100D6EE231DD95BEB4F4472E9E2236A24E0891DF5A19222A6C69D531C9E73DEF6ADAC84D61BC4EEA36E2A9FD64902461BFAF9BF81D699E141EE77A03996DC4586D3487A0E6189696C1D67F91E91595EB584AD1DF9EF5FC64160EAC3F2D88B4FB0E20A7925FE133D71EF9E1DD018101AAF2519072B8B 20160301054157 2 6 100 2047 5 F030C513D5C6694FB09539ECF9D8290608A96280EDDEB74FD66DD43CACE3A5BFD6BC4F02EF38E44F68296DA50091214D9E6C518D715D76E19CCCA0578886B93ADA36E8AFDC23B311DA04EB8AC2FF31F3B87BD27C283519DF9CFCAA9D4EF822ECD2AD5593D3819399CEF3FAF0B786071496A9BD94164F739A2D1E0DEBB798BAEF0540B4388D3762523B68E100D6EE231DD95BEB4F4472E9E2236A24E0891DF5A19222A6C69D531C9E73DEF6ADAC84D61BC4EEA36E2A9FD64902461BFAF9BF81D699E141EE77A03996DC4586D3487A0E6189696C1D67F91E91595EB584AD1DF9EF5FC64160EAC3F2D88B4FB0E20A7925FE133D71EF9E1DD018101AAF25192F631F 20160301054207 2 6 100 2047 5 F030C513D5C6694FB09539ECF9D8290608A96280EDDEB74FD66DD43CACE3A5BFD6BC4F02EF38E44F68296DA50091214D9E6C518D715D76E19CCCA0578886B93ADA36E8AFDC23B311DA04EB8AC2FF31F3B87BD27C283519DF9CFCAA9D4EF822ECD2AD5593D3819399CEF3FAF0B786071496A9BD94164F739A2D1E0DEBB798BAEF0540B4388D3762523B68E100D6EE231DD95BEB4F4472E9E2236A24E0891DF5A19222A6C69D531C9E73DEF6ADAC84D61BC4EEA36E2A9FD64902461BFAF9BF81D699E141EE77A03996DC4586D3487A0E6189696C1D67F91E91595EB584AD1DF9EF5FC64160EAC3F2D88B4FB0E20A7925FE133D71EF9E1DD018101AAF25193F9E7F 20160301054213 2 6 100 2047 5 F030C513D5C6694FB09539ECF9D8290608A96280EDDEB74FD66DD43CACE3A5BFD6BC4F02EF38E44F68296DA50091214D9E6C518D715D76E19CCCA0578886B93ADA36E8AFDC23B311DA04EB8AC2FF31F3B87BD27C283519DF9CFCAA9D4EF822ECD2AD5593D3819399CEF3FAF0B786071496A9BD94164F739A2D1E0DEBB798BAEF0540B4388D3762523B68E100D6EE231DD95BEB4F4472E9E2236A24E0891DF5A19222A6C69D531C9E73DEF6ADAC84D61BC4EEA36E2A9FD64902461BFAF9BF81D699E141EE77A03996DC4586D3487A0E6189696C1D67F91E91595EB584AD1DF9EF5FC64160EAC3F2D88B4FB0E20A7925FE133D71EF9E1DD018101AAF2519475A1F 20160301054301 2 6 100 2047 5 F030C513D5C6694FB09539ECF9D8290608A96280EDDEB74FD66DD43CACE3A5BFD6BC4F02EF38E44F68296DA50091214D9E6C518D715D76E19CCCA0578886B93ADA36E8AFDC23B311DA04EB8AC2FF31F3B87BD27C283519DF9CFCAA9D4EF822ECD2AD5593D3819399CEF3FAF0B786071496A9BD94164F739A2D1E0DEBB798BAEF0540B4388D3762523B68E100D6EE231DD95BEB4F4472E9E2236A24E0891DF5A19222A6C69D531C9E73DEF6ADAC84D61BC4EEA36E2A9FD64902461BFAF9BF81D699E141EE77A03996DC4586D3487A0E6189696C1D67F91E91595EB584AD1DF9EF5FC64160EAC3F2D88B4FB0E20A7925FE133D71EF9E1DD018101AAF2519BA6807 20160301054320 2 6 100 2047 5 F030C513D5C6694FB09539ECF9D8290608A96280EDDEB74FD66DD43CACE3A5BFD6BC4F02EF38E44F68296DA50091214D9E6C518D715D76E19CCCA0578886B93ADA36E8AFDC23B311DA04EB8AC2FF31F3B87BD27C283519DF9CFCAA9D4EF822ECD2AD5593D3819399CEF3FAF0B786071496A9BD94164F739A2D1E0DEBB798BAEF0540B4388D3762523B68E100D6EE231DD95BEB4F4472E9E2236A24E0891DF5A19222A6C69D531C9E73DEF6ADAC84D61BC4EEA36E2A9FD64902461BFAF9BF81D699E141EE77A03996DC4586D3487A0E6189696C1D67F91E91595EB584AD1DF9EF5FC64160EAC3F2D88B4FB0E20A7925FE133D71EF9E1DD018101AAF2519E2FA7F 20160301054340 2 6 100 2047 2 F030C513D5C6694FB09539ECF9D8290608A96280EDDEB74FD66DD43CACE3A5BFD6BC4F02EF38E44F68296DA50091214D9E6C518D715D76E19CCCA0578886B93ADA36E8AFDC23B311DA04EB8AC2FF31F3B87BD27C283519DF9CFCAA9D4EF822ECD2AD5593D3819399CEF3FAF0B786071496A9BD94164F739A2D1E0DEBB798BAEF0540B4388D3762523B68E100D6EE231DD95BEB4F4472E9E2236A24E0891DF5A19222A6C69D531C9E73DEF6ADAC84D61BC4EEA36E2A9FD64902461BFAF9BF81D699E141EE77A03996DC4586D3487A0E6189696C1D67F91E91595EB584AD1DF9EF5FC64160EAC3F2D88B4FB0E20A7925FE133D71EF9E1DD018101AAF251A0CD913 20160301054413 2 6 100 2047 2 F030C513D5C6694FB09539ECF9D8290608A96280EDDEB74FD66DD43CACE3A5BFD6BC4F02EF38E44F68296DA50091214D9E6C518D715D76E19CCCA0578886B93ADA36E8AFDC23B311DA04EB8AC2FF31F3B87BD27C283519DF9CFCAA9D4EF822ECD2AD5593D3819399CEF3FAF0B786071496A9BD94164F739A2D1E0DEBB798BAEF0540B4388D3762523B68E100D6EE231DD95BEB4F4472E9E2236A24E0891DF5A19222A6C69D531C9E73DEF6ADAC84D61BC4EEA36E2A9FD64902461BFAF9BF81D699E141EE77A03996DC4586D3487A0E6189696C1D67F91E91595EB584AD1DF9EF5FC64160EAC3F2D88B4FB0E20A7925FE133D71EF9E1DD018101AAF251A5B8A43 20160301054511 2 6 100 2047 5 F030C513D5C6694FB09539ECF9D8290608A96280EDDEB74FD66DD43CACE3A5BFD6BC4F02EF38E44F68296DA50091214D9E6C518D715D76E19CCCA0578886B93ADA36E8AFDC23B311DA04EB8AC2FF31F3B87BD27C283519DF9CFCAA9D4EF822ECD2AD5593D3819399CEF3FAF0B786071496A9BD94164F739A2D1E0DEBB798BAEF0540B4388D3762523B68E100D6EE231DD95BEB4F4472E9E2236A24E0891DF5A19222A6C69D531C9E73DEF6ADAC84D61BC4EEA36E2A9FD64902461BFAF9BF81D699E141EE77A03996DC4586D3487A0E6189696C1D67F91E91595EB584AD1DF9EF5FC64160EAC3F2D88B4FB0E20A7925FE133D71EF9E1DD018101AAF251AE66597 20160301054527 2 6 100 2047 5 F030C513D5C6694FB09539ECF9D8290608A96280EDDEB74FD66DD43CACE3A5BFD6BC4F02EF38E44F68296DA50091214D9E6C518D715D76E19CCCA0578886B93ADA36E8AFDC23B311DA04EB8AC2FF31F3B87BD27C283519DF9CFCAA9D4EF822ECD2AD5593D3819399CEF3FAF0B786071496A9BD94164F739A2D1E0DEBB798BAEF0540B4388D3762523B68E100D6EE231DD95BEB4F4472E9E2236A24E0891DF5A19222A6C69D531C9E73DEF6ADAC84D61BC4EEA36E2A9FD64902461BFAF9BF81D699E141EE77A03996DC4586D3487A0E6189696C1D67F91E91595EB584AD1DF9EF5FC64160EAC3F2D88B4FB0E20A7925FE133D71EF9E1DD018101AAF251B03A57F 20160301054544 2 6 100 2047 2 F030C513D5C6694FB09539ECF9D8290608A96280EDDEB74FD66DD43CACE3A5BFD6BC4F02EF38E44F68296DA50091214D9E6C518D715D76E19CCCA0578886B93ADA36E8AFDC23B311DA04EB8AC2FF31F3B87BD27C283519DF9CFCAA9D4EF822ECD2AD5593D3819399CEF3FAF0B786071496A9BD94164F739A2D1E0DEBB798BAEF0540B4388D3762523B68E100D6EE231DD95BEB4F4472E9E2236A24E0891DF5A19222A6C69D531C9E73DEF6ADAC84D61BC4EEA36E2A9FD64902461BFAF9BF81D699E141EE77A03996DC4586D3487A0E6189696C1D67F91E91595EB584AD1DF9EF5FC64160EAC3F2D88B4FB0E20A7925FE133D71EF9E1DD018101AAF251B276FBB 20160301054548 2 6 100 2047 2 F030C513D5C6694FB09539ECF9D8290608A96280EDDEB74FD66DD43CACE3A5BFD6BC4F02EF38E44F68296DA50091214D9E6C518D715D76E19CCCA0578886B93ADA36E8AFDC23B311DA04EB8AC2FF31F3B87BD27C283519DF9CFCAA9D4EF822ECD2AD5593D3819399CEF3FAF0B786071496A9BD94164F739A2D1E0DEBB798BAEF0540B4388D3762523B68E100D6EE231DD95BEB4F4472E9E2236A24E0891DF5A19222A6C69D531C9E73DEF6ADAC84D61BC4EEA36E2A9FD64902461BFAF9BF81D699E141EE77A03996DC4586D3487A0E6189696C1D67F91E91595EB584AD1DF9EF5FC64160EAC3F2D88B4FB0E20A7925FE133D71EF9E1DD018101AAF251B2915B3 20160301054621 2 6 100 2047 2 F030C513D5C6694FB09539ECF9D8290608A96280EDDEB74FD66DD43CACE3A5BFD6BC4F02EF38E44F68296DA50091214D9E6C518D715D76E19CCCA0578886B93ADA36E8AFDC23B311DA04EB8AC2FF31F3B87BD27C283519DF9CFCAA9D4EF822ECD2AD5593D3819399CEF3FAF0B786071496A9BD94164F739A2D1E0DEBB798BAEF0540B4388D3762523B68E100D6EE231DD95BEB4F4472E9E2236A24E0891DF5A19222A6C69D531C9E73DEF6ADAC84D61BC4EEA36E2A9FD64902461BFAF9BF81D699E141EE77A03996DC4586D3487A0E6189696C1D67F91E91595EB584AD1DF9EF5FC64160EAC3F2D88B4FB0E20A7925FE133D71EF9E1DD018101AAF251B79A4BB 20160301054714 2 6 100 2047 5 F030C513D5C6694FB09539ECF9D8290608A96280EDDEB74FD66DD43CACE3A5BFD6BC4F02EF38E44F68296DA50091214D9E6C518D715D76E19CCCA0578886B93ADA36E8AFDC23B311DA04EB8AC2FF31F3B87BD27C283519DF9CFCAA9D4EF822ECD2AD5593D3819399CEF3FAF0B786071496A9BD94164F739A2D1E0DEBB798BAEF0540B4388D3762523B68E100D6EE231DD95BEB4F4472E9E2236A24E0891DF5A19222A6C69D531C9E73DEF6ADAC84D61BC4EEA36E2A9FD64902461BFAF9BF81D699E141EE77A03996DC4586D3487A0E6189696C1D67F91E91595EB584AD1DF9EF5FC64160EAC3F2D88B4FB0E20A7925FE133D71EF9E1DD018101AAF251BF77377 20160301054737 2 6 100 2047 2 F030C513D5C6694FB09539ECF9D8290608A96280EDDEB74FD66DD43CACE3A5BFD6BC4F02EF38E44F68296DA50091214D9E6C518D715D76E19CCCA0578886B93ADA36E8AFDC23B311DA04EB8AC2FF31F3B87BD27C283519DF9CFCAA9D4EF822ECD2AD5593D3819399CEF3FAF0B786071496A9BD94164F739A2D1E0DEBB798BAEF0540B4388D3762523B68E100D6EE231DD95BEB4F4472E9E2236A24E0891DF5A19222A6C69D531C9E73DEF6ADAC84D61BC4EEA36E2A9FD64902461BFAF9BF81D699E141EE77A03996DC4586D3487A0E6189696C1D67F91E91595EB584AD1DF9EF5FC64160EAC3F2D88B4FB0E20A7925FE133D71EF9E1DD018101AAF251C28D853 20160301054819 2 6 100 2047 2 F030C513D5C6694FB09539ECF9D8290608A96280EDDEB74FD66DD43CACE3A5BFD6BC4F02EF38E44F68296DA50091214D9E6C518D715D76E19CCCA0578886B93ADA36E8AFDC23B311DA04EB8AC2FF31F3B87BD27C283519DF9CFCAA9D4EF822ECD2AD5593D3819399CEF3FAF0B786071496A9BD94164F739A2D1E0DEBB798BAEF0540B4388D3762523B68E100D6EE231DD95BEB4F4472E9E2236A24E0891DF5A19222A6C69D531C9E73DEF6ADAC84D61BC4EEA36E2A9FD64902461BFAF9BF81D699E141EE77A03996DC4586D3487A0E6189696C1D67F91E91595EB584AD1DF9EF5FC64160EAC3F2D88B4FB0E20A7925FE133D71EF9E1DD018101AAF251C8C959B 20160301054844 2 6 100 2047 2 F030C513D5C6694FB09539ECF9D8290608A96280EDDEB74FD66DD43CACE3A5BFD6BC4F02EF38E44F68296DA50091214D9E6C518D715D76E19CCCA0578886B93ADA36E8AFDC23B311DA04EB8AC2FF31F3B87BD27C283519DF9CFCAA9D4EF822ECD2AD5593D3819399CEF3FAF0B786071496A9BD94164F739A2D1E0DEBB798BAEF0540B4388D3762523B68E100D6EE231DD95BEB4F4472E9E2236A24E0891DF5A19222A6C69D531C9E73DEF6ADAC84D61BC4EEA36E2A9FD64902461BFAF9BF81D699E141EE77A03996DC4586D3487A0E6189696C1D67F91E91595EB584AD1DF9EF5FC64160EAC3F2D88B4FB0E20A7925FE133D71EF9E1DD018101AAF251CC0A39B 20160301055002 2 6 100 2047 5 F030C513D5C6694FB09539ECF9D8290608A96280EDDEB74FD66DD43CACE3A5BFD6BC4F02EF38E44F68296DA50091214D9E6C518D715D76E19CCCA0578886B93ADA36E8AFDC23B311DA04EB8AC2FF31F3B87BD27C283519DF9CFCAA9D4EF822ECD2AD5593D3819399CEF3FAF0B786071496A9BD94164F739A2D1E0DEBB798BAEF0540B4388D3762523B68E100D6EE231DD95BEB4F4472E9E2236A24E0891DF5A19222A6C69D531C9E73DEF6ADAC84D61BC4EEA36E2A9FD64902461BFAF9BF81D699E141EE77A03996DC4586D3487A0E6189696C1D67F91E91595EB584AD1DF9EF5FC64160EAC3F2D88B4FB0E20A7925FE133D71EF9E1DD018101AAF251D7C0A9F 20160301055021 2 6 100 2047 5 F030C513D5C6694FB09539ECF9D8290608A96280EDDEB74FD66DD43CACE3A5BFD6BC4F02EF38E44F68296DA50091214D9E6C518D715D76E19CCCA0578886B93ADA36E8AFDC23B311DA04EB8AC2FF31F3B87BD27C283519DF9CFCAA9D4EF822ECD2AD5593D3819399CEF3FAF0B786071496A9BD94164F739A2D1E0DEBB798BAEF0540B4388D3762523B68E100D6EE231DD95BEB4F4472E9E2236A24E0891DF5A19222A6C69D531C9E73DEF6ADAC84D61BC4EEA36E2A9FD64902461BFAF9BF81D699E141EE77A03996DC4586D3487A0E6189696C1D67F91E91595EB584AD1DF9EF5FC64160EAC3F2D88B4FB0E20A7925FE133D71EF9E1DD018101AAF251DA0A72F 20160301055024 2 6 100 2047 5 F030C513D5C6694FB09539ECF9D8290608A96280EDDEB74FD66DD43CACE3A5BFD6BC4F02EF38E44F68296DA50091214D9E6C518D715D76E19CCCA0578886B93ADA36E8AFDC23B311DA04EB8AC2FF31F3B87BD27C283519DF9CFCAA9D4EF822ECD2AD5593D3819399CEF3FAF0B786071496A9BD94164F739A2D1E0DEBB798BAEF0540B4388D3762523B68E100D6EE231DD95BEB4F4472E9E2236A24E0891DF5A19222A6C69D531C9E73DEF6ADAC84D61BC4EEA36E2A9FD64902461BFAF9BF81D699E141EE77A03996DC4586D3487A0E6189696C1D67F91E91595EB584AD1DF9EF5FC64160EAC3F2D88B4FB0E20A7925FE133D71EF9E1DD018101AAF251DA1003F 20160301055029 2 6 100 2047 5 F030C513D5C6694FB09539ECF9D8290608A96280EDDEB74FD66DD43CACE3A5BFD6BC4F02EF38E44F68296DA50091214D9E6C518D715D76E19CCCA0578886B93ADA36E8AFDC23B311DA04EB8AC2FF31F3B87BD27C283519DF9CFCAA9D4EF822ECD2AD5593D3819399CEF3FAF0B786071496A9BD94164F739A2D1E0DEBB798BAEF0540B4388D3762523B68E100D6EE231DD95BEB4F4472E9E2236A24E0891DF5A19222A6C69D531C9E73DEF6ADAC84D61BC4EEA36E2A9FD64902461BFAF9BF81D699E141EE77A03996DC4586D3487A0E6189696C1D67F91E91595EB584AD1DF9EF5FC64160EAC3F2D88B4FB0E20A7925FE133D71EF9E1DD018101AAF251DA4B607 20160301055034 2 6 100 2047 2 F030C513D5C6694FB09539ECF9D8290608A96280EDDEB74FD66DD43CACE3A5BFD6BC4F02EF38E44F68296DA50091214D9E6C518D715D76E19CCCA0578886B93ADA36E8AFDC23B311DA04EB8AC2FF31F3B87BD27C283519DF9CFCAA9D4EF822ECD2AD5593D3819399CEF3FAF0B786071496A9BD94164F739A2D1E0DEBB798BAEF0540B4388D3762523B68E100D6EE231DD95BEB4F4472E9E2236A24E0891DF5A19222A6C69D531C9E73DEF6ADAC84D61BC4EEA36E2A9FD64902461BFAF9BF81D699E141EE77A03996DC4586D3487A0E6189696C1D67F91E91595EB584AD1DF9EF5FC64160EAC3F2D88B4FB0E20A7925FE133D71EF9E1DD018101AAF251DA82003 20160301055101 2 6 100 2047 2 F030C513D5C6694FB09539ECF9D8290608A96280EDDEB74FD66DD43CACE3A5BFD6BC4F02EF38E44F68296DA50091214D9E6C518D715D76E19CCCA0578886B93ADA36E8AFDC23B311DA04EB8AC2FF31F3B87BD27C283519DF9CFCAA9D4EF822ECD2AD5593D3819399CEF3FAF0B786071496A9BD94164F739A2D1E0DEBB798BAEF0540B4388D3762523B68E100D6EE231DD95BEB4F4472E9E2236A24E0891DF5A19222A6C69D531C9E73DEF6ADAC84D61BC4EEA36E2A9FD64902461BFAF9BF81D699E141EE77A03996DC4586D3487A0E6189696C1D67F91E91595EB584AD1DF9EF5FC64160EAC3F2D88B4FB0E20A7925FE133D71EF9E1DD018101AAF251DE323BB 20160301055123 2 6 100 2047 2 F030C513D5C6694FB09539ECF9D8290608A96280EDDEB74FD66DD43CACE3A5BFD6BC4F02EF38E44F68296DA50091214D9E6C518D715D76E19CCCA0578886B93ADA36E8AFDC23B311DA04EB8AC2FF31F3B87BD27C283519DF9CFCAA9D4EF822ECD2AD5593D3819399CEF3FAF0B786071496A9BD94164F739A2D1E0DEBB798BAEF0540B4388D3762523B68E100D6EE231DD95BEB4F4472E9E2236A24E0891DF5A19222A6C69D531C9E73DEF6ADAC84D61BC4EEA36E2A9FD64902461BFAF9BF81D699E141EE77A03996DC4586D3487A0E6189696C1D67F91E91595EB584AD1DF9EF5FC64160EAC3F2D88B4FB0E20A7925FE133D71EF9E1DD018101AAF251E13DB33 20160301055136 2 6 100 2047 2 F030C513D5C6694FB09539ECF9D8290608A96280EDDEB74FD66DD43CACE3A5BFD6BC4F02EF38E44F68296DA50091214D9E6C518D715D76E19CCCA0578886B93ADA36E8AFDC23B311DA04EB8AC2FF31F3B87BD27C283519DF9CFCAA9D4EF822ECD2AD5593D3819399CEF3FAF0B786071496A9BD94164F739A2D1E0DEBB798BAEF0540B4388D3762523B68E100D6EE231DD95BEB4F4472E9E2236A24E0891DF5A19222A6C69D531C9E73DEF6ADAC84D61BC4EEA36E2A9FD64902461BFAF9BF81D699E141EE77A03996DC4586D3487A0E6189696C1D67F91E91595EB584AD1DF9EF5FC64160EAC3F2D88B4FB0E20A7925FE133D71EF9E1DD018101AAF251E2A2203 20160301055141 2 6 100 2047 2 F030C513D5C6694FB09539ECF9D8290608A96280EDDEB74FD66DD43CACE3A5BFD6BC4F02EF38E44F68296DA50091214D9E6C518D715D76E19CCCA0578886B93ADA36E8AFDC23B311DA04EB8AC2FF31F3B87BD27C283519DF9CFCAA9D4EF822ECD2AD5593D3819399CEF3FAF0B786071496A9BD94164F739A2D1E0DEBB798BAEF0540B4388D3762523B68E100D6EE231DD95BEB4F4472E9E2236A24E0891DF5A19222A6C69D531C9E73DEF6ADAC84D61BC4EEA36E2A9FD64902461BFAF9BF81D699E141EE77A03996DC4586D3487A0E6189696C1D67F91E91595EB584AD1DF9EF5FC64160EAC3F2D88B4FB0E20A7925FE133D71EF9E1DD018101AAF251E2F180B 20160301055208 2 6 100 2047 2 F030C513D5C6694FB09539ECF9D8290608A96280EDDEB74FD66DD43CACE3A5BFD6BC4F02EF38E44F68296DA50091214D9E6C518D715D76E19CCCA0578886B93ADA36E8AFDC23B311DA04EB8AC2FF31F3B87BD27C283519DF9CFCAA9D4EF822ECD2AD5593D3819399CEF3FAF0B786071496A9BD94164F739A2D1E0DEBB798BAEF0540B4388D3762523B68E100D6EE231DD95BEB4F4472E9E2236A24E0891DF5A19222A6C69D531C9E73DEF6ADAC84D61BC4EEA36E2A9FD64902461BFAF9BF81D699E141EE77A03996DC4586D3487A0E6189696C1D67F91E91595EB584AD1DF9EF5FC64160EAC3F2D88B4FB0E20A7925FE133D71EF9E1DD018101AAF251E6B2E8B 20160301055248 2 6 100 2047 2 F030C513D5C6694FB09539ECF9D8290608A96280EDDEB74FD66DD43CACE3A5BFD6BC4F02EF38E44F68296DA50091214D9E6C518D715D76E19CCCA0578886B93ADA36E8AFDC23B311DA04EB8AC2FF31F3B87BD27C283519DF9CFCAA9D4EF822ECD2AD5593D3819399CEF3FAF0B786071496A9BD94164F739A2D1E0DEBB798BAEF0540B4388D3762523B68E100D6EE231DD95BEB4F4472E9E2236A24E0891DF5A19222A6C69D531C9E73DEF6ADAC84D61BC4EEA36E2A9FD64902461BFAF9BF81D699E141EE77A03996DC4586D3487A0E6189696C1D67F91E91595EB584AD1DF9EF5FC64160EAC3F2D88B4FB0E20A7925FE133D71EF9E1DD018101AAF251ECCA61B 20160301055312 2 6 100 2047 5 F030C513D5C6694FB09539ECF9D8290608A96280EDDEB74FD66DD43CACE3A5BFD6BC4F02EF38E44F68296DA50091214D9E6C518D715D76E19CCCA0578886B93ADA36E8AFDC23B311DA04EB8AC2FF31F3B87BD27C283519DF9CFCAA9D4EF822ECD2AD5593D3819399CEF3FAF0B786071496A9BD94164F739A2D1E0DEBB798BAEF0540B4388D3762523B68E100D6EE231DD95BEB4F4472E9E2236A24E0891DF5A19222A6C69D531C9E73DEF6ADAC84D61BC4EEA36E2A9FD64902461BFAF9BF81D699E141EE77A03996DC4586D3487A0E6189696C1D67F91E91595EB584AD1DF9EF5FC64160EAC3F2D88B4FB0E20A7925FE133D71EF9E1DD018101AAF251EFFD5C7 20160301055319 2 6 100 2047 2 F030C513D5C6694FB09539ECF9D8290608A96280EDDEB74FD66DD43CACE3A5BFD6BC4F02EF38E44F68296DA50091214D9E6C518D715D76E19CCCA0578886B93ADA36E8AFDC23B311DA04EB8AC2FF31F3B87BD27C283519DF9CFCAA9D4EF822ECD2AD5593D3819399CEF3FAF0B786071496A9BD94164F739A2D1E0DEBB798BAEF0540B4388D3762523B68E100D6EE231DD95BEB4F4472E9E2236A24E0891DF5A19222A6C69D531C9E73DEF6ADAC84D61BC4EEA36E2A9FD64902461BFAF9BF81D699E141EE77A03996DC4586D3487A0E6189696C1D67F91E91595EB584AD1DF9EF5FC64160EAC3F2D88B4FB0E20A7925FE133D71EF9E1DD018101AAF251F08AD6B 20160301055413 2 6 100 2047 2 F030C513D5C6694FB09539ECF9D8290608A96280EDDEB74FD66DD43CACE3A5BFD6BC4F02EF38E44F68296DA50091214D9E6C518D715D76E19CCCA0578886B93ADA36E8AFDC23B311DA04EB8AC2FF31F3B87BD27C283519DF9CFCAA9D4EF822ECD2AD5593D3819399CEF3FAF0B786071496A9BD94164F739A2D1E0DEBB798BAEF0540B4388D3762523B68E100D6EE231DD95BEB4F4472E9E2236A24E0891DF5A19222A6C69D531C9E73DEF6ADAC84D61BC4EEA36E2A9FD64902461BFAF9BF81D699E141EE77A03996DC4586D3487A0E6189696C1D67F91E91595EB584AD1DF9EF5FC64160EAC3F2D88B4FB0E20A7925FE133D71EF9E1DD018101AAF251F881A4B 20160301055420 2 6 100 2047 5 F030C513D5C6694FB09539ECF9D8290608A96280EDDEB74FD66DD43CACE3A5BFD6BC4F02EF38E44F68296DA50091214D9E6C518D715D76E19CCCA0578886B93ADA36E8AFDC23B311DA04EB8AC2FF31F3B87BD27C283519DF9CFCAA9D4EF822ECD2AD5593D3819399CEF3FAF0B786071496A9BD94164F739A2D1E0DEBB798BAEF0540B4388D3762523B68E100D6EE231DD95BEB4F4472E9E2236A24E0891DF5A19222A6C69D531C9E73DEF6ADAC84D61BC4EEA36E2A9FD64902461BFAF9BF81D699E141EE77A03996DC4586D3487A0E6189696C1D67F91E91595EB584AD1DF9EF5FC64160EAC3F2D88B4FB0E20A7925FE133D71EF9E1DD018101AAF251F8FC967 20160301055438 2 6 100 2047 2 F030C513D5C6694FB09539ECF9D8290608A96280EDDEB74FD66DD43CACE3A5BFD6BC4F02EF38E44F68296DA50091214D9E6C518D715D76E19CCCA0578886B93ADA36E8AFDC23B311DA04EB8AC2FF31F3B87BD27C283519DF9CFCAA9D4EF822ECD2AD5593D3819399CEF3FAF0B786071496A9BD94164F739A2D1E0DEBB798BAEF0540B4388D3762523B68E100D6EE231DD95BEB4F4472E9E2236A24E0891DF5A19222A6C69D531C9E73DEF6ADAC84D61BC4EEA36E2A9FD64902461BFAF9BF81D699E141EE77A03996DC4586D3487A0E6189696C1D67F91E91595EB584AD1DF9EF5FC64160EAC3F2D88B4FB0E20A7925FE133D71EF9E1DD018101AAF251FB8102B 20160301055505 2 6 100 2047 2 F030C513D5C6694FB09539ECF9D8290608A96280EDDEB74FD66DD43CACE3A5BFD6BC4F02EF38E44F68296DA50091214D9E6C518D715D76E19CCCA0578886B93ADA36E8AFDC23B311DA04EB8AC2FF31F3B87BD27C283519DF9CFCAA9D4EF822ECD2AD5593D3819399CEF3FAF0B786071496A9BD94164F739A2D1E0DEBB798BAEF0540B4388D3762523B68E100D6EE231DD95BEB4F4472E9E2236A24E0891DF5A19222A6C69D531C9E73DEF6ADAC84D61BC4EEA36E2A9FD64902461BFAF9BF81D699E141EE77A03996DC4586D3487A0E6189696C1D67F91E91595EB584AD1DF9EF5FC64160EAC3F2D88B4FB0E20A7925FE133D71EF9E1DD018101AAF251FF16983 20160301061411 2 6 100 3071 2 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26C5D83833 20160301061835 2 6 100 3071 5 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26C6AAA907 20160301062447 2 6 100 3071 5 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26C7D2DF17 20160301062535 2 6 100 3071 2 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26C7F0856B 20160301062652 2 6 100 3071 2 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26C8266573 20160301062708 2 6 100 3071 5 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26C82B4297 20160301063801 2 6 100 3071 5 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26CA342897 20160301063920 2 6 100 3071 2 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26CA6B6B53 20160301064001 2 6 100 3071 2 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26CA83D25B 20160301064133 2 6 100 3071 5 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26CAC6E0AF 20160301064312 2 6 100 3071 5 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26CB0B8B2F 20160301064624 2 6 100 3071 2 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26CB9E9EBB 20160301064954 2 6 100 3071 2 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26CC41F773 20160301065030 2 6 100 3071 5 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26CC56680F 20160301065134 2 6 100 3071 2 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26CC82B2B3 20160301065432 2 6 100 3071 2 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26CD0A0833 20160301065614 2 6 100 3071 5 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26CD54CA17 20160301070010 2 6 100 3071 2 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26CE0A7B73 20160301070046 2 6 100 3071 2 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26CE21045B 20160301070141 2 6 100 3071 2 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26CE4560CB 20160301070334 2 6 100 3071 5 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26CE9951EF 20160301070607 2 6 100 3071 2 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26CF0C830B 20160301070911 2 6 100 3071 2 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26CF96B75B 20160301070931 2 6 100 3071 5 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26CF9EB207 20160301071405 2 6 100 3071 2 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26D07614DB 20160301071648 2 6 100 3071 2 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26D0F1177B 20160301071915 2 6 100 3071 5 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26D15E484F 20160301071932 2 6 100 3071 2 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26D16371F3 20160301072032 2 6 100 3071 2 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26D18BD843 20160301072158 2 6 100 3071 2 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26D1C7632B 20160301072445 2 6 100 3071 5 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26D2450187 20160301072709 2 6 100 3071 2 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26D2B15CFB 20160301073130 2 6 100 3071 5 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26D37B3327 20160301073142 2 6 100 3071 2 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26D37C7FA3 20160301073822 2 6 100 3071 2 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26D4B57B13 20160301074016 2 6 100 3071 5 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26D50A615F 20160301074134 2 6 100 3071 5 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26D5419827 20160301074208 2 6 100 3071 5 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26D554AA2F 20160301074359 2 6 100 3071 2 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26D5A29FEB 20160301074457 2 6 100 3071 2 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26D5C6DA83 20160301074620 2 6 100 3071 2 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26D601594B 20160301074846 2 6 100 3071 2 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26D66D7E6B 20160301074917 2 6 100 3071 5 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26D67D64E7 20160301075053 2 6 100 3071 2 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26D6C27B8B 20160301075132 2 6 100 3071 2 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26D6DB9C33 20160301075225 2 6 100 3071 5 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26D6FE9337 20160301075252 2 6 100 3071 5 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26D70AF577 20160301075345 2 6 100 3071 2 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26D72CB613 20160301075358 2 6 100 3071 2 E2871F8AF82B8E1038DDACF268D3690580ED64FC99F13D64B8322F1F6F19B0860BD4CB74BD2FF72ADF1090B0506E77743EA2C3102093C10A5045A17F92E403AE24B4E9276F9999A4AAD7DF5F2C03EB72B6BB303FE894149BFD670A13ADEDEFBD726A12A7F32919BC4FFFC8FA3E2E73645B432EB894D6906D1E6E8CD5C8BB882953EAA0306508205B6BC0B99177C81E9E9192D8185185CE82CF310AD42A24DB83039A4F10D1C55E7EA7D4C020BD12947A25732829D1AC6100ED9DA3F4D834D8EB28875F37B399C5AE21D6A122950A41680857CEB6A25158A108E8E0338047A2DD979AB97E9F84ABA18FB1DD43FD630F494CEACF0F7FFEF38BC14968B0FDF4942927D0169B46E84D52356EB1B7D04EFCDF2239AEA21A63B6F64E83AC18F81EB6EAEF03328B830860C184B4434B39FA6AE31C751FB5BA1AEA1BD8D41457D9AE58C6EFD230493454BA3C5EB791E74CAB907D0AF1173FFB99D78953660B23127550350A9A09B0116099087A04B56078C274874507ED92ECD2D98A7F064C26D72F088B 20160301080151 2 6 100 3071 5 F5B3EB8BEBA51E3899E7F8C7E202FBB132EF5731B3C2AC07945AEDA6A77A194E69538E08ABB8BBC3FC5AC2D3F66E582AA280D1832065E63F462AE71CD69CB3523656358545BF625F0F0BA9A8902D2A09484BE915E4AB809B8C767F84AADC75744E07F691893DA5DCCCD3FE8A7140858A9CF09A52E3A8F1050913A592B5750BC54682523B6920F626D87A717D6680B4EE430317DDF7B36458D479ADF6855FE46D865D02F8161D8BD8F4D0F330EE27B28AA40D48B6EA8E183223FCBC4E9C4F1F615DE750A5F8BE130EE46DC23970AD5A3CB93F5822A53084553A3B27A72ADD55958935D98B06D6398B00A718EA6BCE075DD6708F714002AF5A75C67D087DB8308B6FCEC775DBE8415F57CCD39C13496F0782D4834C03241D1B2EFE5CD07D702BD489DE25DAF08CA1DE5FDA5962A8CC6E0283B992640B8706B076531844CF66D26BEC2DD5A0BCDABE6A048BA55F8C25621E8CAA55F2D9E011896DEA823CF9FFBC76143FF7F4653C3BBDC34138A482A150A221E2CA2BE774B7BD22B2481F1FA94507 20160301080332 2 6 100 3071 5 F5B3EB8BEBA51E3899E7F8C7E202FBB132EF5731B3C2AC07945AEDA6A77A194E69538E08ABB8BBC3FC5AC2D3F66E582AA280D1832065E63F462AE71CD69CB3523656358545BF625F0F0BA9A8902D2A09484BE915E4AB809B8C767F84AADC75744E07F691893DA5DCCCD3FE8A7140858A9CF09A52E3A8F1050913A592B5750BC54682523B6920F626D87A717D6680B4EE430317DDF7B36458D479ADF6855FE46D865D02F8161D8BD8F4D0F330EE27B28AA40D48B6EA8E183223FCBC4E9C4F1F615DE750A5F8BE130EE46DC23970AD5A3CB93F5822A53084553A3B27A72ADD55958935D98B06D6398B00A718EA6BCE075DD6708F714002AF5A75C67D087DB8308B6FCEC775DBE8415F57CCD39C13496F0782D4834C03241D1B2EFE5CD07D702BD489DE25DAF08CA1DE5FDA5962A8CC6E0283B992640B8706B076531844CF66D26BEC2DD5A0BCDABE6A048BA55F8C25621E8CAA55F2D9E011896DEA823CF9FFBC76143FF7F4653C3BBDC34138A482A150A221E2CA2BE774B7BD22B2481F1FF62A2F 20160301080512 2 6 100 3071 5 F5B3EB8BEBA51E3899E7F8C7E202FBB132EF5731B3C2AC07945AEDA6A77A194E69538E08ABB8BBC3FC5AC2D3F66E582AA280D1832065E63F462AE71CD69CB3523656358545BF625F0F0BA9A8902D2A09484BE915E4AB809B8C767F84AADC75744E07F691893DA5DCCCD3FE8A7140858A9CF09A52E3A8F1050913A592B5750BC54682523B6920F626D87A717D6680B4EE430317DDF7B36458D479ADF6855FE46D865D02F8161D8BD8F4D0F330EE27B28AA40D48B6EA8E183223FCBC4E9C4F1F615DE750A5F8BE130EE46DC23970AD5A3CB93F5822A53084553A3B27A72ADD55958935D98B06D6398B00A718EA6BCE075DD6708F714002AF5A75C67D087DB8308B6FCEC775DBE8415F57CCD39C13496F0782D4834C03241D1B2EFE5CD07D702BD489DE25DAF08CA1DE5FDA5962A8CC6E0283B992640B8706B076531844CF66D26BEC2DD5A0BCDABE6A048BA55F8C25621E8CAA55F2D9E011896DEA823CF9FFBC76143FF7F4653C3BBDC34138A482A150A221E2CA2BE774B7BD22B2481F203E0E3F 20160301080759 2 6 100 3071 5 F5B3EB8BEBA51E3899E7F8C7E202FBB132EF5731B3C2AC07945AEDA6A77A194E69538E08ABB8BBC3FC5AC2D3F66E582AA280D1832065E63F462AE71CD69CB3523656358545BF625F0F0BA9A8902D2A09484BE915E4AB809B8C767F84AADC75744E07F691893DA5DCCCD3FE8A7140858A9CF09A52E3A8F1050913A592B5750BC54682523B6920F626D87A717D6680B4EE430317DDF7B36458D479ADF6855FE46D865D02F8161D8BD8F4D0F330EE27B28AA40D48B6EA8E183223FCBC4E9C4F1F615DE750A5F8BE130EE46DC23970AD5A3CB93F5822A53084553A3B27A72ADD55958935D98B06D6398B00A718EA6BCE075DD6708F714002AF5A75C67D087DB8308B6FCEC775DBE8415F57CCD39C13496F0782D4834C03241D1B2EFE5CD07D702BD489DE25DAF08CA1DE5FDA5962A8CC6E0283B992640B8706B076531844CF66D26BEC2DD5A0BCDABE6A048BA55F8C25621E8CAA55F2D9E011896DEA823CF9FFBC76143FF7F4653C3BBDC34138A482A150A221E2CA2BE774B7BD22B2481F20BE897F 20160301081008 2 6 100 3071 2 F5B3EB8BEBA51E3899E7F8C7E202FBB132EF5731B3C2AC07945AEDA6A77A194E69538E08ABB8BBC3FC5AC2D3F66E582AA280D1832065E63F462AE71CD69CB3523656358545BF625F0F0BA9A8902D2A09484BE915E4AB809B8C767F84AADC75744E07F691893DA5DCCCD3FE8A7140858A9CF09A52E3A8F1050913A592B5750BC54682523B6920F626D87A717D6680B4EE430317DDF7B36458D479ADF6855FE46D865D02F8161D8BD8F4D0F330EE27B28AA40D48B6EA8E183223FCBC4E9C4F1F615DE750A5F8BE130EE46DC23970AD5A3CB93F5822A53084553A3B27A72ADD55958935D98B06D6398B00A718EA6BCE075DD6708F714002AF5A75C67D087DB8308B6FCEC775DBE8415F57CCD39C13496F0782D4834C03241D1B2EFE5CD07D702BD489DE25DAF08CA1DE5FDA5962A8CC6E0283B992640B8706B076531844CF66D26BEC2DD5A0BCDABE6A048BA55F8C25621E8CAA55F2D9E011896DEA823CF9FFBC76143FF7F4653C3BBDC34138A482A150A221E2CA2BE774B7BD22B2481F211E8DAB 20160301081510 2 6 100 3071 2 F5B3EB8BEBA51E3899E7F8C7E202FBB132EF5731B3C2AC07945AEDA6A77A194E69538E08ABB8BBC3FC5AC2D3F66E582AA280D1832065E63F462AE71CD69CB3523656358545BF625F0F0BA9A8902D2A09484BE915E4AB809B8C767F84AADC75744E07F691893DA5DCCCD3FE8A7140858A9CF09A52E3A8F1050913A592B5750BC54682523B6920F626D87A717D6680B4EE430317DDF7B36458D479ADF6855FE46D865D02F8161D8BD8F4D0F330EE27B28AA40D48B6EA8E183223FCBC4E9C4F1F615DE750A5F8BE130EE46DC23970AD5A3CB93F5822A53084553A3B27A72ADD55958935D98B06D6398B00A718EA6BCE075DD6708F714002AF5A75C67D087DB8308B6FCEC775DBE8415F57CCD39C13496F0782D4834C03241D1B2EFE5CD07D702BD489DE25DAF08CA1DE5FDA5962A8CC6E0283B992640B8706B076531844CF66D26BEC2DD5A0BCDABE6A048BA55F8C25621E8CAA55F2D9E011896DEA823CF9FFBC76143FF7F4653C3BBDC34138A482A150A221E2CA2BE774B7BD22B2481F220FBEBB 20160301081725 2 6 100 3071 2 F5B3EB8BEBA51E3899E7F8C7E202FBB132EF5731B3C2AC07945AEDA6A77A194E69538E08ABB8BBC3FC5AC2D3F66E582AA280D1832065E63F462AE71CD69CB3523656358545BF625F0F0BA9A8902D2A09484BE915E4AB809B8C767F84AADC75744E07F691893DA5DCCCD3FE8A7140858A9CF09A52E3A8F1050913A592B5750BC54682523B6920F626D87A717D6680B4EE430317DDF7B36458D479ADF6855FE46D865D02F8161D8BD8F4D0F330EE27B28AA40D48B6EA8E183223FCBC4E9C4F1F615DE750A5F8BE130EE46DC23970AD5A3CB93F5822A53084553A3B27A72ADD55958935D98B06D6398B00A718EA6BCE075DD6708F714002AF5A75C67D087DB8308B6FCEC775DBE8415F57CCD39C13496F0782D4834C03241D1B2EFE5CD07D702BD489DE25DAF08CA1DE5FDA5962A8CC6E0283B992640B8706B076531844CF66D26BEC2DD5A0BCDABE6A048BA55F8C25621E8CAA55F2D9E011896DEA823CF9FFBC76143FF7F4653C3BBDC34138A482A150A221E2CA2BE774B7BD22B2481F22727C13 20160301082213 2 6 100 3071 5 F5B3EB8BEBA51E3899E7F8C7E202FBB132EF5731B3C2AC07945AEDA6A77A194E69538E08ABB8BBC3FC5AC2D3F66E582AA280D1832065E63F462AE71CD69CB3523656358545BF625F0F0BA9A8902D2A09484BE915E4AB809B8C767F84AADC75744E07F691893DA5DCCCD3FE8A7140858A9CF09A52E3A8F1050913A592B5750BC54682523B6920F626D87A717D6680B4EE430317DDF7B36458D479ADF6855FE46D865D02F8161D8BD8F4D0F330EE27B28AA40D48B6EA8E183223FCBC4E9C4F1F615DE750A5F8BE130EE46DC23970AD5A3CB93F5822A53084553A3B27A72ADD55958935D98B06D6398B00A718EA6BCE075DD6708F714002AF5A75C67D087DB8308B6FCEC775DBE8415F57CCD39C13496F0782D4834C03241D1B2EFE5CD07D702BD489DE25DAF08CA1DE5FDA5962A8CC6E0283B992640B8706B076531844CF66D26BEC2DD5A0BCDABE6A048BA55F8C25621E8CAA55F2D9E011896DEA823CF9FFBC76143FF7F4653C3BBDC34138A482A150A221E2CA2BE774B7BD22B2481F2352279F 20160301083400 2 6 100 3071 5 F5B3EB8BEBA51E3899E7F8C7E202FBB132EF5731B3C2AC07945AEDA6A77A194E69538E08ABB8BBC3FC5AC2D3F66E582AA280D1832065E63F462AE71CD69CB3523656358545BF625F0F0BA9A8902D2A09484BE915E4AB809B8C767F84AADC75744E07F691893DA5DCCCD3FE8A7140858A9CF09A52E3A8F1050913A592B5750BC54682523B6920F626D87A717D6680B4EE430317DDF7B36458D479ADF6855FE46D865D02F8161D8BD8F4D0F330EE27B28AA40D48B6EA8E183223FCBC4E9C4F1F615DE750A5F8BE130EE46DC23970AD5A3CB93F5822A53084553A3B27A72ADD55958935D98B06D6398B00A718EA6BCE075DD6708F714002AF5A75C67D087DB8308B6FCEC775DBE8415F57CCD39C13496F0782D4834C03241D1B2EFE5CD07D702BD489DE25DAF08CA1DE5FDA5962A8CC6E0283B992640B8706B076531844CF66D26BEC2DD5A0BCDABE6A048BA55F8C25621E8CAA55F2D9E011896DEA823CF9FFBC76143FF7F4653C3BBDC34138A482A150A221E2CA2BE774B7BD22B2481F25905AEF 20160301083955 2 6 100 3071 2 F5B3EB8BEBA51E3899E7F8C7E202FBB132EF5731B3C2AC07945AEDA6A77A194E69538E08ABB8BBC3FC5AC2D3F66E582AA280D1832065E63F462AE71CD69CB3523656358545BF625F0F0BA9A8902D2A09484BE915E4AB809B8C767F84AADC75744E07F691893DA5DCCCD3FE8A7140858A9CF09A52E3A8F1050913A592B5750BC54682523B6920F626D87A717D6680B4EE430317DDF7B36458D479ADF6855FE46D865D02F8161D8BD8F4D0F330EE27B28AA40D48B6EA8E183223FCBC4E9C4F1F615DE750A5F8BE130EE46DC23970AD5A3CB93F5822A53084553A3B27A72ADD55958935D98B06D6398B00A718EA6BCE075DD6708F714002AF5A75C67D087DB8308B6FCEC775DBE8415F57CCD39C13496F0782D4834C03241D1B2EFE5CD07D702BD489DE25DAF08CA1DE5FDA5962A8CC6E0283B992640B8706B076531844CF66D26BEC2DD5A0BCDABE6A048BA55F8C25621E8CAA55F2D9E011896DEA823CF9FFBC76143FF7F4653C3BBDC34138A482A150A221E2CA2BE774B7BD22B2481F26AB557B 20160301084035 2 6 100 3071 5 F5B3EB8BEBA51E3899E7F8C7E202FBB132EF5731B3C2AC07945AEDA6A77A194E69538E08ABB8BBC3FC5AC2D3F66E582AA280D1832065E63F462AE71CD69CB3523656358545BF625F0F0BA9A8902D2A09484BE915E4AB809B8C767F84AADC75744E07F691893DA5DCCCD3FE8A7140858A9CF09A52E3A8F1050913A592B5750BC54682523B6920F626D87A717D6680B4EE430317DDF7B36458D479ADF6855FE46D865D02F8161D8BD8F4D0F330EE27B28AA40D48B6EA8E183223FCBC4E9C4F1F615DE750A5F8BE130EE46DC23970AD5A3CB93F5822A53084553A3B27A72ADD55958935D98B06D6398B00A718EA6BCE075DD6708F714002AF5A75C67D087DB8308B6FCEC775DBE8415F57CCD39C13496F0782D4834C03241D1B2EFE5CD07D702BD489DE25DAF08CA1DE5FDA5962A8CC6E0283B992640B8706B076531844CF66D26BEC2DD5A0BCDABE6A048BA55F8C25621E8CAA55F2D9E011896DEA823CF9FFBC76143FF7F4653C3BBDC34138A482A150A221E2CA2BE774B7BD22B2481F26C1D647 20160301084145 2 6 100 3071 2 F5B3EB8BEBA51E3899E7F8C7E202FBB132EF5731B3C2AC07945AEDA6A77A194E69538E08ABB8BBC3FC5AC2D3F66E582AA280D1832065E63F462AE71CD69CB3523656358545BF625F0F0BA9A8902D2A09484BE915E4AB809B8C767F84AADC75744E07F691893DA5DCCCD3FE8A7140858A9CF09A52E3A8F1050913A592B5750BC54682523B6920F626D87A717D6680B4EE430317DDF7B36458D479ADF6855FE46D865D02F8161D8BD8F4D0F330EE27B28AA40D48B6EA8E183223FCBC4E9C4F1F615DE750A5F8BE130EE46DC23970AD5A3CB93F5822A53084553A3B27A72ADD55958935D98B06D6398B00A718EA6BCE075DD6708F714002AF5A75C67D087DB8308B6FCEC775DBE8415F57CCD39C13496F0782D4834C03241D1B2EFE5CD07D702BD489DE25DAF08CA1DE5FDA5962A8CC6E0283B992640B8706B076531844CF66D26BEC2DD5A0BCDABE6A048BA55F8C25621E8CAA55F2D9E011896DEA823CF9FFBC76143FF7F4653C3BBDC34138A482A150A221E2CA2BE774B7BD22B2481F26F0E75B 20160301084827 2 6 100 3071 2 F5B3EB8BEBA51E3899E7F8C7E202FBB132EF5731B3C2AC07945AEDA6A77A194E69538E08ABB8BBC3FC5AC2D3F66E582AA280D1832065E63F462AE71CD69CB3523656358545BF625F0F0BA9A8902D2A09484BE915E4AB809B8C767F84AADC75744E07F691893DA5DCCCD3FE8A7140858A9CF09A52E3A8F1050913A592B5750BC54682523B6920F626D87A717D6680B4EE430317DDF7B36458D479ADF6855FE46D865D02F8161D8BD8F4D0F330EE27B28AA40D48B6EA8E183223FCBC4E9C4F1F615DE750A5F8BE130EE46DC23970AD5A3CB93F5822A53084553A3B27A72ADD55958935D98B06D6398B00A718EA6BCE075DD6708F714002AF5A75C67D087DB8308B6FCEC775DBE8415F57CCD39C13496F0782D4834C03241D1B2EFE5CD07D702BD489DE25DAF08CA1DE5FDA5962A8CC6E0283B992640B8706B076531844CF66D26BEC2DD5A0BCDABE6A048BA55F8C25621E8CAA55F2D9E011896DEA823CF9FFBC76143FF7F4653C3BBDC34138A482A150A221E2CA2BE774B7BD22B2481F282FE7DB 20160301084906 2 6 100 3071 5 F5B3EB8BEBA51E3899E7F8C7E202FBB132EF5731B3C2AC07945AEDA6A77A194E69538E08ABB8BBC3FC5AC2D3F66E582AA280D1832065E63F462AE71CD69CB3523656358545BF625F0F0BA9A8902D2A09484BE915E4AB809B8C767F84AADC75744E07F691893DA5DCCCD3FE8A7140858A9CF09A52E3A8F1050913A592B5750BC54682523B6920F626D87A717D6680B4EE430317DDF7B36458D479ADF6855FE46D865D02F8161D8BD8F4D0F330EE27B28AA40D48B6EA8E183223FCBC4E9C4F1F615DE750A5F8BE130EE46DC23970AD5A3CB93F5822A53084553A3B27A72ADD55958935D98B06D6398B00A718EA6BCE075DD6708F714002AF5A75C67D087DB8308B6FCEC775DBE8415F57CCD39C13496F0782D4834C03241D1B2EFE5CD07D702BD489DE25DAF08CA1DE5FDA5962A8CC6E0283B992640B8706B076531844CF66D26BEC2DD5A0BCDABE6A048BA55F8C25621E8CAA55F2D9E011896DEA823CF9FFBC76143FF7F4653C3BBDC34138A482A150A221E2CA2BE774B7BD22B2481F2847CBF7 20160301085226 2 6 100 3071 2 F5B3EB8BEBA51E3899E7F8C7E202FBB132EF5731B3C2AC07945AEDA6A77A194E69538E08ABB8BBC3FC5AC2D3F66E582AA280D1832065E63F462AE71CD69CB3523656358545BF625F0F0BA9A8902D2A09484BE915E4AB809B8C767F84AADC75744E07F691893DA5DCCCD3FE8A7140858A9CF09A52E3A8F1050913A592B5750BC54682523B6920F626D87A717D6680B4EE430317DDF7B36458D479ADF6855FE46D865D02F8161D8BD8F4D0F330EE27B28AA40D48B6EA8E183223FCBC4E9C4F1F615DE750A5F8BE130EE46DC23970AD5A3CB93F5822A53084553A3B27A72ADD55958935D98B06D6398B00A718EA6BCE075DD6708F714002AF5A75C67D087DB8308B6FCEC775DBE8415F57CCD39C13496F0782D4834C03241D1B2EFE5CD07D702BD489DE25DAF08CA1DE5FDA5962A8CC6E0283B992640B8706B076531844CF66D26BEC2DD5A0BCDABE6A048BA55F8C25621E8CAA55F2D9E011896DEA823CF9FFBC76143FF7F4653C3BBDC34138A482A150A221E2CA2BE774B7BD22B2481F28E1E963 20160301085254 2 6 100 3071 2 F5B3EB8BEBA51E3899E7F8C7E202FBB132EF5731B3C2AC07945AEDA6A77A194E69538E08ABB8BBC3FC5AC2D3F66E582AA280D1832065E63F462AE71CD69CB3523656358545BF625F0F0BA9A8902D2A09484BE915E4AB809B8C767F84AADC75744E07F691893DA5DCCCD3FE8A7140858A9CF09A52E3A8F1050913A592B5750BC54682523B6920F626D87A717D6680B4EE430317DDF7B36458D479ADF6855FE46D865D02F8161D8BD8F4D0F330EE27B28AA40D48B6EA8E183223FCBC4E9C4F1F615DE750A5F8BE130EE46DC23970AD5A3CB93F5822A53084553A3B27A72ADD55958935D98B06D6398B00A718EA6BCE075DD6708F714002AF5A75C67D087DB8308B6FCEC775DBE8415F57CCD39C13496F0782D4834C03241D1B2EFE5CD07D702BD489DE25DAF08CA1DE5FDA5962A8CC6E0283B992640B8706B076531844CF66D26BEC2DD5A0BCDABE6A048BA55F8C25621E8CAA55F2D9E011896DEA823CF9FFBC76143FF7F4653C3BBDC34138A482A150A221E2CA2BE774B7BD22B2481F28EF835B 20160301085737 2 6 100 3071 2 F5B3EB8BEBA51E3899E7F8C7E202FBB132EF5731B3C2AC07945AEDA6A77A194E69538E08ABB8BBC3FC5AC2D3F66E582AA280D1832065E63F462AE71CD69CB3523656358545BF625F0F0BA9A8902D2A09484BE915E4AB809B8C767F84AADC75744E07F691893DA5DCCCD3FE8A7140858A9CF09A52E3A8F1050913A592B5750BC54682523B6920F626D87A717D6680B4EE430317DDF7B36458D479ADF6855FE46D865D02F8161D8BD8F4D0F330EE27B28AA40D48B6EA8E183223FCBC4E9C4F1F615DE750A5F8BE130EE46DC23970AD5A3CB93F5822A53084553A3B27A72ADD55958935D98B06D6398B00A718EA6BCE075DD6708F714002AF5A75C67D087DB8308B6FCEC775DBE8415F57CCD39C13496F0782D4834C03241D1B2EFE5CD07D702BD489DE25DAF08CA1DE5FDA5962A8CC6E0283B992640B8706B076531844CF66D26BEC2DD5A0BCDABE6A048BA55F8C25621E8CAA55F2D9E011896DEA823CF9FFBC76143FF7F4653C3BBDC34138A482A150A221E2CA2BE774B7BD22B2481F29D012DB 20160301085933 2 6 100 3071 2 F5B3EB8BEBA51E3899E7F8C7E202FBB132EF5731B3C2AC07945AEDA6A77A194E69538E08ABB8BBC3FC5AC2D3F66E582AA280D1832065E63F462AE71CD69CB3523656358545BF625F0F0BA9A8902D2A09484BE915E4AB809B8C767F84AADC75744E07F691893DA5DCCCD3FE8A7140858A9CF09A52E3A8F1050913A592B5750BC54682523B6920F626D87A717D6680B4EE430317DDF7B36458D479ADF6855FE46D865D02F8161D8BD8F4D0F330EE27B28AA40D48B6EA8E183223FCBC4E9C4F1F615DE750A5F8BE130EE46DC23970AD5A3CB93F5822A53084553A3B27A72ADD55958935D98B06D6398B00A718EA6BCE075DD6708F714002AF5A75C67D087DB8308B6FCEC775DBE8415F57CCD39C13496F0782D4834C03241D1B2EFE5CD07D702BD489DE25DAF08CA1DE5FDA5962A8CC6E0283B992640B8706B076531844CF66D26BEC2DD5A0BCDABE6A048BA55F8C25621E8CAA55F2D9E011896DEA823CF9FFBC76143FF7F4653C3BBDC34138A482A150A221E2CA2BE774B7BD22B2481F2A259503 20160301090045 2 6 100 3071 5 F5B3EB8BEBA51E3899E7F8C7E202FBB132EF5731B3C2AC07945AEDA6A77A194E69538E08ABB8BBC3FC5AC2D3F66E582AA280D1832065E63F462AE71CD69CB3523656358545BF625F0F0BA9A8902D2A09484BE915E4AB809B8C767F84AADC75744E07F691893DA5DCCCD3FE8A7140858A9CF09A52E3A8F1050913A592B5750BC54682523B6920F626D87A717D6680B4EE430317DDF7B36458D479ADF6855FE46D865D02F8161D8BD8F4D0F330EE27B28AA40D48B6EA8E183223FCBC4E9C4F1F615DE750A5F8BE130EE46DC23970AD5A3CB93F5822A53084553A3B27A72ADD55958935D98B06D6398B00A718EA6BCE075DD6708F714002AF5A75C67D087DB8308B6FCEC775DBE8415F57CCD39C13496F0782D4834C03241D1B2EFE5CD07D702BD489DE25DAF08CA1DE5FDA5962A8CC6E0283B992640B8706B076531844CF66D26BEC2DD5A0BCDABE6A048BA55F8C25621E8CAA55F2D9E011896DEA823CF9FFBC76143FF7F4653C3BBDC34138A482A150A221E2CA2BE774B7BD22B2481F2A569E5F 20160301090201 2 6 100 3071 5 F5B3EB8BEBA51E3899E7F8C7E202FBB132EF5731B3C2AC07945AEDA6A77A194E69538E08ABB8BBC3FC5AC2D3F66E582AA280D1832065E63F462AE71CD69CB3523656358545BF625F0F0BA9A8902D2A09484BE915E4AB809B8C767F84AADC75744E07F691893DA5DCCCD3FE8A7140858A9CF09A52E3A8F1050913A592B5750BC54682523B6920F626D87A717D6680B4EE430317DDF7B36458D479ADF6855FE46D865D02F8161D8BD8F4D0F330EE27B28AA40D48B6EA8E183223FCBC4E9C4F1F615DE750A5F8BE130EE46DC23970AD5A3CB93F5822A53084553A3B27A72ADD55958935D98B06D6398B00A718EA6BCE075DD6708F714002AF5A75C67D087DB8308B6FCEC775DBE8415F57CCD39C13496F0782D4834C03241D1B2EFE5CD07D702BD489DE25DAF08CA1DE5FDA5962A8CC6E0283B992640B8706B076531844CF66D26BEC2DD5A0BCDABE6A048BA55F8C25621E8CAA55F2D9E011896DEA823CF9FFBC76143FF7F4653C3BBDC34138A482A150A221E2CA2BE774B7BD22B2481F2A89EEB7 20160301090441 2 6 100 3071 5 F5B3EB8BEBA51E3899E7F8C7E202FBB132EF5731B3C2AC07945AEDA6A77A194E69538E08ABB8BBC3FC5AC2D3F66E582AA280D1832065E63F462AE71CD69CB3523656358545BF625F0F0BA9A8902D2A09484BE915E4AB809B8C767F84AADC75744E07F691893DA5DCCCD3FE8A7140858A9CF09A52E3A8F1050913A592B5750BC54682523B6920F626D87A717D6680B4EE430317DDF7B36458D479ADF6855FE46D865D02F8161D8BD8F4D0F330EE27B28AA40D48B6EA8E183223FCBC4E9C4F1F615DE750A5F8BE130EE46DC23970AD5A3CB93F5822A53084553A3B27A72ADD55958935D98B06D6398B00A718EA6BCE075DD6708F714002AF5A75C67D087DB8308B6FCEC775DBE8415F57CCD39C13496F0782D4834C03241D1B2EFE5CD07D702BD489DE25DAF08CA1DE5FDA5962A8CC6E0283B992640B8706B076531844CF66D26BEC2DD5A0BCDABE6A048BA55F8C25621E8CAA55F2D9E011896DEA823CF9FFBC76143FF7F4653C3BBDC34138A482A150A221E2CA2BE774B7BD22B2481F2B037B2F 20160301090534 2 6 100 3071 2 F5B3EB8BEBA51E3899E7F8C7E202FBB132EF5731B3C2AC07945AEDA6A77A194E69538E08ABB8BBC3FC5AC2D3F66E582AA280D1832065E63F462AE71CD69CB3523656358545BF625F0F0BA9A8902D2A09484BE915E4AB809B8C767F84AADC75744E07F691893DA5DCCCD3FE8A7140858A9CF09A52E3A8F1050913A592B5750BC54682523B6920F626D87A717D6680B4EE430317DDF7B36458D479ADF6855FE46D865D02F8161D8BD8F4D0F330EE27B28AA40D48B6EA8E183223FCBC4E9C4F1F615DE750A5F8BE130EE46DC23970AD5A3CB93F5822A53084553A3B27A72ADD55958935D98B06D6398B00A718EA6BCE075DD6708F714002AF5A75C67D087DB8308B6FCEC775DBE8415F57CCD39C13496F0782D4834C03241D1B2EFE5CD07D702BD489DE25DAF08CA1DE5FDA5962A8CC6E0283B992640B8706B076531844CF66D26BEC2DD5A0BCDABE6A048BA55F8C25621E8CAA55F2D9E011896DEA823CF9FFBC76143FF7F4653C3BBDC34138A482A150A221E2CA2BE774B7BD22B2481F2B2559FB 20160301090628 2 6 100 3071 2 F5B3EB8BEBA51E3899E7F8C7E202FBB132EF5731B3C2AC07945AEDA6A77A194E69538E08ABB8BBC3FC5AC2D3F66E582AA280D1832065E63F462AE71CD69CB3523656358545BF625F0F0BA9A8902D2A09484BE915E4AB809B8C767F84AADC75744E07F691893DA5DCCCD3FE8A7140858A9CF09A52E3A8F1050913A592B5750BC54682523B6920F626D87A717D6680B4EE430317DDF7B36458D479ADF6855FE46D865D02F8161D8BD8F4D0F330EE27B28AA40D48B6EA8E183223FCBC4E9C4F1F615DE750A5F8BE130EE46DC23970AD5A3CB93F5822A53084553A3B27A72ADD55958935D98B06D6398B00A718EA6BCE075DD6708F714002AF5A75C67D087DB8308B6FCEC775DBE8415F57CCD39C13496F0782D4834C03241D1B2EFE5CD07D702BD489DE25DAF08CA1DE5FDA5962A8CC6E0283B992640B8706B076531844CF66D26BEC2DD5A0BCDABE6A048BA55F8C25621E8CAA55F2D9E011896DEA823CF9FFBC76143FF7F4653C3BBDC34138A482A150A221E2CA2BE774B7BD22B2481F2B484193 20160301092125 2 6 100 3071 5 F5B3EB8BEBA51E3899E7F8C7E202FBB132EF5731B3C2AC07945AEDA6A77A194E69538E08ABB8BBC3FC5AC2D3F66E582AA280D1832065E63F462AE71CD69CB3523656358545BF625F0F0BA9A8902D2A09484BE915E4AB809B8C767F84AADC75744E07F691893DA5DCCCD3FE8A7140858A9CF09A52E3A8F1050913A592B5750BC54682523B6920F626D87A717D6680B4EE430317DDF7B36458D479ADF6855FE46D865D02F8161D8BD8F4D0F330EE27B28AA40D48B6EA8E183223FCBC4E9C4F1F615DE750A5F8BE130EE46DC23970AD5A3CB93F5822A53084553A3B27A72ADD55958935D98B06D6398B00A718EA6BCE075DD6708F714002AF5A75C67D087DB8308B6FCEC775DBE8415F57CCD39C13496F0782D4834C03241D1B2EFE5CD07D702BD489DE25DAF08CA1DE5FDA5962A8CC6E0283B992640B8706B076531844CF66D26BEC2DD5A0BCDABE6A048BA55F8C25621E8CAA55F2D9E011896DEA823CF9FFBC76143FF7F4653C3BBDC34138A482A150A221E2CA2BE774B7BD22B2481F2E1E1337 20160301092513 2 6 100 3071 2 F5B3EB8BEBA51E3899E7F8C7E202FBB132EF5731B3C2AC07945AEDA6A77A194E69538E08ABB8BBC3FC5AC2D3F66E582AA280D1832065E63F462AE71CD69CB3523656358545BF625F0F0BA9A8902D2A09484BE915E4AB809B8C767F84AADC75744E07F691893DA5DCCCD3FE8A7140858A9CF09A52E3A8F1050913A592B5750BC54682523B6920F626D87A717D6680B4EE430317DDF7B36458D479ADF6855FE46D865D02F8161D8BD8F4D0F330EE27B28AA40D48B6EA8E183223FCBC4E9C4F1F615DE750A5F8BE130EE46DC23970AD5A3CB93F5822A53084553A3B27A72ADD55958935D98B06D6398B00A718EA6BCE075DD6708F714002AF5A75C67D087DB8308B6FCEC775DBE8415F57CCD39C13496F0782D4834C03241D1B2EFE5CD07D702BD489DE25DAF08CA1DE5FDA5962A8CC6E0283B992640B8706B076531844CF66D26BEC2DD5A0BCDABE6A048BA55F8C25621E8CAA55F2D9E011896DEA823CF9FFBC76143FF7F4653C3BBDC34138A482A150A221E2CA2BE774B7BD22B2481F2ECC261B 20160301093051 2 6 100 3071 2 F5B3EB8BEBA51E3899E7F8C7E202FBB132EF5731B3C2AC07945AEDA6A77A194E69538E08ABB8BBC3FC5AC2D3F66E582AA280D1832065E63F462AE71CD69CB3523656358545BF625F0F0BA9A8902D2A09484BE915E4AB809B8C767F84AADC75744E07F691893DA5DCCCD3FE8A7140858A9CF09A52E3A8F1050913A592B5750BC54682523B6920F626D87A717D6680B4EE430317DDF7B36458D479ADF6855FE46D865D02F8161D8BD8F4D0F330EE27B28AA40D48B6EA8E183223FCBC4E9C4F1F615DE750A5F8BE130EE46DC23970AD5A3CB93F5822A53084553A3B27A72ADD55958935D98B06D6398B00A718EA6BCE075DD6708F714002AF5A75C67D087DB8308B6FCEC775DBE8415F57CCD39C13496F0782D4834C03241D1B2EFE5CD07D702BD489DE25DAF08CA1DE5FDA5962A8CC6E0283B992640B8706B076531844CF66D26BEC2DD5A0BCDABE6A048BA55F8C25621E8CAA55F2D9E011896DEA823CF9FFBC76143FF7F4653C3BBDC34138A482A150A221E2CA2BE774B7BD22B2481F2FD6418B 20160301101954 2 6 100 4095 2 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F29E60ED3CB 20160301104238 2 6 100 4095 2 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F29E7F21B53 20160301105433 2 6 100 4095 2 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F29E8EA1923 20160301110823 2 6 100 4095 2 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F29EA099523 20160301111806 2 6 100 4095 2 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F29EAD0379B 20160301112515 2 6 100 4095 5 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F29EB5F9FF7 20160301112655 2 6 100 4095 2 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F29EB7A3C73 20160301113152 2 6 100 4095 5 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F29EBD8A1AF 20160301114603 2 6 100 4095 5 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F29ED0421CF 20160301115854 2 6 100 4095 5 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F29EE10BE07 20160301122138 2 6 100 4095 5 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F29EFED1757 20160301124138 2 6 100 4095 2 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F29F18BB82B 20160301124341 2 6 100 4095 2 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F29F1AE9F93 20160301130540 2 6 100 4095 2 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F29F378431B 20160301132038 2 6 100 4095 2 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F29F4B041CB 20160301132156 2 6 100 4095 2 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F29F4C33A3B 20160301133248 2 6 100 4095 5 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F29F59F1817 20160301135039 2 6 100 4095 5 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F29F70D3707 20160301135200 2 6 100 4095 2 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F29F720CFD3 20160301135955 2 6 100 4095 5 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F29F7BFD4BF 20160301141625 2 6 100 4095 5 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F29F9118567 20160301143329 2 6 100 4095 2 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F29FA446E3B 20160301143411 2 6 100 4095 2 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F29FA4A5D73 20160301143511 2 6 100 4095 2 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F29FA57571B 20160301145341 2 6 100 4095 2 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F29FBCEC3DB 20160301150532 2 6 100 4095 2 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F29FCBAFB3B 20160301150756 2 6 100 4095 2 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F29FCE5B5B3 20160301151026 2 6 100 4095 2 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F29FD119B83 20160301152435 2 6 100 4095 2 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F29FE2CAD43 20160301152638 2 6 100 4095 2 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F29FE504DD3 20160301153829 2 6 100 4095 2 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F29FF425A73 20160301154015 2 6 100 4095 2 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F29FF5FBCDB 20160301154135 2 6 100 4095 5 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F29FF725ADF 20160301154325 2 6 100 4095 2 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F29FF9005B3 20160301155218 2 6 100 4095 2 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F2A00430653 20160301160626 2 6 100 4095 2 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F2A01612A43 20160301160831 2 6 100 4095 5 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F2A01842FE7 20160301161542 2 6 100 4095 2 EF7840BC7248E3E12D223BD86584358750562F5FCB298632E269C7F4347DC441CEBCBAF5B8AD25C3A3EE85A97FC342EF2B320425ACE6A816200E4A46596E6D911E8E5940E4ED1F64275D1A2A1E2DC8A34E26026A8DD9D20AF2E36B2BEB467168E516F1DF9145DBA60CE4BE46B34E918D36F581B2860BEBD153A09BF5B51348137CEB0BFA43FDEF5398C538CB9854BED966017DC918E4EA26E0E1A283AEA90F41B2D27CBC34E6AA64FE7E370D532BE4A0DB2E77958CA6E570DEDA817FB91351B65E227BAF96383323820AC5CF785CD686E99398773DF19C1E33D7199A5104337AD3C8CF78FE1AF5D8A4A2B8C092E1FD2688F2829E006C050257DC4C16576AB12AC01AE40F35785586902058735024E0CF90B1DD3B547647AC6F98A70BE3CA9EF80E9A1E408D29FDBE7935625B9AB863891D6D30A54903DD23933303055B8E864751CEB7A153A841D2E1CD3C5943C7F6F1BB2836ED387BE4FB3075363317A1E813965497F5CC621A72B1CF5B50813B418F391FB7C4530B6C19416B4A942063012798536BBF853166697747F39827832A3D135ABFB03BF15990787F64D25E629ED1A6009BADF5447730445ACF2684715A84ECBC4B3A1E2C93E3EFCF4D9373E1355740776F66353576D7359C69EAE48FCFB06CA7536F4B132BFCE6DB2FDBD687B24E7A0AD1EBCBF887A7258C24D8AC9BB86BF847D9AC980919AD9BAF3F2A020ED50B 20160301165149 2 6 100 4095 2 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE54C87A80B 20160301165241 2 6 100 4095 2 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE54C91EA2B 20160301165750 2 6 100 4095 2 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE54CFA74E3 20160301173839 2 6 100 4095 2 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE5504AEAFB 20160301174247 2 6 100 4095 5 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE5509AF4D7 20160301174504 2 6 100 4095 5 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE550BFB1D7 20160301180608 2 6 100 4095 5 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE5526F5F0F 20160301181854 2 6 100 4095 2 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE55377C36B 20160301182221 2 6 100 4095 2 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE553B4B8F3 20160301183911 2 6 100 4095 2 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE55510470B 20160301184110 2 6 100 4095 5 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE555338897 20160301184426 2 6 100 4095 5 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE55571A23F 20160301190148 2 6 100 4095 2 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE556DEB983 20160301192446 2 6 100 4095 2 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE558BD1523 20160301193428 2 6 100 4095 5 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE559875F5F 20160301193505 2 6 100 4095 2 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE5598BF0AB 20160301194148 2 6 100 4095 2 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE55A0E82C3 20160301195020 2 6 100 4095 2 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE55AB8837B 20160301195917 2 6 100 4095 2 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE55B6C5AB3 20160301200332 2 6 100 4095 2 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE55BBC661B 20160301201317 2 6 100 4095 5 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE55C7D9887 20160301201523 2 6 100 4095 2 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE55CA30A3B 20160301202029 2 6 100 4095 2 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE55D044403 20160301203514 2 6 100 4095 2 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE55E324A43 20160301203700 2 6 100 4095 2 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE55E4D607B 20160301204309 2 6 100 4095 5 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE55EC519A7 20160301205135 2 6 100 4095 2 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE55F6BDE23 20160301205244 2 6 100 4095 2 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE55F7B0B23 20160301205520 2 6 100 4095 5 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE55FA81627 20160301205558 2 6 100 4095 5 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE55FACF2AF 20160301213318 2 6 100 4095 5 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE562B75737 20160301214847 2 6 100 4095 2 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE563F5D2EB 20160301215746 2 6 100 4095 2 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE564AA7C23 20160301220025 2 6 100 4095 2 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE564DC00EB 20160301222154 2 6 100 4095 5 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE5669AE6CF 20160301223932 2 6 100 4095 2 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE567FEFC33 20160301225302 2 6 100 4095 5 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE569139497 20160301225705 2 6 100 4095 5 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE5695E7AB7 20160301230308 2 6 100 4095 2 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE569D3D2B3 20160301230751 2 6 100 4095 2 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE56A2CD9CB 20160301231012 2 6 100 4095 2 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE56A537EDB 20160301231655 2 6 100 4095 2 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE56AD78EE3 20160301232437 2 6 100 4095 2 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE56B7299EB 20160301232518 2 6 100 4095 2 E268D4796069A7E90EC81DC69831656A982D57FD2C1E7810FD32855F3A67C150F52C2B45EC5C1183DE82AE98202BCD0CA7D1CD0A4D15AE296B23B6FCC0BD171005C939D9D1D75DEA733A6B4F3DA9A96759881B7482ABC3CF967763F261D0D6BEDDEE374F138597B347A57A4E21F8F801CD8F8A33FB3638FE0CE021E052AD5CE00E23E3A6644C844E8F79749384DBD4AC2D46B7804D797174F4BF19F92D8710B18BAE576F69449EA91681A92B0E8E95EECB47CCB0720DA611EF8686A09A7DB37726E1357EA9A1CFB7B2DB04529147BD30F96515123A7B5540890860D45C7C033DC0FAF079A0A7825C6A6DFD9B87189F2EEFBE5F68BA9B1DDA8E3BF26ECA3A8A261BF5C67E2A01C8E4BDFAA1C221950596216C69468493E424DBBCEFB8BCCF0A83C773123087F355A15EE7515BC3C6536FFCA05B50F8FB7F3A57103DDB6FA82E2B902991086E2EA9284CB09FEC7A4184EBA09A700930188711313FD16C27B338BA4BA55736E0C7B4C6E731933BD9FD7DDC80BC3A23676FF871FE3E21945BFC83B22C3992E2219F75A6C7AD05F66F2D09B8C805C2E1FFBEDBE5115FD9FB023B58B37FAFEA2CDE16C52A54BD7090C03438EF19F04D8FC630055FC96AFEA891B8CDF6016A6E101A9C27C1E6A5A3B81DC785B6E8808EF59414B58C1CBC5E3E1428DA520F1AA2E8BF6A6554F2DCA1CE30972E13BED33D2744621C763D387AE56B78E563 20160302001351 2 6 100 6143 2 D9752DD196C5E138B7F542FD56561455DDBDF05DCC107F8A5C8F393529CEBAE3CECA54E85766015CBFE1856D830D7A20385951C0941FF754570F697951C77F6FC064C28B708E8A691BDA8C6C1921C7559288EE8A024EB50D923EFF9F143E76B053D2B5FF1779C1CDC0E5856BBE4396928E605009866CFD212C68183120D5A7EA14BD3878690406069F8BC9AED334AEB6C25FD4CD9421F860893256B1A7741F729982BC109E3B6DF4D86CCFCDC1EBAB2EB13836E7988CB9F32F3EC5120E6B2DD74FF13E456A1A01E313E00A728D2ED690A656DACB1C71C6BADCA959CD944EBA762FC8B0B3CEF237386ED3D4FC6983A8F950B956DC76C09B6AAE22B5B8501B73B6E685FA40AA56139A8C02F6E0B7836E3F08EB5F9D4EC83A8BDA394FC5DA24D2CF078AE7491E3856A18FCA2C68BF9BC82ABCDE494CDFB31F82E5FE8C20D7832412F478BFC67A2B4B2CF5F266DDF53CB62372957861B95FFD2C82C46E48ACD75CAEC30E8453C8A24020ABB6143665441179478D8E33E505C2E34C1EA8F22205CA8FB31A48209BCF10ACD56B6B0060DE1836A4C9EF3C062C552C1BC8528D262FF0A2BEB56626C69A8CC7BA24F65FC39768212BB7C41BFFEDDAFD1A1528F6258F2ABC102F693425FDDF20D9EC9601FBFDC6FCD43E551C082A8A1373A1CB5E83BCD8175D9B60662D03ED5894D3EF4325180633C33FA1DD0964CC0CAEDE403146E7A5B8ED74FC6AB359EE1909A45A445429B17C04658E7F4F31F84DD194FDFBF3EF345C1B4EF2563E16351808FE4262B52D0C8AA748DF502FEF3A92C9F6A6A03BDE903DD1392177265313C08E767B003614AC6C6BFC501AAC24737BB3C8CC0160D81FC3BC6244974E1D83D15E676976F92999AEE25A66E7FE124A94D52A902E035FA5F866833D7AD3387BE2423095930671D8588E49510AEC9430ED1F03A02F3160124D893833D44FA4B51FED9044AE5B4136105466D5CD711FDFC37690183BA1D4930347148433D76B98A857EF4962FE0F48A16F20454555411EC778B248529F50503C4E0D62A122EEF42CA6BEFC7B3517CCB75A293AF2532E29FC2889DFDF880CFD33 20160302060207 2 6 100 6143 5 D9752DD196C5E138B7F542FD56561455DDBDF05DCC107F8A5C8F393529CEBAE3CECA54E85766015CBFE1856D830D7A20385951C0941FF754570F697951C77F6FC064C28B708E8A691BDA8C6C1921C7559288EE8A024EB50D923EFF9F143E76B053D2B5FF1779C1CDC0E5856BBE4396928E605009866CFD212C68183120D5A7EA14BD3878690406069F8BC9AED334AEB6C25FD4CD9421F860893256B1A7741F729982BC109E3B6DF4D86CCFCDC1EBAB2EB13836E7988CB9F32F3EC5120E6B2DD74FF13E456A1A01E313E00A728D2ED690A656DACB1C71C6BADCA959CD944EBA762FC8B0B3CEF237386ED3D4FC6983A8F950B956DC76C09B6AAE22B5B8501B73B6E685FA40AA56139A8C02F6E0B7836E3F08EB5F9D4EC83A8BDA394FC5DA24D2CF078AE7491E3856A18FCA2C68BF9BC82ABCDE494CDFB31F82E5FE8C20D7832412F478BFC67A2B4B2CF5F266DDF53CB62372957861B95FFD2C82C46E48ACD75CAEC30E8453C8A24020ABB6143665441179478D8E33E505C2E34C1EA8F22205CA8FB31A48209BCF10ACD56B6B0060DE1836A4C9EF3C062C552C1BC8528D262FF0A2BEB56626C69A8CC7BA24F65FC39768212BB7C41BFFEDDAFD1A1528F6258F2ABC102F693425FDDF20D9EC9601FBFDC6FCD43E551C082A8A1373A1CB5E83BCD8175D9B60662D03ED5894D3EF4325180633C33FA1DD0964CC0CAEDE403146E7A5B8ED74FC6AB359EE1909A45A445429B17C04658E7F4F31F84DD194FDFBF3EF345C1B4EF2563E16351808FE4262B52D0C8AA748DF502FEF3A92C9F6A6A03BDE903DD1392177265313C08E767B003614AC6C6BFC501AAC24737BB3C8CC0160D81FC3BC6244974E1D83D15E676976F92999AEE25A66E7FE124A94D52A902E035FA5F866833D7AD3387BE2423095930671D8588E49510AEC9430ED1F03A02F3160124D893833D44FA4B51FED9044AE5B4136105466D5CD711FDFC37690183BA1D4930347148433D76B98A857EF4962FE0F48A16F20454555411EC778B248529F50503C4E0D62A122EEF42CA6BEFC7B3517CCB75A293AF2532E29FC2889DFDF915C8E67 20160302080221 2 6 100 6143 2 D9752DD196C5E138B7F542FD56561455DDBDF05DCC107F8A5C8F393529CEBAE3CECA54E85766015CBFE1856D830D7A20385951C0941FF754570F697951C77F6FC064C28B708E8A691BDA8C6C1921C7559288EE8A024EB50D923EFF9F143E76B053D2B5FF1779C1CDC0E5856BBE4396928E605009866CFD212C68183120D5A7EA14BD3878690406069F8BC9AED334AEB6C25FD4CD9421F860893256B1A7741F729982BC109E3B6DF4D86CCFCDC1EBAB2EB13836E7988CB9F32F3EC5120E6B2DD74FF13E456A1A01E313E00A728D2ED690A656DACB1C71C6BADCA959CD944EBA762FC8B0B3CEF237386ED3D4FC6983A8F950B956DC76C09B6AAE22B5B8501B73B6E685FA40AA56139A8C02F6E0B7836E3F08EB5F9D4EC83A8BDA394FC5DA24D2CF078AE7491E3856A18FCA2C68BF9BC82ABCDE494CDFB31F82E5FE8C20D7832412F478BFC67A2B4B2CF5F266DDF53CB62372957861B95FFD2C82C46E48ACD75CAEC30E8453C8A24020ABB6143665441179478D8E33E505C2E34C1EA8F22205CA8FB31A48209BCF10ACD56B6B0060DE1836A4C9EF3C062C552C1BC8528D262FF0A2BEB56626C69A8CC7BA24F65FC39768212BB7C41BFFEDDAFD1A1528F6258F2ABC102F693425FDDF20D9EC9601FBFDC6FCD43E551C082A8A1373A1CB5E83BCD8175D9B60662D03ED5894D3EF4325180633C33FA1DD0964CC0CAEDE403146E7A5B8ED74FC6AB359EE1909A45A445429B17C04658E7F4F31F84DD194FDFBF3EF345C1B4EF2563E16351808FE4262B52D0C8AA748DF502FEF3A92C9F6A6A03BDE903DD1392177265313C08E767B003614AC6C6BFC501AAC24737BB3C8CC0160D81FC3BC6244974E1D83D15E676976F92999AEE25A66E7FE124A94D52A902E035FA5F866833D7AD3387BE2423095930671D8588E49510AEC9430ED1F03A02F3160124D893833D44FA4B51FED9044AE5B4136105466D5CD711FDFC37690183BA1D4930347148433D76B98A857EF4962FE0F48A16F20454555411EC778B248529F50503C4E0D62A122EEF42CA6BEFC7B3517CCB75A293AF2532E29FC2889DFDF9484D603 20160302085858 2 6 100 6143 2 D9752DD196C5E138B7F542FD56561455DDBDF05DCC107F8A5C8F393529CEBAE3CECA54E85766015CBFE1856D830D7A20385951C0941FF754570F697951C77F6FC064C28B708E8A691BDA8C6C1921C7559288EE8A024EB50D923EFF9F143E76B053D2B5FF1779C1CDC0E5856BBE4396928E605009866CFD212C68183120D5A7EA14BD3878690406069F8BC9AED334AEB6C25FD4CD9421F860893256B1A7741F729982BC109E3B6DF4D86CCFCDC1EBAB2EB13836E7988CB9F32F3EC5120E6B2DD74FF13E456A1A01E313E00A728D2ED690A656DACB1C71C6BADCA959CD944EBA762FC8B0B3CEF237386ED3D4FC6983A8F950B956DC76C09B6AAE22B5B8501B73B6E685FA40AA56139A8C02F6E0B7836E3F08EB5F9D4EC83A8BDA394FC5DA24D2CF078AE7491E3856A18FCA2C68BF9BC82ABCDE494CDFB31F82E5FE8C20D7832412F478BFC67A2B4B2CF5F266DDF53CB62372957861B95FFD2C82C46E48ACD75CAEC30E8453C8A24020ABB6143665441179478D8E33E505C2E34C1EA8F22205CA8FB31A48209BCF10ACD56B6B0060DE1836A4C9EF3C062C552C1BC8528D262FF0A2BEB56626C69A8CC7BA24F65FC39768212BB7C41BFFEDDAFD1A1528F6258F2ABC102F693425FDDF20D9EC9601FBFDC6FCD43E551C082A8A1373A1CB5E83BCD8175D9B60662D03ED5894D3EF4325180633C33FA1DD0964CC0CAEDE403146E7A5B8ED74FC6AB359EE1909A45A445429B17C04658E7F4F31F84DD194FDFBF3EF345C1B4EF2563E16351808FE4262B52D0C8AA748DF502FEF3A92C9F6A6A03BDE903DD1392177265313C08E767B003614AC6C6BFC501AAC24737BB3C8CC0160D81FC3BC6244974E1D83D15E676976F92999AEE25A66E7FE124A94D52A902E035FA5F866833D7AD3387BE2423095930671D8588E49510AEC9430ED1F03A02F3160124D893833D44FA4B51FED9044AE5B4136105466D5CD711FDFC37690183BA1D4930347148433D76B98A857EF4962FE0F48A16F20454555411EC778B248529F50503C4E0D62A122EEF42CA6BEFC7B3517CCB75A293AF2532E29FC2889DFDF95FD5243 20160302110323 2 6 100 6143 2 D9752DD196C5E138B7F542FD56561455DDBDF05DCC107F8A5C8F393529CEBAE3CECA54E85766015CBFE1856D830D7A20385951C0941FF754570F697951C77F6FC064C28B708E8A691BDA8C6C1921C7559288EE8A024EB50D923EFF9F143E76B053D2B5FF1779C1CDC0E5856BBE4396928E605009866CFD212C68183120D5A7EA14BD3878690406069F8BC9AED334AEB6C25FD4CD9421F860893256B1A7741F729982BC109E3B6DF4D86CCFCDC1EBAB2EB13836E7988CB9F32F3EC5120E6B2DD74FF13E456A1A01E313E00A728D2ED690A656DACB1C71C6BADCA959CD944EBA762FC8B0B3CEF237386ED3D4FC6983A8F950B956DC76C09B6AAE22B5B8501B73B6E685FA40AA56139A8C02F6E0B7836E3F08EB5F9D4EC83A8BDA394FC5DA24D2CF078AE7491E3856A18FCA2C68BF9BC82ABCDE494CDFB31F82E5FE8C20D7832412F478BFC67A2B4B2CF5F266DDF53CB62372957861B95FFD2C82C46E48ACD75CAEC30E8453C8A24020ABB6143665441179478D8E33E505C2E34C1EA8F22205CA8FB31A48209BCF10ACD56B6B0060DE1836A4C9EF3C062C552C1BC8528D262FF0A2BEB56626C69A8CC7BA24F65FC39768212BB7C41BFFEDDAFD1A1528F6258F2ABC102F693425FDDF20D9EC9601FBFDC6FCD43E551C082A8A1373A1CB5E83BCD8175D9B60662D03ED5894D3EF4325180633C33FA1DD0964CC0CAEDE403146E7A5B8ED74FC6AB359EE1909A45A445429B17C04658E7F4F31F84DD194FDFBF3EF345C1B4EF2563E16351808FE4262B52D0C8AA748DF502FEF3A92C9F6A6A03BDE903DD1392177265313C08E767B003614AC6C6BFC501AAC24737BB3C8CC0160D81FC3BC6244974E1D83D15E676976F92999AEE25A66E7FE124A94D52A902E035FA5F866833D7AD3387BE2423095930671D8588E49510AEC9430ED1F03A02F3160124D893833D44FA4B51FED9044AE5B4136105466D5CD711FDFC37690183BA1D4930347148433D76B98A857EF4962FE0F48A16F20454555411EC778B248529F50503C4E0D62A122EEF42CA6BEFC7B3517CCB75A293AF2532E29FC2889DFDF99425D23 20160302115537 2 6 100 6143 5 D9752DD196C5E138B7F542FD56561455DDBDF05DCC107F8A5C8F393529CEBAE3CECA54E85766015CBFE1856D830D7A20385951C0941FF754570F697951C77F6FC064C28B708E8A691BDA8C6C1921C7559288EE8A024EB50D923EFF9F143E76B053D2B5FF1779C1CDC0E5856BBE4396928E605009866CFD212C68183120D5A7EA14BD3878690406069F8BC9AED334AEB6C25FD4CD9421F860893256B1A7741F729982BC109E3B6DF4D86CCFCDC1EBAB2EB13836E7988CB9F32F3EC5120E6B2DD74FF13E456A1A01E313E00A728D2ED690A656DACB1C71C6BADCA959CD944EBA762FC8B0B3CEF237386ED3D4FC6983A8F950B956DC76C09B6AAE22B5B8501B73B6E685FA40AA56139A8C02F6E0B7836E3F08EB5F9D4EC83A8BDA394FC5DA24D2CF078AE7491E3856A18FCA2C68BF9BC82ABCDE494CDFB31F82E5FE8C20D7832412F478BFC67A2B4B2CF5F266DDF53CB62372957861B95FFD2C82C46E48ACD75CAEC30E8453C8A24020ABB6143665441179478D8E33E505C2E34C1EA8F22205CA8FB31A48209BCF10ACD56B6B0060DE1836A4C9EF3C062C552C1BC8528D262FF0A2BEB56626C69A8CC7BA24F65FC39768212BB7C41BFFEDDAFD1A1528F6258F2ABC102F693425FDDF20D9EC9601FBFDC6FCD43E551C082A8A1373A1CB5E83BCD8175D9B60662D03ED5894D3EF4325180633C33FA1DD0964CC0CAEDE403146E7A5B8ED74FC6AB359EE1909A45A445429B17C04658E7F4F31F84DD194FDFBF3EF345C1B4EF2563E16351808FE4262B52D0C8AA748DF502FEF3A92C9F6A6A03BDE903DD1392177265313C08E767B003614AC6C6BFC501AAC24737BB3C8CC0160D81FC3BC6244974E1D83D15E676976F92999AEE25A66E7FE124A94D52A902E035FA5F866833D7AD3387BE2423095930671D8588E49510AEC9430ED1F03A02F3160124D893833D44FA4B51FED9044AE5B4136105466D5CD711FDFC37690183BA1D4930347148433D76B98A857EF4962FE0F48A16F20454555411EC778B248529F50503C4E0D62A122EEF42CA6BEFC7B3517CCB75A293AF2532E29FC2889DFDF9AA4530F 20160302121026 2 6 100 6143 2 D9752DD196C5E138B7F542FD56561455DDBDF05DCC107F8A5C8F393529CEBAE3CECA54E85766015CBFE1856D830D7A20385951C0941FF754570F697951C77F6FC064C28B708E8A691BDA8C6C1921C7559288EE8A024EB50D923EFF9F143E76B053D2B5FF1779C1CDC0E5856BBE4396928E605009866CFD212C68183120D5A7EA14BD3878690406069F8BC9AED334AEB6C25FD4CD9421F860893256B1A7741F729982BC109E3B6DF4D86CCFCDC1EBAB2EB13836E7988CB9F32F3EC5120E6B2DD74FF13E456A1A01E313E00A728D2ED690A656DACB1C71C6BADCA959CD944EBA762FC8B0B3CEF237386ED3D4FC6983A8F950B956DC76C09B6AAE22B5B8501B73B6E685FA40AA56139A8C02F6E0B7836E3F08EB5F9D4EC83A8BDA394FC5DA24D2CF078AE7491E3856A18FCA2C68BF9BC82ABCDE494CDFB31F82E5FE8C20D7832412F478BFC67A2B4B2CF5F266DDF53CB62372957861B95FFD2C82C46E48ACD75CAEC30E8453C8A24020ABB6143665441179478D8E33E505C2E34C1EA8F22205CA8FB31A48209BCF10ACD56B6B0060DE1836A4C9EF3C062C552C1BC8528D262FF0A2BEB56626C69A8CC7BA24F65FC39768212BB7C41BFFEDDAFD1A1528F6258F2ABC102F693425FDDF20D9EC9601FBFDC6FCD43E551C082A8A1373A1CB5E83BCD8175D9B60662D03ED5894D3EF4325180633C33FA1DD0964CC0CAEDE403146E7A5B8ED74FC6AB359EE1909A45A445429B17C04658E7F4F31F84DD194FDFBF3EF345C1B4EF2563E16351808FE4262B52D0C8AA748DF502FEF3A92C9F6A6A03BDE903DD1392177265313C08E767B003614AC6C6BFC501AAC24737BB3C8CC0160D81FC3BC6244974E1D83D15E676976F92999AEE25A66E7FE124A94D52A902E035FA5F866833D7AD3387BE2423095930671D8588E49510AEC9430ED1F03A02F3160124D893833D44FA4B51FED9044AE5B4136105466D5CD711FDFC37690183BA1D4930347148433D76B98A857EF4962FE0F48A16F20454555411EC778B248529F50503C4E0D62A122EEF42CA6BEFC7B3517CCB75A293AF2532E29FC2889DFDF9AFF17B3 20160302125303 2 6 100 6143 2 D9752DD196C5E138B7F542FD56561455DDBDF05DCC107F8A5C8F393529CEBAE3CECA54E85766015CBFE1856D830D7A20385951C0941FF754570F697951C77F6FC064C28B708E8A691BDA8C6C1921C7559288EE8A024EB50D923EFF9F143E76B053D2B5FF1779C1CDC0E5856BBE4396928E605009866CFD212C68183120D5A7EA14BD3878690406069F8BC9AED334AEB6C25FD4CD9421F860893256B1A7741F729982BC109E3B6DF4D86CCFCDC1EBAB2EB13836E7988CB9F32F3EC5120E6B2DD74FF13E456A1A01E313E00A728D2ED690A656DACB1C71C6BADCA959CD944EBA762FC8B0B3CEF237386ED3D4FC6983A8F950B956DC76C09B6AAE22B5B8501B73B6E685FA40AA56139A8C02F6E0B7836E3F08EB5F9D4EC83A8BDA394FC5DA24D2CF078AE7491E3856A18FCA2C68BF9BC82ABCDE494CDFB31F82E5FE8C20D7832412F478BFC67A2B4B2CF5F266DDF53CB62372957861B95FFD2C82C46E48ACD75CAEC30E8453C8A24020ABB6143665441179478D8E33E505C2E34C1EA8F22205CA8FB31A48209BCF10ACD56B6B0060DE1836A4C9EF3C062C552C1BC8528D262FF0A2BEB56626C69A8CC7BA24F65FC39768212BB7C41BFFEDDAFD1A1528F6258F2ABC102F693425FDDF20D9EC9601FBFDC6FCD43E551C082A8A1373A1CB5E83BCD8175D9B60662D03ED5894D3EF4325180633C33FA1DD0964CC0CAEDE403146E7A5B8ED74FC6AB359EE1909A45A445429B17C04658E7F4F31F84DD194FDFBF3EF345C1B4EF2563E16351808FE4262B52D0C8AA748DF502FEF3A92C9F6A6A03BDE903DD1392177265313C08E767B003614AC6C6BFC501AAC24737BB3C8CC0160D81FC3BC6244974E1D83D15E676976F92999AEE25A66E7FE124A94D52A902E035FA5F866833D7AD3387BE2423095930671D8588E49510AEC9430ED1F03A02F3160124D893833D44FA4B51FED9044AE5B4136105466D5CD711FDFC37690183BA1D4930347148433D76B98A857EF4962FE0F48A16F20454555411EC778B248529F50503C4E0D62A122EEF42CA6BEFC7B3517CCB75A293AF2532E29FC2889DFDF9C1752FB 20160302132855 2 6 100 6143 2 D9752DD196C5E138B7F542FD56561455DDBDF05DCC107F8A5C8F393529CEBAE3CECA54E85766015CBFE1856D830D7A20385951C0941FF754570F697951C77F6FC064C28B708E8A691BDA8C6C1921C7559288EE8A024EB50D923EFF9F143E76B053D2B5FF1779C1CDC0E5856BBE4396928E605009866CFD212C68183120D5A7EA14BD3878690406069F8BC9AED334AEB6C25FD4CD9421F860893256B1A7741F729982BC109E3B6DF4D86CCFCDC1EBAB2EB13836E7988CB9F32F3EC5120E6B2DD74FF13E456A1A01E313E00A728D2ED690A656DACB1C71C6BADCA959CD944EBA762FC8B0B3CEF237386ED3D4FC6983A8F950B956DC76C09B6AAE22B5B8501B73B6E685FA40AA56139A8C02F6E0B7836E3F08EB5F9D4EC83A8BDA394FC5DA24D2CF078AE7491E3856A18FCA2C68BF9BC82ABCDE494CDFB31F82E5FE8C20D7832412F478BFC67A2B4B2CF5F266DDF53CB62372957861B95FFD2C82C46E48ACD75CAEC30E8453C8A24020ABB6143665441179478D8E33E505C2E34C1EA8F22205CA8FB31A48209BCF10ACD56B6B0060DE1836A4C9EF3C062C552C1BC8528D262FF0A2BEB56626C69A8CC7BA24F65FC39768212BB7C41BFFEDDAFD1A1528F6258F2ABC102F693425FDDF20D9EC9601FBFDC6FCD43E551C082A8A1373A1CB5E83BCD8175D9B60662D03ED5894D3EF4325180633C33FA1DD0964CC0CAEDE403146E7A5B8ED74FC6AB359EE1909A45A445429B17C04658E7F4F31F84DD194FDFBF3EF345C1B4EF2563E16351808FE4262B52D0C8AA748DF502FEF3A92C9F6A6A03BDE903DD1392177265313C08E767B003614AC6C6BFC501AAC24737BB3C8CC0160D81FC3BC6244974E1D83D15E676976F92999AEE25A66E7FE124A94D52A902E035FA5F866833D7AD3387BE2423095930671D8588E49510AEC9430ED1F03A02F3160124D893833D44FA4B51FED9044AE5B4136105466D5CD711FDFC37690183BA1D4930347148433D76B98A857EF4962FE0F48A16F20454555411EC778B248529F50503C4E0D62A122EEF42CA6BEFC7B3517CCB75A293AF2532E29FC2889DFDF9D055A3B 20160302145027 2 6 100 6143 2 D9752DD196C5E138B7F542FD56561455DDBDF05DCC107F8A5C8F393529CEBAE3CECA54E85766015CBFE1856D830D7A20385951C0941FF754570F697951C77F6FC064C28B708E8A691BDA8C6C1921C7559288EE8A024EB50D923EFF9F143E76B053D2B5FF1779C1CDC0E5856BBE4396928E605009866CFD212C68183120D5A7EA14BD3878690406069F8BC9AED334AEB6C25FD4CD9421F860893256B1A7741F729982BC109E3B6DF4D86CCFCDC1EBAB2EB13836E7988CB9F32F3EC5120E6B2DD74FF13E456A1A01E313E00A728D2ED690A656DACB1C71C6BADCA959CD944EBA762FC8B0B3CEF237386ED3D4FC6983A8F950B956DC76C09B6AAE22B5B8501B73B6E685FA40AA56139A8C02F6E0B7836E3F08EB5F9D4EC83A8BDA394FC5DA24D2CF078AE7491E3856A18FCA2C68BF9BC82ABCDE494CDFB31F82E5FE8C20D7832412F478BFC67A2B4B2CF5F266DDF53CB62372957861B95FFD2C82C46E48ACD75CAEC30E8453C8A24020ABB6143665441179478D8E33E505C2E34C1EA8F22205CA8FB31A48209BCF10ACD56B6B0060DE1836A4C9EF3C062C552C1BC8528D262FF0A2BEB56626C69A8CC7BA24F65FC39768212BB7C41BFFEDDAFD1A1528F6258F2ABC102F693425FDDF20D9EC9601FBFDC6FCD43E551C082A8A1373A1CB5E83BCD8175D9B60662D03ED5894D3EF4325180633C33FA1DD0964CC0CAEDE403146E7A5B8ED74FC6AB359EE1909A45A445429B17C04658E7F4F31F84DD194FDFBF3EF345C1B4EF2563E16351808FE4262B52D0C8AA748DF502FEF3A92C9F6A6A03BDE903DD1392177265313C08E767B003614AC6C6BFC501AAC24737BB3C8CC0160D81FC3BC6244974E1D83D15E676976F92999AEE25A66E7FE124A94D52A902E035FA5F866833D7AD3387BE2423095930671D8588E49510AEC9430ED1F03A02F3160124D893833D44FA4B51FED9044AE5B4136105466D5CD711FDFC37690183BA1D4930347148433D76B98A857EF4962FE0F48A16F20454555411EC778B248529F50503C4E0D62A122EEF42CA6BEFC7B3517CCB75A293AF2532E29FC2889DFDF9F210C3B 20160302160128 2 6 100 6143 5 D9752DD196C5E138B7F542FD56561455DDBDF05DCC107F8A5C8F393529CEBAE3CECA54E85766015CBFE1856D830D7A20385951C0941FF754570F697951C77F6FC064C28B708E8A691BDA8C6C1921C7559288EE8A024EB50D923EFF9F143E76B053D2B5FF1779C1CDC0E5856BBE4396928E605009866CFD212C68183120D5A7EA14BD3878690406069F8BC9AED334AEB6C25FD4CD9421F860893256B1A7741F729982BC109E3B6DF4D86CCFCDC1EBAB2EB13836E7988CB9F32F3EC5120E6B2DD74FF13E456A1A01E313E00A728D2ED690A656DACB1C71C6BADCA959CD944EBA762FC8B0B3CEF237386ED3D4FC6983A8F950B956DC76C09B6AAE22B5B8501B73B6E685FA40AA56139A8C02F6E0B7836E3F08EB5F9D4EC83A8BDA394FC5DA24D2CF078AE7491E3856A18FCA2C68BF9BC82ABCDE494CDFB31F82E5FE8C20D7832412F478BFC67A2B4B2CF5F266DDF53CB62372957861B95FFD2C82C46E48ACD75CAEC30E8453C8A24020ABB6143665441179478D8E33E505C2E34C1EA8F22205CA8FB31A48209BCF10ACD56B6B0060DE1836A4C9EF3C062C552C1BC8528D262FF0A2BEB56626C69A8CC7BA24F65FC39768212BB7C41BFFEDDAFD1A1528F6258F2ABC102F693425FDDF20D9EC9601FBFDC6FCD43E551C082A8A1373A1CB5E83BCD8175D9B60662D03ED5894D3EF4325180633C33FA1DD0964CC0CAEDE403146E7A5B8ED74FC6AB359EE1909A45A445429B17C04658E7F4F31F84DD194FDFBF3EF345C1B4EF2563E16351808FE4262B52D0C8AA748DF502FEF3A92C9F6A6A03BDE903DD1392177265313C08E767B003614AC6C6BFC501AAC24737BB3C8CC0160D81FC3BC6244974E1D83D15E676976F92999AEE25A66E7FE124A94D52A902E035FA5F866833D7AD3387BE2423095930671D8588E49510AEC9430ED1F03A02F3160124D893833D44FA4B51FED9044AE5B4136105466D5CD711FDFC37690183BA1D4930347148433D76B98A857EF4962FE0F48A16F20454555411EC778B248529F50503C4E0D62A122EEF42CA6BEFC7B3517CCB75A293AF2532E29FC2889DFDFA0F799CF 20160302164318 2 6 100 6143 2 D9752DD196C5E138B7F542FD56561455DDBDF05DCC107F8A5C8F393529CEBAE3CECA54E85766015CBFE1856D830D7A20385951C0941FF754570F697951C77F6FC064C28B708E8A691BDA8C6C1921C7559288EE8A024EB50D923EFF9F143E76B053D2B5FF1779C1CDC0E5856BBE4396928E605009866CFD212C68183120D5A7EA14BD3878690406069F8BC9AED334AEB6C25FD4CD9421F860893256B1A7741F729982BC109E3B6DF4D86CCFCDC1EBAB2EB13836E7988CB9F32F3EC5120E6B2DD74FF13E456A1A01E313E00A728D2ED690A656DACB1C71C6BADCA959CD944EBA762FC8B0B3CEF237386ED3D4FC6983A8F950B956DC76C09B6AAE22B5B8501B73B6E685FA40AA56139A8C02F6E0B7836E3F08EB5F9D4EC83A8BDA394FC5DA24D2CF078AE7491E3856A18FCA2C68BF9BC82ABCDE494CDFB31F82E5FE8C20D7832412F478BFC67A2B4B2CF5F266DDF53CB62372957861B95FFD2C82C46E48ACD75CAEC30E8453C8A24020ABB6143665441179478D8E33E505C2E34C1EA8F22205CA8FB31A48209BCF10ACD56B6B0060DE1836A4C9EF3C062C552C1BC8528D262FF0A2BEB56626C69A8CC7BA24F65FC39768212BB7C41BFFEDDAFD1A1528F6258F2ABC102F693425FDDF20D9EC9601FBFDC6FCD43E551C082A8A1373A1CB5E83BCD8175D9B60662D03ED5894D3EF4325180633C33FA1DD0964CC0CAEDE403146E7A5B8ED74FC6AB359EE1909A45A445429B17C04658E7F4F31F84DD194FDFBF3EF345C1B4EF2563E16351808FE4262B52D0C8AA748DF502FEF3A92C9F6A6A03BDE903DD1392177265313C08E767B003614AC6C6BFC501AAC24737BB3C8CC0160D81FC3BC6244974E1D83D15E676976F92999AEE25A66E7FE124A94D52A902E035FA5F866833D7AD3387BE2423095930671D8588E49510AEC9430ED1F03A02F3160124D893833D44FA4B51FED9044AE5B4136105466D5CD711FDFC37690183BA1D4930347148433D76B98A857EF4962FE0F48A16F20454555411EC778B248529F50503C4E0D62A122EEF42CA6BEFC7B3517CCB75A293AF2532E29FC2889DFDFA205C49B 20160302193543 2 6 100 6143 2 D9752DD196C5E138B7F542FD56561455DDBDF05DCC107F8A5C8F393529CEBAE3CECA54E85766015CBFE1856D830D7A20385951C0941FF754570F697951C77F6FC064C28B708E8A691BDA8C6C1921C7559288EE8A024EB50D923EFF9F143E76B053D2B5FF1779C1CDC0E5856BBE4396928E605009866CFD212C68183120D5A7EA14BD3878690406069F8BC9AED334AEB6C25FD4CD9421F860893256B1A7741F729982BC109E3B6DF4D86CCFCDC1EBAB2EB13836E7988CB9F32F3EC5120E6B2DD74FF13E456A1A01E313E00A728D2ED690A656DACB1C71C6BADCA959CD944EBA762FC8B0B3CEF237386ED3D4FC6983A8F950B956DC76C09B6AAE22B5B8501B73B6E685FA40AA56139A8C02F6E0B7836E3F08EB5F9D4EC83A8BDA394FC5DA24D2CF078AE7491E3856A18FCA2C68BF9BC82ABCDE494CDFB31F82E5FE8C20D7832412F478BFC67A2B4B2CF5F266DDF53CB62372957861B95FFD2C82C46E48ACD75CAEC30E8453C8A24020ABB6143665441179478D8E33E505C2E34C1EA8F22205CA8FB31A48209BCF10ACD56B6B0060DE1836A4C9EF3C062C552C1BC8528D262FF0A2BEB56626C69A8CC7BA24F65FC39768212BB7C41BFFEDDAFD1A1528F6258F2ABC102F693425FDDF20D9EC9601FBFDC6FCD43E551C082A8A1373A1CB5E83BCD8175D9B60662D03ED5894D3EF4325180633C33FA1DD0964CC0CAEDE403146E7A5B8ED74FC6AB359EE1909A45A445429B17C04658E7F4F31F84DD194FDFBF3EF345C1B4EF2563E16351808FE4262B52D0C8AA748DF502FEF3A92C9F6A6A03BDE903DD1392177265313C08E767B003614AC6C6BFC501AAC24737BB3C8CC0160D81FC3BC6244974E1D83D15E676976F92999AEE25A66E7FE124A94D52A902E035FA5F866833D7AD3387BE2423095930671D8588E49510AEC9430ED1F03A02F3160124D893833D44FA4B51FED9044AE5B4136105466D5CD711FDFC37690183BA1D4930347148433D76B98A857EF4962FE0F48A16F20454555411EC778B248529F50503C4E0D62A122EEF42CA6BEFC7B3517CCB75A293AF2532E29FC2889DFDFA66F725B 20160302223446 2 6 100 6143 5 D9752DD196C5E138B7F542FD56561455DDBDF05DCC107F8A5C8F393529CEBAE3CECA54E85766015CBFE1856D830D7A20385951C0941FF754570F697951C77F6FC064C28B708E8A691BDA8C6C1921C7559288EE8A024EB50D923EFF9F143E76B053D2B5FF1779C1CDC0E5856BBE4396928E605009866CFD212C68183120D5A7EA14BD3878690406069F8BC9AED334AEB6C25FD4CD9421F860893256B1A7741F729982BC109E3B6DF4D86CCFCDC1EBAB2EB13836E7988CB9F32F3EC5120E6B2DD74FF13E456A1A01E313E00A728D2ED690A656DACB1C71C6BADCA959CD944EBA762FC8B0B3CEF237386ED3D4FC6983A8F950B956DC76C09B6AAE22B5B8501B73B6E685FA40AA56139A8C02F6E0B7836E3F08EB5F9D4EC83A8BDA394FC5DA24D2CF078AE7491E3856A18FCA2C68BF9BC82ABCDE494CDFB31F82E5FE8C20D7832412F478BFC67A2B4B2CF5F266DDF53CB62372957861B95FFD2C82C46E48ACD75CAEC30E8453C8A24020ABB6143665441179478D8E33E505C2E34C1EA8F22205CA8FB31A48209BCF10ACD56B6B0060DE1836A4C9EF3C062C552C1BC8528D262FF0A2BEB56626C69A8CC7BA24F65FC39768212BB7C41BFFEDDAFD1A1528F6258F2ABC102F693425FDDF20D9EC9601FBFDC6FCD43E551C082A8A1373A1CB5E83BCD8175D9B60662D03ED5894D3EF4325180633C33FA1DD0964CC0CAEDE403146E7A5B8ED74FC6AB359EE1909A45A445429B17C04658E7F4F31F84DD194FDFBF3EF345C1B4EF2563E16351808FE4262B52D0C8AA748DF502FEF3A92C9F6A6A03BDE903DD1392177265313C08E767B003614AC6C6BFC501AAC24737BB3C8CC0160D81FC3BC6244974E1D83D15E676976F92999AEE25A66E7FE124A94D52A902E035FA5F866833D7AD3387BE2423095930671D8588E49510AEC9430ED1F03A02F3160124D893833D44FA4B51FED9044AE5B4136105466D5CD711FDFC37690183BA1D4930347148433D76B98A857EF4962FE0F48A16F20454555411EC778B248529F50503C4E0D62A122EEF42CA6BEFC7B3517CCB75A293AF2532E29FC2889DFDFAB045BFF 20160302230706 2 6 100 6143 5 D9752DD196C5E138B7F542FD56561455DDBDF05DCC107F8A5C8F393529CEBAE3CECA54E85766015CBFE1856D830D7A20385951C0941FF754570F697951C77F6FC064C28B708E8A691BDA8C6C1921C7559288EE8A024EB50D923EFF9F143E76B053D2B5FF1779C1CDC0E5856BBE4396928E605009866CFD212C68183120D5A7EA14BD3878690406069F8BC9AED334AEB6C25FD4CD9421F860893256B1A7741F729982BC109E3B6DF4D86CCFCDC1EBAB2EB13836E7988CB9F32F3EC5120E6B2DD74FF13E456A1A01E313E00A728D2ED690A656DACB1C71C6BADCA959CD944EBA762FC8B0B3CEF237386ED3D4FC6983A8F950B956DC76C09B6AAE22B5B8501B73B6E685FA40AA56139A8C02F6E0B7836E3F08EB5F9D4EC83A8BDA394FC5DA24D2CF078AE7491E3856A18FCA2C68BF9BC82ABCDE494CDFB31F82E5FE8C20D7832412F478BFC67A2B4B2CF5F266DDF53CB62372957861B95FFD2C82C46E48ACD75CAEC30E8453C8A24020ABB6143665441179478D8E33E505C2E34C1EA8F22205CA8FB31A48209BCF10ACD56B6B0060DE1836A4C9EF3C062C552C1BC8528D262FF0A2BEB56626C69A8CC7BA24F65FC39768212BB7C41BFFEDDAFD1A1528F6258F2ABC102F693425FDDF20D9EC9601FBFDC6FCD43E551C082A8A1373A1CB5E83BCD8175D9B60662D03ED5894D3EF4325180633C33FA1DD0964CC0CAEDE403146E7A5B8ED74FC6AB359EE1909A45A445429B17C04658E7F4F31F84DD194FDFBF3EF345C1B4EF2563E16351808FE4262B52D0C8AA748DF502FEF3A92C9F6A6A03BDE903DD1392177265313C08E767B003614AC6C6BFC501AAC24737BB3C8CC0160D81FC3BC6244974E1D83D15E676976F92999AEE25A66E7FE124A94D52A902E035FA5F866833D7AD3387BE2423095930671D8588E49510AEC9430ED1F03A02F3160124D893833D44FA4B51FED9044AE5B4136105466D5CD711FDFC37690183BA1D4930347148433D76B98A857EF4962FE0F48A16F20454555411EC778B248529F50503C4E0D62A122EEF42CA6BEFC7B3517CCB75A293AF2532E29FC2889DFDFABD44B9F 20160303005014 2 6 100 6143 2 D9752DD196C5E138B7F542FD56561455DDBDF05DCC107F8A5C8F393529CEBAE3CECA54E85766015CBFE1856D830D7A20385951C0941FF754570F697951C77F6FC064C28B708E8A691BDA8C6C1921C7559288EE8A024EB50D923EFF9F143E76B053D2B5FF1779C1CDC0E5856BBE4396928E605009866CFD212C68183120D5A7EA14BD3878690406069F8BC9AED334AEB6C25FD4CD9421F860893256B1A7741F729982BC109E3B6DF4D86CCFCDC1EBAB2EB13836E7988CB9F32F3EC5120E6B2DD74FF13E456A1A01E313E00A728D2ED690A656DACB1C71C6BADCA959CD944EBA762FC8B0B3CEF237386ED3D4FC6983A8F950B956DC76C09B6AAE22B5B8501B73B6E685FA40AA56139A8C02F6E0B7836E3F08EB5F9D4EC83A8BDA394FC5DA24D2CF078AE7491E3856A18FCA2C68BF9BC82ABCDE494CDFB31F82E5FE8C20D7832412F478BFC67A2B4B2CF5F266DDF53CB62372957861B95FFD2C82C46E48ACD75CAEC30E8453C8A24020ABB6143665441179478D8E33E505C2E34C1EA8F22205CA8FB31A48209BCF10ACD56B6B0060DE1836A4C9EF3C062C552C1BC8528D262FF0A2BEB56626C69A8CC7BA24F65FC39768212BB7C41BFFEDDAFD1A1528F6258F2ABC102F693425FDDF20D9EC9601FBFDC6FCD43E551C082A8A1373A1CB5E83BCD8175D9B60662D03ED5894D3EF4325180633C33FA1DD0964CC0CAEDE403146E7A5B8ED74FC6AB359EE1909A45A445429B17C04658E7F4F31F84DD194FDFBF3EF345C1B4EF2563E16351808FE4262B52D0C8AA748DF502FEF3A92C9F6A6A03BDE903DD1392177265313C08E767B003614AC6C6BFC501AAC24737BB3C8CC0160D81FC3BC6244974E1D83D15E676976F92999AEE25A66E7FE124A94D52A902E035FA5F866833D7AD3387BE2423095930671D8588E49510AEC9430ED1F03A02F3160124D893833D44FA4B51FED9044AE5B4136105466D5CD711FDFC37690183BA1D4930347148433D76B98A857EF4962FE0F48A16F20454555411EC778B248529F50503C4E0D62A122EEF42CA6BEFC7B3517CCB75A293AF2532E29FC2889DFDFAE7817DB 20160303013053 2 6 100 6143 2 D9752DD196C5E138B7F542FD56561455DDBDF05DCC107F8A5C8F393529CEBAE3CECA54E85766015CBFE1856D830D7A20385951C0941FF754570F697951C77F6FC064C28B708E8A691BDA8C6C1921C7559288EE8A024EB50D923EFF9F143E76B053D2B5FF1779C1CDC0E5856BBE4396928E605009866CFD212C68183120D5A7EA14BD3878690406069F8BC9AED334AEB6C25FD4CD9421F860893256B1A7741F729982BC109E3B6DF4D86CCFCDC1EBAB2EB13836E7988CB9F32F3EC5120E6B2DD74FF13E456A1A01E313E00A728D2ED690A656DACB1C71C6BADCA959CD944EBA762FC8B0B3CEF237386ED3D4FC6983A8F950B956DC76C09B6AAE22B5B8501B73B6E685FA40AA56139A8C02F6E0B7836E3F08EB5F9D4EC83A8BDA394FC5DA24D2CF078AE7491E3856A18FCA2C68BF9BC82ABCDE494CDFB31F82E5FE8C20D7832412F478BFC67A2B4B2CF5F266DDF53CB62372957861B95FFD2C82C46E48ACD75CAEC30E8453C8A24020ABB6143665441179478D8E33E505C2E34C1EA8F22205CA8FB31A48209BCF10ACD56B6B0060DE1836A4C9EF3C062C552C1BC8528D262FF0A2BEB56626C69A8CC7BA24F65FC39768212BB7C41BFFEDDAFD1A1528F6258F2ABC102F693425FDDF20D9EC9601FBFDC6FCD43E551C082A8A1373A1CB5E83BCD8175D9B60662D03ED5894D3EF4325180633C33FA1DD0964CC0CAEDE403146E7A5B8ED74FC6AB359EE1909A45A445429B17C04658E7F4F31F84DD194FDFBF3EF345C1B4EF2563E16351808FE4262B52D0C8AA748DF502FEF3A92C9F6A6A03BDE903DD1392177265313C08E767B003614AC6C6BFC501AAC24737BB3C8CC0160D81FC3BC6244974E1D83D15E676976F92999AEE25A66E7FE124A94D52A902E035FA5F866833D7AD3387BE2423095930671D8588E49510AEC9430ED1F03A02F3160124D893833D44FA4B51FED9044AE5B4136105466D5CD711FDFC37690183BA1D4930347148433D76B98A857EF4962FE0F48A16F20454555411EC778B248529F50503C4E0D62A122EEF42CA6BEFC7B3517CCB75A293AF2532E29FC2889DFDFAF76805B 20160303031806 2 6 100 6143 2 D9752DD196C5E138B7F542FD56561455DDBDF05DCC107F8A5C8F393529CEBAE3CECA54E85766015CBFE1856D830D7A20385951C0941FF754570F697951C77F6FC064C28B708E8A691BDA8C6C1921C7559288EE8A024EB50D923EFF9F143E76B053D2B5FF1779C1CDC0E5856BBE4396928E605009866CFD212C68183120D5A7EA14BD3878690406069F8BC9AED334AEB6C25FD4CD9421F860893256B1A7741F729982BC109E3B6DF4D86CCFCDC1EBAB2EB13836E7988CB9F32F3EC5120E6B2DD74FF13E456A1A01E313E00A728D2ED690A656DACB1C71C6BADCA959CD944EBA762FC8B0B3CEF237386ED3D4FC6983A8F950B956DC76C09B6AAE22B5B8501B73B6E685FA40AA56139A8C02F6E0B7836E3F08EB5F9D4EC83A8BDA394FC5DA24D2CF078AE7491E3856A18FCA2C68BF9BC82ABCDE494CDFB31F82E5FE8C20D7832412F478BFC67A2B4B2CF5F266DDF53CB62372957861B95FFD2C82C46E48ACD75CAEC30E8453C8A24020ABB6143665441179478D8E33E505C2E34C1EA8F22205CA8FB31A48209BCF10ACD56B6B0060DE1836A4C9EF3C062C552C1BC8528D262FF0A2BEB56626C69A8CC7BA24F65FC39768212BB7C41BFFEDDAFD1A1528F6258F2ABC102F693425FDDF20D9EC9601FBFDC6FCD43E551C082A8A1373A1CB5E83BCD8175D9B60662D03ED5894D3EF4325180633C33FA1DD0964CC0CAEDE403146E7A5B8ED74FC6AB359EE1909A45A445429B17C04658E7F4F31F84DD194FDFBF3EF345C1B4EF2563E16351808FE4262B52D0C8AA748DF502FEF3A92C9F6A6A03BDE903DD1392177265313C08E767B003614AC6C6BFC501AAC24737BB3C8CC0160D81FC3BC6244974E1D83D15E676976F92999AEE25A66E7FE124A94D52A902E035FA5F866833D7AD3387BE2423095930671D8588E49510AEC9430ED1F03A02F3160124D893833D44FA4B51FED9044AE5B4136105466D5CD711FDFC37690183BA1D4930347148433D76B98A857EF4962FE0F48A16F20454555411EC778B248529F50503C4E0D62A122EEF42CA6BEFC7B3517CCB75A293AF2532E29FC2889DFDFB234F5BB 20160303034446 2 6 100 6143 2 D9752DD196C5E138B7F542FD56561455DDBDF05DCC107F8A5C8F393529CEBAE3CECA54E85766015CBFE1856D830D7A20385951C0941FF754570F697951C77F6FC064C28B708E8A691BDA8C6C1921C7559288EE8A024EB50D923EFF9F143E76B053D2B5FF1779C1CDC0E5856BBE4396928E605009866CFD212C68183120D5A7EA14BD3878690406069F8BC9AED334AEB6C25FD4CD9421F860893256B1A7741F729982BC109E3B6DF4D86CCFCDC1EBAB2EB13836E7988CB9F32F3EC5120E6B2DD74FF13E456A1A01E313E00A728D2ED690A656DACB1C71C6BADCA959CD944EBA762FC8B0B3CEF237386ED3D4FC6983A8F950B956DC76C09B6AAE22B5B8501B73B6E685FA40AA56139A8C02F6E0B7836E3F08EB5F9D4EC83A8BDA394FC5DA24D2CF078AE7491E3856A18FCA2C68BF9BC82ABCDE494CDFB31F82E5FE8C20D7832412F478BFC67A2B4B2CF5F266DDF53CB62372957861B95FFD2C82C46E48ACD75CAEC30E8453C8A24020ABB6143665441179478D8E33E505C2E34C1EA8F22205CA8FB31A48209BCF10ACD56B6B0060DE1836A4C9EF3C062C552C1BC8528D262FF0A2BEB56626C69A8CC7BA24F65FC39768212BB7C41BFFEDDAFD1A1528F6258F2ABC102F693425FDDF20D9EC9601FBFDC6FCD43E551C082A8A1373A1CB5E83BCD8175D9B60662D03ED5894D3EF4325180633C33FA1DD0964CC0CAEDE403146E7A5B8ED74FC6AB359EE1909A45A445429B17C04658E7F4F31F84DD194FDFBF3EF345C1B4EF2563E16351808FE4262B52D0C8AA748DF502FEF3A92C9F6A6A03BDE903DD1392177265313C08E767B003614AC6C6BFC501AAC24737BB3C8CC0160D81FC3BC6244974E1D83D15E676976F92999AEE25A66E7FE124A94D52A902E035FA5F866833D7AD3387BE2423095930671D8588E49510AEC9430ED1F03A02F3160124D893833D44FA4B51FED9044AE5B4136105466D5CD711FDFC37690183BA1D4930347148433D76B98A857EF4962FE0F48A16F20454555411EC778B248529F50503C4E0D62A122EEF42CA6BEFC7B3517CCB75A293AF2532E29FC2889DFDFB2DCD713 20160303042131 2 6 100 6143 2 D9752DD196C5E138B7F542FD56561455DDBDF05DCC107F8A5C8F393529CEBAE3CECA54E85766015CBFE1856D830D7A20385951C0941FF754570F697951C77F6FC064C28B708E8A691BDA8C6C1921C7559288EE8A024EB50D923EFF9F143E76B053D2B5FF1779C1CDC0E5856BBE4396928E605009866CFD212C68183120D5A7EA14BD3878690406069F8BC9AED334AEB6C25FD4CD9421F860893256B1A7741F729982BC109E3B6DF4D86CCFCDC1EBAB2EB13836E7988CB9F32F3EC5120E6B2DD74FF13E456A1A01E313E00A728D2ED690A656DACB1C71C6BADCA959CD944EBA762FC8B0B3CEF237386ED3D4FC6983A8F950B956DC76C09B6AAE22B5B8501B73B6E685FA40AA56139A8C02F6E0B7836E3F08EB5F9D4EC83A8BDA394FC5DA24D2CF078AE7491E3856A18FCA2C68BF9BC82ABCDE494CDFB31F82E5FE8C20D7832412F478BFC67A2B4B2CF5F266DDF53CB62372957861B95FFD2C82C46E48ACD75CAEC30E8453C8A24020ABB6143665441179478D8E33E505C2E34C1EA8F22205CA8FB31A48209BCF10ACD56B6B0060DE1836A4C9EF3C062C552C1BC8528D262FF0A2BEB56626C69A8CC7BA24F65FC39768212BB7C41BFFEDDAFD1A1528F6258F2ABC102F693425FDDF20D9EC9601FBFDC6FCD43E551C082A8A1373A1CB5E83BCD8175D9B60662D03ED5894D3EF4325180633C33FA1DD0964CC0CAEDE403146E7A5B8ED74FC6AB359EE1909A45A445429B17C04658E7F4F31F84DD194FDFBF3EF345C1B4EF2563E16351808FE4262B52D0C8AA748DF502FEF3A92C9F6A6A03BDE903DD1392177265313C08E767B003614AC6C6BFC501AAC24737BB3C8CC0160D81FC3BC6244974E1D83D15E676976F92999AEE25A66E7FE124A94D52A902E035FA5F866833D7AD3387BE2423095930671D8588E49510AEC9430ED1F03A02F3160124D893833D44FA4B51FED9044AE5B4136105466D5CD711FDFC37690183BA1D4930347148433D76B98A857EF4962FE0F48A16F20454555411EC778B248529F50503C4E0D62A122EEF42CA6BEFC7B3517CCB75A293AF2532E29FC2889DFDFB3CABEBB 20160303052710 2 6 100 6143 5 D9752DD196C5E138B7F542FD56561455DDBDF05DCC107F8A5C8F393529CEBAE3CECA54E85766015CBFE1856D830D7A20385951C0941FF754570F697951C77F6FC064C28B708E8A691BDA8C6C1921C7559288EE8A024EB50D923EFF9F143E76B053D2B5FF1779C1CDC0E5856BBE4396928E605009866CFD212C68183120D5A7EA14BD3878690406069F8BC9AED334AEB6C25FD4CD9421F860893256B1A7741F729982BC109E3B6DF4D86CCFCDC1EBAB2EB13836E7988CB9F32F3EC5120E6B2DD74FF13E456A1A01E313E00A728D2ED690A656DACB1C71C6BADCA959CD944EBA762FC8B0B3CEF237386ED3D4FC6983A8F950B956DC76C09B6AAE22B5B8501B73B6E685FA40AA56139A8C02F6E0B7836E3F08EB5F9D4EC83A8BDA394FC5DA24D2CF078AE7491E3856A18FCA2C68BF9BC82ABCDE494CDFB31F82E5FE8C20D7832412F478BFC67A2B4B2CF5F266DDF53CB62372957861B95FFD2C82C46E48ACD75CAEC30E8453C8A24020ABB6143665441179478D8E33E505C2E34C1EA8F22205CA8FB31A48209BCF10ACD56B6B0060DE1836A4C9EF3C062C552C1BC8528D262FF0A2BEB56626C69A8CC7BA24F65FC39768212BB7C41BFFEDDAFD1A1528F6258F2ABC102F693425FDDF20D9EC9601FBFDC6FCD43E551C082A8A1373A1CB5E83BCD8175D9B60662D03ED5894D3EF4325180633C33FA1DD0964CC0CAEDE403146E7A5B8ED74FC6AB359EE1909A45A445429B17C04658E7F4F31F84DD194FDFBF3EF345C1B4EF2563E16351808FE4262B52D0C8AA748DF502FEF3A92C9F6A6A03BDE903DD1392177265313C08E767B003614AC6C6BFC501AAC24737BB3C8CC0160D81FC3BC6244974E1D83D15E676976F92999AEE25A66E7FE124A94D52A902E035FA5F866833D7AD3387BE2423095930671D8588E49510AEC9430ED1F03A02F3160124D893833D44FA4B51FED9044AE5B4136105466D5CD711FDFC37690183BA1D4930347148433D76B98A857EF4962FE0F48A16F20454555411EC778B248529F50503C4E0D62A122EEF42CA6BEFC7B3517CCB75A293AF2532E29FC2889DFDFB569F28F 20160303064237 2 6 100 6143 5 D9752DD196C5E138B7F542FD56561455DDBDF05DCC107F8A5C8F393529CEBAE3CECA54E85766015CBFE1856D830D7A20385951C0941FF754570F697951C77F6FC064C28B708E8A691BDA8C6C1921C7559288EE8A024EB50D923EFF9F143E76B053D2B5FF1779C1CDC0E5856BBE4396928E605009866CFD212C68183120D5A7EA14BD3878690406069F8BC9AED334AEB6C25FD4CD9421F860893256B1A7741F729982BC109E3B6DF4D86CCFCDC1EBAB2EB13836E7988CB9F32F3EC5120E6B2DD74FF13E456A1A01E313E00A728D2ED690A656DACB1C71C6BADCA959CD944EBA762FC8B0B3CEF237386ED3D4FC6983A8F950B956DC76C09B6AAE22B5B8501B73B6E685FA40AA56139A8C02F6E0B7836E3F08EB5F9D4EC83A8BDA394FC5DA24D2CF078AE7491E3856A18FCA2C68BF9BC82ABCDE494CDFB31F82E5FE8C20D7832412F478BFC67A2B4B2CF5F266DDF53CB62372957861B95FFD2C82C46E48ACD75CAEC30E8453C8A24020ABB6143665441179478D8E33E505C2E34C1EA8F22205CA8FB31A48209BCF10ACD56B6B0060DE1836A4C9EF3C062C552C1BC8528D262FF0A2BEB56626C69A8CC7BA24F65FC39768212BB7C41BFFEDDAFD1A1528F6258F2ABC102F693425FDDF20D9EC9601FBFDC6FCD43E551C082A8A1373A1CB5E83BCD8175D9B60662D03ED5894D3EF4325180633C33FA1DD0964CC0CAEDE403146E7A5B8ED74FC6AB359EE1909A45A445429B17C04658E7F4F31F84DD194FDFBF3EF345C1B4EF2563E16351808FE4262B52D0C8AA748DF502FEF3A92C9F6A6A03BDE903DD1392177265313C08E767B003614AC6C6BFC501AAC24737BB3C8CC0160D81FC3BC6244974E1D83D15E676976F92999AEE25A66E7FE124A94D52A902E035FA5F866833D7AD3387BE2423095930671D8588E49510AEC9430ED1F03A02F3160124D893833D44FA4B51FED9044AE5B4136105466D5CD711FDFC37690183BA1D4930347148433D76B98A857EF4962FE0F48A16F20454555411EC778B248529F50503C4E0D62A122EEF42CA6BEFC7B3517CCB75A293AF2532E29FC2889DFDFB744D6A7 20160303074318 2 6 100 6143 5 D9752DD196C5E138B7F542FD56561455DDBDF05DCC107F8A5C8F393529CEBAE3CECA54E85766015CBFE1856D830D7A20385951C0941FF754570F697951C77F6FC064C28B708E8A691BDA8C6C1921C7559288EE8A024EB50D923EFF9F143E76B053D2B5FF1779C1CDC0E5856BBE4396928E605009866CFD212C68183120D5A7EA14BD3878690406069F8BC9AED334AEB6C25FD4CD9421F860893256B1A7741F729982BC109E3B6DF4D86CCFCDC1EBAB2EB13836E7988CB9F32F3EC5120E6B2DD74FF13E456A1A01E313E00A728D2ED690A656DACB1C71C6BADCA959CD944EBA762FC8B0B3CEF237386ED3D4FC6983A8F950B956DC76C09B6AAE22B5B8501B73B6E685FA40AA56139A8C02F6E0B7836E3F08EB5F9D4EC83A8BDA394FC5DA24D2CF078AE7491E3856A18FCA2C68BF9BC82ABCDE494CDFB31F82E5FE8C20D7832412F478BFC67A2B4B2CF5F266DDF53CB62372957861B95FFD2C82C46E48ACD75CAEC30E8453C8A24020ABB6143665441179478D8E33E505C2E34C1EA8F22205CA8FB31A48209BCF10ACD56B6B0060DE1836A4C9EF3C062C552C1BC8528D262FF0A2BEB56626C69A8CC7BA24F65FC39768212BB7C41BFFEDDAFD1A1528F6258F2ABC102F693425FDDF20D9EC9601FBFDC6FCD43E551C082A8A1373A1CB5E83BCD8175D9B60662D03ED5894D3EF4325180633C33FA1DD0964CC0CAEDE403146E7A5B8ED74FC6AB359EE1909A45A445429B17C04658E7F4F31F84DD194FDFBF3EF345C1B4EF2563E16351808FE4262B52D0C8AA748DF502FEF3A92C9F6A6A03BDE903DD1392177265313C08E767B003614AC6C6BFC501AAC24737BB3C8CC0160D81FC3BC6244974E1D83D15E676976F92999AEE25A66E7FE124A94D52A902E035FA5F866833D7AD3387BE2423095930671D8588E49510AEC9430ED1F03A02F3160124D893833D44FA4B51FED9044AE5B4136105466D5CD711FDFC37690183BA1D4930347148433D76B98A857EF4962FE0F48A16F20454555411EC778B248529F50503C4E0D62A122EEF42CA6BEFC7B3517CCB75A293AF2532E29FC2889DFDFB8C38E87 20160303091435 2 6 100 6143 5 D9752DD196C5E138B7F542FD56561455DDBDF05DCC107F8A5C8F393529CEBAE3CECA54E85766015CBFE1856D830D7A20385951C0941FF754570F697951C77F6FC064C28B708E8A691BDA8C6C1921C7559288EE8A024EB50D923EFF9F143E76B053D2B5FF1779C1CDC0E5856BBE4396928E605009866CFD212C68183120D5A7EA14BD3878690406069F8BC9AED334AEB6C25FD4CD9421F860893256B1A7741F729982BC109E3B6DF4D86CCFCDC1EBAB2EB13836E7988CB9F32F3EC5120E6B2DD74FF13E456A1A01E313E00A728D2ED690A656DACB1C71C6BADCA959CD944EBA762FC8B0B3CEF237386ED3D4FC6983A8F950B956DC76C09B6AAE22B5B8501B73B6E685FA40AA56139A8C02F6E0B7836E3F08EB5F9D4EC83A8BDA394FC5DA24D2CF078AE7491E3856A18FCA2C68BF9BC82ABCDE494CDFB31F82E5FE8C20D7832412F478BFC67A2B4B2CF5F266DDF53CB62372957861B95FFD2C82C46E48ACD75CAEC30E8453C8A24020ABB6143665441179478D8E33E505C2E34C1EA8F22205CA8FB31A48209BCF10ACD56B6B0060DE1836A4C9EF3C062C552C1BC8528D262FF0A2BEB56626C69A8CC7BA24F65FC39768212BB7C41BFFEDDAFD1A1528F6258F2ABC102F693425FDDF20D9EC9601FBFDC6FCD43E551C082A8A1373A1CB5E83BCD8175D9B60662D03ED5894D3EF4325180633C33FA1DD0964CC0CAEDE403146E7A5B8ED74FC6AB359EE1909A45A445429B17C04658E7F4F31F84DD194FDFBF3EF345C1B4EF2563E16351808FE4262B52D0C8AA748DF502FEF3A92C9F6A6A03BDE903DD1392177265313C08E767B003614AC6C6BFC501AAC24737BB3C8CC0160D81FC3BC6244974E1D83D15E676976F92999AEE25A66E7FE124A94D52A902E035FA5F866833D7AD3387BE2423095930671D8588E49510AEC9430ED1F03A02F3160124D893833D44FA4B51FED9044AE5B4136105466D5CD711FDFC37690183BA1D4930347148433D76B98A857EF4962FE0F48A16F20454555411EC778B248529F50503C4E0D62A122EEF42CA6BEFC7B3517CCB75A293AF2532E29FC2889DFDFBB0B707F 20160303111232 2 6 100 6143 2 D9752DD196C5E138B7F542FD56561455DDBDF05DCC107F8A5C8F393529CEBAE3CECA54E85766015CBFE1856D830D7A20385951C0941FF754570F697951C77F6FC064C28B708E8A691BDA8C6C1921C7559288EE8A024EB50D923EFF9F143E76B053D2B5FF1779C1CDC0E5856BBE4396928E605009866CFD212C68183120D5A7EA14BD3878690406069F8BC9AED334AEB6C25FD4CD9421F860893256B1A7741F729982BC109E3B6DF4D86CCFCDC1EBAB2EB13836E7988CB9F32F3EC5120E6B2DD74FF13E456A1A01E313E00A728D2ED690A656DACB1C71C6BADCA959CD944EBA762FC8B0B3CEF237386ED3D4FC6983A8F950B956DC76C09B6AAE22B5B8501B73B6E685FA40AA56139A8C02F6E0B7836E3F08EB5F9D4EC83A8BDA394FC5DA24D2CF078AE7491E3856A18FCA2C68BF9BC82ABCDE494CDFB31F82E5FE8C20D7832412F478BFC67A2B4B2CF5F266DDF53CB62372957861B95FFD2C82C46E48ACD75CAEC30E8453C8A24020ABB6143665441179478D8E33E505C2E34C1EA8F22205CA8FB31A48209BCF10ACD56B6B0060DE1836A4C9EF3C062C552C1BC8528D262FF0A2BEB56626C69A8CC7BA24F65FC39768212BB7C41BFFEDDAFD1A1528F6258F2ABC102F693425FDDF20D9EC9601FBFDC6FCD43E551C082A8A1373A1CB5E83BCD8175D9B60662D03ED5894D3EF4325180633C33FA1DD0964CC0CAEDE403146E7A5B8ED74FC6AB359EE1909A45A445429B17C04658E7F4F31F84DD194FDFBF3EF345C1B4EF2563E16351808FE4262B52D0C8AA748DF502FEF3A92C9F6A6A03BDE903DD1392177265313C08E767B003614AC6C6BFC501AAC24737BB3C8CC0160D81FC3BC6244974E1D83D15E676976F92999AEE25A66E7FE124A94D52A902E035FA5F866833D7AD3387BE2423095930671D8588E49510AEC9430ED1F03A02F3160124D893833D44FA4B51FED9044AE5B4136105466D5CD711FDFC37690183BA1D4930347148433D76B98A857EF4962FE0F48A16F20454555411EC778B248529F50503C4E0D62A122EEF42CA6BEFC7B3517CCB75A293AF2532E29FC2889DFDFBE003643 20160303112343 2 6 100 6143 2 D9752DD196C5E138B7F542FD56561455DDBDF05DCC107F8A5C8F393529CEBAE3CECA54E85766015CBFE1856D830D7A20385951C0941FF754570F697951C77F6FC064C28B708E8A691BDA8C6C1921C7559288EE8A024EB50D923EFF9F143E76B053D2B5FF1779C1CDC0E5856BBE4396928E605009866CFD212C68183120D5A7EA14BD3878690406069F8BC9AED334AEB6C25FD4CD9421F860893256B1A7741F729982BC109E3B6DF4D86CCFCDC1EBAB2EB13836E7988CB9F32F3EC5120E6B2DD74FF13E456A1A01E313E00A728D2ED690A656DACB1C71C6BADCA959CD944EBA762FC8B0B3CEF237386ED3D4FC6983A8F950B956DC76C09B6AAE22B5B8501B73B6E685FA40AA56139A8C02F6E0B7836E3F08EB5F9D4EC83A8BDA394FC5DA24D2CF078AE7491E3856A18FCA2C68BF9BC82ABCDE494CDFB31F82E5FE8C20D7832412F478BFC67A2B4B2CF5F266DDF53CB62372957861B95FFD2C82C46E48ACD75CAEC30E8453C8A24020ABB6143665441179478D8E33E505C2E34C1EA8F22205CA8FB31A48209BCF10ACD56B6B0060DE1836A4C9EF3C062C552C1BC8528D262FF0A2BEB56626C69A8CC7BA24F65FC39768212BB7C41BFFEDDAFD1A1528F6258F2ABC102F693425FDDF20D9EC9601FBFDC6FCD43E551C082A8A1373A1CB5E83BCD8175D9B60662D03ED5894D3EF4325180633C33FA1DD0964CC0CAEDE403146E7A5B8ED74FC6AB359EE1909A45A445429B17C04658E7F4F31F84DD194FDFBF3EF345C1B4EF2563E16351808FE4262B52D0C8AA748DF502FEF3A92C9F6A6A03BDE903DD1392177265313C08E767B003614AC6C6BFC501AAC24737BB3C8CC0160D81FC3BC6244974E1D83D15E676976F92999AEE25A66E7FE124A94D52A902E035FA5F866833D7AD3387BE2423095930671D8588E49510AEC9430ED1F03A02F3160124D893833D44FA4B51FED9044AE5B4136105466D5CD711FDFC37690183BA1D4930347148433D76B98A857EF4962FE0F48A16F20454555411EC778B248529F50503C4E0D62A122EEF42CA6BEFC7B3517CCB75A293AF2532E29FC2889DFDFBE40A0B3 20160303113550 2 6 100 6143 5 D9752DD196C5E138B7F542FD56561455DDBDF05DCC107F8A5C8F393529CEBAE3CECA54E85766015CBFE1856D830D7A20385951C0941FF754570F697951C77F6FC064C28B708E8A691BDA8C6C1921C7559288EE8A024EB50D923EFF9F143E76B053D2B5FF1779C1CDC0E5856BBE4396928E605009866CFD212C68183120D5A7EA14BD3878690406069F8BC9AED334AEB6C25FD4CD9421F860893256B1A7741F729982BC109E3B6DF4D86CCFCDC1EBAB2EB13836E7988CB9F32F3EC5120E6B2DD74FF13E456A1A01E313E00A728D2ED690A656DACB1C71C6BADCA959CD944EBA762FC8B0B3CEF237386ED3D4FC6983A8F950B956DC76C09B6AAE22B5B8501B73B6E685FA40AA56139A8C02F6E0B7836E3F08EB5F9D4EC83A8BDA394FC5DA24D2CF078AE7491E3856A18FCA2C68BF9BC82ABCDE494CDFB31F82E5FE8C20D7832412F478BFC67A2B4B2CF5F266DDF53CB62372957861B95FFD2C82C46E48ACD75CAEC30E8453C8A24020ABB6143665441179478D8E33E505C2E34C1EA8F22205CA8FB31A48209BCF10ACD56B6B0060DE1836A4C9EF3C062C552C1BC8528D262FF0A2BEB56626C69A8CC7BA24F65FC39768212BB7C41BFFEDDAFD1A1528F6258F2ABC102F693425FDDF20D9EC9601FBFDC6FCD43E551C082A8A1373A1CB5E83BCD8175D9B60662D03ED5894D3EF4325180633C33FA1DD0964CC0CAEDE403146E7A5B8ED74FC6AB359EE1909A45A445429B17C04658E7F4F31F84DD194FDFBF3EF345C1B4EF2563E16351808FE4262B52D0C8AA748DF502FEF3A92C9F6A6A03BDE903DD1392177265313C08E767B003614AC6C6BFC501AAC24737BB3C8CC0160D81FC3BC6244974E1D83D15E676976F92999AEE25A66E7FE124A94D52A902E035FA5F866833D7AD3387BE2423095930671D8588E49510AEC9430ED1F03A02F3160124D893833D44FA4B51FED9044AE5B4136105466D5CD711FDFC37690183BA1D4930347148433D76B98A857EF4962FE0F48A16F20454555411EC778B248529F50503C4E0D62A122EEF42CA6BEFC7B3517CCB75A293AF2532E29FC2889DFDFBE87B0BF 20160303120708 2 6 100 6143 2 D9752DD196C5E138B7F542FD56561455DDBDF05DCC107F8A5C8F393529CEBAE3CECA54E85766015CBFE1856D830D7A20385951C0941FF754570F697951C77F6FC064C28B708E8A691BDA8C6C1921C7559288EE8A024EB50D923EFF9F143E76B053D2B5FF1779C1CDC0E5856BBE4396928E605009866CFD212C68183120D5A7EA14BD3878690406069F8BC9AED334AEB6C25FD4CD9421F860893256B1A7741F729982BC109E3B6DF4D86CCFCDC1EBAB2EB13836E7988CB9F32F3EC5120E6B2DD74FF13E456A1A01E313E00A728D2ED690A656DACB1C71C6BADCA959CD944EBA762FC8B0B3CEF237386ED3D4FC6983A8F950B956DC76C09B6AAE22B5B8501B73B6E685FA40AA56139A8C02F6E0B7836E3F08EB5F9D4EC83A8BDA394FC5DA24D2CF078AE7491E3856A18FCA2C68BF9BC82ABCDE494CDFB31F82E5FE8C20D7832412F478BFC67A2B4B2CF5F266DDF53CB62372957861B95FFD2C82C46E48ACD75CAEC30E8453C8A24020ABB6143665441179478D8E33E505C2E34C1EA8F22205CA8FB31A48209BCF10ACD56B6B0060DE1836A4C9EF3C062C552C1BC8528D262FF0A2BEB56626C69A8CC7BA24F65FC39768212BB7C41BFFEDDAFD1A1528F6258F2ABC102F693425FDDF20D9EC9601FBFDC6FCD43E551C082A8A1373A1CB5E83BCD8175D9B60662D03ED5894D3EF4325180633C33FA1DD0964CC0CAEDE403146E7A5B8ED74FC6AB359EE1909A45A445429B17C04658E7F4F31F84DD194FDFBF3EF345C1B4EF2563E16351808FE4262B52D0C8AA748DF502FEF3A92C9F6A6A03BDE903DD1392177265313C08E767B003614AC6C6BFC501AAC24737BB3C8CC0160D81FC3BC6244974E1D83D15E676976F92999AEE25A66E7FE124A94D52A902E035FA5F866833D7AD3387BE2423095930671D8588E49510AEC9430ED1F03A02F3160124D893833D44FA4B51FED9044AE5B4136105466D5CD711FDFC37690183BA1D4930347148433D76B98A857EF4962FE0F48A16F20454555411EC778B248529F50503C4E0D62A122EEF42CA6BEFC7B3517CCB75A293AF2532E29FC2889DFDFBF49A92B 20160303122005 2 6 100 6143 2 D9752DD196C5E138B7F542FD56561455DDBDF05DCC107F8A5C8F393529CEBAE3CECA54E85766015CBFE1856D830D7A20385951C0941FF754570F697951C77F6FC064C28B708E8A691BDA8C6C1921C7559288EE8A024EB50D923EFF9F143E76B053D2B5FF1779C1CDC0E5856BBE4396928E605009866CFD212C68183120D5A7EA14BD3878690406069F8BC9AED334AEB6C25FD4CD9421F860893256B1A7741F729982BC109E3B6DF4D86CCFCDC1EBAB2EB13836E7988CB9F32F3EC5120E6B2DD74FF13E456A1A01E313E00A728D2ED690A656DACB1C71C6BADCA959CD944EBA762FC8B0B3CEF237386ED3D4FC6983A8F950B956DC76C09B6AAE22B5B8501B73B6E685FA40AA56139A8C02F6E0B7836E3F08EB5F9D4EC83A8BDA394FC5DA24D2CF078AE7491E3856A18FCA2C68BF9BC82ABCDE494CDFB31F82E5FE8C20D7832412F478BFC67A2B4B2CF5F266DDF53CB62372957861B95FFD2C82C46E48ACD75CAEC30E8453C8A24020ABB6143665441179478D8E33E505C2E34C1EA8F22205CA8FB31A48209BCF10ACD56B6B0060DE1836A4C9EF3C062C552C1BC8528D262FF0A2BEB56626C69A8CC7BA24F65FC39768212BB7C41BFFEDDAFD1A1528F6258F2ABC102F693425FDDF20D9EC9601FBFDC6FCD43E551C082A8A1373A1CB5E83BCD8175D9B60662D03ED5894D3EF4325180633C33FA1DD0964CC0CAEDE403146E7A5B8ED74FC6AB359EE1909A45A445429B17C04658E7F4F31F84DD194FDFBF3EF345C1B4EF2563E16351808FE4262B52D0C8AA748DF502FEF3A92C9F6A6A03BDE903DD1392177265313C08E767B003614AC6C6BFC501AAC24737BB3C8CC0160D81FC3BC6244974E1D83D15E676976F92999AEE25A66E7FE124A94D52A902E035FA5F866833D7AD3387BE2423095930671D8588E49510AEC9430ED1F03A02F3160124D893833D44FA4B51FED9044AE5B4136105466D5CD711FDFC37690183BA1D4930347148433D76B98A857EF4962FE0F48A16F20454555411EC778B248529F50503C4E0D62A122EEF42CA6BEFC7B3517CCB75A293AF2532E29FC2889DFDFBF954093 20160303134821 2 6 100 6143 5 D9752DD196C5E138B7F542FD56561455DDBDF05DCC107F8A5C8F393529CEBAE3CECA54E85766015CBFE1856D830D7A20385951C0941FF754570F697951C77F6FC064C28B708E8A691BDA8C6C1921C7559288EE8A024EB50D923EFF9F143E76B053D2B5FF1779C1CDC0E5856BBE4396928E605009866CFD212C68183120D5A7EA14BD3878690406069F8BC9AED334AEB6C25FD4CD9421F860893256B1A7741F729982BC109E3B6DF4D86CCFCDC1EBAB2EB13836E7988CB9F32F3EC5120E6B2DD74FF13E456A1A01E313E00A728D2ED690A656DACB1C71C6BADCA959CD944EBA762FC8B0B3CEF237386ED3D4FC6983A8F950B956DC76C09B6AAE22B5B8501B73B6E685FA40AA56139A8C02F6E0B7836E3F08EB5F9D4EC83A8BDA394FC5DA24D2CF078AE7491E3856A18FCA2C68BF9BC82ABCDE494CDFB31F82E5FE8C20D7832412F478BFC67A2B4B2CF5F266DDF53CB62372957861B95FFD2C82C46E48ACD75CAEC30E8453C8A24020ABB6143665441179478D8E33E505C2E34C1EA8F22205CA8FB31A48209BCF10ACD56B6B0060DE1836A4C9EF3C062C552C1BC8528D262FF0A2BEB56626C69A8CC7BA24F65FC39768212BB7C41BFFEDDAFD1A1528F6258F2ABC102F693425FDDF20D9EC9601FBFDC6FCD43E551C082A8A1373A1CB5E83BCD8175D9B60662D03ED5894D3EF4325180633C33FA1DD0964CC0CAEDE403146E7A5B8ED74FC6AB359EE1909A45A445429B17C04658E7F4F31F84DD194FDFBF3EF345C1B4EF2563E16351808FE4262B52D0C8AA748DF502FEF3A92C9F6A6A03BDE903DD1392177265313C08E767B003614AC6C6BFC501AAC24737BB3C8CC0160D81FC3BC6244974E1D83D15E676976F92999AEE25A66E7FE124A94D52A902E035FA5F866833D7AD3387BE2423095930671D8588E49510AEC9430ED1F03A02F3160124D893833D44FA4B51FED9044AE5B4136105466D5CD711FDFC37690183BA1D4930347148433D76B98A857EF4962FE0F48A16F20454555411EC778B248529F50503C4E0D62A122EEF42CA6BEFC7B3517CCB75A293AF2532E29FC2889DFDFC1C0AD17 20160303183137 2 6 100 6143 5 D9752DD196C5E138B7F542FD56561455DDBDF05DCC107F8A5C8F393529CEBAE3CECA54E85766015CBFE1856D830D7A20385951C0941FF754570F697951C77F6FC064C28B708E8A691BDA8C6C1921C7559288EE8A024EB50D923EFF9F143E76B053D2B5FF1779C1CDC0E5856BBE4396928E605009866CFD212C68183120D5A7EA14BD3878690406069F8BC9AED334AEB6C25FD4CD9421F860893256B1A7741F729982BC109E3B6DF4D86CCFCDC1EBAB2EB13836E7988CB9F32F3EC5120E6B2DD74FF13E456A1A01E313E00A728D2ED690A656DACB1C71C6BADCA959CD944EBA762FC8B0B3CEF237386ED3D4FC6983A8F950B956DC76C09B6AAE22B5B8501B73B6E685FA40AA56139A8C02F6E0B7836E3F08EB5F9D4EC83A8BDA394FC5DA24D2CF078AE7491E3856A18FCA2C68BF9BC82ABCDE494CDFB31F82E5FE8C20D7832412F478BFC67A2B4B2CF5F266DDF53CB62372957861B95FFD2C82C46E48ACD75CAEC30E8453C8A24020ABB6143665441179478D8E33E505C2E34C1EA8F22205CA8FB31A48209BCF10ACD56B6B0060DE1836A4C9EF3C062C552C1BC8528D262FF0A2BEB56626C69A8CC7BA24F65FC39768212BB7C41BFFEDDAFD1A1528F6258F2ABC102F693425FDDF20D9EC9601FBFDC6FCD43E551C082A8A1373A1CB5E83BCD8175D9B60662D03ED5894D3EF4325180633C33FA1DD0964CC0CAEDE403146E7A5B8ED74FC6AB359EE1909A45A445429B17C04658E7F4F31F84DD194FDFBF3EF345C1B4EF2563E16351808FE4262B52D0C8AA748DF502FEF3A92C9F6A6A03BDE903DD1392177265313C08E767B003614AC6C6BFC501AAC24737BB3C8CC0160D81FC3BC6244974E1D83D15E676976F92999AEE25A66E7FE124A94D52A902E035FA5F866833D7AD3387BE2423095930671D8588E49510AEC9430ED1F03A02F3160124D893833D44FA4B51FED9044AE5B4136105466D5CD711FDFC37690183BA1D4930347148433D76B98A857EF4962FE0F48A16F20454555411EC778B248529F50503C4E0D62A122EEF42CA6BEFC7B3517CCB75A293AF2532E29FC2889DFDFC8B45457 20160303204451 2 6 100 6143 2 D9752DD196C5E138B7F542FD56561455DDBDF05DCC107F8A5C8F393529CEBAE3CECA54E85766015CBFE1856D830D7A20385951C0941FF754570F697951C77F6FC064C28B708E8A691BDA8C6C1921C7559288EE8A024EB50D923EFF9F143E76B053D2B5FF1779C1CDC0E5856BBE4396928E605009866CFD212C68183120D5A7EA14BD3878690406069F8BC9AED334AEB6C25FD4CD9421F860893256B1A7741F729982BC109E3B6DF4D86CCFCDC1EBAB2EB13836E7988CB9F32F3EC5120E6B2DD74FF13E456A1A01E313E00A728D2ED690A656DACB1C71C6BADCA959CD944EBA762FC8B0B3CEF237386ED3D4FC6983A8F950B956DC76C09B6AAE22B5B8501B73B6E685FA40AA56139A8C02F6E0B7836E3F08EB5F9D4EC83A8BDA394FC5DA24D2CF078AE7491E3856A18FCA2C68BF9BC82ABCDE494CDFB31F82E5FE8C20D7832412F478BFC67A2B4B2CF5F266DDF53CB62372957861B95FFD2C82C46E48ACD75CAEC30E8453C8A24020ABB6143665441179478D8E33E505C2E34C1EA8F22205CA8FB31A48209BCF10ACD56B6B0060DE1836A4C9EF3C062C552C1BC8528D262FF0A2BEB56626C69A8CC7BA24F65FC39768212BB7C41BFFEDDAFD1A1528F6258F2ABC102F693425FDDF20D9EC9601FBFDC6FCD43E551C082A8A1373A1CB5E83BCD8175D9B60662D03ED5894D3EF4325180633C33FA1DD0964CC0CAEDE403146E7A5B8ED74FC6AB359EE1909A45A445429B17C04658E7F4F31F84DD194FDFBF3EF345C1B4EF2563E16351808FE4262B52D0C8AA748DF502FEF3A92C9F6A6A03BDE903DD1392177265313C08E767B003614AC6C6BFC501AAC24737BB3C8CC0160D81FC3BC6244974E1D83D15E676976F92999AEE25A66E7FE124A94D52A902E035FA5F866833D7AD3387BE2423095930671D8588E49510AEC9430ED1F03A02F3160124D893833D44FA4B51FED9044AE5B4136105466D5CD711FDFC37690183BA1D4930347148433D76B98A857EF4962FE0F48A16F20454555411EC778B248529F50503C4E0D62A122EEF42CA6BEFC7B3517CCB75A293AF2532E29FC2889DFDFCBFBCF5B 20160303210530 2 6 100 6143 2 D9752DD196C5E138B7F542FD56561455DDBDF05DCC107F8A5C8F393529CEBAE3CECA54E85766015CBFE1856D830D7A20385951C0941FF754570F697951C77F6FC064C28B708E8A691BDA8C6C1921C7559288EE8A024EB50D923EFF9F143E76B053D2B5FF1779C1CDC0E5856BBE4396928E605009866CFD212C68183120D5A7EA14BD3878690406069F8BC9AED334AEB6C25FD4CD9421F860893256B1A7741F729982BC109E3B6DF4D86CCFCDC1EBAB2EB13836E7988CB9F32F3EC5120E6B2DD74FF13E456A1A01E313E00A728D2ED690A656DACB1C71C6BADCA959CD944EBA762FC8B0B3CEF237386ED3D4FC6983A8F950B956DC76C09B6AAE22B5B8501B73B6E685FA40AA56139A8C02F6E0B7836E3F08EB5F9D4EC83A8BDA394FC5DA24D2CF078AE7491E3856A18FCA2C68BF9BC82ABCDE494CDFB31F82E5FE8C20D7832412F478BFC67A2B4B2CF5F266DDF53CB62372957861B95FFD2C82C46E48ACD75CAEC30E8453C8A24020ABB6143665441179478D8E33E505C2E34C1EA8F22205CA8FB31A48209BCF10ACD56B6B0060DE1836A4C9EF3C062C552C1BC8528D262FF0A2BEB56626C69A8CC7BA24F65FC39768212BB7C41BFFEDDAFD1A1528F6258F2ABC102F693425FDDF20D9EC9601FBFDC6FCD43E551C082A8A1373A1CB5E83BCD8175D9B60662D03ED5894D3EF4325180633C33FA1DD0964CC0CAEDE403146E7A5B8ED74FC6AB359EE1909A45A445429B17C04658E7F4F31F84DD194FDFBF3EF345C1B4EF2563E16351808FE4262B52D0C8AA748DF502FEF3A92C9F6A6A03BDE903DD1392177265313C08E767B003614AC6C6BFC501AAC24737BB3C8CC0160D81FC3BC6244974E1D83D15E676976F92999AEE25A66E7FE124A94D52A902E035FA5F866833D7AD3387BE2423095930671D8588E49510AEC9430ED1F03A02F3160124D893833D44FA4B51FED9044AE5B4136105466D5CD711FDFC37690183BA1D4930347148433D76B98A857EF4962FE0F48A16F20454555411EC778B248529F50503C4E0D62A122EEF42CA6BEFC7B3517CCB75A293AF2532E29FC2889DFDFCC756893 20160303224116 2 6 100 6143 2 D9752DD196C5E138B7F542FD56561455DDBDF05DCC107F8A5C8F393529CEBAE3CECA54E85766015CBFE1856D830D7A20385951C0941FF754570F697951C77F6FC064C28B708E8A691BDA8C6C1921C7559288EE8A024EB50D923EFF9F143E76B053D2B5FF1779C1CDC0E5856BBE4396928E605009866CFD212C68183120D5A7EA14BD3878690406069F8BC9AED334AEB6C25FD4CD9421F860893256B1A7741F729982BC109E3B6DF4D86CCFCDC1EBAB2EB13836E7988CB9F32F3EC5120E6B2DD74FF13E456A1A01E313E00A728D2ED690A656DACB1C71C6BADCA959CD944EBA762FC8B0B3CEF237386ED3D4FC6983A8F950B956DC76C09B6AAE22B5B8501B73B6E685FA40AA56139A8C02F6E0B7836E3F08EB5F9D4EC83A8BDA394FC5DA24D2CF078AE7491E3856A18FCA2C68BF9BC82ABCDE494CDFB31F82E5FE8C20D7832412F478BFC67A2B4B2CF5F266DDF53CB62372957861B95FFD2C82C46E48ACD75CAEC30E8453C8A24020ABB6143665441179478D8E33E505C2E34C1EA8F22205CA8FB31A48209BCF10ACD56B6B0060DE1836A4C9EF3C062C552C1BC8528D262FF0A2BEB56626C69A8CC7BA24F65FC39768212BB7C41BFFEDDAFD1A1528F6258F2ABC102F693425FDDF20D9EC9601FBFDC6FCD43E551C082A8A1373A1CB5E83BCD8175D9B60662D03ED5894D3EF4325180633C33FA1DD0964CC0CAEDE403146E7A5B8ED74FC6AB359EE1909A45A445429B17C04658E7F4F31F84DD194FDFBF3EF345C1B4EF2563E16351808FE4262B52D0C8AA748DF502FEF3A92C9F6A6A03BDE903DD1392177265313C08E767B003614AC6C6BFC501AAC24737BB3C8CC0160D81FC3BC6244974E1D83D15E676976F92999AEE25A66E7FE124A94D52A902E035FA5F866833D7AD3387BE2423095930671D8588E49510AEC9430ED1F03A02F3160124D893833D44FA4B51FED9044AE5B4136105466D5CD711FDFC37690183BA1D4930347148433D76B98A857EF4962FE0F48A16F20454555411EC778B248529F50503C4E0D62A122EEF42CA6BEFC7B3517CCB75A293AF2532E29FC2889DFDFCEC94F0B 20160304002011 2 6 100 6143 2 FC87210E608B51094653AB8D5963CAEF1C053FBDBBEDF91B83BBD945C79B4F67E96E8FA2C32DD50643434724257CC86C29F3CA2D266A719934B4D350E933D37153610C332F148D4B22D7D790A2A83995B0600254F640BD5E48B7D97D1BCEE76515FE078CE062EFB08529A5670F773DF514EC5392403D50C33577AFCDDE7D90224AEED69799AE17968CADDBFDC81A6E10B1CDE4A0D3F41C4B82CE346E0621973BE07918EAD36D7C67BCF2984D0F78BCD1E540847CA4DC90D909845862D4F699ABFA17F5749554774BC2C59443265CE386C655055202009B32590EB0FD85F203E63425342E756AB57F5BA14BD2E283B617A230E11A955442F0C1F53AF4F08DFD1D2606DD5DD04486C40A0E6D2DB2B390D664A97D32ED7868A6AAC5F2E534B7C880EE0F6834EC100D547B823547443D02980F1EBB2EBB6D57E9368BC70C440BB5406220630583D59AB11C489B0B0B8591A7F9FF322BFD4B9FE0672800A402F9734652EF151B44180D4EA7A713C66873A245691AAF295272BFF02979772EC48D65CF34540F38EDF2B95BDF8E7A88062866A8F5471F29993E1D4A4F1638A447D237964907CA1090C0CE1D4FDD79277219F9E1CE63E3E95BAFF8017639969710AE8520769B09C318BDD8A0CB3560DDC3A6281E1816EF16D942980934B6B381D44FD19311FDE8457113B6F8FBC9101EC20F6F216712BC17A63A753F0724BA90EA9A4766FF93BBA39020CC72E0B33CB6CC3C3D87A13CB86BA9C1A9B9086DBD905F62B29782E5AAD4C27704913415E583A0EF1F2586C612DCA66CA31FD1F797752EC984E543616C7575ADC6BDAB9788F82C9258DF1E58777440BDAD5D93A2CBEAC466D6BE37CC4307CA0534B00B6EBEE4C3958BC587117E8E26D13E36B1D4A9D0F7DB2F00E9568EB21F6530EF635650C51DC9D04B788439BE01ACBF5501D673896A170037E0048882DCF5A09F7605AEFEA5615A534B5CAE77D46B00E27CAC0C7685AA235EBC0941B056FCE7737E3BD6597EF0C5774D1535F294645B12025F17474F9066DA7DFD867B72E3706FAEECD892C05D92494D7A3BEE52080BAC6FCA8F213AE3B5BB 20160304013213 2 6 100 6143 5 FC87210E608B51094653AB8D5963CAEF1C053FBDBBEDF91B83BBD945C79B4F67E96E8FA2C32DD50643434724257CC86C29F3CA2D266A719934B4D350E933D37153610C332F148D4B22D7D790A2A83995B0600254F640BD5E48B7D97D1BCEE76515FE078CE062EFB08529A5670F773DF514EC5392403D50C33577AFCDDE7D90224AEED69799AE17968CADDBFDC81A6E10B1CDE4A0D3F41C4B82CE346E0621973BE07918EAD36D7C67BCF2984D0F78BCD1E540847CA4DC90D909845862D4F699ABFA17F5749554774BC2C59443265CE386C655055202009B32590EB0FD85F203E63425342E756AB57F5BA14BD2E283B617A230E11A955442F0C1F53AF4F08DFD1D2606DD5DD04486C40A0E6D2DB2B390D664A97D32ED7868A6AAC5F2E534B7C880EE0F6834EC100D547B823547443D02980F1EBB2EBB6D57E9368BC70C440BB5406220630583D59AB11C489B0B0B8591A7F9FF322BFD4B9FE0672800A402F9734652EF151B44180D4EA7A713C66873A245691AAF295272BFF02979772EC48D65CF34540F38EDF2B95BDF8E7A88062866A8F5471F29993E1D4A4F1638A447D237964907CA1090C0CE1D4FDD79277219F9E1CE63E3E95BAFF8017639969710AE8520769B09C318BDD8A0CB3560DDC3A6281E1816EF16D942980934B6B381D44FD19311FDE8457113B6F8FBC9101EC20F6F216712BC17A63A753F0724BA90EA9A4766FF93BBA39020CC72E0B33CB6CC3C3D87A13CB86BA9C1A9B9086DBD905F62B29782E5AAD4C27704913415E583A0EF1F2586C612DCA66CA31FD1F797752EC984E543616C7575ADC6BDAB9788F82C9258DF1E58777440BDAD5D93A2CBEAC466D6BE37CC4307CA0534B00B6EBEE4C3958BC587117E8E26D13E36B1D4A9D0F7DB2F00E9568EB21F6530EF635650C51DC9D04B788439BE01ACBF5501D673896A170037E0048882DCF5A09F7605AEFEA5615A534B5CAE77D46B00E27CAC0C7685AA235EBC0941B056FCE7737E3BD6597EF0C5774D1535F294645B12025F17474F9066DA7DFD867B72E3706FAEECD892C05D92494D7A3BEE52080BAC6FCA8F213CCC818F 20160304014837 2 6 100 6143 5 FC87210E608B51094653AB8D5963CAEF1C053FBDBBEDF91B83BBD945C79B4F67E96E8FA2C32DD50643434724257CC86C29F3CA2D266A719934B4D350E933D37153610C332F148D4B22D7D790A2A83995B0600254F640BD5E48B7D97D1BCEE76515FE078CE062EFB08529A5670F773DF514EC5392403D50C33577AFCDDE7D90224AEED69799AE17968CADDBFDC81A6E10B1CDE4A0D3F41C4B82CE346E0621973BE07918EAD36D7C67BCF2984D0F78BCD1E540847CA4DC90D909845862D4F699ABFA17F5749554774BC2C59443265CE386C655055202009B32590EB0FD85F203E63425342E756AB57F5BA14BD2E283B617A230E11A955442F0C1F53AF4F08DFD1D2606DD5DD04486C40A0E6D2DB2B390D664A97D32ED7868A6AAC5F2E534B7C880EE0F6834EC100D547B823547443D02980F1EBB2EBB6D57E9368BC70C440BB5406220630583D59AB11C489B0B0B8591A7F9FF322BFD4B9FE0672800A402F9734652EF151B44180D4EA7A713C66873A245691AAF295272BFF02979772EC48D65CF34540F38EDF2B95BDF8E7A88062866A8F5471F29993E1D4A4F1638A447D237964907CA1090C0CE1D4FDD79277219F9E1CE63E3E95BAFF8017639969710AE8520769B09C318BDD8A0CB3560DDC3A6281E1816EF16D942980934B6B381D44FD19311FDE8457113B6F8FBC9101EC20F6F216712BC17A63A753F0724BA90EA9A4766FF93BBA39020CC72E0B33CB6CC3C3D87A13CB86BA9C1A9B9086DBD905F62B29782E5AAD4C27704913415E583A0EF1F2586C612DCA66CA31FD1F797752EC984E543616C7575ADC6BDAB9788F82C9258DF1E58777440BDAD5D93A2CBEAC466D6BE37CC4307CA0534B00B6EBEE4C3958BC587117E8E26D13E36B1D4A9D0F7DB2F00E9568EB21F6530EF635650C51DC9D04B788439BE01ACBF5501D673896A170037E0048882DCF5A09F7605AEFEA5615A534B5CAE77D46B00E27CAC0C7685AA235EBC0941B056FCE7737E3BD6597EF0C5774D1535F294645B12025F17474F9066DA7DFD867B72E3706FAEECD892C05D92494D7A3BEE52080BAC6FCA8F213D3357F7 20160304050100 2 6 100 6143 2 FC87210E608B51094653AB8D5963CAEF1C053FBDBBEDF91B83BBD945C79B4F67E96E8FA2C32DD50643434724257CC86C29F3CA2D266A719934B4D350E933D37153610C332F148D4B22D7D790A2A83995B0600254F640BD5E48B7D97D1BCEE76515FE078CE062EFB08529A5670F773DF514EC5392403D50C33577AFCDDE7D90224AEED69799AE17968CADDBFDC81A6E10B1CDE4A0D3F41C4B82CE346E0621973BE07918EAD36D7C67BCF2984D0F78BCD1E540847CA4DC90D909845862D4F699ABFA17F5749554774BC2C59443265CE386C655055202009B32590EB0FD85F203E63425342E756AB57F5BA14BD2E283B617A230E11A955442F0C1F53AF4F08DFD1D2606DD5DD04486C40A0E6D2DB2B390D664A97D32ED7868A6AAC5F2E534B7C880EE0F6834EC100D547B823547443D02980F1EBB2EBB6D57E9368BC70C440BB5406220630583D59AB11C489B0B0B8591A7F9FF322BFD4B9FE0672800A402F9734652EF151B44180D4EA7A713C66873A245691AAF295272BFF02979772EC48D65CF34540F38EDF2B95BDF8E7A88062866A8F5471F29993E1D4A4F1638A447D237964907CA1090C0CE1D4FDD79277219F9E1CE63E3E95BAFF8017639969710AE8520769B09C318BDD8A0CB3560DDC3A6281E1816EF16D942980934B6B381D44FD19311FDE8457113B6F8FBC9101EC20F6F216712BC17A63A753F0724BA90EA9A4766FF93BBA39020CC72E0B33CB6CC3C3D87A13CB86BA9C1A9B9086DBD905F62B29782E5AAD4C27704913415E583A0EF1F2586C612DCA66CA31FD1F797752EC984E543616C7575ADC6BDAB9788F82C9258DF1E58777440BDAD5D93A2CBEAC466D6BE37CC4307CA0534B00B6EBEE4C3958BC587117E8E26D13E36B1D4A9D0F7DB2F00E9568EB21F6530EF635650C51DC9D04B788439BE01ACBF5501D673896A170037E0048882DCF5A09F7605AEFEA5615A534B5CAE77D46B00E27CAC0C7685AA235EBC0941B056FCE7737E3BD6597EF0C5774D1535F294645B12025F17474F9066DA7DFD867B72E3706FAEECD892C05D92494D7A3BEE52080BAC6FCA8F21426DAC33 20160304070516 2 6 100 6143 2 FC87210E608B51094653AB8D5963CAEF1C053FBDBBEDF91B83BBD945C79B4F67E96E8FA2C32DD50643434724257CC86C29F3CA2D266A719934B4D350E933D37153610C332F148D4B22D7D790A2A83995B0600254F640BD5E48B7D97D1BCEE76515FE078CE062EFB08529A5670F773DF514EC5392403D50C33577AFCDDE7D90224AEED69799AE17968CADDBFDC81A6E10B1CDE4A0D3F41C4B82CE346E0621973BE07918EAD36D7C67BCF2984D0F78BCD1E540847CA4DC90D909845862D4F699ABFA17F5749554774BC2C59443265CE386C655055202009B32590EB0FD85F203E63425342E756AB57F5BA14BD2E283B617A230E11A955442F0C1F53AF4F08DFD1D2606DD5DD04486C40A0E6D2DB2B390D664A97D32ED7868A6AAC5F2E534B7C880EE0F6834EC100D547B823547443D02980F1EBB2EBB6D57E9368BC70C440BB5406220630583D59AB11C489B0B0B8591A7F9FF322BFD4B9FE0672800A402F9734652EF151B44180D4EA7A713C66873A245691AAF295272BFF02979772EC48D65CF34540F38EDF2B95BDF8E7A88062866A8F5471F29993E1D4A4F1638A447D237964907CA1090C0CE1D4FDD79277219F9E1CE63E3E95BAFF8017639969710AE8520769B09C318BDD8A0CB3560DDC3A6281E1816EF16D942980934B6B381D44FD19311FDE8457113B6F8FBC9101EC20F6F216712BC17A63A753F0724BA90EA9A4766FF93BBA39020CC72E0B33CB6CC3C3D87A13CB86BA9C1A9B9086DBD905F62B29782E5AAD4C27704913415E583A0EF1F2586C612DCA66CA31FD1F797752EC984E543616C7575ADC6BDAB9788F82C9258DF1E58777440BDAD5D93A2CBEAC466D6BE37CC4307CA0534B00B6EBEE4C3958BC587117E8E26D13E36B1D4A9D0F7DB2F00E9568EB21F6530EF635650C51DC9D04B788439BE01ACBF5501D673896A170037E0048882DCF5A09F7605AEFEA5615A534B5CAE77D46B00E27CAC0C7685AA235EBC0941B056FCE7737E3BD6597EF0C5774D1535F294645B12025F17474F9066DA7DFD867B72E3706FAEECD892C05D92494D7A3BEE52080BAC6FCA8F2145B0AFE3 20160304085926 2 6 100 6143 2 FC87210E608B51094653AB8D5963CAEF1C053FBDBBEDF91B83BBD945C79B4F67E96E8FA2C32DD50643434724257CC86C29F3CA2D266A719934B4D350E933D37153610C332F148D4B22D7D790A2A83995B0600254F640BD5E48B7D97D1BCEE76515FE078CE062EFB08529A5670F773DF514EC5392403D50C33577AFCDDE7D90224AEED69799AE17968CADDBFDC81A6E10B1CDE4A0D3F41C4B82CE346E0621973BE07918EAD36D7C67BCF2984D0F78BCD1E540847CA4DC90D909845862D4F699ABFA17F5749554774BC2C59443265CE386C655055202009B32590EB0FD85F203E63425342E756AB57F5BA14BD2E283B617A230E11A955442F0C1F53AF4F08DFD1D2606DD5DD04486C40A0E6D2DB2B390D664A97D32ED7868A6AAC5F2E534B7C880EE0F6834EC100D547B823547443D02980F1EBB2EBB6D57E9368BC70C440BB5406220630583D59AB11C489B0B0B8591A7F9FF322BFD4B9FE0672800A402F9734652EF151B44180D4EA7A713C66873A245691AAF295272BFF02979772EC48D65CF34540F38EDF2B95BDF8E7A88062866A8F5471F29993E1D4A4F1638A447D237964907CA1090C0CE1D4FDD79277219F9E1CE63E3E95BAFF8017639969710AE8520769B09C318BDD8A0CB3560DDC3A6281E1816EF16D942980934B6B381D44FD19311FDE8457113B6F8FBC9101EC20F6F216712BC17A63A753F0724BA90EA9A4766FF93BBA39020CC72E0B33CB6CC3C3D87A13CB86BA9C1A9B9086DBD905F62B29782E5AAD4C27704913415E583A0EF1F2586C612DCA66CA31FD1F797752EC984E543616C7575ADC6BDAB9788F82C9258DF1E58777440BDAD5D93A2CBEAC466D6BE37CC4307CA0534B00B6EBEE4C3958BC587117E8E26D13E36B1D4A9D0F7DB2F00E9568EB21F6530EF635650C51DC9D04B788439BE01ACBF5501D673896A170037E0048882DCF5A09F7605AEFEA5615A534B5CAE77D46B00E27CAC0C7685AA235EBC0941B056FCE7737E3BD6597EF0C5774D1535F294645B12025F17474F9066DA7DFD867B72E3706FAEECD892C05D92494D7A3BEE52080BAC6FCA8F2148A9E96B 20160304092251 2 6 100 6143 2 FC87210E608B51094653AB8D5963CAEF1C053FBDBBEDF91B83BBD945C79B4F67E96E8FA2C32DD50643434724257CC86C29F3CA2D266A719934B4D350E933D37153610C332F148D4B22D7D790A2A83995B0600254F640BD5E48B7D97D1BCEE76515FE078CE062EFB08529A5670F773DF514EC5392403D50C33577AFCDDE7D90224AEED69799AE17968CADDBFDC81A6E10B1CDE4A0D3F41C4B82CE346E0621973BE07918EAD36D7C67BCF2984D0F78BCD1E540847CA4DC90D909845862D4F699ABFA17F5749554774BC2C59443265CE386C655055202009B32590EB0FD85F203E63425342E756AB57F5BA14BD2E283B617A230E11A955442F0C1F53AF4F08DFD1D2606DD5DD04486C40A0E6D2DB2B390D664A97D32ED7868A6AAC5F2E534B7C880EE0F6834EC100D547B823547443D02980F1EBB2EBB6D57E9368BC70C440BB5406220630583D59AB11C489B0B0B8591A7F9FF322BFD4B9FE0672800A402F9734652EF151B44180D4EA7A713C66873A245691AAF295272BFF02979772EC48D65CF34540F38EDF2B95BDF8E7A88062866A8F5471F29993E1D4A4F1638A447D237964907CA1090C0CE1D4FDD79277219F9E1CE63E3E95BAFF8017639969710AE8520769B09C318BDD8A0CB3560DDC3A6281E1816EF16D942980934B6B381D44FD19311FDE8457113B6F8FBC9101EC20F6F216712BC17A63A753F0724BA90EA9A4766FF93BBA39020CC72E0B33CB6CC3C3D87A13CB86BA9C1A9B9086DBD905F62B29782E5AAD4C27704913415E583A0EF1F2586C612DCA66CA31FD1F797752EC984E543616C7575ADC6BDAB9788F82C9258DF1E58777440BDAD5D93A2CBEAC466D6BE37CC4307CA0534B00B6EBEE4C3958BC587117E8E26D13E36B1D4A9D0F7DB2F00E9568EB21F6530EF635650C51DC9D04B788439BE01ACBF5501D673896A170037E0048882DCF5A09F7605AEFEA5615A534B5CAE77D46B00E27CAC0C7685AA235EBC0941B056FCE7737E3BD6597EF0C5774D1535F294645B12025F17474F9066DA7DFD867B72E3706FAEECD892C05D92494D7A3BEE52080BAC6FCA8F21493F5C9B 20160304092815 2 6 100 6143 2 FC87210E608B51094653AB8D5963CAEF1C053FBDBBEDF91B83BBD945C79B4F67E96E8FA2C32DD50643434724257CC86C29F3CA2D266A719934B4D350E933D37153610C332F148D4B22D7D790A2A83995B0600254F640BD5E48B7D97D1BCEE76515FE078CE062EFB08529A5670F773DF514EC5392403D50C33577AFCDDE7D90224AEED69799AE17968CADDBFDC81A6E10B1CDE4A0D3F41C4B82CE346E0621973BE07918EAD36D7C67BCF2984D0F78BCD1E540847CA4DC90D909845862D4F699ABFA17F5749554774BC2C59443265CE386C655055202009B32590EB0FD85F203E63425342E756AB57F5BA14BD2E283B617A230E11A955442F0C1F53AF4F08DFD1D2606DD5DD04486C40A0E6D2DB2B390D664A97D32ED7868A6AAC5F2E534B7C880EE0F6834EC100D547B823547443D02980F1EBB2EBB6D57E9368BC70C440BB5406220630583D59AB11C489B0B0B8591A7F9FF322BFD4B9FE0672800A402F9734652EF151B44180D4EA7A713C66873A245691AAF295272BFF02979772EC48D65CF34540F38EDF2B95BDF8E7A88062866A8F5471F29993E1D4A4F1638A447D237964907CA1090C0CE1D4FDD79277219F9E1CE63E3E95BAFF8017639969710AE8520769B09C318BDD8A0CB3560DDC3A6281E1816EF16D942980934B6B381D44FD19311FDE8457113B6F8FBC9101EC20F6F216712BC17A63A753F0724BA90EA9A4766FF93BBA39020CC72E0B33CB6CC3C3D87A13CB86BA9C1A9B9086DBD905F62B29782E5AAD4C27704913415E583A0EF1F2586C612DCA66CA31FD1F797752EC984E543616C7575ADC6BDAB9788F82C9258DF1E58777440BDAD5D93A2CBEAC466D6BE37CC4307CA0534B00B6EBEE4C3958BC587117E8E26D13E36B1D4A9D0F7DB2F00E9568EB21F6530EF635650C51DC9D04B788439BE01ACBF5501D673896A170037E0048882DCF5A09F7605AEFEA5615A534B5CAE77D46B00E27CAC0C7685AA235EBC0941B056FCE7737E3BD6597EF0C5774D1535F294645B12025F17474F9066DA7DFD867B72E3706FAEECD892C05D92494D7A3BEE52080BAC6FCA8F21495C2BA3 20160304115839 2 6 100 6143 2 FC87210E608B51094653AB8D5963CAEF1C053FBDBBEDF91B83BBD945C79B4F67E96E8FA2C32DD50643434724257CC86C29F3CA2D266A719934B4D350E933D37153610C332F148D4B22D7D790A2A83995B0600254F640BD5E48B7D97D1BCEE76515FE078CE062EFB08529A5670F773DF514EC5392403D50C33577AFCDDE7D90224AEED69799AE17968CADDBFDC81A6E10B1CDE4A0D3F41C4B82CE346E0621973BE07918EAD36D7C67BCF2984D0F78BCD1E540847CA4DC90D909845862D4F699ABFA17F5749554774BC2C59443265CE386C655055202009B32590EB0FD85F203E63425342E756AB57F5BA14BD2E283B617A230E11A955442F0C1F53AF4F08DFD1D2606DD5DD04486C40A0E6D2DB2B390D664A97D32ED7868A6AAC5F2E534B7C880EE0F6834EC100D547B823547443D02980F1EBB2EBB6D57E9368BC70C440BB5406220630583D59AB11C489B0B0B8591A7F9FF322BFD4B9FE0672800A402F9734652EF151B44180D4EA7A713C66873A245691AAF295272BFF02979772EC48D65CF34540F38EDF2B95BDF8E7A88062866A8F5471F29993E1D4A4F1638A447D237964907CA1090C0CE1D4FDD79277219F9E1CE63E3E95BAFF8017639969710AE8520769B09C318BDD8A0CB3560DDC3A6281E1816EF16D942980934B6B381D44FD19311FDE8457113B6F8FBC9101EC20F6F216712BC17A63A753F0724BA90EA9A4766FF93BBA39020CC72E0B33CB6CC3C3D87A13CB86BA9C1A9B9086DBD905F62B29782E5AAD4C27704913415E583A0EF1F2586C612DCA66CA31FD1F797752EC984E543616C7575ADC6BDAB9788F82C9258DF1E58777440BDAD5D93A2CBEAC466D6BE37CC4307CA0534B00B6EBEE4C3958BC587117E8E26D13E36B1D4A9D0F7DB2F00E9568EB21F6530EF635650C51DC9D04B788439BE01ACBF5501D673896A170037E0048882DCF5A09F7605AEFEA5615A534B5CAE77D46B00E27CAC0C7685AA235EBC0941B056FCE7737E3BD6597EF0C5774D1535F294645B12025F17474F9066DA7DFD867B72E3706FAEECD892C05D92494D7A3BEE52080BAC6FCA8F214D4FED23 20160304122842 2 6 100 6143 5 FC87210E608B51094653AB8D5963CAEF1C053FBDBBEDF91B83BBD945C79B4F67E96E8FA2C32DD50643434724257CC86C29F3CA2D266A719934B4D350E933D37153610C332F148D4B22D7D790A2A83995B0600254F640BD5E48B7D97D1BCEE76515FE078CE062EFB08529A5670F773DF514EC5392403D50C33577AFCDDE7D90224AEED69799AE17968CADDBFDC81A6E10B1CDE4A0D3F41C4B82CE346E0621973BE07918EAD36D7C67BCF2984D0F78BCD1E540847CA4DC90D909845862D4F699ABFA17F5749554774BC2C59443265CE386C655055202009B32590EB0FD85F203E63425342E756AB57F5BA14BD2E283B617A230E11A955442F0C1F53AF4F08DFD1D2606DD5DD04486C40A0E6D2DB2B390D664A97D32ED7868A6AAC5F2E534B7C880EE0F6834EC100D547B823547443D02980F1EBB2EBB6D57E9368BC70C440BB5406220630583D59AB11C489B0B0B8591A7F9FF322BFD4B9FE0672800A402F9734652EF151B44180D4EA7A713C66873A245691AAF295272BFF02979772EC48D65CF34540F38EDF2B95BDF8E7A88062866A8F5471F29993E1D4A4F1638A447D237964907CA1090C0CE1D4FDD79277219F9E1CE63E3E95BAFF8017639969710AE8520769B09C318BDD8A0CB3560DDC3A6281E1816EF16D942980934B6B381D44FD19311FDE8457113B6F8FBC9101EC20F6F216712BC17A63A753F0724BA90EA9A4766FF93BBA39020CC72E0B33CB6CC3C3D87A13CB86BA9C1A9B9086DBD905F62B29782E5AAD4C27704913415E583A0EF1F2586C612DCA66CA31FD1F797752EC984E543616C7575ADC6BDAB9788F82C9258DF1E58777440BDAD5D93A2CBEAC466D6BE37CC4307CA0534B00B6EBEE4C3958BC587117E8E26D13E36B1D4A9D0F7DB2F00E9568EB21F6530EF635650C51DC9D04B788439BE01ACBF5501D673896A170037E0048882DCF5A09F7605AEFEA5615A534B5CAE77D46B00E27CAC0C7685AA235EBC0941B056FCE7737E3BD6597EF0C5774D1535F294645B12025F17474F9066DA7DFD867B72E3706FAEECD892C05D92494D7A3BEE52080BAC6FCA8F214E130FAF 20160304143749 2 6 100 6143 5 FC87210E608B51094653AB8D5963CAEF1C053FBDBBEDF91B83BBD945C79B4F67E96E8FA2C32DD50643434724257CC86C29F3CA2D266A719934B4D350E933D37153610C332F148D4B22D7D790A2A83995B0600254F640BD5E48B7D97D1BCEE76515FE078CE062EFB08529A5670F773DF514EC5392403D50C33577AFCDDE7D90224AEED69799AE17968CADDBFDC81A6E10B1CDE4A0D3F41C4B82CE346E0621973BE07918EAD36D7C67BCF2984D0F78BCD1E540847CA4DC90D909845862D4F699ABFA17F5749554774BC2C59443265CE386C655055202009B32590EB0FD85F203E63425342E756AB57F5BA14BD2E283B617A230E11A955442F0C1F53AF4F08DFD1D2606DD5DD04486C40A0E6D2DB2B390D664A97D32ED7868A6AAC5F2E534B7C880EE0F6834EC100D547B823547443D02980F1EBB2EBB6D57E9368BC70C440BB5406220630583D59AB11C489B0B0B8591A7F9FF322BFD4B9FE0672800A402F9734652EF151B44180D4EA7A713C66873A245691AAF295272BFF02979772EC48D65CF34540F38EDF2B95BDF8E7A88062866A8F5471F29993E1D4A4F1638A447D237964907CA1090C0CE1D4FDD79277219F9E1CE63E3E95BAFF8017639969710AE8520769B09C318BDD8A0CB3560DDC3A6281E1816EF16D942980934B6B381D44FD19311FDE8457113B6F8FBC9101EC20F6F216712BC17A63A753F0724BA90EA9A4766FF93BBA39020CC72E0B33CB6CC3C3D87A13CB86BA9C1A9B9086DBD905F62B29782E5AAD4C27704913415E583A0EF1F2586C612DCA66CA31FD1F797752EC984E543616C7575ADC6BDAB9788F82C9258DF1E58777440BDAD5D93A2CBEAC466D6BE37CC4307CA0534B00B6EBEE4C3958BC587117E8E26D13E36B1D4A9D0F7DB2F00E9568EB21F6530EF635650C51DC9D04B788439BE01ACBF5501D673896A170037E0048882DCF5A09F7605AEFEA5615A534B5CAE77D46B00E27CAC0C7685AA235EBC0941B056FCE7737E3BD6597EF0C5774D1535F294645B12025F17474F9066DA7DFD867B72E3706FAEECD892C05D92494D7A3BEE52080BAC6FCA8F215161823F 20160304160139 2 6 100 6143 2 FC87210E608B51094653AB8D5963CAEF1C053FBDBBEDF91B83BBD945C79B4F67E96E8FA2C32DD50643434724257CC86C29F3CA2D266A719934B4D350E933D37153610C332F148D4B22D7D790A2A83995B0600254F640BD5E48B7D97D1BCEE76515FE078CE062EFB08529A5670F773DF514EC5392403D50C33577AFCDDE7D90224AEED69799AE17968CADDBFDC81A6E10B1CDE4A0D3F41C4B82CE346E0621973BE07918EAD36D7C67BCF2984D0F78BCD1E540847CA4DC90D909845862D4F699ABFA17F5749554774BC2C59443265CE386C655055202009B32590EB0FD85F203E63425342E756AB57F5BA14BD2E283B617A230E11A955442F0C1F53AF4F08DFD1D2606DD5DD04486C40A0E6D2DB2B390D664A97D32ED7868A6AAC5F2E534B7C880EE0F6834EC100D547B823547443D02980F1EBB2EBB6D57E9368BC70C440BB5406220630583D59AB11C489B0B0B8591A7F9FF322BFD4B9FE0672800A402F9734652EF151B44180D4EA7A713C66873A245691AAF295272BFF02979772EC48D65CF34540F38EDF2B95BDF8E7A88062866A8F5471F29993E1D4A4F1638A447D237964907CA1090C0CE1D4FDD79277219F9E1CE63E3E95BAFF8017639969710AE8520769B09C318BDD8A0CB3560DDC3A6281E1816EF16D942980934B6B381D44FD19311FDE8457113B6F8FBC9101EC20F6F216712BC17A63A753F0724BA90EA9A4766FF93BBA39020CC72E0B33CB6CC3C3D87A13CB86BA9C1A9B9086DBD905F62B29782E5AAD4C27704913415E583A0EF1F2586C612DCA66CA31FD1F797752EC984E543616C7575ADC6BDAB9788F82C9258DF1E58777440BDAD5D93A2CBEAC466D6BE37CC4307CA0534B00B6EBEE4C3958BC587117E8E26D13E36B1D4A9D0F7DB2F00E9568EB21F6530EF635650C51DC9D04B788439BE01ACBF5501D673896A170037E0048882DCF5A09F7605AEFEA5615A534B5CAE77D46B00E27CAC0C7685AA235EBC0941B056FCE7737E3BD6597EF0C5774D1535F294645B12025F17474F9066DA7DFD867B72E3706FAEECD892C05D92494D7A3BEE52080BAC6FCA8F2153888D53 20160304160440 2 6 100 6143 2 FC87210E608B51094653AB8D5963CAEF1C053FBDBBEDF91B83BBD945C79B4F67E96E8FA2C32DD50643434724257CC86C29F3CA2D266A719934B4D350E933D37153610C332F148D4B22D7D790A2A83995B0600254F640BD5E48B7D97D1BCEE76515FE078CE062EFB08529A5670F773DF514EC5392403D50C33577AFCDDE7D90224AEED69799AE17968CADDBFDC81A6E10B1CDE4A0D3F41C4B82CE346E0621973BE07918EAD36D7C67BCF2984D0F78BCD1E540847CA4DC90D909845862D4F699ABFA17F5749554774BC2C59443265CE386C655055202009B32590EB0FD85F203E63425342E756AB57F5BA14BD2E283B617A230E11A955442F0C1F53AF4F08DFD1D2606DD5DD04486C40A0E6D2DB2B390D664A97D32ED7868A6AAC5F2E534B7C880EE0F6834EC100D547B823547443D02980F1EBB2EBB6D57E9368BC70C440BB5406220630583D59AB11C489B0B0B8591A7F9FF322BFD4B9FE0672800A402F9734652EF151B44180D4EA7A713C66873A245691AAF295272BFF02979772EC48D65CF34540F38EDF2B95BDF8E7A88062866A8F5471F29993E1D4A4F1638A447D237964907CA1090C0CE1D4FDD79277219F9E1CE63E3E95BAFF8017639969710AE8520769B09C318BDD8A0CB3560DDC3A6281E1816EF16D942980934B6B381D44FD19311FDE8457113B6F8FBC9101EC20F6F216712BC17A63A753F0724BA90EA9A4766FF93BBA39020CC72E0B33CB6CC3C3D87A13CB86BA9C1A9B9086DBD905F62B29782E5AAD4C27704913415E583A0EF1F2586C612DCA66CA31FD1F797752EC984E543616C7575ADC6BDAB9788F82C9258DF1E58777440BDAD5D93A2CBEAC466D6BE37CC4307CA0534B00B6EBEE4C3958BC587117E8E26D13E36B1D4A9D0F7DB2F00E9568EB21F6530EF635650C51DC9D04B788439BE01ACBF5501D673896A170037E0048882DCF5A09F7605AEFEA5615A534B5CAE77D46B00E27CAC0C7685AA235EBC0941B056FCE7737E3BD6597EF0C5774D1535F294645B12025F17474F9066DA7DFD867B72E3706FAEECD892C05D92494D7A3BEE52080BAC6FCA8F215394B933 20160304162214 2 6 100 6143 2 FC87210E608B51094653AB8D5963CAEF1C053FBDBBEDF91B83BBD945C79B4F67E96E8FA2C32DD50643434724257CC86C29F3CA2D266A719934B4D350E933D37153610C332F148D4B22D7D790A2A83995B0600254F640BD5E48B7D97D1BCEE76515FE078CE062EFB08529A5670F773DF514EC5392403D50C33577AFCDDE7D90224AEED69799AE17968CADDBFDC81A6E10B1CDE4A0D3F41C4B82CE346E0621973BE07918EAD36D7C67BCF2984D0F78BCD1E540847CA4DC90D909845862D4F699ABFA17F5749554774BC2C59443265CE386C655055202009B32590EB0FD85F203E63425342E756AB57F5BA14BD2E283B617A230E11A955442F0C1F53AF4F08DFD1D2606DD5DD04486C40A0E6D2DB2B390D664A97D32ED7868A6AAC5F2E534B7C880EE0F6834EC100D547B823547443D02980F1EBB2EBB6D57E9368BC70C440BB5406220630583D59AB11C489B0B0B8591A7F9FF322BFD4B9FE0672800A402F9734652EF151B44180D4EA7A713C66873A245691AAF295272BFF02979772EC48D65CF34540F38EDF2B95BDF8E7A88062866A8F5471F29993E1D4A4F1638A447D237964907CA1090C0CE1D4FDD79277219F9E1CE63E3E95BAFF8017639969710AE8520769B09C318BDD8A0CB3560DDC3A6281E1816EF16D942980934B6B381D44FD19311FDE8457113B6F8FBC9101EC20F6F216712BC17A63A753F0724BA90EA9A4766FF93BBA39020CC72E0B33CB6CC3C3D87A13CB86BA9C1A9B9086DBD905F62B29782E5AAD4C27704913415E583A0EF1F2586C612DCA66CA31FD1F797752EC984E543616C7575ADC6BDAB9788F82C9258DF1E58777440BDAD5D93A2CBEAC466D6BE37CC4307CA0534B00B6EBEE4C3958BC587117E8E26D13E36B1D4A9D0F7DB2F00E9568EB21F6530EF635650C51DC9D04B788439BE01ACBF5501D673896A170037E0048882DCF5A09F7605AEFEA5615A534B5CAE77D46B00E27CAC0C7685AA235EBC0941B056FCE7737E3BD6597EF0C5774D1535F294645B12025F17474F9066DA7DFD867B72E3706FAEECD892C05D92494D7A3BEE52080BAC6FCA8F215400CF9B 20160304212008 2 6 100 6143 2 FC87210E608B51094653AB8D5963CAEF1C053FBDBBEDF91B83BBD945C79B4F67E96E8FA2C32DD50643434724257CC86C29F3CA2D266A719934B4D350E933D37153610C332F148D4B22D7D790A2A83995B0600254F640BD5E48B7D97D1BCEE76515FE078CE062EFB08529A5670F773DF514EC5392403D50C33577AFCDDE7D90224AEED69799AE17968CADDBFDC81A6E10B1CDE4A0D3F41C4B82CE346E0621973BE07918EAD36D7C67BCF2984D0F78BCD1E540847CA4DC90D909845862D4F699ABFA17F5749554774BC2C59443265CE386C655055202009B32590EB0FD85F203E63425342E756AB57F5BA14BD2E283B617A230E11A955442F0C1F53AF4F08DFD1D2606DD5DD04486C40A0E6D2DB2B390D664A97D32ED7868A6AAC5F2E534B7C880EE0F6834EC100D547B823547443D02980F1EBB2EBB6D57E9368BC70C440BB5406220630583D59AB11C489B0B0B8591A7F9FF322BFD4B9FE0672800A402F9734652EF151B44180D4EA7A713C66873A245691AAF295272BFF02979772EC48D65CF34540F38EDF2B95BDF8E7A88062866A8F5471F29993E1D4A4F1638A447D237964907CA1090C0CE1D4FDD79277219F9E1CE63E3E95BAFF8017639969710AE8520769B09C318BDD8A0CB3560DDC3A6281E1816EF16D942980934B6B381D44FD19311FDE8457113B6F8FBC9101EC20F6F216712BC17A63A753F0724BA90EA9A4766FF93BBA39020CC72E0B33CB6CC3C3D87A13CB86BA9C1A9B9086DBD905F62B29782E5AAD4C27704913415E583A0EF1F2586C612DCA66CA31FD1F797752EC984E543616C7575ADC6BDAB9788F82C9258DF1E58777440BDAD5D93A2CBEAC466D6BE37CC4307CA0534B00B6EBEE4C3958BC587117E8E26D13E36B1D4A9D0F7DB2F00E9568EB21F6530EF635650C51DC9D04B788439BE01ACBF5501D673896A170037E0048882DCF5A09F7605AEFEA5615A534B5CAE77D46B00E27CAC0C7685AA235EBC0941B056FCE7737E3BD6597EF0C5774D1535F294645B12025F17474F9066DA7DFD867B72E3706FAEECD892C05D92494D7A3BEE52080BAC6FCA8F215BACC633 20160304221341 2 6 100 6143 5 FC87210E608B51094653AB8D5963CAEF1C053FBDBBEDF91B83BBD945C79B4F67E96E8FA2C32DD50643434724257CC86C29F3CA2D266A719934B4D350E933D37153610C332F148D4B22D7D790A2A83995B0600254F640BD5E48B7D97D1BCEE76515FE078CE062EFB08529A5670F773DF514EC5392403D50C33577AFCDDE7D90224AEED69799AE17968CADDBFDC81A6E10B1CDE4A0D3F41C4B82CE346E0621973BE07918EAD36D7C67BCF2984D0F78BCD1E540847CA4DC90D909845862D4F699ABFA17F5749554774BC2C59443265CE386C655055202009B32590EB0FD85F203E63425342E756AB57F5BA14BD2E283B617A230E11A955442F0C1F53AF4F08DFD1D2606DD5DD04486C40A0E6D2DB2B390D664A97D32ED7868A6AAC5F2E534B7C880EE0F6834EC100D547B823547443D02980F1EBB2EBB6D57E9368BC70C440BB5406220630583D59AB11C489B0B0B8591A7F9FF322BFD4B9FE0672800A402F9734652EF151B44180D4EA7A713C66873A245691AAF295272BFF02979772EC48D65CF34540F38EDF2B95BDF8E7A88062866A8F5471F29993E1D4A4F1638A447D237964907CA1090C0CE1D4FDD79277219F9E1CE63E3E95BAFF8017639969710AE8520769B09C318BDD8A0CB3560DDC3A6281E1816EF16D942980934B6B381D44FD19311FDE8457113B6F8FBC9101EC20F6F216712BC17A63A753F0724BA90EA9A4766FF93BBA39020CC72E0B33CB6CC3C3D87A13CB86BA9C1A9B9086DBD905F62B29782E5AAD4C27704913415E583A0EF1F2586C612DCA66CA31FD1F797752EC984E543616C7575ADC6BDAB9788F82C9258DF1E58777440BDAD5D93A2CBEAC466D6BE37CC4307CA0534B00B6EBEE4C3958BC587117E8E26D13E36B1D4A9D0F7DB2F00E9568EB21F6530EF635650C51DC9D04B788439BE01ACBF5501D673896A170037E0048882DCF5A09F7605AEFEA5615A534B5CAE77D46B00E27CAC0C7685AA235EBC0941B056FCE7737E3BD6597EF0C5774D1535F294645B12025F17474F9066DA7DFD867B72E3706FAEECD892C05D92494D7A3BEE52080BAC6FCA8F215D065E4F 20160304221614 2 6 100 6143 5 FC87210E608B51094653AB8D5963CAEF1C053FBDBBEDF91B83BBD945C79B4F67E96E8FA2C32DD50643434724257CC86C29F3CA2D266A719934B4D350E933D37153610C332F148D4B22D7D790A2A83995B0600254F640BD5E48B7D97D1BCEE76515FE078CE062EFB08529A5670F773DF514EC5392403D50C33577AFCDDE7D90224AEED69799AE17968CADDBFDC81A6E10B1CDE4A0D3F41C4B82CE346E0621973BE07918EAD36D7C67BCF2984D0F78BCD1E540847CA4DC90D909845862D4F699ABFA17F5749554774BC2C59443265CE386C655055202009B32590EB0FD85F203E63425342E756AB57F5BA14BD2E283B617A230E11A955442F0C1F53AF4F08DFD1D2606DD5DD04486C40A0E6D2DB2B390D664A97D32ED7868A6AAC5F2E534B7C880EE0F6834EC100D547B823547443D02980F1EBB2EBB6D57E9368BC70C440BB5406220630583D59AB11C489B0B0B8591A7F9FF322BFD4B9FE0672800A402F9734652EF151B44180D4EA7A713C66873A245691AAF295272BFF02979772EC48D65CF34540F38EDF2B95BDF8E7A88062866A8F5471F29993E1D4A4F1638A447D237964907CA1090C0CE1D4FDD79277219F9E1CE63E3E95BAFF8017639969710AE8520769B09C318BDD8A0CB3560DDC3A6281E1816EF16D942980934B6B381D44FD19311FDE8457113B6F8FBC9101EC20F6F216712BC17A63A753F0724BA90EA9A4766FF93BBA39020CC72E0B33CB6CC3C3D87A13CB86BA9C1A9B9086DBD905F62B29782E5AAD4C27704913415E583A0EF1F2586C612DCA66CA31FD1F797752EC984E543616C7575ADC6BDAB9788F82C9258DF1E58777440BDAD5D93A2CBEAC466D6BE37CC4307CA0534B00B6EBEE4C3958BC587117E8E26D13E36B1D4A9D0F7DB2F00E9568EB21F6530EF635650C51DC9D04B788439BE01ACBF5501D673896A170037E0048882DCF5A09F7605AEFEA5615A534B5CAE77D46B00E27CAC0C7685AA235EBC0941B056FCE7737E3BD6597EF0C5774D1535F294645B12025F17474F9066DA7DFD867B72E3706FAEECD892C05D92494D7A3BEE52080BAC6FCA8F215D0E8A6F 20160305022340 2 6 100 6143 2 FC87210E608B51094653AB8D5963CAEF1C053FBDBBEDF91B83BBD945C79B4F67E96E8FA2C32DD50643434724257CC86C29F3CA2D266A719934B4D350E933D37153610C332F148D4B22D7D790A2A83995B0600254F640BD5E48B7D97D1BCEE76515FE078CE062EFB08529A5670F773DF514EC5392403D50C33577AFCDDE7D90224AEED69799AE17968CADDBFDC81A6E10B1CDE4A0D3F41C4B82CE346E0621973BE07918EAD36D7C67BCF2984D0F78BCD1E540847CA4DC90D909845862D4F699ABFA17F5749554774BC2C59443265CE386C655055202009B32590EB0FD85F203E63425342E756AB57F5BA14BD2E283B617A230E11A955442F0C1F53AF4F08DFD1D2606DD5DD04486C40A0E6D2DB2B390D664A97D32ED7868A6AAC5F2E534B7C880EE0F6834EC100D547B823547443D02980F1EBB2EBB6D57E9368BC70C440BB5406220630583D59AB11C489B0B0B8591A7F9FF322BFD4B9FE0672800A402F9734652EF151B44180D4EA7A713C66873A245691AAF295272BFF02979772EC48D65CF34540F38EDF2B95BDF8E7A88062866A8F5471F29993E1D4A4F1638A447D237964907CA1090C0CE1D4FDD79277219F9E1CE63E3E95BAFF8017639969710AE8520769B09C318BDD8A0CB3560DDC3A6281E1816EF16D942980934B6B381D44FD19311FDE8457113B6F8FBC9101EC20F6F216712BC17A63A753F0724BA90EA9A4766FF93BBA39020CC72E0B33CB6CC3C3D87A13CB86BA9C1A9B9086DBD905F62B29782E5AAD4C27704913415E583A0EF1F2586C612DCA66CA31FD1F797752EC984E543616C7575ADC6BDAB9788F82C9258DF1E58777440BDAD5D93A2CBEAC466D6BE37CC4307CA0534B00B6EBEE4C3958BC587117E8E26D13E36B1D4A9D0F7DB2F00E9568EB21F6530EF635650C51DC9D04B788439BE01ACBF5501D673896A170037E0048882DCF5A09F7605AEFEA5615A534B5CAE77D46B00E27CAC0C7685AA235EBC0941B056FCE7737E3BD6597EF0C5774D1535F294645B12025F17474F9066DA7DFD867B72E3706FAEECD892C05D92494D7A3BEE52080BAC6FCA8F216368CBBB 20160305044620 2 6 100 6143 5 FC87210E608B51094653AB8D5963CAEF1C053FBDBBEDF91B83BBD945C79B4F67E96E8FA2C32DD50643434724257CC86C29F3CA2D266A719934B4D350E933D37153610C332F148D4B22D7D790A2A83995B0600254F640BD5E48B7D97D1BCEE76515FE078CE062EFB08529A5670F773DF514EC5392403D50C33577AFCDDE7D90224AEED69799AE17968CADDBFDC81A6E10B1CDE4A0D3F41C4B82CE346E0621973BE07918EAD36D7C67BCF2984D0F78BCD1E540847CA4DC90D909845862D4F699ABFA17F5749554774BC2C59443265CE386C655055202009B32590EB0FD85F203E63425342E756AB57F5BA14BD2E283B617A230E11A955442F0C1F53AF4F08DFD1D2606DD5DD04486C40A0E6D2DB2B390D664A97D32ED7868A6AAC5F2E534B7C880EE0F6834EC100D547B823547443D02980F1EBB2EBB6D57E9368BC70C440BB5406220630583D59AB11C489B0B0B8591A7F9FF322BFD4B9FE0672800A402F9734652EF151B44180D4EA7A713C66873A245691AAF295272BFF02979772EC48D65CF34540F38EDF2B95BDF8E7A88062866A8F5471F29993E1D4A4F1638A447D237964907CA1090C0CE1D4FDD79277219F9E1CE63E3E95BAFF8017639969710AE8520769B09C318BDD8A0CB3560DDC3A6281E1816EF16D942980934B6B381D44FD19311FDE8457113B6F8FBC9101EC20F6F216712BC17A63A753F0724BA90EA9A4766FF93BBA39020CC72E0B33CB6CC3C3D87A13CB86BA9C1A9B9086DBD905F62B29782E5AAD4C27704913415E583A0EF1F2586C612DCA66CA31FD1F797752EC984E543616C7575ADC6BDAB9788F82C9258DF1E58777440BDAD5D93A2CBEAC466D6BE37CC4307CA0534B00B6EBEE4C3958BC587117E8E26D13E36B1D4A9D0F7DB2F00E9568EB21F6530EF635650C51DC9D04B788439BE01ACBF5501D673896A170037E0048882DCF5A09F7605AEFEA5615A534B5CAE77D46B00E27CAC0C7685AA235EBC0941B056FCE7737E3BD6597EF0C5774D1535F294645B12025F17474F9066DA7DFD867B72E3706FAEECD892C05D92494D7A3BEE52080BAC6FCA8F216709F6C7 20160305053801 2 6 100 6143 2 FC87210E608B51094653AB8D5963CAEF1C053FBDBBEDF91B83BBD945C79B4F67E96E8FA2C32DD50643434724257CC86C29F3CA2D266A719934B4D350E933D37153610C332F148D4B22D7D790A2A83995B0600254F640BD5E48B7D97D1BCEE76515FE078CE062EFB08529A5670F773DF514EC5392403D50C33577AFCDDE7D90224AEED69799AE17968CADDBFDC81A6E10B1CDE4A0D3F41C4B82CE346E0621973BE07918EAD36D7C67BCF2984D0F78BCD1E540847CA4DC90D909845862D4F699ABFA17F5749554774BC2C59443265CE386C655055202009B32590EB0FD85F203E63425342E756AB57F5BA14BD2E283B617A230E11A955442F0C1F53AF4F08DFD1D2606DD5DD04486C40A0E6D2DB2B390D664A97D32ED7868A6AAC5F2E534B7C880EE0F6834EC100D547B823547443D02980F1EBB2EBB6D57E9368BC70C440BB5406220630583D59AB11C489B0B0B8591A7F9FF322BFD4B9FE0672800A402F9734652EF151B44180D4EA7A713C66873A245691AAF295272BFF02979772EC48D65CF34540F38EDF2B95BDF8E7A88062866A8F5471F29993E1D4A4F1638A447D237964907CA1090C0CE1D4FDD79277219F9E1CE63E3E95BAFF8017639969710AE8520769B09C318BDD8A0CB3560DDC3A6281E1816EF16D942980934B6B381D44FD19311FDE8457113B6F8FBC9101EC20F6F216712BC17A63A753F0724BA90EA9A4766FF93BBA39020CC72E0B33CB6CC3C3D87A13CB86BA9C1A9B9086DBD905F62B29782E5AAD4C27704913415E583A0EF1F2586C612DCA66CA31FD1F797752EC984E543616C7575ADC6BDAB9788F82C9258DF1E58777440BDAD5D93A2CBEAC466D6BE37CC4307CA0534B00B6EBEE4C3958BC587117E8E26D13E36B1D4A9D0F7DB2F00E9568EB21F6530EF635650C51DC9D04B788439BE01ACBF5501D673896A170037E0048882DCF5A09F7605AEFEA5615A534B5CAE77D46B00E27CAC0C7685AA235EBC0941B056FCE7737E3BD6597EF0C5774D1535F294645B12025F17474F9066DA7DFD867B72E3706FAEECD892C05D92494D7A3BEE52080BAC6FCA8F2168484233 20160305060125 2 6 100 6143 5 FC87210E608B51094653AB8D5963CAEF1C053FBDBBEDF91B83BBD945C79B4F67E96E8FA2C32DD50643434724257CC86C29F3CA2D266A719934B4D350E933D37153610C332F148D4B22D7D790A2A83995B0600254F640BD5E48B7D97D1BCEE76515FE078CE062EFB08529A5670F773DF514EC5392403D50C33577AFCDDE7D90224AEED69799AE17968CADDBFDC81A6E10B1CDE4A0D3F41C4B82CE346E0621973BE07918EAD36D7C67BCF2984D0F78BCD1E540847CA4DC90D909845862D4F699ABFA17F5749554774BC2C59443265CE386C655055202009B32590EB0FD85F203E63425342E756AB57F5BA14BD2E283B617A230E11A955442F0C1F53AF4F08DFD1D2606DD5DD04486C40A0E6D2DB2B390D664A97D32ED7868A6AAC5F2E534B7C880EE0F6834EC100D547B823547443D02980F1EBB2EBB6D57E9368BC70C440BB5406220630583D59AB11C489B0B0B8591A7F9FF322BFD4B9FE0672800A402F9734652EF151B44180D4EA7A713C66873A245691AAF295272BFF02979772EC48D65CF34540F38EDF2B95BDF8E7A88062866A8F5471F29993E1D4A4F1638A447D237964907CA1090C0CE1D4FDD79277219F9E1CE63E3E95BAFF8017639969710AE8520769B09C318BDD8A0CB3560DDC3A6281E1816EF16D942980934B6B381D44FD19311FDE8457113B6F8FBC9101EC20F6F216712BC17A63A753F0724BA90EA9A4766FF93BBA39020CC72E0B33CB6CC3C3D87A13CB86BA9C1A9B9086DBD905F62B29782E5AAD4C27704913415E583A0EF1F2586C612DCA66CA31FD1F797752EC984E543616C7575ADC6BDAB9788F82C9258DF1E58777440BDAD5D93A2CBEAC466D6BE37CC4307CA0534B00B6EBEE4C3958BC587117E8E26D13E36B1D4A9D0F7DB2F00E9568EB21F6530EF635650C51DC9D04B788439BE01ACBF5501D673896A170037E0048882DCF5A09F7605AEFEA5615A534B5CAE77D46B00E27CAC0C7685AA235EBC0941B056FCE7737E3BD6597EF0C5774D1535F294645B12025F17474F9066DA7DFD867B72E3706FAEECD892C05D92494D7A3BEE52080BAC6FCA8F2168D0E0E7 20160305081042 2 6 100 6143 2 FC87210E608B51094653AB8D5963CAEF1C053FBDBBEDF91B83BBD945C79B4F67E96E8FA2C32DD50643434724257CC86C29F3CA2D266A719934B4D350E933D37153610C332F148D4B22D7D790A2A83995B0600254F640BD5E48B7D97D1BCEE76515FE078CE062EFB08529A5670F773DF514EC5392403D50C33577AFCDDE7D90224AEED69799AE17968CADDBFDC81A6E10B1CDE4A0D3F41C4B82CE346E0621973BE07918EAD36D7C67BCF2984D0F78BCD1E540847CA4DC90D909845862D4F699ABFA17F5749554774BC2C59443265CE386C655055202009B32590EB0FD85F203E63425342E756AB57F5BA14BD2E283B617A230E11A955442F0C1F53AF4F08DFD1D2606DD5DD04486C40A0E6D2DB2B390D664A97D32ED7868A6AAC5F2E534B7C880EE0F6834EC100D547B823547443D02980F1EBB2EBB6D57E9368BC70C440BB5406220630583D59AB11C489B0B0B8591A7F9FF322BFD4B9FE0672800A402F9734652EF151B44180D4EA7A713C66873A245691AAF295272BFF02979772EC48D65CF34540F38EDF2B95BDF8E7A88062866A8F5471F29993E1D4A4F1638A447D237964907CA1090C0CE1D4FDD79277219F9E1CE63E3E95BAFF8017639969710AE8520769B09C318BDD8A0CB3560DDC3A6281E1816EF16D942980934B6B381D44FD19311FDE8457113B6F8FBC9101EC20F6F216712BC17A63A753F0724BA90EA9A4766FF93BBA39020CC72E0B33CB6CC3C3D87A13CB86BA9C1A9B9086DBD905F62B29782E5AAD4C27704913415E583A0EF1F2586C612DCA66CA31FD1F797752EC984E543616C7575ADC6BDAB9788F82C9258DF1E58777440BDAD5D93A2CBEAC466D6BE37CC4307CA0534B00B6EBEE4C3958BC587117E8E26D13E36B1D4A9D0F7DB2F00E9568EB21F6530EF635650C51DC9D04B788439BE01ACBF5501D673896A170037E0048882DCF5A09F7605AEFEA5615A534B5CAE77D46B00E27CAC0C7685AA235EBC0941B056FCE7737E3BD6597EF0C5774D1535F294645B12025F17474F9066DA7DFD867B72E3706FAEECD892C05D92494D7A3BEE52080BAC6FCA8F216C1797FB 20160305094218 2 6 100 6143 2 FC87210E608B51094653AB8D5963CAEF1C053FBDBBEDF91B83BBD945C79B4F67E96E8FA2C32DD50643434724257CC86C29F3CA2D266A719934B4D350E933D37153610C332F148D4B22D7D790A2A83995B0600254F640BD5E48B7D97D1BCEE76515FE078CE062EFB08529A5670F773DF514EC5392403D50C33577AFCDDE7D90224AEED69799AE17968CADDBFDC81A6E10B1CDE4A0D3F41C4B82CE346E0621973BE07918EAD36D7C67BCF2984D0F78BCD1E540847CA4DC90D909845862D4F699ABFA17F5749554774BC2C59443265CE386C655055202009B32590EB0FD85F203E63425342E756AB57F5BA14BD2E283B617A230E11A955442F0C1F53AF4F08DFD1D2606DD5DD04486C40A0E6D2DB2B390D664A97D32ED7868A6AAC5F2E534B7C880EE0F6834EC100D547B823547443D02980F1EBB2EBB6D57E9368BC70C440BB5406220630583D59AB11C489B0B0B8591A7F9FF322BFD4B9FE0672800A402F9734652EF151B44180D4EA7A713C66873A245691AAF295272BFF02979772EC48D65CF34540F38EDF2B95BDF8E7A88062866A8F5471F29993E1D4A4F1638A447D237964907CA1090C0CE1D4FDD79277219F9E1CE63E3E95BAFF8017639969710AE8520769B09C318BDD8A0CB3560DDC3A6281E1816EF16D942980934B6B381D44FD19311FDE8457113B6F8FBC9101EC20F6F216712BC17A63A753F0724BA90EA9A4766FF93BBA39020CC72E0B33CB6CC3C3D87A13CB86BA9C1A9B9086DBD905F62B29782E5AAD4C27704913415E583A0EF1F2586C612DCA66CA31FD1F797752EC984E543616C7575ADC6BDAB9788F82C9258DF1E58777440BDAD5D93A2CBEAC466D6BE37CC4307CA0534B00B6EBEE4C3958BC587117E8E26D13E36B1D4A9D0F7DB2F00E9568EB21F6530EF635650C51DC9D04B788439BE01ACBF5501D673896A170037E0048882DCF5A09F7605AEFEA5615A534B5CAE77D46B00E27CAC0C7685AA235EBC0941B056FCE7737E3BD6597EF0C5774D1535F294645B12025F17474F9066DA7DFD867B72E3706FAEECD892C05D92494D7A3BEE52080BAC6FCA8F216E608403 20160305095044 2 6 100 6143 5 FC87210E608B51094653AB8D5963CAEF1C053FBDBBEDF91B83BBD945C79B4F67E96E8FA2C32DD50643434724257CC86C29F3CA2D266A719934B4D350E933D37153610C332F148D4B22D7D790A2A83995B0600254F640BD5E48B7D97D1BCEE76515FE078CE062EFB08529A5670F773DF514EC5392403D50C33577AFCDDE7D90224AEED69799AE17968CADDBFDC81A6E10B1CDE4A0D3F41C4B82CE346E0621973BE07918EAD36D7C67BCF2984D0F78BCD1E540847CA4DC90D909845862D4F699ABFA17F5749554774BC2C59443265CE386C655055202009B32590EB0FD85F203E63425342E756AB57F5BA14BD2E283B617A230E11A955442F0C1F53AF4F08DFD1D2606DD5DD04486C40A0E6D2DB2B390D664A97D32ED7868A6AAC5F2E534B7C880EE0F6834EC100D547B823547443D02980F1EBB2EBB6D57E9368BC70C440BB5406220630583D59AB11C489B0B0B8591A7F9FF322BFD4B9FE0672800A402F9734652EF151B44180D4EA7A713C66873A245691AAF295272BFF02979772EC48D65CF34540F38EDF2B95BDF8E7A88062866A8F5471F29993E1D4A4F1638A447D237964907CA1090C0CE1D4FDD79277219F9E1CE63E3E95BAFF8017639969710AE8520769B09C318BDD8A0CB3560DDC3A6281E1816EF16D942980934B6B381D44FD19311FDE8457113B6F8FBC9101EC20F6F216712BC17A63A753F0724BA90EA9A4766FF93BBA39020CC72E0B33CB6CC3C3D87A13CB86BA9C1A9B9086DBD905F62B29782E5AAD4C27704913415E583A0EF1F2586C612DCA66CA31FD1F797752EC984E543616C7575ADC6BDAB9788F82C9258DF1E58777440BDAD5D93A2CBEAC466D6BE37CC4307CA0534B00B6EBEE4C3958BC587117E8E26D13E36B1D4A9D0F7DB2F00E9568EB21F6530EF635650C51DC9D04B788439BE01ACBF5501D673896A170037E0048882DCF5A09F7605AEFEA5615A534B5CAE77D46B00E27CAC0C7685AA235EBC0941B056FCE7737E3BD6597EF0C5774D1535F294645B12025F17474F9066DA7DFD867B72E3706FAEECD892C05D92494D7A3BEE52080BAC6FCA8F216E8BAD0F 20160305095440 2 6 100 6143 5 FC87210E608B51094653AB8D5963CAEF1C053FBDBBEDF91B83BBD945C79B4F67E96E8FA2C32DD50643434724257CC86C29F3CA2D266A719934B4D350E933D37153610C332F148D4B22D7D790A2A83995B0600254F640BD5E48B7D97D1BCEE76515FE078CE062EFB08529A5670F773DF514EC5392403D50C33577AFCDDE7D90224AEED69799AE17968CADDBFDC81A6E10B1CDE4A0D3F41C4B82CE346E0621973BE07918EAD36D7C67BCF2984D0F78BCD1E540847CA4DC90D909845862D4F699ABFA17F5749554774BC2C59443265CE386C655055202009B32590EB0FD85F203E63425342E756AB57F5BA14BD2E283B617A230E11A955442F0C1F53AF4F08DFD1D2606DD5DD04486C40A0E6D2DB2B390D664A97D32ED7868A6AAC5F2E534B7C880EE0F6834EC100D547B823547443D02980F1EBB2EBB6D57E9368BC70C440BB5406220630583D59AB11C489B0B0B8591A7F9FF322BFD4B9FE0672800A402F9734652EF151B44180D4EA7A713C66873A245691AAF295272BFF02979772EC48D65CF34540F38EDF2B95BDF8E7A88062866A8F5471F29993E1D4A4F1638A447D237964907CA1090C0CE1D4FDD79277219F9E1CE63E3E95BAFF8017639969710AE8520769B09C318BDD8A0CB3560DDC3A6281E1816EF16D942980934B6B381D44FD19311FDE8457113B6F8FBC9101EC20F6F216712BC17A63A753F0724BA90EA9A4766FF93BBA39020CC72E0B33CB6CC3C3D87A13CB86BA9C1A9B9086DBD905F62B29782E5AAD4C27704913415E583A0EF1F2586C612DCA66CA31FD1F797752EC984E543616C7575ADC6BDAB9788F82C9258DF1E58777440BDAD5D93A2CBEAC466D6BE37CC4307CA0534B00B6EBEE4C3958BC587117E8E26D13E36B1D4A9D0F7DB2F00E9568EB21F6530EF635650C51DC9D04B788439BE01ACBF5501D673896A170037E0048882DCF5A09F7605AEFEA5615A534B5CAE77D46B00E27CAC0C7685AA235EBC0941B056FCE7737E3BD6597EF0C5774D1535F294645B12025F17474F9066DA7DFD867B72E3706FAEECD892C05D92494D7A3BEE52080BAC6FCA8F216E9B001F 20160305111737 2 6 100 6143 2 FC87210E608B51094653AB8D5963CAEF1C053FBDBBEDF91B83BBD945C79B4F67E96E8FA2C32DD50643434724257CC86C29F3CA2D266A719934B4D350E933D37153610C332F148D4B22D7D790A2A83995B0600254F640BD5E48B7D97D1BCEE76515FE078CE062EFB08529A5670F773DF514EC5392403D50C33577AFCDDE7D90224AEED69799AE17968CADDBFDC81A6E10B1CDE4A0D3F41C4B82CE346E0621973BE07918EAD36D7C67BCF2984D0F78BCD1E540847CA4DC90D909845862D4F699ABFA17F5749554774BC2C59443265CE386C655055202009B32590EB0FD85F203E63425342E756AB57F5BA14BD2E283B617A230E11A955442F0C1F53AF4F08DFD1D2606DD5DD04486C40A0E6D2DB2B390D664A97D32ED7868A6AAC5F2E534B7C880EE0F6834EC100D547B823547443D02980F1EBB2EBB6D57E9368BC70C440BB5406220630583D59AB11C489B0B0B8591A7F9FF322BFD4B9FE0672800A402F9734652EF151B44180D4EA7A713C66873A245691AAF295272BFF02979772EC48D65CF34540F38EDF2B95BDF8E7A88062866A8F5471F29993E1D4A4F1638A447D237964907CA1090C0CE1D4FDD79277219F9E1CE63E3E95BAFF8017639969710AE8520769B09C318BDD8A0CB3560DDC3A6281E1816EF16D942980934B6B381D44FD19311FDE8457113B6F8FBC9101EC20F6F216712BC17A63A753F0724BA90EA9A4766FF93BBA39020CC72E0B33CB6CC3C3D87A13CB86BA9C1A9B9086DBD905F62B29782E5AAD4C27704913415E583A0EF1F2586C612DCA66CA31FD1F797752EC984E543616C7575ADC6BDAB9788F82C9258DF1E58777440BDAD5D93A2CBEAC466D6BE37CC4307CA0534B00B6EBEE4C3958BC587117E8E26D13E36B1D4A9D0F7DB2F00E9568EB21F6530EF635650C51DC9D04B788439BE01ACBF5501D673896A170037E0048882DCF5A09F7605AEFEA5615A534B5CAE77D46B00E27CAC0C7685AA235EBC0941B056FCE7737E3BD6597EF0C5774D1535F294645B12025F17474F9066DA7DFD867B72E3706FAEECD892C05D92494D7A3BEE52080BAC6FCA8F2170A72F1B 20160305152313 2 6 100 6143 2 FC87210E608B51094653AB8D5963CAEF1C053FBDBBEDF91B83BBD945C79B4F67E96E8FA2C32DD50643434724257CC86C29F3CA2D266A719934B4D350E933D37153610C332F148D4B22D7D790A2A83995B0600254F640BD5E48B7D97D1BCEE76515FE078CE062EFB08529A5670F773DF514EC5392403D50C33577AFCDDE7D90224AEED69799AE17968CADDBFDC81A6E10B1CDE4A0D3F41C4B82CE346E0621973BE07918EAD36D7C67BCF2984D0F78BCD1E540847CA4DC90D909845862D4F699ABFA17F5749554774BC2C59443265CE386C655055202009B32590EB0FD85F203E63425342E756AB57F5BA14BD2E283B617A230E11A955442F0C1F53AF4F08DFD1D2606DD5DD04486C40A0E6D2DB2B390D664A97D32ED7868A6AAC5F2E534B7C880EE0F6834EC100D547B823547443D02980F1EBB2EBB6D57E9368BC70C440BB5406220630583D59AB11C489B0B0B8591A7F9FF322BFD4B9FE0672800A402F9734652EF151B44180D4EA7A713C66873A245691AAF295272BFF02979772EC48D65CF34540F38EDF2B95BDF8E7A88062866A8F5471F29993E1D4A4F1638A447D237964907CA1090C0CE1D4FDD79277219F9E1CE63E3E95BAFF8017639969710AE8520769B09C318BDD8A0CB3560DDC3A6281E1816EF16D942980934B6B381D44FD19311FDE8457113B6F8FBC9101EC20F6F216712BC17A63A753F0724BA90EA9A4766FF93BBA39020CC72E0B33CB6CC3C3D87A13CB86BA9C1A9B9086DBD905F62B29782E5AAD4C27704913415E583A0EF1F2586C612DCA66CA31FD1F797752EC984E543616C7575ADC6BDAB9788F82C9258DF1E58777440BDAD5D93A2CBEAC466D6BE37CC4307CA0534B00B6EBEE4C3958BC587117E8E26D13E36B1D4A9D0F7DB2F00E9568EB21F6530EF635650C51DC9D04B788439BE01ACBF5501D673896A170037E0048882DCF5A09F7605AEFEA5615A534B5CAE77D46B00E27CAC0C7685AA235EBC0941B056FCE7737E3BD6597EF0C5774D1535F294645B12025F17474F9066DA7DFD867B72E3706FAEECD892C05D92494D7A3BEE52080BAC6FCA8F2176C19D53 20160305152947 2 6 100 6143 2 FC87210E608B51094653AB8D5963CAEF1C053FBDBBEDF91B83BBD945C79B4F67E96E8FA2C32DD50643434724257CC86C29F3CA2D266A719934B4D350E933D37153610C332F148D4B22D7D790A2A83995B0600254F640BD5E48B7D97D1BCEE76515FE078CE062EFB08529A5670F773DF514EC5392403D50C33577AFCDDE7D90224AEED69799AE17968CADDBFDC81A6E10B1CDE4A0D3F41C4B82CE346E0621973BE07918EAD36D7C67BCF2984D0F78BCD1E540847CA4DC90D909845862D4F699ABFA17F5749554774BC2C59443265CE386C655055202009B32590EB0FD85F203E63425342E756AB57F5BA14BD2E283B617A230E11A955442F0C1F53AF4F08DFD1D2606DD5DD04486C40A0E6D2DB2B390D664A97D32ED7868A6AAC5F2E534B7C880EE0F6834EC100D547B823547443D02980F1EBB2EBB6D57E9368BC70C440BB5406220630583D59AB11C489B0B0B8591A7F9FF322BFD4B9FE0672800A402F9734652EF151B44180D4EA7A713C66873A245691AAF295272BFF02979772EC48D65CF34540F38EDF2B95BDF8E7A88062866A8F5471F29993E1D4A4F1638A447D237964907CA1090C0CE1D4FDD79277219F9E1CE63E3E95BAFF8017639969710AE8520769B09C318BDD8A0CB3560DDC3A6281E1816EF16D942980934B6B381D44FD19311FDE8457113B6F8FBC9101EC20F6F216712BC17A63A753F0724BA90EA9A4766FF93BBA39020CC72E0B33CB6CC3C3D87A13CB86BA9C1A9B9086DBD905F62B29782E5AAD4C27704913415E583A0EF1F2586C612DCA66CA31FD1F797752EC984E543616C7575ADC6BDAB9788F82C9258DF1E58777440BDAD5D93A2CBEAC466D6BE37CC4307CA0534B00B6EBEE4C3958BC587117E8E26D13E36B1D4A9D0F7DB2F00E9568EB21F6530EF635650C51DC9D04B788439BE01ACBF5501D673896A170037E0048882DCF5A09F7605AEFEA5615A534B5CAE77D46B00E27CAC0C7685AA235EBC0941B056FCE7737E3BD6597EF0C5774D1535F294645B12025F17474F9066DA7DFD867B72E3706FAEECD892C05D92494D7A3BEE52080BAC6FCA8F2176E37BCB 20160305154608 2 6 100 6143 2 FC87210E608B51094653AB8D5963CAEF1C053FBDBBEDF91B83BBD945C79B4F67E96E8FA2C32DD50643434724257CC86C29F3CA2D266A719934B4D350E933D37153610C332F148D4B22D7D790A2A83995B0600254F640BD5E48B7D97D1BCEE76515FE078CE062EFB08529A5670F773DF514EC5392403D50C33577AFCDDE7D90224AEED69799AE17968CADDBFDC81A6E10B1CDE4A0D3F41C4B82CE346E0621973BE07918EAD36D7C67BCF2984D0F78BCD1E540847CA4DC90D909845862D4F699ABFA17F5749554774BC2C59443265CE386C655055202009B32590EB0FD85F203E63425342E756AB57F5BA14BD2E283B617A230E11A955442F0C1F53AF4F08DFD1D2606DD5DD04486C40A0E6D2DB2B390D664A97D32ED7868A6AAC5F2E534B7C880EE0F6834EC100D547B823547443D02980F1EBB2EBB6D57E9368BC70C440BB5406220630583D59AB11C489B0B0B8591A7F9FF322BFD4B9FE0672800A402F9734652EF151B44180D4EA7A713C66873A245691AAF295272BFF02979772EC48D65CF34540F38EDF2B95BDF8E7A88062866A8F5471F29993E1D4A4F1638A447D237964907CA1090C0CE1D4FDD79277219F9E1CE63E3E95BAFF8017639969710AE8520769B09C318BDD8A0CB3560DDC3A6281E1816EF16D942980934B6B381D44FD19311FDE8457113B6F8FBC9101EC20F6F216712BC17A63A753F0724BA90EA9A4766FF93BBA39020CC72E0B33CB6CC3C3D87A13CB86BA9C1A9B9086DBD905F62B29782E5AAD4C27704913415E583A0EF1F2586C612DCA66CA31FD1F797752EC984E543616C7575ADC6BDAB9788F82C9258DF1E58777440BDAD5D93A2CBEAC466D6BE37CC4307CA0534B00B6EBEE4C3958BC587117E8E26D13E36B1D4A9D0F7DB2F00E9568EB21F6530EF635650C51DC9D04B788439BE01ACBF5501D673896A170037E0048882DCF5A09F7605AEFEA5615A534B5CAE77D46B00E27CAC0C7685AA235EBC0941B056FCE7737E3BD6597EF0C5774D1535F294645B12025F17474F9066DA7DFD867B72E3706FAEECD892C05D92494D7A3BEE52080BAC6FCA8F217744E9E3 20160305161226 2 6 100 6143 5 FC87210E608B51094653AB8D5963CAEF1C053FBDBBEDF91B83BBD945C79B4F67E96E8FA2C32DD50643434724257CC86C29F3CA2D266A719934B4D350E933D37153610C332F148D4B22D7D790A2A83995B0600254F640BD5E48B7D97D1BCEE76515FE078CE062EFB08529A5670F773DF514EC5392403D50C33577AFCDDE7D90224AEED69799AE17968CADDBFDC81A6E10B1CDE4A0D3F41C4B82CE346E0621973BE07918EAD36D7C67BCF2984D0F78BCD1E540847CA4DC90D909845862D4F699ABFA17F5749554774BC2C59443265CE386C655055202009B32590EB0FD85F203E63425342E756AB57F5BA14BD2E283B617A230E11A955442F0C1F53AF4F08DFD1D2606DD5DD04486C40A0E6D2DB2B390D664A97D32ED7868A6AAC5F2E534B7C880EE0F6834EC100D547B823547443D02980F1EBB2EBB6D57E9368BC70C440BB5406220630583D59AB11C489B0B0B8591A7F9FF322BFD4B9FE0672800A402F9734652EF151B44180D4EA7A713C66873A245691AAF295272BFF02979772EC48D65CF34540F38EDF2B95BDF8E7A88062866A8F5471F29993E1D4A4F1638A447D237964907CA1090C0CE1D4FDD79277219F9E1CE63E3E95BAFF8017639969710AE8520769B09C318BDD8A0CB3560DDC3A6281E1816EF16D942980934B6B381D44FD19311FDE8457113B6F8FBC9101EC20F6F216712BC17A63A753F0724BA90EA9A4766FF93BBA39020CC72E0B33CB6CC3C3D87A13CB86BA9C1A9B9086DBD905F62B29782E5AAD4C27704913415E583A0EF1F2586C612DCA66CA31FD1F797752EC984E543616C7575ADC6BDAB9788F82C9258DF1E58777440BDAD5D93A2CBEAC466D6BE37CC4307CA0534B00B6EBEE4C3958BC587117E8E26D13E36B1D4A9D0F7DB2F00E9568EB21F6530EF635650C51DC9D04B788439BE01ACBF5501D673896A170037E0048882DCF5A09F7605AEFEA5615A534B5CAE77D46B00E27CAC0C7685AA235EBC0941B056FCE7737E3BD6597EF0C5774D1535F294645B12025F17474F9066DA7DFD867B72E3706FAEECD892C05D92494D7A3BEE52080BAC6FCA8F2177E547CF 20160305173357 2 6 100 6143 2 FC87210E608B51094653AB8D5963CAEF1C053FBDBBEDF91B83BBD945C79B4F67E96E8FA2C32DD50643434724257CC86C29F3CA2D266A719934B4D350E933D37153610C332F148D4B22D7D790A2A83995B0600254F640BD5E48B7D97D1BCEE76515FE078CE062EFB08529A5670F773DF514EC5392403D50C33577AFCDDE7D90224AEED69799AE17968CADDBFDC81A6E10B1CDE4A0D3F41C4B82CE346E0621973BE07918EAD36D7C67BCF2984D0F78BCD1E540847CA4DC90D909845862D4F699ABFA17F5749554774BC2C59443265CE386C655055202009B32590EB0FD85F203E63425342E756AB57F5BA14BD2E283B617A230E11A955442F0C1F53AF4F08DFD1D2606DD5DD04486C40A0E6D2DB2B390D664A97D32ED7868A6AAC5F2E534B7C880EE0F6834EC100D547B823547443D02980F1EBB2EBB6D57E9368BC70C440BB5406220630583D59AB11C489B0B0B8591A7F9FF322BFD4B9FE0672800A402F9734652EF151B44180D4EA7A713C66873A245691AAF295272BFF02979772EC48D65CF34540F38EDF2B95BDF8E7A88062866A8F5471F29993E1D4A4F1638A447D237964907CA1090C0CE1D4FDD79277219F9E1CE63E3E95BAFF8017639969710AE8520769B09C318BDD8A0CB3560DDC3A6281E1816EF16D942980934B6B381D44FD19311FDE8457113B6F8FBC9101EC20F6F216712BC17A63A753F0724BA90EA9A4766FF93BBA39020CC72E0B33CB6CC3C3D87A13CB86BA9C1A9B9086DBD905F62B29782E5AAD4C27704913415E583A0EF1F2586C612DCA66CA31FD1F797752EC984E543616C7575ADC6BDAB9788F82C9258DF1E58777440BDAD5D93A2CBEAC466D6BE37CC4307CA0534B00B6EBEE4C3958BC587117E8E26D13E36B1D4A9D0F7DB2F00E9568EB21F6530EF635650C51DC9D04B788439BE01ACBF5501D673896A170037E0048882DCF5A09F7605AEFEA5615A534B5CAE77D46B00E27CAC0C7685AA235EBC0941B056FCE7737E3BD6597EF0C5774D1535F294645B12025F17474F9066DA7DFD867B72E3706FAEECD892C05D92494D7A3BEE52080BAC6FCA8F2179D3586B 20160305235825 2 6 100 7679 2 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B0B4DFC33 20160306022229 2 6 100 7679 2 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B0D65D0DB 20160306093737 2 6 100 7679 5 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B13D7D927 20160306094452 2 6 100 7679 2 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B13E933BB 20160306160337 2 6 100 7679 2 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B1971D123 20160306224032 2 6 100 7679 2 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B1F3B6DAB 20160306225345 2 6 100 7679 5 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B1F6160BF 20160306233854 2 6 100 7679 5 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B2005324F 20160307010902 2 6 100 7679 2 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B214E9673 20160307051433 2 6 100 7679 5 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B24C9A09F 20160307062817 2 6 100 7679 2 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B25CA759B 20160307113227 2 6 100 7679 2 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B2A201EFB 20160307123109 2 6 100 7679 5 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B2AEC017F 20160307185147 2 6 100 7679 2 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B3059D223 20160308031623 2 6 100 7679 2 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B3779276B 20160308074434 2 6 100 7679 5 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B3B36AF7F 20160308080500 2 6 100 7679 2 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B3B735E1B 20160308090559 2 6 100 7679 2 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B3C46A863 20160308204809 2 6 100 7679 2 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B45F50A43 20160308220844 2 6 100 7679 2 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B47098FDB 20160309000534 2 6 100 7679 2 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B4893E51B 20160309035855 2 6 100 7679 2 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B4B9D5AF3 20160309042540 2 6 100 7679 2 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B4BEF4FBB 20160309152136 2 6 100 7679 2 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B54B515AB 20160309192852 2 6 100 7679 5 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B57FBEBF7 20160310013359 2 6 100 7679 2 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B5CE29283 20160310035549 2 6 100 7679 2 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B5EB8EE13 20160310075706 2 6 100 7679 5 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B61EA384F 20160310173812 2 6 100 7679 2 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B6993761B 20160310190029 2 6 100 7679 5 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B6A9FDA07 20160310193821 2 6 100 7679 2 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B6B156863 20160311033330 2 6 100 7679 2 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B714D2463 20160311043906 2 6 100 7679 5 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B7225A617 20160311054129 2 6 100 7679 2 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B72E8A083 20160311060123 2 6 100 7679 5 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B7320D78F 20160311060829 2 6 100 7679 2 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B732F58C3 20160311071819 2 6 100 7679 2 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B740FC84B 20160311081031 2 6 100 7679 5 CDE6C545B0D2F4A803F7AA7269ADA925DA60EAE55764AE38A7C61738B71DA67096F9E2CABF9B30B2E33E1FE97BFE4CE54B53041F2B2A0DAEF6135B6FB4990BE5C32AA56F223B6FDA4599B58517C6B78EA50C8E17CBB37865B5DB8AB5AB0F9A30B27AD76B11F758F10643A569346816280CE9368A159957E161B5E877CBD33D838B725F3CBAA53F6BC1B8F0062B9ED6D756CBB077B92A0A010636B4B92D570C8E0E3BA5553A92B7F1BF41C7AF7354849491B1C63886EE4A52DDBCF24444D5EA1636F883C1B5482E5ECBCA45BB5C741E9A302554B218DEC84908A75D6A2FB12CD96B1C6046A27FCBEDF260AA445C90A156DC17A1147861792E81840E71D0C8DA6BFC54BE0AA2409B7B23807FC07EF4B2B88B6AA9755809D084448E20D06890B4F299F4A38653F34BB52F38E06E4BC7AECD019E6E06FE39238F661726D7FD4AF8F5CFD49177CE8F8D324C99A00D4FF37B5CE5845106893B0AB4600F0A47BC5C3A536969498548EB86BC2ADB0155F9D2F94B02E7198CCE6E03D091191F63F7CD9AF5F2781D32C105A5DD8425090F90FD2099FE37630A69DB179A7161A226B0CD24C93C087B3AC90EF711C2358DC39EA53C0B9BEAF30851B9DCC5BCE27B4595D391DB68336FF330D3A1E90358A2CB1B35765C6F629D737EF13D6565390D25F3DC8E5A17FDDAF740568659F064CC5DB9F4A3A6CA3BA027A58CD18880F4941CC9B372BDB9B3398FBC357B7672EFEA922537846A4F4B7F393B927786A30DEEC3E5234CFB2D9CE459D1CB2140DE33052CF325BF81C4AA80928FB4906B6700F9CC2628747894CDF90FE2C2F07303F435CFD182F661B19E802092BEDB3E22C275A9AB635DD60A442E2E3D6B61CB204898EB0F0D888CE8903FA8521B9EF18046904F63B66C70B2C503CD1E2A2EEF203274D59D5A86F1B2758B9DDC9F97708841322C99BE9A47524A8BE01D7152B9ACF12C0181BB8C1884DD03FF26FA916FD95A4325DAC03139C80F7931F24694AFDDC150848579C28276BC4DA72400277F560A1E9701186148B5ADADDA2BCC8F7ED47A999DC77C3D6C7E20AD7F3C0A4DFAD3B8EEA0C0C402A28B27B01EAE661CF48CB7A8E14FF0597612798D954B1AC078984BAC3353F2A9829E9F29D88562F5EF90DF5A5E81A97C4BC9565F2F915B43ECD333B189D3C774E18B397D3B6640D8F4902DE3A90BF4E2646302A4BE7341A40F83AEC49B7DC31C0B91CF4BF022EBC8623CDFAD234CECD39942649B386CC65EBED4676F6B0FBC015D2C300B252A7DE8DC6434270DF9918D48FF541CAFFEE9485166EFB82C4F4FB2FA109C6C16D475052E530B12FB81DF189F77C08A9DC2F6A4F37E38601B74B68FAF 20160311170649 2 6 100 7679 5 EC435B7E292EBAAEC94B8E8A53ED9F3FF717BB820D4893F0BBE6589BD3AF344B765A6000950C6244B2E4262E7E500BF699AF0FF49605A15EB80C61429C9FB79F658C3E0F8DB516AF9703BCB5E84ABA314292808DC70D183C513609A6D345F5D8676256E25108EE70B210C0293B5C804CF21FD843D2F5F79F91F57CF2C2EFB7052CA5F73544F0568A68FA5583CA6EDD300817AAB25E650B0AB9523C6C60156726F4B5243A8BE580308BB6297E23785893119D49B2407D4D8DACD551D08A5F9BB32BD7965313EC6C9DDCD685A62F7AFC8E71DF10F9E1FA25EB3DCD41D7DBDEFE5DB565BAE0CB62F192AA573A126FB92C9638457E73EB4C007268142D9506B17D20A4D73B51E21983D9AC86F7ABBDCE9B9D10BE307642C49382E27B45ADB32E9FF7A2203F395C71EAF7656DF83F57E527CCA37A2BE9AFBA89FB718DB95CC041BF4025FF1CB5F463C8A09FD374AF3F143EE53FF4B369117BDBE0743335B1B5650B68C5B4F64E42D4CF0B329316F4FCD5E66F4A1359F2B29684961CA04EC5AC787FD4BF990F3FBE698D69FAF946DE12A4215392928E29ACF24F940AE4046C74BC6E799EE1D85BA8264C6C7DFF62A244CA2D05C4352870E0E8EF71F884AEFA4A4CA704B6C6607D2E59D36253350AF73C1FBE9C5D61A26A9024B715B45ECF1487D23970C5E405B46029403DD95B2F5672E61863E48CBB280300B2CF87C749F0ACC52940819688C819250B71E54397C8792AAB31655BCE19FAD3A7C59BD64904CC806304AEB6DC8B534081CD2EFD2808977FAC9BAB540EC153DD98D8B33984EC40BCFBC0C5D5B95AB3E183961DB2EE8883B174A3CFEC21CBE7F200FDD2879C1BA808B65A03B02793688FBB1F753333A23A4139766DD3ECD30742E55C25474D068CAB008BA6957CB014E4D46C4BF3084C8343D61231B6B997A8BCEE761D907E4323B92EED55575A38048D686B04F6614B7F931BF1F7D2CF35912E3472F424B11FEBA41F6D569B1A13002A33D5660844A896436AA4D8BC74B6951C75F883D747690B6AD3501B84C6C5B4E29C4153A98C0F2DF38CAFDF00E15CFE8DB0939E5611518DB4547CB2880B5F2D431526082D608384FA3BDD78B75157F25C7A2448249E635C20051C39577AE777C75E7B424CB647B76C9880E905E401DA09DE7A6A5F3E59376B24DCAC613C6EF263741FA15E83B64C78C03016FD34AB608D77100FD8733F130F63A0725B8E7CCD344F5E9A460D2F4F5BE139A6B57A3955A47726A02D6425EF8D1440709517F2DE1D8BB1D054BF69B77E44B4C4427F26EC6303F91CF197298214820264AFACBD355F08E278734BDBF1E116ADF6C1C03ADF5E73212A7073B9B171F787 20160311195449 2 6 100 7679 5 EC435B7E292EBAAEC94B8E8A53ED9F3FF717BB820D4893F0BBE6589BD3AF344B765A6000950C6244B2E4262E7E500BF699AF0FF49605A15EB80C61429C9FB79F658C3E0F8DB516AF9703BCB5E84ABA314292808DC70D183C513609A6D345F5D8676256E25108EE70B210C0293B5C804CF21FD843D2F5F79F91F57CF2C2EFB7052CA5F73544F0568A68FA5583CA6EDD300817AAB25E650B0AB9523C6C60156726F4B5243A8BE580308BB6297E23785893119D49B2407D4D8DACD551D08A5F9BB32BD7965313EC6C9DDCD685A62F7AFC8E71DF10F9E1FA25EB3DCD41D7DBDEFE5DB565BAE0CB62F192AA573A126FB92C9638457E73EB4C007268142D9506B17D20A4D73B51E21983D9AC86F7ABBDCE9B9D10BE307642C49382E27B45ADB32E9FF7A2203F395C71EAF7656DF83F57E527CCA37A2BE9AFBA89FB718DB95CC041BF4025FF1CB5F463C8A09FD374AF3F143EE53FF4B369117BDBE0743335B1B5650B68C5B4F64E42D4CF0B329316F4FCD5E66F4A1359F2B29684961CA04EC5AC787FD4BF990F3FBE698D69FAF946DE12A4215392928E29ACF24F940AE4046C74BC6E799EE1D85BA8264C6C7DFF62A244CA2D05C4352870E0E8EF71F884AEFA4A4CA704B6C6607D2E59D36253350AF73C1FBE9C5D61A26A9024B715B45ECF1487D23970C5E405B46029403DD95B2F5672E61863E48CBB280300B2CF87C749F0ACC52940819688C819250B71E54397C8792AAB31655BCE19FAD3A7C59BD64904CC806304AEB6DC8B534081CD2EFD2808977FAC9BAB540EC153DD98D8B33984EC40BCFBC0C5D5B95AB3E183961DB2EE8883B174A3CFEC21CBE7F200FDD2879C1BA808B65A03B02793688FBB1F753333A23A4139766DD3ECD30742E55C25474D068CAB008BA6957CB014E4D46C4BF3084C8343D61231B6B997A8BCEE761D907E4323B92EED55575A38048D686B04F6614B7F931BF1F7D2CF35912E3472F424B11FEBA41F6D569B1A13002A33D5660844A896436AA4D8BC74B6951C75F883D747690B6AD3501B84C6C5B4E29C4153A98C0F2DF38CAFDF00E15CFE8DB0939E5611518DB4547CB2880B5F2D431526082D608384FA3BDD78B75157F25C7A2448249E635C20051C39577AE777C75E7B424CB647B76C9880E905E401DA09DE7A6A5F3E59376B24DCAC613C6EF263741FA15E83B64C78C03016FD34AB608D77100FD8733F130F63A0725B8E7CCD344F5E9A460D2F4F5BE139A6B57A3955A47726A02D6425EF8D1440709517F2DE1D8BB1D054BF69B77E44B4C4427F26EC6303F91CF197298214820264AFACBD355F08E278734BDBF1E116ADF6C1C03ADF5E73212A7073B9B3EAFC07 20160312113901 2 6 100 7679 2 EC435B7E292EBAAEC94B8E8A53ED9F3FF717BB820D4893F0BBE6589BD3AF344B765A6000950C6244B2E4262E7E500BF699AF0FF49605A15EB80C61429C9FB79F658C3E0F8DB516AF9703BCB5E84ABA314292808DC70D183C513609A6D345F5D8676256E25108EE70B210C0293B5C804CF21FD843D2F5F79F91F57CF2C2EFB7052CA5F73544F0568A68FA5583CA6EDD300817AAB25E650B0AB9523C6C60156726F4B5243A8BE580308BB6297E23785893119D49B2407D4D8DACD551D08A5F9BB32BD7965313EC6C9DDCD685A62F7AFC8E71DF10F9E1FA25EB3DCD41D7DBDEFE5DB565BAE0CB62F192AA573A126FB92C9638457E73EB4C007268142D9506B17D20A4D73B51E21983D9AC86F7ABBDCE9B9D10BE307642C49382E27B45ADB32E9FF7A2203F395C71EAF7656DF83F57E527CCA37A2BE9AFBA89FB718DB95CC041BF4025FF1CB5F463C8A09FD374AF3F143EE53FF4B369117BDBE0743335B1B5650B68C5B4F64E42D4CF0B329316F4FCD5E66F4A1359F2B29684961CA04EC5AC787FD4BF990F3FBE698D69FAF946DE12A4215392928E29ACF24F940AE4046C74BC6E799EE1D85BA8264C6C7DFF62A244CA2D05C4352870E0E8EF71F884AEFA4A4CA704B6C6607D2E59D36253350AF73C1FBE9C5D61A26A9024B715B45ECF1487D23970C5E405B46029403DD95B2F5672E61863E48CBB280300B2CF87C749F0ACC52940819688C819250B71E54397C8792AAB31655BCE19FAD3A7C59BD64904CC806304AEB6DC8B534081CD2EFD2808977FAC9BAB540EC153DD98D8B33984EC40BCFBC0C5D5B95AB3E183961DB2EE8883B174A3CFEC21CBE7F200FDD2879C1BA808B65A03B02793688FBB1F753333A23A4139766DD3ECD30742E55C25474D068CAB008BA6957CB014E4D46C4BF3084C8343D61231B6B997A8BCEE761D907E4323B92EED55575A38048D686B04F6614B7F931BF1F7D2CF35912E3472F424B11FEBA41F6D569B1A13002A33D5660844A896436AA4D8BC74B6951C75F883D747690B6AD3501B84C6C5B4E29C4153A98C0F2DF38CAFDF00E15CFE8DB0939E5611518DB4547CB2880B5F2D431526082D608384FA3BDD78B75157F25C7A2448249E635C20051C39577AE777C75E7B424CB647B76C9880E905E401DA09DE7A6A5F3E59376B24DCAC613C6EF263741FA15E83B64C78C03016FD34AB608D77100FD8733F130F63A0725B8E7CCD344F5E9A460D2F4F5BE139A6B57A3955A47726A02D6425EF8D1440709517F2DE1D8BB1D054BF69B77E44B4C4427F26EC6303F91CF197298214820264AFACBD355F08E278734BDBF1E116ADF6C1C03ADF5E73212A7073B9C1FC4A03 20160312141825 2 6 100 7679 2 EC435B7E292EBAAEC94B8E8A53ED9F3FF717BB820D4893F0BBE6589BD3AF344B765A6000950C6244B2E4262E7E500BF699AF0FF49605A15EB80C61429C9FB79F658C3E0F8DB516AF9703BCB5E84ABA314292808DC70D183C513609A6D345F5D8676256E25108EE70B210C0293B5C804CF21FD843D2F5F79F91F57CF2C2EFB7052CA5F73544F0568A68FA5583CA6EDD300817AAB25E650B0AB9523C6C60156726F4B5243A8BE580308BB6297E23785893119D49B2407D4D8DACD551D08A5F9BB32BD7965313EC6C9DDCD685A62F7AFC8E71DF10F9E1FA25EB3DCD41D7DBDEFE5DB565BAE0CB62F192AA573A126FB92C9638457E73EB4C007268142D9506B17D20A4D73B51E21983D9AC86F7ABBDCE9B9D10BE307642C49382E27B45ADB32E9FF7A2203F395C71EAF7656DF83F57E527CCA37A2BE9AFBA89FB718DB95CC041BF4025FF1CB5F463C8A09FD374AF3F143EE53FF4B369117BDBE0743335B1B5650B68C5B4F64E42D4CF0B329316F4FCD5E66F4A1359F2B29684961CA04EC5AC787FD4BF990F3FBE698D69FAF946DE12A4215392928E29ACF24F940AE4046C74BC6E799EE1D85BA8264C6C7DFF62A244CA2D05C4352870E0E8EF71F884AEFA4A4CA704B6C6607D2E59D36253350AF73C1FBE9C5D61A26A9024B715B45ECF1487D23970C5E405B46029403DD95B2F5672E61863E48CBB280300B2CF87C749F0ACC52940819688C819250B71E54397C8792AAB31655BCE19FAD3A7C59BD64904CC806304AEB6DC8B534081CD2EFD2808977FAC9BAB540EC153DD98D8B33984EC40BCFBC0C5D5B95AB3E183961DB2EE8883B174A3CFEC21CBE7F200FDD2879C1BA808B65A03B02793688FBB1F753333A23A4139766DD3ECD30742E55C25474D068CAB008BA6957CB014E4D46C4BF3084C8343D61231B6B997A8BCEE761D907E4323B92EED55575A38048D686B04F6614B7F931BF1F7D2CF35912E3472F424B11FEBA41F6D569B1A13002A33D5660844A896436AA4D8BC74B6951C75F883D747690B6AD3501B84C6C5B4E29C4153A98C0F2DF38CAFDF00E15CFE8DB0939E5611518DB4547CB2880B5F2D431526082D608384FA3BDD78B75157F25C7A2448249E635C20051C39577AE777C75E7B424CB647B76C9880E905E401DA09DE7A6A5F3E59376B24DCAC613C6EF263741FA15E83B64C78C03016FD34AB608D77100FD8733F130F63A0725B8E7CCD344F5E9A460D2F4F5BE139A6B57A3955A47726A02D6425EF8D1440709517F2DE1D8BB1D054BF69B77E44B4C4427F26EC6303F91CF197298214820264AFACBD355F08E278734BDBF1E116ADF6C1C03ADF5E73212A7073B9C45A6C9B 20160312221956 2 6 100 7679 5 EC435B7E292EBAAEC94B8E8A53ED9F3FF717BB820D4893F0BBE6589BD3AF344B765A6000950C6244B2E4262E7E500BF699AF0FF49605A15EB80C61429C9FB79F658C3E0F8DB516AF9703BCB5E84ABA314292808DC70D183C513609A6D345F5D8676256E25108EE70B210C0293B5C804CF21FD843D2F5F79F91F57CF2C2EFB7052CA5F73544F0568A68FA5583CA6EDD300817AAB25E650B0AB9523C6C60156726F4B5243A8BE580308BB6297E23785893119D49B2407D4D8DACD551D08A5F9BB32BD7965313EC6C9DDCD685A62F7AFC8E71DF10F9E1FA25EB3DCD41D7DBDEFE5DB565BAE0CB62F192AA573A126FB92C9638457E73EB4C007268142D9506B17D20A4D73B51E21983D9AC86F7ABBDCE9B9D10BE307642C49382E27B45ADB32E9FF7A2203F395C71EAF7656DF83F57E527CCA37A2BE9AFBA89FB718DB95CC041BF4025FF1CB5F463C8A09FD374AF3F143EE53FF4B369117BDBE0743335B1B5650B68C5B4F64E42D4CF0B329316F4FCD5E66F4A1359F2B29684961CA04EC5AC787FD4BF990F3FBE698D69FAF946DE12A4215392928E29ACF24F940AE4046C74BC6E799EE1D85BA8264C6C7DFF62A244CA2D05C4352870E0E8EF71F884AEFA4A4CA704B6C6607D2E59D36253350AF73C1FBE9C5D61A26A9024B715B45ECF1487D23970C5E405B46029403DD95B2F5672E61863E48CBB280300B2CF87C749F0ACC52940819688C819250B71E54397C8792AAB31655BCE19FAD3A7C59BD64904CC806304AEB6DC8B534081CD2EFD2808977FAC9BAB540EC153DD98D8B33984EC40BCFBC0C5D5B95AB3E183961DB2EE8883B174A3CFEC21CBE7F200FDD2879C1BA808B65A03B02793688FBB1F753333A23A4139766DD3ECD30742E55C25474D068CAB008BA6957CB014E4D46C4BF3084C8343D61231B6B997A8BCEE761D907E4323B92EED55575A38048D686B04F6614B7F931BF1F7D2CF35912E3472F424B11FEBA41F6D569B1A13002A33D5660844A896436AA4D8BC74B6951C75F883D747690B6AD3501B84C6C5B4E29C4153A98C0F2DF38CAFDF00E15CFE8DB0939E5611518DB4547CB2880B5F2D431526082D608384FA3BDD78B75157F25C7A2448249E635C20051C39577AE777C75E7B424CB647B76C9880E905E401DA09DE7A6A5F3E59376B24DCAC613C6EF263741FA15E83B64C78C03016FD34AB608D77100FD8733F130F63A0725B8E7CCD344F5E9A460D2F4F5BE139A6B57A3955A47726A02D6425EF8D1440709517F2DE1D8BB1D054BF69B77E44B4C4427F26EC6303F91CF197298214820264AFACBD355F08E278734BDBF1E116ADF6C1C03ADF5E73212A7073B9CB35C95F 20160313023234 2 6 100 7679 2 EC435B7E292EBAAEC94B8E8A53ED9F3FF717BB820D4893F0BBE6589BD3AF344B765A6000950C6244B2E4262E7E500BF699AF0FF49605A15EB80C61429C9FB79F658C3E0F8DB516AF9703BCB5E84ABA314292808DC70D183C513609A6D345F5D8676256E25108EE70B210C0293B5C804CF21FD843D2F5F79F91F57CF2C2EFB7052CA5F73544F0568A68FA5583CA6EDD300817AAB25E650B0AB9523C6C60156726F4B5243A8BE580308BB6297E23785893119D49B2407D4D8DACD551D08A5F9BB32BD7965313EC6C9DDCD685A62F7AFC8E71DF10F9E1FA25EB3DCD41D7DBDEFE5DB565BAE0CB62F192AA573A126FB92C9638457E73EB4C007268142D9506B17D20A4D73B51E21983D9AC86F7ABBDCE9B9D10BE307642C49382E27B45ADB32E9FF7A2203F395C71EAF7656DF83F57E527CCA37A2BE9AFBA89FB718DB95CC041BF4025FF1CB5F463C8A09FD374AF3F143EE53FF4B369117BDBE0743335B1B5650B68C5B4F64E42D4CF0B329316F4FCD5E66F4A1359F2B29684961CA04EC5AC787FD4BF990F3FBE698D69FAF946DE12A4215392928E29ACF24F940AE4046C74BC6E799EE1D85BA8264C6C7DFF62A244CA2D05C4352870E0E8EF71F884AEFA4A4CA704B6C6607D2E59D36253350AF73C1FBE9C5D61A26A9024B715B45ECF1487D23970C5E405B46029403DD95B2F5672E61863E48CBB280300B2CF87C749F0ACC52940819688C819250B71E54397C8792AAB31655BCE19FAD3A7C59BD64904CC806304AEB6DC8B534081CD2EFD2808977FAC9BAB540EC153DD98D8B33984EC40BCFBC0C5D5B95AB3E183961DB2EE8883B174A3CFEC21CBE7F200FDD2879C1BA808B65A03B02793688FBB1F753333A23A4139766DD3ECD30742E55C25474D068CAB008BA6957CB014E4D46C4BF3084C8343D61231B6B997A8BCEE761D907E4323B92EED55575A38048D686B04F6614B7F931BF1F7D2CF35912E3472F424B11FEBA41F6D569B1A13002A33D5660844A896436AA4D8BC74B6951C75F883D747690B6AD3501B84C6C5B4E29C4153A98C0F2DF38CAFDF00E15CFE8DB0939E5611518DB4547CB2880B5F2D431526082D608384FA3BDD78B75157F25C7A2448249E635C20051C39577AE777C75E7B424CB647B76C9880E905E401DA09DE7A6A5F3E59376B24DCAC613C6EF263741FA15E83B64C78C03016FD34AB608D77100FD8733F130F63A0725B8E7CCD344F5E9A460D2F4F5BE139A6B57A3955A47726A02D6425EF8D1440709517F2DE1D8BB1D054BF69B77E44B4C4427F26EC6303F91CF197298214820264AFACBD355F08E278734BDBF1E116ADF6C1C03ADF5E73212A7073B9CED021AB 20160313062450 2 6 100 7679 5 EC435B7E292EBAAEC94B8E8A53ED9F3FF717BB820D4893F0BBE6589BD3AF344B765A6000950C6244B2E4262E7E500BF699AF0FF49605A15EB80C61429C9FB79F658C3E0F8DB516AF9703BCB5E84ABA314292808DC70D183C513609A6D345F5D8676256E25108EE70B210C0293B5C804CF21FD843D2F5F79F91F57CF2C2EFB7052CA5F73544F0568A68FA5583CA6EDD300817AAB25E650B0AB9523C6C60156726F4B5243A8BE580308BB6297E23785893119D49B2407D4D8DACD551D08A5F9BB32BD7965313EC6C9DDCD685A62F7AFC8E71DF10F9E1FA25EB3DCD41D7DBDEFE5DB565BAE0CB62F192AA573A126FB92C9638457E73EB4C007268142D9506B17D20A4D73B51E21983D9AC86F7ABBDCE9B9D10BE307642C49382E27B45ADB32E9FF7A2203F395C71EAF7656DF83F57E527CCA37A2BE9AFBA89FB718DB95CC041BF4025FF1CB5F463C8A09FD374AF3F143EE53FF4B369117BDBE0743335B1B5650B68C5B4F64E42D4CF0B329316F4FCD5E66F4A1359F2B29684961CA04EC5AC787FD4BF990F3FBE698D69FAF946DE12A4215392928E29ACF24F940AE4046C74BC6E799EE1D85BA8264C6C7DFF62A244CA2D05C4352870E0E8EF71F884AEFA4A4CA704B6C6607D2E59D36253350AF73C1FBE9C5D61A26A9024B715B45ECF1487D23970C5E405B46029403DD95B2F5672E61863E48CBB280300B2CF87C749F0ACC52940819688C819250B71E54397C8792AAB31655BCE19FAD3A7C59BD64904CC806304AEB6DC8B534081CD2EFD2808977FAC9BAB540EC153DD98D8B33984EC40BCFBC0C5D5B95AB3E183961DB2EE8883B174A3CFEC21CBE7F200FDD2879C1BA808B65A03B02793688FBB1F753333A23A4139766DD3ECD30742E55C25474D068CAB008BA6957CB014E4D46C4BF3084C8343D61231B6B997A8BCEE761D907E4323B92EED55575A38048D686B04F6614B7F931BF1F7D2CF35912E3472F424B11FEBA41F6D569B1A13002A33D5660844A896436AA4D8BC74B6951C75F883D747690B6AD3501B84C6C5B4E29C4153A98C0F2DF38CAFDF00E15CFE8DB0939E5611518DB4547CB2880B5F2D431526082D608384FA3BDD78B75157F25C7A2448249E635C20051C39577AE777C75E7B424CB647B76C9880E905E401DA09DE7A6A5F3E59376B24DCAC613C6EF263741FA15E83B64C78C03016FD34AB608D77100FD8733F130F63A0725B8E7CCD344F5E9A460D2F4F5BE139A6B57A3955A47726A02D6425EF8D1440709517F2DE1D8BB1D054BF69B77E44B4C4427F26EC6303F91CF197298214820264AFACBD355F08E278734BDBF1E116ADF6C1C03ADF5E73212A7073B9D2124DF7 20160313135733 2 6 100 7679 2 EC435B7E292EBAAEC94B8E8A53ED9F3FF717BB820D4893F0BBE6589BD3AF344B765A6000950C6244B2E4262E7E500BF699AF0FF49605A15EB80C61429C9FB79F658C3E0F8DB516AF9703BCB5E84ABA314292808DC70D183C513609A6D345F5D8676256E25108EE70B210C0293B5C804CF21FD843D2F5F79F91F57CF2C2EFB7052CA5F73544F0568A68FA5583CA6EDD300817AAB25E650B0AB9523C6C60156726F4B5243A8BE580308BB6297E23785893119D49B2407D4D8DACD551D08A5F9BB32BD7965313EC6C9DDCD685A62F7AFC8E71DF10F9E1FA25EB3DCD41D7DBDEFE5DB565BAE0CB62F192AA573A126FB92C9638457E73EB4C007268142D9506B17D20A4D73B51E21983D9AC86F7ABBDCE9B9D10BE307642C49382E27B45ADB32E9FF7A2203F395C71EAF7656DF83F57E527CCA37A2BE9AFBA89FB718DB95CC041BF4025FF1CB5F463C8A09FD374AF3F143EE53FF4B369117BDBE0743335B1B5650B68C5B4F64E42D4CF0B329316F4FCD5E66F4A1359F2B29684961CA04EC5AC787FD4BF990F3FBE698D69FAF946DE12A4215392928E29ACF24F940AE4046C74BC6E799EE1D85BA8264C6C7DFF62A244CA2D05C4352870E0E8EF71F884AEFA4A4CA704B6C6607D2E59D36253350AF73C1FBE9C5D61A26A9024B715B45ECF1487D23970C5E405B46029403DD95B2F5672E61863E48CBB280300B2CF87C749F0ACC52940819688C819250B71E54397C8792AAB31655BCE19FAD3A7C59BD64904CC806304AEB6DC8B534081CD2EFD2808977FAC9BAB540EC153DD98D8B33984EC40BCFBC0C5D5B95AB3E183961DB2EE8883B174A3CFEC21CBE7F200FDD2879C1BA808B65A03B02793688FBB1F753333A23A4139766DD3ECD30742E55C25474D068CAB008BA6957CB014E4D46C4BF3084C8343D61231B6B997A8BCEE761D907E4323B92EED55575A38048D686B04F6614B7F931BF1F7D2CF35912E3472F424B11FEBA41F6D569B1A13002A33D5660844A896436AA4D8BC74B6951C75F883D747690B6AD3501B84C6C5B4E29C4153A98C0F2DF38CAFDF00E15CFE8DB0939E5611518DB4547CB2880B5F2D431526082D608384FA3BDD78B75157F25C7A2448249E635C20051C39577AE777C75E7B424CB647B76C9880E905E401DA09DE7A6A5F3E59376B24DCAC613C6EF263741FA15E83B64C78C03016FD34AB608D77100FD8733F130F63A0725B8E7CCD344F5E9A460D2F4F5BE139A6B57A3955A47726A02D6425EF8D1440709517F2DE1D8BB1D054BF69B77E44B4C4427F26EC6303F91CF197298214820264AFACBD355F08E278734BDBF1E116ADF6C1C03ADF5E73212A7073B9D880F89B 20160314002320 2 6 100 7679 2 EC435B7E292EBAAEC94B8E8A53ED9F3FF717BB820D4893F0BBE6589BD3AF344B765A6000950C6244B2E4262E7E500BF699AF0FF49605A15EB80C61429C9FB79F658C3E0F8DB516AF9703BCB5E84ABA314292808DC70D183C513609A6D345F5D8676256E25108EE70B210C0293B5C804CF21FD843D2F5F79F91F57CF2C2EFB7052CA5F73544F0568A68FA5583CA6EDD300817AAB25E650B0AB9523C6C60156726F4B5243A8BE580308BB6297E23785893119D49B2407D4D8DACD551D08A5F9BB32BD7965313EC6C9DDCD685A62F7AFC8E71DF10F9E1FA25EB3DCD41D7DBDEFE5DB565BAE0CB62F192AA573A126FB92C9638457E73EB4C007268142D9506B17D20A4D73B51E21983D9AC86F7ABBDCE9B9D10BE307642C49382E27B45ADB32E9FF7A2203F395C71EAF7656DF83F57E527CCA37A2BE9AFBA89FB718DB95CC041BF4025FF1CB5F463C8A09FD374AF3F143EE53FF4B369117BDBE0743335B1B5650B68C5B4F64E42D4CF0B329316F4FCD5E66F4A1359F2B29684961CA04EC5AC787FD4BF990F3FBE698D69FAF946DE12A4215392928E29ACF24F940AE4046C74BC6E799EE1D85BA8264C6C7DFF62A244CA2D05C4352870E0E8EF71F884AEFA4A4CA704B6C6607D2E59D36253350AF73C1FBE9C5D61A26A9024B715B45ECF1487D23970C5E405B46029403DD95B2F5672E61863E48CBB280300B2CF87C749F0ACC52940819688C819250B71E54397C8792AAB31655BCE19FAD3A7C59BD64904CC806304AEB6DC8B534081CD2EFD2808977FAC9BAB540EC153DD98D8B33984EC40BCFBC0C5D5B95AB3E183961DB2EE8883B174A3CFEC21CBE7F200FDD2879C1BA808B65A03B02793688FBB1F753333A23A4139766DD3ECD30742E55C25474D068CAB008BA6957CB014E4D46C4BF3084C8343D61231B6B997A8BCEE761D907E4323B92EED55575A38048D686B04F6614B7F931BF1F7D2CF35912E3472F424B11FEBA41F6D569B1A13002A33D5660844A896436AA4D8BC74B6951C75F883D747690B6AD3501B84C6C5B4E29C4153A98C0F2DF38CAFDF00E15CFE8DB0939E5611518DB4547CB2880B5F2D431526082D608384FA3BDD78B75157F25C7A2448249E635C20051C39577AE777C75E7B424CB647B76C9880E905E401DA09DE7A6A5F3E59376B24DCAC613C6EF263741FA15E83B64C78C03016FD34AB608D77100FD8733F130F63A0725B8E7CCD344F5E9A460D2F4F5BE139A6B57A3955A47726A02D6425EF8D1440709517F2DE1D8BB1D054BF69B77E44B4C4427F26EC6303F91CF197298214820264AFACBD355F08E278734BDBF1E116ADF6C1C03ADF5E73212A7073B9E14CBED3 20160314074608 2 6 100 7679 2 EC435B7E292EBAAEC94B8E8A53ED9F3FF717BB820D4893F0BBE6589BD3AF344B765A6000950C6244B2E4262E7E500BF699AF0FF49605A15EB80C61429C9FB79F658C3E0F8DB516AF9703BCB5E84ABA314292808DC70D183C513609A6D345F5D8676256E25108EE70B210C0293B5C804CF21FD843D2F5F79F91F57CF2C2EFB7052CA5F73544F0568A68FA5583CA6EDD300817AAB25E650B0AB9523C6C60156726F4B5243A8BE580308BB6297E23785893119D49B2407D4D8DACD551D08A5F9BB32BD7965313EC6C9DDCD685A62F7AFC8E71DF10F9E1FA25EB3DCD41D7DBDEFE5DB565BAE0CB62F192AA573A126FB92C9638457E73EB4C007268142D9506B17D20A4D73B51E21983D9AC86F7ABBDCE9B9D10BE307642C49382E27B45ADB32E9FF7A2203F395C71EAF7656DF83F57E527CCA37A2BE9AFBA89FB718DB95CC041BF4025FF1CB5F463C8A09FD374AF3F143EE53FF4B369117BDBE0743335B1B5650B68C5B4F64E42D4CF0B329316F4FCD5E66F4A1359F2B29684961CA04EC5AC787FD4BF990F3FBE698D69FAF946DE12A4215392928E29ACF24F940AE4046C74BC6E799EE1D85BA8264C6C7DFF62A244CA2D05C4352870E0E8EF71F884AEFA4A4CA704B6C6607D2E59D36253350AF73C1FBE9C5D61A26A9024B715B45ECF1487D23970C5E405B46029403DD95B2F5672E61863E48CBB280300B2CF87C749F0ACC52940819688C819250B71E54397C8792AAB31655BCE19FAD3A7C59BD64904CC806304AEB6DC8B534081CD2EFD2808977FAC9BAB540EC153DD98D8B33984EC40BCFBC0C5D5B95AB3E183961DB2EE8883B174A3CFEC21CBE7F200FDD2879C1BA808B65A03B02793688FBB1F753333A23A4139766DD3ECD30742E55C25474D068CAB008BA6957CB014E4D46C4BF3084C8343D61231B6B997A8BCEE761D907E4323B92EED55575A38048D686B04F6614B7F931BF1F7D2CF35912E3472F424B11FEBA41F6D569B1A13002A33D5660844A896436AA4D8BC74B6951C75F883D747690B6AD3501B84C6C5B4E29C4153A98C0F2DF38CAFDF00E15CFE8DB0939E5611518DB4547CB2880B5F2D431526082D608384FA3BDD78B75157F25C7A2448249E635C20051C39577AE777C75E7B424CB647B76C9880E905E401DA09DE7A6A5F3E59376B24DCAC613C6EF263741FA15E83B64C78C03016FD34AB608D77100FD8733F130F63A0725B8E7CCD344F5E9A460D2F4F5BE139A6B57A3955A47726A02D6425EF8D1440709517F2DE1D8BB1D054BF69B77E44B4C4427F26EC6303F91CF197298214820264AFACBD355F08E278734BDBF1E116ADF6C1C03ADF5E73212A7073B9E75C54D3 20160314135741 2 6 100 7679 2 EC435B7E292EBAAEC94B8E8A53ED9F3FF717BB820D4893F0BBE6589BD3AF344B765A6000950C6244B2E4262E7E500BF699AF0FF49605A15EB80C61429C9FB79F658C3E0F8DB516AF9703BCB5E84ABA314292808DC70D183C513609A6D345F5D8676256E25108EE70B210C0293B5C804CF21FD843D2F5F79F91F57CF2C2EFB7052CA5F73544F0568A68FA5583CA6EDD300817AAB25E650B0AB9523C6C60156726F4B5243A8BE580308BB6297E23785893119D49B2407D4D8DACD551D08A5F9BB32BD7965313EC6C9DDCD685A62F7AFC8E71DF10F9E1FA25EB3DCD41D7DBDEFE5DB565BAE0CB62F192AA573A126FB92C9638457E73EB4C007268142D9506B17D20A4D73B51E21983D9AC86F7ABBDCE9B9D10BE307642C49382E27B45ADB32E9FF7A2203F395C71EAF7656DF83F57E527CCA37A2BE9AFBA89FB718DB95CC041BF4025FF1CB5F463C8A09FD374AF3F143EE53FF4B369117BDBE0743335B1B5650B68C5B4F64E42D4CF0B329316F4FCD5E66F4A1359F2B29684961CA04EC5AC787FD4BF990F3FBE698D69FAF946DE12A4215392928E29ACF24F940AE4046C74BC6E799EE1D85BA8264C6C7DFF62A244CA2D05C4352870E0E8EF71F884AEFA4A4CA704B6C6607D2E59D36253350AF73C1FBE9C5D61A26A9024B715B45ECF1487D23970C5E405B46029403DD95B2F5672E61863E48CBB280300B2CF87C749F0ACC52940819688C819250B71E54397C8792AAB31655BCE19FAD3A7C59BD64904CC806304AEB6DC8B534081CD2EFD2808977FAC9BAB540EC153DD98D8B33984EC40BCFBC0C5D5B95AB3E183961DB2EE8883B174A3CFEC21CBE7F200FDD2879C1BA808B65A03B02793688FBB1F753333A23A4139766DD3ECD30742E55C25474D068CAB008BA6957CB014E4D46C4BF3084C8343D61231B6B997A8BCEE761D907E4323B92EED55575A38048D686B04F6614B7F931BF1F7D2CF35912E3472F424B11FEBA41F6D569B1A13002A33D5660844A896436AA4D8BC74B6951C75F883D747690B6AD3501B84C6C5B4E29C4153A98C0F2DF38CAFDF00E15CFE8DB0939E5611518DB4547CB2880B5F2D431526082D608384FA3BDD78B75157F25C7A2448249E635C20051C39577AE777C75E7B424CB647B76C9880E905E401DA09DE7A6A5F3E59376B24DCAC613C6EF263741FA15E83B64C78C03016FD34AB608D77100FD8733F130F63A0725B8E7CCD344F5E9A460D2F4F5BE139A6B57A3955A47726A02D6425EF8D1440709517F2DE1D8BB1D054BF69B77E44B4C4427F26EC6303F91CF197298214820264AFACBD355F08E278734BDBF1E116ADF6C1C03ADF5E73212A7073B9EC7E3DAB 20160314140815 2 6 100 7679 5 EC435B7E292EBAAEC94B8E8A53ED9F3FF717BB820D4893F0BBE6589BD3AF344B765A6000950C6244B2E4262E7E500BF699AF0FF49605A15EB80C61429C9FB79F658C3E0F8DB516AF9703BCB5E84ABA314292808DC70D183C513609A6D345F5D8676256E25108EE70B210C0293B5C804CF21FD843D2F5F79F91F57CF2C2EFB7052CA5F73544F0568A68FA5583CA6EDD300817AAB25E650B0AB9523C6C60156726F4B5243A8BE580308BB6297E23785893119D49B2407D4D8DACD551D08A5F9BB32BD7965313EC6C9DDCD685A62F7AFC8E71DF10F9E1FA25EB3DCD41D7DBDEFE5DB565BAE0CB62F192AA573A126FB92C9638457E73EB4C007268142D9506B17D20A4D73B51E21983D9AC86F7ABBDCE9B9D10BE307642C49382E27B45ADB32E9FF7A2203F395C71EAF7656DF83F57E527CCA37A2BE9AFBA89FB718DB95CC041BF4025FF1CB5F463C8A09FD374AF3F143EE53FF4B369117BDBE0743335B1B5650B68C5B4F64E42D4CF0B329316F4FCD5E66F4A1359F2B29684961CA04EC5AC787FD4BF990F3FBE698D69FAF946DE12A4215392928E29ACF24F940AE4046C74BC6E799EE1D85BA8264C6C7DFF62A244CA2D05C4352870E0E8EF71F884AEFA4A4CA704B6C6607D2E59D36253350AF73C1FBE9C5D61A26A9024B715B45ECF1487D23970C5E405B46029403DD95B2F5672E61863E48CBB280300B2CF87C749F0ACC52940819688C819250B71E54397C8792AAB31655BCE19FAD3A7C59BD64904CC806304AEB6DC8B534081CD2EFD2808977FAC9BAB540EC153DD98D8B33984EC40BCFBC0C5D5B95AB3E183961DB2EE8883B174A3CFEC21CBE7F200FDD2879C1BA808B65A03B02793688FBB1F753333A23A4139766DD3ECD30742E55C25474D068CAB008BA6957CB014E4D46C4BF3084C8343D61231B6B997A8BCEE761D907E4323B92EED55575A38048D686B04F6614B7F931BF1F7D2CF35912E3472F424B11FEBA41F6D569B1A13002A33D5660844A896436AA4D8BC74B6951C75F883D747690B6AD3501B84C6C5B4E29C4153A98C0F2DF38CAFDF00E15CFE8DB0939E5611518DB4547CB2880B5F2D431526082D608384FA3BDD78B75157F25C7A2448249E635C20051C39577AE777C75E7B424CB647B76C9880E905E401DA09DE7A6A5F3E59376B24DCAC613C6EF263741FA15E83B64C78C03016FD34AB608D77100FD8733F130F63A0725B8E7CCD344F5E9A460D2F4F5BE139A6B57A3955A47726A02D6425EF8D1440709517F2DE1D8BB1D054BF69B77E44B4C4427F26EC6303F91CF197298214820264AFACBD355F08E278734BDBF1E116ADF6C1C03ADF5E73212A7073B9EC9AC0E7 20160314202745 2 6 100 7679 2 EC435B7E292EBAAEC94B8E8A53ED9F3FF717BB820D4893F0BBE6589BD3AF344B765A6000950C6244B2E4262E7E500BF699AF0FF49605A15EB80C61429C9FB79F658C3E0F8DB516AF9703BCB5E84ABA314292808DC70D183C513609A6D345F5D8676256E25108EE70B210C0293B5C804CF21FD843D2F5F79F91F57CF2C2EFB7052CA5F73544F0568A68FA5583CA6EDD300817AAB25E650B0AB9523C6C60156726F4B5243A8BE580308BB6297E23785893119D49B2407D4D8DACD551D08A5F9BB32BD7965313EC6C9DDCD685A62F7AFC8E71DF10F9E1FA25EB3DCD41D7DBDEFE5DB565BAE0CB62F192AA573A126FB92C9638457E73EB4C007268142D9506B17D20A4D73B51E21983D9AC86F7ABBDCE9B9D10BE307642C49382E27B45ADB32E9FF7A2203F395C71EAF7656DF83F57E527CCA37A2BE9AFBA89FB718DB95CC041BF4025FF1CB5F463C8A09FD374AF3F143EE53FF4B369117BDBE0743335B1B5650B68C5B4F64E42D4CF0B329316F4FCD5E66F4A1359F2B29684961CA04EC5AC787FD4BF990F3FBE698D69FAF946DE12A4215392928E29ACF24F940AE4046C74BC6E799EE1D85BA8264C6C7DFF62A244CA2D05C4352870E0E8EF71F884AEFA4A4CA704B6C6607D2E59D36253350AF73C1FBE9C5D61A26A9024B715B45ECF1487D23970C5E405B46029403DD95B2F5672E61863E48CBB280300B2CF87C749F0ACC52940819688C819250B71E54397C8792AAB31655BCE19FAD3A7C59BD64904CC806304AEB6DC8B534081CD2EFD2808977FAC9BAB540EC153DD98D8B33984EC40BCFBC0C5D5B95AB3E183961DB2EE8883B174A3CFEC21CBE7F200FDD2879C1BA808B65A03B02793688FBB1F753333A23A4139766DD3ECD30742E55C25474D068CAB008BA6957CB014E4D46C4BF3084C8343D61231B6B997A8BCEE761D907E4323B92EED55575A38048D686B04F6614B7F931BF1F7D2CF35912E3472F424B11FEBA41F6D569B1A13002A33D5660844A896436AA4D8BC74B6951C75F883D747690B6AD3501B84C6C5B4E29C4153A98C0F2DF38CAFDF00E15CFE8DB0939E5611518DB4547CB2880B5F2D431526082D608384FA3BDD78B75157F25C7A2448249E635C20051C39577AE777C75E7B424CB647B76C9880E905E401DA09DE7A6A5F3E59376B24DCAC613C6EF263741FA15E83B64C78C03016FD34AB608D77100FD8733F130F63A0725B8E7CCD344F5E9A460D2F4F5BE139A6B57A3955A47726A02D6425EF8D1440709517F2DE1D8BB1D054BF69B77E44B4C4427F26EC6303F91CF197298214820264AFACBD355F08E278734BDBF1E116ADF6C1C03ADF5E73212A7073B9F1BD98C3 20160314223316 2 6 100 7679 2 EC435B7E292EBAAEC94B8E8A53ED9F3FF717BB820D4893F0BBE6589BD3AF344B765A6000950C6244B2E4262E7E500BF699AF0FF49605A15EB80C61429C9FB79F658C3E0F8DB516AF9703BCB5E84ABA314292808DC70D183C513609A6D345F5D8676256E25108EE70B210C0293B5C804CF21FD843D2F5F79F91F57CF2C2EFB7052CA5F73544F0568A68FA5583CA6EDD300817AAB25E650B0AB9523C6C60156726F4B5243A8BE580308BB6297E23785893119D49B2407D4D8DACD551D08A5F9BB32BD7965313EC6C9DDCD685A62F7AFC8E71DF10F9E1FA25EB3DCD41D7DBDEFE5DB565BAE0CB62F192AA573A126FB92C9638457E73EB4C007268142D9506B17D20A4D73B51E21983D9AC86F7ABBDCE9B9D10BE307642C49382E27B45ADB32E9FF7A2203F395C71EAF7656DF83F57E527CCA37A2BE9AFBA89FB718DB95CC041BF4025FF1CB5F463C8A09FD374AF3F143EE53FF4B369117BDBE0743335B1B5650B68C5B4F64E42D4CF0B329316F4FCD5E66F4A1359F2B29684961CA04EC5AC787FD4BF990F3FBE698D69FAF946DE12A4215392928E29ACF24F940AE4046C74BC6E799EE1D85BA8264C6C7DFF62A244CA2D05C4352870E0E8EF71F884AEFA4A4CA704B6C6607D2E59D36253350AF73C1FBE9C5D61A26A9024B715B45ECF1487D23970C5E405B46029403DD95B2F5672E61863E48CBB280300B2CF87C749F0ACC52940819688C819250B71E54397C8792AAB31655BCE19FAD3A7C59BD64904CC806304AEB6DC8B534081CD2EFD2808977FAC9BAB540EC153DD98D8B33984EC40BCFBC0C5D5B95AB3E183961DB2EE8883B174A3CFEC21CBE7F200FDD2879C1BA808B65A03B02793688FBB1F753333A23A4139766DD3ECD30742E55C25474D068CAB008BA6957CB014E4D46C4BF3084C8343D61231B6B997A8BCEE761D907E4323B92EED55575A38048D686B04F6614B7F931BF1F7D2CF35912E3472F424B11FEBA41F6D569B1A13002A33D5660844A896436AA4D8BC74B6951C75F883D747690B6AD3501B84C6C5B4E29C4153A98C0F2DF38CAFDF00E15CFE8DB0939E5611518DB4547CB2880B5F2D431526082D608384FA3BDD78B75157F25C7A2448249E635C20051C39577AE777C75E7B424CB647B76C9880E905E401DA09DE7A6A5F3E59376B24DCAC613C6EF263741FA15E83B64C78C03016FD34AB608D77100FD8733F130F63A0725B8E7CCD344F5E9A460D2F4F5BE139A6B57A3955A47726A02D6425EF8D1440709517F2DE1D8BB1D054BF69B77E44B4C4427F26EC6303F91CF197298214820264AFACBD355F08E278734BDBF1E116ADF6C1C03ADF5E73212A7073B9F36F08D3 20160315005016 2 6 100 7679 5 EC435B7E292EBAAEC94B8E8A53ED9F3FF717BB820D4893F0BBE6589BD3AF344B765A6000950C6244B2E4262E7E500BF699AF0FF49605A15EB80C61429C9FB79F658C3E0F8DB516AF9703BCB5E84ABA314292808DC70D183C513609A6D345F5D8676256E25108EE70B210C0293B5C804CF21FD843D2F5F79F91F57CF2C2EFB7052CA5F73544F0568A68FA5583CA6EDD300817AAB25E650B0AB9523C6C60156726F4B5243A8BE580308BB6297E23785893119D49B2407D4D8DACD551D08A5F9BB32BD7965313EC6C9DDCD685A62F7AFC8E71DF10F9E1FA25EB3DCD41D7DBDEFE5DB565BAE0CB62F192AA573A126FB92C9638457E73EB4C007268142D9506B17D20A4D73B51E21983D9AC86F7ABBDCE9B9D10BE307642C49382E27B45ADB32E9FF7A2203F395C71EAF7656DF83F57E527CCA37A2BE9AFBA89FB718DB95CC041BF4025FF1CB5F463C8A09FD374AF3F143EE53FF4B369117BDBE0743335B1B5650B68C5B4F64E42D4CF0B329316F4FCD5E66F4A1359F2B29684961CA04EC5AC787FD4BF990F3FBE698D69FAF946DE12A4215392928E29ACF24F940AE4046C74BC6E799EE1D85BA8264C6C7DFF62A244CA2D05C4352870E0E8EF71F884AEFA4A4CA704B6C6607D2E59D36253350AF73C1FBE9C5D61A26A9024B715B45ECF1487D23970C5E405B46029403DD95B2F5672E61863E48CBB280300B2CF87C749F0ACC52940819688C819250B71E54397C8792AAB31655BCE19FAD3A7C59BD64904CC806304AEB6DC8B534081CD2EFD2808977FAC9BAB540EC153DD98D8B33984EC40BCFBC0C5D5B95AB3E183961DB2EE8883B174A3CFEC21CBE7F200FDD2879C1BA808B65A03B02793688FBB1F753333A23A4139766DD3ECD30742E55C25474D068CAB008BA6957CB014E4D46C4BF3084C8343D61231B6B997A8BCEE761D907E4323B92EED55575A38048D686B04F6614B7F931BF1F7D2CF35912E3472F424B11FEBA41F6D569B1A13002A33D5660844A896436AA4D8BC74B6951C75F883D747690B6AD3501B84C6C5B4E29C4153A98C0F2DF38CAFDF00E15CFE8DB0939E5611518DB4547CB2880B5F2D431526082D608384FA3BDD78B75157F25C7A2448249E635C20051C39577AE777C75E7B424CB647B76C9880E905E401DA09DE7A6A5F3E59376B24DCAC613C6EF263741FA15E83B64C78C03016FD34AB608D77100FD8733F130F63A0725B8E7CCD344F5E9A460D2F4F5BE139A6B57A3955A47726A02D6425EF8D1440709517F2DE1D8BB1D054BF69B77E44B4C4427F26EC6303F91CF197298214820264AFACBD355F08E278734BDBF1E116ADF6C1C03ADF5E73212A7073B9F54715BF 20160315013952 2 6 100 7679 2 EC435B7E292EBAAEC94B8E8A53ED9F3FF717BB820D4893F0BBE6589BD3AF344B765A6000950C6244B2E4262E7E500BF699AF0FF49605A15EB80C61429C9FB79F658C3E0F8DB516AF9703BCB5E84ABA314292808DC70D183C513609A6D345F5D8676256E25108EE70B210C0293B5C804CF21FD843D2F5F79F91F57CF2C2EFB7052CA5F73544F0568A68FA5583CA6EDD300817AAB25E650B0AB9523C6C60156726F4B5243A8BE580308BB6297E23785893119D49B2407D4D8DACD551D08A5F9BB32BD7965313EC6C9DDCD685A62F7AFC8E71DF10F9E1FA25EB3DCD41D7DBDEFE5DB565BAE0CB62F192AA573A126FB92C9638457E73EB4C007268142D9506B17D20A4D73B51E21983D9AC86F7ABBDCE9B9D10BE307642C49382E27B45ADB32E9FF7A2203F395C71EAF7656DF83F57E527CCA37A2BE9AFBA89FB718DB95CC041BF4025FF1CB5F463C8A09FD374AF3F143EE53FF4B369117BDBE0743335B1B5650B68C5B4F64E42D4CF0B329316F4FCD5E66F4A1359F2B29684961CA04EC5AC787FD4BF990F3FBE698D69FAF946DE12A4215392928E29ACF24F940AE4046C74BC6E799EE1D85BA8264C6C7DFF62A244CA2D05C4352870E0E8EF71F884AEFA4A4CA704B6C6607D2E59D36253350AF73C1FBE9C5D61A26A9024B715B45ECF1487D23970C5E405B46029403DD95B2F5672E61863E48CBB280300B2CF87C749F0ACC52940819688C819250B71E54397C8792AAB31655BCE19FAD3A7C59BD64904CC806304AEB6DC8B534081CD2EFD2808977FAC9BAB540EC153DD98D8B33984EC40BCFBC0C5D5B95AB3E183961DB2EE8883B174A3CFEC21CBE7F200FDD2879C1BA808B65A03B02793688FBB1F753333A23A4139766DD3ECD30742E55C25474D068CAB008BA6957CB014E4D46C4BF3084C8343D61231B6B997A8BCEE761D907E4323B92EED55575A38048D686B04F6614B7F931BF1F7D2CF35912E3472F424B11FEBA41F6D569B1A13002A33D5660844A896436AA4D8BC74B6951C75F883D747690B6AD3501B84C6C5B4E29C4153A98C0F2DF38CAFDF00E15CFE8DB0939E5611518DB4547CB2880B5F2D431526082D608384FA3BDD78B75157F25C7A2448249E635C20051C39577AE777C75E7B424CB647B76C9880E905E401DA09DE7A6A5F3E59376B24DCAC613C6EF263741FA15E83B64C78C03016FD34AB608D77100FD8733F130F63A0725B8E7CCD344F5E9A460D2F4F5BE139A6B57A3955A47726A02D6425EF8D1440709517F2DE1D8BB1D054BF69B77E44B4C4427F26EC6303F91CF197298214820264AFACBD355F08E278734BDBF1E116ADF6C1C03ADF5E73212A7073B9F5E3A7F3 20160315060542 2 6 100 7679 2 EC435B7E292EBAAEC94B8E8A53ED9F3FF717BB820D4893F0BBE6589BD3AF344B765A6000950C6244B2E4262E7E500BF699AF0FF49605A15EB80C61429C9FB79F658C3E0F8DB516AF9703BCB5E84ABA314292808DC70D183C513609A6D345F5D8676256E25108EE70B210C0293B5C804CF21FD843D2F5F79F91F57CF2C2EFB7052CA5F73544F0568A68FA5583CA6EDD300817AAB25E650B0AB9523C6C60156726F4B5243A8BE580308BB6297E23785893119D49B2407D4D8DACD551D08A5F9BB32BD7965313EC6C9DDCD685A62F7AFC8E71DF10F9E1FA25EB3DCD41D7DBDEFE5DB565BAE0CB62F192AA573A126FB92C9638457E73EB4C007268142D9506B17D20A4D73B51E21983D9AC86F7ABBDCE9B9D10BE307642C49382E27B45ADB32E9FF7A2203F395C71EAF7656DF83F57E527CCA37A2BE9AFBA89FB718DB95CC041BF4025FF1CB5F463C8A09FD374AF3F143EE53FF4B369117BDBE0743335B1B5650B68C5B4F64E42D4CF0B329316F4FCD5E66F4A1359F2B29684961CA04EC5AC787FD4BF990F3FBE698D69FAF946DE12A4215392928E29ACF24F940AE4046C74BC6E799EE1D85BA8264C6C7DFF62A244CA2D05C4352870E0E8EF71F884AEFA4A4CA704B6C6607D2E59D36253350AF73C1FBE9C5D61A26A9024B715B45ECF1487D23970C5E405B46029403DD95B2F5672E61863E48CBB280300B2CF87C749F0ACC52940819688C819250B71E54397C8792AAB31655BCE19FAD3A7C59BD64904CC806304AEB6DC8B534081CD2EFD2808977FAC9BAB540EC153DD98D8B33984EC40BCFBC0C5D5B95AB3E183961DB2EE8883B174A3CFEC21CBE7F200FDD2879C1BA808B65A03B02793688FBB1F753333A23A4139766DD3ECD30742E55C25474D068CAB008BA6957CB014E4D46C4BF3084C8343D61231B6B997A8BCEE761D907E4323B92EED55575A38048D686B04F6614B7F931BF1F7D2CF35912E3472F424B11FEBA41F6D569B1A13002A33D5660844A896436AA4D8BC74B6951C75F883D747690B6AD3501B84C6C5B4E29C4153A98C0F2DF38CAFDF00E15CFE8DB0939E5611518DB4547CB2880B5F2D431526082D608384FA3BDD78B75157F25C7A2448249E635C20051C39577AE777C75E7B424CB647B76C9880E905E401DA09DE7A6A5F3E59376B24DCAC613C6EF263741FA15E83B64C78C03016FD34AB608D77100FD8733F130F63A0725B8E7CCD344F5E9A460D2F4F5BE139A6B57A3955A47726A02D6425EF8D1440709517F2DE1D8BB1D054BF69B77E44B4C4427F26EC6303F91CF197298214820264AFACBD355F08E278734BDBF1E116ADF6C1C03ADF5E73212A7073B9F968A573 20160315072619 2 6 100 7679 2 EC435B7E292EBAAEC94B8E8A53ED9F3FF717BB820D4893F0BBE6589BD3AF344B765A6000950C6244B2E4262E7E500BF699AF0FF49605A15EB80C61429C9FB79F658C3E0F8DB516AF9703BCB5E84ABA314292808DC70D183C513609A6D345F5D8676256E25108EE70B210C0293B5C804CF21FD843D2F5F79F91F57CF2C2EFB7052CA5F73544F0568A68FA5583CA6EDD300817AAB25E650B0AB9523C6C60156726F4B5243A8BE580308BB6297E23785893119D49B2407D4D8DACD551D08A5F9BB32BD7965313EC6C9DDCD685A62F7AFC8E71DF10F9E1FA25EB3DCD41D7DBDEFE5DB565BAE0CB62F192AA573A126FB92C9638457E73EB4C007268142D9506B17D20A4D73B51E21983D9AC86F7ABBDCE9B9D10BE307642C49382E27B45ADB32E9FF7A2203F395C71EAF7656DF83F57E527CCA37A2BE9AFBA89FB718DB95CC041BF4025FF1CB5F463C8A09FD374AF3F143EE53FF4B369117BDBE0743335B1B5650B68C5B4F64E42D4CF0B329316F4FCD5E66F4A1359F2B29684961CA04EC5AC787FD4BF990F3FBE698D69FAF946DE12A4215392928E29ACF24F940AE4046C74BC6E799EE1D85BA8264C6C7DFF62A244CA2D05C4352870E0E8EF71F884AEFA4A4CA704B6C6607D2E59D36253350AF73C1FBE9C5D61A26A9024B715B45ECF1487D23970C5E405B46029403DD95B2F5672E61863E48CBB280300B2CF87C749F0ACC52940819688C819250B71E54397C8792AAB31655BCE19FAD3A7C59BD64904CC806304AEB6DC8B534081CD2EFD2808977FAC9BAB540EC153DD98D8B33984EC40BCFBC0C5D5B95AB3E183961DB2EE8883B174A3CFEC21CBE7F200FDD2879C1BA808B65A03B02793688FBB1F753333A23A4139766DD3ECD30742E55C25474D068CAB008BA6957CB014E4D46C4BF3084C8343D61231B6B997A8BCEE761D907E4323B92EED55575A38048D686B04F6614B7F931BF1F7D2CF35912E3472F424B11FEBA41F6D569B1A13002A33D5660844A896436AA4D8BC74B6951C75F883D747690B6AD3501B84C6C5B4E29C4153A98C0F2DF38CAFDF00E15CFE8DB0939E5611518DB4547CB2880B5F2D431526082D608384FA3BDD78B75157F25C7A2448249E635C20051C39577AE777C75E7B424CB647B76C9880E905E401DA09DE7A6A5F3E59376B24DCAC613C6EF263741FA15E83B64C78C03016FD34AB608D77100FD8733F130F63A0725B8E7CCD344F5E9A460D2F4F5BE139A6B57A3955A47726A02D6425EF8D1440709517F2DE1D8BB1D054BF69B77E44B4C4427F26EC6303F91CF197298214820264AFACBD355F08E278734BDBF1E116ADF6C1C03ADF5E73212A7073B9FA7969D3 20160315105849 2 6 100 7679 2 EC435B7E292EBAAEC94B8E8A53ED9F3FF717BB820D4893F0BBE6589BD3AF344B765A6000950C6244B2E4262E7E500BF699AF0FF49605A15EB80C61429C9FB79F658C3E0F8DB516AF9703BCB5E84ABA314292808DC70D183C513609A6D345F5D8676256E25108EE70B210C0293B5C804CF21FD843D2F5F79F91F57CF2C2EFB7052CA5F73544F0568A68FA5583CA6EDD300817AAB25E650B0AB9523C6C60156726F4B5243A8BE580308BB6297E23785893119D49B2407D4D8DACD551D08A5F9BB32BD7965313EC6C9DDCD685A62F7AFC8E71DF10F9E1FA25EB3DCD41D7DBDEFE5DB565BAE0CB62F192AA573A126FB92C9638457E73EB4C007268142D9506B17D20A4D73B51E21983D9AC86F7ABBDCE9B9D10BE307642C49382E27B45ADB32E9FF7A2203F395C71EAF7656DF83F57E527CCA37A2BE9AFBA89FB718DB95CC041BF4025FF1CB5F463C8A09FD374AF3F143EE53FF4B369117BDBE0743335B1B5650B68C5B4F64E42D4CF0B329316F4FCD5E66F4A1359F2B29684961CA04EC5AC787FD4BF990F3FBE698D69FAF946DE12A4215392928E29ACF24F940AE4046C74BC6E799EE1D85BA8264C6C7DFF62A244CA2D05C4352870E0E8EF71F884AEFA4A4CA704B6C6607D2E59D36253350AF73C1FBE9C5D61A26A9024B715B45ECF1487D23970C5E405B46029403DD95B2F5672E61863E48CBB280300B2CF87C749F0ACC52940819688C819250B71E54397C8792AAB31655BCE19FAD3A7C59BD64904CC806304AEB6DC8B534081CD2EFD2808977FAC9BAB540EC153DD98D8B33984EC40BCFBC0C5D5B95AB3E183961DB2EE8883B174A3CFEC21CBE7F200FDD2879C1BA808B65A03B02793688FBB1F753333A23A4139766DD3ECD30742E55C25474D068CAB008BA6957CB014E4D46C4BF3084C8343D61231B6B997A8BCEE761D907E4323B92EED55575A38048D686B04F6614B7F931BF1F7D2CF35912E3472F424B11FEBA41F6D569B1A13002A33D5660844A896436AA4D8BC74B6951C75F883D747690B6AD3501B84C6C5B4E29C4153A98C0F2DF38CAFDF00E15CFE8DB0939E5611518DB4547CB2880B5F2D431526082D608384FA3BDD78B75157F25C7A2448249E635C20051C39577AE777C75E7B424CB647B76C9880E905E401DA09DE7A6A5F3E59376B24DCAC613C6EF263741FA15E83B64C78C03016FD34AB608D77100FD8733F130F63A0725B8E7CCD344F5E9A460D2F4F5BE139A6B57A3955A47726A02D6425EF8D1440709517F2DE1D8BB1D054BF69B77E44B4C4427F26EC6303F91CF197298214820264AFACBD355F08E278734BDBF1E116ADF6C1C03ADF5E73212A7073B9FD4C31DB 20160315120521 2 6 100 7679 5 EC435B7E292EBAAEC94B8E8A53ED9F3FF717BB820D4893F0BBE6589BD3AF344B765A6000950C6244B2E4262E7E500BF699AF0FF49605A15EB80C61429C9FB79F658C3E0F8DB516AF9703BCB5E84ABA314292808DC70D183C513609A6D345F5D8676256E25108EE70B210C0293B5C804CF21FD843D2F5F79F91F57CF2C2EFB7052CA5F73544F0568A68FA5583CA6EDD300817AAB25E650B0AB9523C6C60156726F4B5243A8BE580308BB6297E23785893119D49B2407D4D8DACD551D08A5F9BB32BD7965313EC6C9DDCD685A62F7AFC8E71DF10F9E1FA25EB3DCD41D7DBDEFE5DB565BAE0CB62F192AA573A126FB92C9638457E73EB4C007268142D9506B17D20A4D73B51E21983D9AC86F7ABBDCE9B9D10BE307642C49382E27B45ADB32E9FF7A2203F395C71EAF7656DF83F57E527CCA37A2BE9AFBA89FB718DB95CC041BF4025FF1CB5F463C8A09FD374AF3F143EE53FF4B369117BDBE0743335B1B5650B68C5B4F64E42D4CF0B329316F4FCD5E66F4A1359F2B29684961CA04EC5AC787FD4BF990F3FBE698D69FAF946DE12A4215392928E29ACF24F940AE4046C74BC6E799EE1D85BA8264C6C7DFF62A244CA2D05C4352870E0E8EF71F884AEFA4A4CA704B6C6607D2E59D36253350AF73C1FBE9C5D61A26A9024B715B45ECF1487D23970C5E405B46029403DD95B2F5672E61863E48CBB280300B2CF87C749F0ACC52940819688C819250B71E54397C8792AAB31655BCE19FAD3A7C59BD64904CC806304AEB6DC8B534081CD2EFD2808977FAC9BAB540EC153DD98D8B33984EC40BCFBC0C5D5B95AB3E183961DB2EE8883B174A3CFEC21CBE7F200FDD2879C1BA808B65A03B02793688FBB1F753333A23A4139766DD3ECD30742E55C25474D068CAB008BA6957CB014E4D46C4BF3084C8343D61231B6B997A8BCEE761D907E4323B92EED55575A38048D686B04F6614B7F931BF1F7D2CF35912E3472F424B11FEBA41F6D569B1A13002A33D5660844A896436AA4D8BC74B6951C75F883D747690B6AD3501B84C6C5B4E29C4153A98C0F2DF38CAFDF00E15CFE8DB0939E5611518DB4547CB2880B5F2D431526082D608384FA3BDD78B75157F25C7A2448249E635C20051C39577AE777C75E7B424CB647B76C9880E905E401DA09DE7A6A5F3E59376B24DCAC613C6EF263741FA15E83B64C78C03016FD34AB608D77100FD8733F130F63A0725B8E7CCD344F5E9A460D2F4F5BE139A6B57A3955A47726A02D6425EF8D1440709517F2DE1D8BB1D054BF69B77E44B4C4427F26EC6303F91CF197298214820264AFACBD355F08E278734BDBF1E116ADF6C1C03ADF5E73212A7073B9FE292087 20160315121136 2 6 100 7679 2 EC435B7E292EBAAEC94B8E8A53ED9F3FF717BB820D4893F0BBE6589BD3AF344B765A6000950C6244B2E4262E7E500BF699AF0FF49605A15EB80C61429C9FB79F658C3E0F8DB516AF9703BCB5E84ABA314292808DC70D183C513609A6D345F5D8676256E25108EE70B210C0293B5C804CF21FD843D2F5F79F91F57CF2C2EFB7052CA5F73544F0568A68FA5583CA6EDD300817AAB25E650B0AB9523C6C60156726F4B5243A8BE580308BB6297E23785893119D49B2407D4D8DACD551D08A5F9BB32BD7965313EC6C9DDCD685A62F7AFC8E71DF10F9E1FA25EB3DCD41D7DBDEFE5DB565BAE0CB62F192AA573A126FB92C9638457E73EB4C007268142D9506B17D20A4D73B51E21983D9AC86F7ABBDCE9B9D10BE307642C49382E27B45ADB32E9FF7A2203F395C71EAF7656DF83F57E527CCA37A2BE9AFBA89FB718DB95CC041BF4025FF1CB5F463C8A09FD374AF3F143EE53FF4B369117BDBE0743335B1B5650B68C5B4F64E42D4CF0B329316F4FCD5E66F4A1359F2B29684961CA04EC5AC787FD4BF990F3FBE698D69FAF946DE12A4215392928E29ACF24F940AE4046C74BC6E799EE1D85BA8264C6C7DFF62A244CA2D05C4352870E0E8EF71F884AEFA4A4CA704B6C6607D2E59D36253350AF73C1FBE9C5D61A26A9024B715B45ECF1487D23970C5E405B46029403DD95B2F5672E61863E48CBB280300B2CF87C749F0ACC52940819688C819250B71E54397C8792AAB31655BCE19FAD3A7C59BD64904CC806304AEB6DC8B534081CD2EFD2808977FAC9BAB540EC153DD98D8B33984EC40BCFBC0C5D5B95AB3E183961DB2EE8883B174A3CFEC21CBE7F200FDD2879C1BA808B65A03B02793688FBB1F753333A23A4139766DD3ECD30742E55C25474D068CAB008BA6957CB014E4D46C4BF3084C8343D61231B6B997A8BCEE761D907E4323B92EED55575A38048D686B04F6614B7F931BF1F7D2CF35912E3472F424B11FEBA41F6D569B1A13002A33D5660844A896436AA4D8BC74B6951C75F883D747690B6AD3501B84C6C5B4E29C4153A98C0F2DF38CAFDF00E15CFE8DB0939E5611518DB4547CB2880B5F2D431526082D608384FA3BDD78B75157F25C7A2448249E635C20051C39577AE777C75E7B424CB647B76C9880E905E401DA09DE7A6A5F3E59376B24DCAC613C6EF263741FA15E83B64C78C03016FD34AB608D77100FD8733F130F63A0725B8E7CCD344F5E9A460D2F4F5BE139A6B57A3955A47726A02D6425EF8D1440709517F2DE1D8BB1D054BF69B77E44B4C4427F26EC6303F91CF197298214820264AFACBD355F08E278734BDBF1E116ADF6C1C03ADF5E73212A7073B9FE352FC3 20160315152946 2 6 100 7679 2 EC435B7E292EBAAEC94B8E8A53ED9F3FF717BB820D4893F0BBE6589BD3AF344B765A6000950C6244B2E4262E7E500BF699AF0FF49605A15EB80C61429C9FB79F658C3E0F8DB516AF9703BCB5E84ABA314292808DC70D183C513609A6D345F5D8676256E25108EE70B210C0293B5C804CF21FD843D2F5F79F91F57CF2C2EFB7052CA5F73544F0568A68FA5583CA6EDD300817AAB25E650B0AB9523C6C60156726F4B5243A8BE580308BB6297E23785893119D49B2407D4D8DACD551D08A5F9BB32BD7965313EC6C9DDCD685A62F7AFC8E71DF10F9E1FA25EB3DCD41D7DBDEFE5DB565BAE0CB62F192AA573A126FB92C9638457E73EB4C007268142D9506B17D20A4D73B51E21983D9AC86F7ABBDCE9B9D10BE307642C49382E27B45ADB32E9FF7A2203F395C71EAF7656DF83F57E527CCA37A2BE9AFBA89FB718DB95CC041BF4025FF1CB5F463C8A09FD374AF3F143EE53FF4B369117BDBE0743335B1B5650B68C5B4F64E42D4CF0B329316F4FCD5E66F4A1359F2B29684961CA04EC5AC787FD4BF990F3FBE698D69FAF946DE12A4215392928E29ACF24F940AE4046C74BC6E799EE1D85BA8264C6C7DFF62A244CA2D05C4352870E0E8EF71F884AEFA4A4CA704B6C6607D2E59D36253350AF73C1FBE9C5D61A26A9024B715B45ECF1487D23970C5E405B46029403DD95B2F5672E61863E48CBB280300B2CF87C749F0ACC52940819688C819250B71E54397C8792AAB31655BCE19FAD3A7C59BD64904CC806304AEB6DC8B534081CD2EFD2808977FAC9BAB540EC153DD98D8B33984EC40BCFBC0C5D5B95AB3E183961DB2EE8883B174A3CFEC21CBE7F200FDD2879C1BA808B65A03B02793688FBB1F753333A23A4139766DD3ECD30742E55C25474D068CAB008BA6957CB014E4D46C4BF3084C8343D61231B6B997A8BCEE761D907E4323B92EED55575A38048D686B04F6614B7F931BF1F7D2CF35912E3472F424B11FEBA41F6D569B1A13002A33D5660844A896436AA4D8BC74B6951C75F883D747690B6AD3501B84C6C5B4E29C4153A98C0F2DF38CAFDF00E15CFE8DB0939E5611518DB4547CB2880B5F2D431526082D608384FA3BDD78B75157F25C7A2448249E635C20051C39577AE777C75E7B424CB647B76C9880E905E401DA09DE7A6A5F3E59376B24DCAC613C6EF263741FA15E83B64C78C03016FD34AB608D77100FD8733F130F63A0725B8E7CCD344F5E9A460D2F4F5BE139A6B57A3955A47726A02D6425EF8D1440709517F2DE1D8BB1D054BF69B77E44B4C4427F26EC6303F91CF197298214820264AFACBD355F08E278734BDBF1E116ADF6C1C03ADF5E73212A7073BA00CB151B 20160315165331 2 6 100 7679 5 EC435B7E292EBAAEC94B8E8A53ED9F3FF717BB820D4893F0BBE6589BD3AF344B765A6000950C6244B2E4262E7E500BF699AF0FF49605A15EB80C61429C9FB79F658C3E0F8DB516AF9703BCB5E84ABA314292808DC70D183C513609A6D345F5D8676256E25108EE70B210C0293B5C804CF21FD843D2F5F79F91F57CF2C2EFB7052CA5F73544F0568A68FA5583CA6EDD300817AAB25E650B0AB9523C6C60156726F4B5243A8BE580308BB6297E23785893119D49B2407D4D8DACD551D08A5F9BB32BD7965313EC6C9DDCD685A62F7AFC8E71DF10F9E1FA25EB3DCD41D7DBDEFE5DB565BAE0CB62F192AA573A126FB92C9638457E73EB4C007268142D9506B17D20A4D73B51E21983D9AC86F7ABBDCE9B9D10BE307642C49382E27B45ADB32E9FF7A2203F395C71EAF7656DF83F57E527CCA37A2BE9AFBA89FB718DB95CC041BF4025FF1CB5F463C8A09FD374AF3F143EE53FF4B369117BDBE0743335B1B5650B68C5B4F64E42D4CF0B329316F4FCD5E66F4A1359F2B29684961CA04EC5AC787FD4BF990F3FBE698D69FAF946DE12A4215392928E29ACF24F940AE4046C74BC6E799EE1D85BA8264C6C7DFF62A244CA2D05C4352870E0E8EF71F884AEFA4A4CA704B6C6607D2E59D36253350AF73C1FBE9C5D61A26A9024B715B45ECF1487D23970C5E405B46029403DD95B2F5672E61863E48CBB280300B2CF87C749F0ACC52940819688C819250B71E54397C8792AAB31655BCE19FAD3A7C59BD64904CC806304AEB6DC8B534081CD2EFD2808977FAC9BAB540EC153DD98D8B33984EC40BCFBC0C5D5B95AB3E183961DB2EE8883B174A3CFEC21CBE7F200FDD2879C1BA808B65A03B02793688FBB1F753333A23A4139766DD3ECD30742E55C25474D068CAB008BA6957CB014E4D46C4BF3084C8343D61231B6B997A8BCEE761D907E4323B92EED55575A38048D686B04F6614B7F931BF1F7D2CF35912E3472F424B11FEBA41F6D569B1A13002A33D5660844A896436AA4D8BC74B6951C75F883D747690B6AD3501B84C6C5B4E29C4153A98C0F2DF38CAFDF00E15CFE8DB0939E5611518DB4547CB2880B5F2D431526082D608384FA3BDD78B75157F25C7A2448249E635C20051C39577AE777C75E7B424CB647B76C9880E905E401DA09DE7A6A5F3E59376B24DCAC613C6EF263741FA15E83B64C78C03016FD34AB608D77100FD8733F130F63A0725B8E7CCD344F5E9A460D2F4F5BE139A6B57A3955A47726A02D6425EF8D1440709517F2DE1D8BB1D054BF69B77E44B4C4427F26EC6303F91CF197298214820264AFACBD355F08E278734BDBF1E116ADF6C1C03ADF5E73212A7073BA01DFD347 20160315184225 2 6 100 7679 5 EC435B7E292EBAAEC94B8E8A53ED9F3FF717BB820D4893F0BBE6589BD3AF344B765A6000950C6244B2E4262E7E500BF699AF0FF49605A15EB80C61429C9FB79F658C3E0F8DB516AF9703BCB5E84ABA314292808DC70D183C513609A6D345F5D8676256E25108EE70B210C0293B5C804CF21FD843D2F5F79F91F57CF2C2EFB7052CA5F73544F0568A68FA5583CA6EDD300817AAB25E650B0AB9523C6C60156726F4B5243A8BE580308BB6297E23785893119D49B2407D4D8DACD551D08A5F9BB32BD7965313EC6C9DDCD685A62F7AFC8E71DF10F9E1FA25EB3DCD41D7DBDEFE5DB565BAE0CB62F192AA573A126FB92C9638457E73EB4C007268142D9506B17D20A4D73B51E21983D9AC86F7ABBDCE9B9D10BE307642C49382E27B45ADB32E9FF7A2203F395C71EAF7656DF83F57E527CCA37A2BE9AFBA89FB718DB95CC041BF4025FF1CB5F463C8A09FD374AF3F143EE53FF4B369117BDBE0743335B1B5650B68C5B4F64E42D4CF0B329316F4FCD5E66F4A1359F2B29684961CA04EC5AC787FD4BF990F3FBE698D69FAF946DE12A4215392928E29ACF24F940AE4046C74BC6E799EE1D85BA8264C6C7DFF62A244CA2D05C4352870E0E8EF71F884AEFA4A4CA704B6C6607D2E59D36253350AF73C1FBE9C5D61A26A9024B715B45ECF1487D23970C5E405B46029403DD95B2F5672E61863E48CBB280300B2CF87C749F0ACC52940819688C819250B71E54397C8792AAB31655BCE19FAD3A7C59BD64904CC806304AEB6DC8B534081CD2EFD2808977FAC9BAB540EC153DD98D8B33984EC40BCFBC0C5D5B95AB3E183961DB2EE8883B174A3CFEC21CBE7F200FDD2879C1BA808B65A03B02793688FBB1F753333A23A4139766DD3ECD30742E55C25474D068CAB008BA6957CB014E4D46C4BF3084C8343D61231B6B997A8BCEE761D907E4323B92EED55575A38048D686B04F6614B7F931BF1F7D2CF35912E3472F424B11FEBA41F6D569B1A13002A33D5660844A896436AA4D8BC74B6951C75F883D747690B6AD3501B84C6C5B4E29C4153A98C0F2DF38CAFDF00E15CFE8DB0939E5611518DB4547CB2880B5F2D431526082D608384FA3BDD78B75157F25C7A2448249E635C20051C39577AE777C75E7B424CB647B76C9880E905E401DA09DE7A6A5F3E59376B24DCAC613C6EF263741FA15E83B64C78C03016FD34AB608D77100FD8733F130F63A0725B8E7CCD344F5E9A460D2F4F5BE139A6B57A3955A47726A02D6425EF8D1440709517F2DE1D8BB1D054BF69B77E44B4C4427F26EC6303F91CF197298214820264AFACBD355F08E278734BDBF1E116ADF6C1C03ADF5E73212A7073BA034D7527 20160315214330 2 6 100 7679 2 EC435B7E292EBAAEC94B8E8A53ED9F3FF717BB820D4893F0BBE6589BD3AF344B765A6000950C6244B2E4262E7E500BF699AF0FF49605A15EB80C61429C9FB79F658C3E0F8DB516AF9703BCB5E84ABA314292808DC70D183C513609A6D345F5D8676256E25108EE70B210C0293B5C804CF21FD843D2F5F79F91F57CF2C2EFB7052CA5F73544F0568A68FA5583CA6EDD300817AAB25E650B0AB9523C6C60156726F4B5243A8BE580308BB6297E23785893119D49B2407D4D8DACD551D08A5F9BB32BD7965313EC6C9DDCD685A62F7AFC8E71DF10F9E1FA25EB3DCD41D7DBDEFE5DB565BAE0CB62F192AA573A126FB92C9638457E73EB4C007268142D9506B17D20A4D73B51E21983D9AC86F7ABBDCE9B9D10BE307642C49382E27B45ADB32E9FF7A2203F395C71EAF7656DF83F57E527CCA37A2BE9AFBA89FB718DB95CC041BF4025FF1CB5F463C8A09FD374AF3F143EE53FF4B369117BDBE0743335B1B5650B68C5B4F64E42D4CF0B329316F4FCD5E66F4A1359F2B29684961CA04EC5AC787FD4BF990F3FBE698D69FAF946DE12A4215392928E29ACF24F940AE4046C74BC6E799EE1D85BA8264C6C7DFF62A244CA2D05C4352870E0E8EF71F884AEFA4A4CA704B6C6607D2E59D36253350AF73C1FBE9C5D61A26A9024B715B45ECF1487D23970C5E405B46029403DD95B2F5672E61863E48CBB280300B2CF87C749F0ACC52940819688C819250B71E54397C8792AAB31655BCE19FAD3A7C59BD64904CC806304AEB6DC8B534081CD2EFD2808977FAC9BAB540EC153DD98D8B33984EC40BCFBC0C5D5B95AB3E183961DB2EE8883B174A3CFEC21CBE7F200FDD2879C1BA808B65A03B02793688FBB1F753333A23A4139766DD3ECD30742E55C25474D068CAB008BA6957CB014E4D46C4BF3084C8343D61231B6B997A8BCEE761D907E4323B92EED55575A38048D686B04F6614B7F931BF1F7D2CF35912E3472F424B11FEBA41F6D569B1A13002A33D5660844A896436AA4D8BC74B6951C75F883D747690B6AD3501B84C6C5B4E29C4153A98C0F2DF38CAFDF00E15CFE8DB0939E5611518DB4547CB2880B5F2D431526082D608384FA3BDD78B75157F25C7A2448249E635C20051C39577AE777C75E7B424CB647B76C9880E905E401DA09DE7A6A5F3E59376B24DCAC613C6EF263741FA15E83B64C78C03016FD34AB608D77100FD8733F130F63A0725B8E7CCD344F5E9A460D2F4F5BE139A6B57A3955A47726A02D6425EF8D1440709517F2DE1D8BB1D054BF69B77E44B4C4427F26EC6303F91CF197298214820264AFACBD355F08E278734BDBF1E116ADF6C1C03ADF5E73212A7073BA05A75E33 20160316020204 2 6 100 7679 5 EC435B7E292EBAAEC94B8E8A53ED9F3FF717BB820D4893F0BBE6589BD3AF344B765A6000950C6244B2E4262E7E500BF699AF0FF49605A15EB80C61429C9FB79F658C3E0F8DB516AF9703BCB5E84ABA314292808DC70D183C513609A6D345F5D8676256E25108EE70B210C0293B5C804CF21FD843D2F5F79F91F57CF2C2EFB7052CA5F73544F0568A68FA5583CA6EDD300817AAB25E650B0AB9523C6C60156726F4B5243A8BE580308BB6297E23785893119D49B2407D4D8DACD551D08A5F9BB32BD7965313EC6C9DDCD685A62F7AFC8E71DF10F9E1FA25EB3DCD41D7DBDEFE5DB565BAE0CB62F192AA573A126FB92C9638457E73EB4C007268142D9506B17D20A4D73B51E21983D9AC86F7ABBDCE9B9D10BE307642C49382E27B45ADB32E9FF7A2203F395C71EAF7656DF83F57E527CCA37A2BE9AFBA89FB718DB95CC041BF4025FF1CB5F463C8A09FD374AF3F143EE53FF4B369117BDBE0743335B1B5650B68C5B4F64E42D4CF0B329316F4FCD5E66F4A1359F2B29684961CA04EC5AC787FD4BF990F3FBE698D69FAF946DE12A4215392928E29ACF24F940AE4046C74BC6E799EE1D85BA8264C6C7DFF62A244CA2D05C4352870E0E8EF71F884AEFA4A4CA704B6C6607D2E59D36253350AF73C1FBE9C5D61A26A9024B715B45ECF1487D23970C5E405B46029403DD95B2F5672E61863E48CBB280300B2CF87C749F0ACC52940819688C819250B71E54397C8792AAB31655BCE19FAD3A7C59BD64904CC806304AEB6DC8B534081CD2EFD2808977FAC9BAB540EC153DD98D8B33984EC40BCFBC0C5D5B95AB3E183961DB2EE8883B174A3CFEC21CBE7F200FDD2879C1BA808B65A03B02793688FBB1F753333A23A4139766DD3ECD30742E55C25474D068CAB008BA6957CB014E4D46C4BF3084C8343D61231B6B997A8BCEE761D907E4323B92EED55575A38048D686B04F6614B7F931BF1F7D2CF35912E3472F424B11FEBA41F6D569B1A13002A33D5660844A896436AA4D8BC74B6951C75F883D747690B6AD3501B84C6C5B4E29C4153A98C0F2DF38CAFDF00E15CFE8DB0939E5611518DB4547CB2880B5F2D431526082D608384FA3BDD78B75157F25C7A2448249E635C20051C39577AE777C75E7B424CB647B76C9880E905E401DA09DE7A6A5F3E59376B24DCAC613C6EF263741FA15E83B64C78C03016FD34AB608D77100FD8733F130F63A0725B8E7CCD344F5E9A460D2F4F5BE139A6B57A3955A47726A02D6425EF8D1440709517F2DE1D8BB1D054BF69B77E44B4C4427F26EC6303F91CF197298214820264AFACBD355F08E278734BDBF1E116ADF6C1C03ADF5E73212A7073BA0912D52F 20160316065014 2 6 100 7679 5 EC435B7E292EBAAEC94B8E8A53ED9F3FF717BB820D4893F0BBE6589BD3AF344B765A6000950C6244B2E4262E7E500BF699AF0FF49605A15EB80C61429C9FB79F658C3E0F8DB516AF9703BCB5E84ABA314292808DC70D183C513609A6D345F5D8676256E25108EE70B210C0293B5C804CF21FD843D2F5F79F91F57CF2C2EFB7052CA5F73544F0568A68FA5583CA6EDD300817AAB25E650B0AB9523C6C60156726F4B5243A8BE580308BB6297E23785893119D49B2407D4D8DACD551D08A5F9BB32BD7965313EC6C9DDCD685A62F7AFC8E71DF10F9E1FA25EB3DCD41D7DBDEFE5DB565BAE0CB62F192AA573A126FB92C9638457E73EB4C007268142D9506B17D20A4D73B51E21983D9AC86F7ABBDCE9B9D10BE307642C49382E27B45ADB32E9FF7A2203F395C71EAF7656DF83F57E527CCA37A2BE9AFBA89FB718DB95CC041BF4025FF1CB5F463C8A09FD374AF3F143EE53FF4B369117BDBE0743335B1B5650B68C5B4F64E42D4CF0B329316F4FCD5E66F4A1359F2B29684961CA04EC5AC787FD4BF990F3FBE698D69FAF946DE12A4215392928E29ACF24F940AE4046C74BC6E799EE1D85BA8264C6C7DFF62A244CA2D05C4352870E0E8EF71F884AEFA4A4CA704B6C6607D2E59D36253350AF73C1FBE9C5D61A26A9024B715B45ECF1487D23970C5E405B46029403DD95B2F5672E61863E48CBB280300B2CF87C749F0ACC52940819688C819250B71E54397C8792AAB31655BCE19FAD3A7C59BD64904CC806304AEB6DC8B534081CD2EFD2808977FAC9BAB540EC153DD98D8B33984EC40BCFBC0C5D5B95AB3E183961DB2EE8883B174A3CFEC21CBE7F200FDD2879C1BA808B65A03B02793688FBB1F753333A23A4139766DD3ECD30742E55C25474D068CAB008BA6957CB014E4D46C4BF3084C8343D61231B6B997A8BCEE761D907E4323B92EED55575A38048D686B04F6614B7F931BF1F7D2CF35912E3472F424B11FEBA41F6D569B1A13002A33D5660844A896436AA4D8BC74B6951C75F883D747690B6AD3501B84C6C5B4E29C4153A98C0F2DF38CAFDF00E15CFE8DB0939E5611518DB4547CB2880B5F2D431526082D608384FA3BDD78B75157F25C7A2448249E635C20051C39577AE777C75E7B424CB647B76C9880E905E401DA09DE7A6A5F3E59376B24DCAC613C6EF263741FA15E83B64C78C03016FD34AB608D77100FD8733F130F63A0725B8E7CCD344F5E9A460D2F4F5BE139A6B57A3955A47726A02D6425EF8D1440709517F2DE1D8BB1D054BF69B77E44B4C4427F26EC6303F91CF197298214820264AFACBD355F08E278734BDBF1E116ADF6C1C03ADF5E73212A7073BA0CD7441F 20160316121031 2 6 100 7679 2 EC435B7E292EBAAEC94B8E8A53ED9F3FF717BB820D4893F0BBE6589BD3AF344B765A6000950C6244B2E4262E7E500BF699AF0FF49605A15EB80C61429C9FB79F658C3E0F8DB516AF9703BCB5E84ABA314292808DC70D183C513609A6D345F5D8676256E25108EE70B210C0293B5C804CF21FD843D2F5F79F91F57CF2C2EFB7052CA5F73544F0568A68FA5583CA6EDD300817AAB25E650B0AB9523C6C60156726F4B5243A8BE580308BB6297E23785893119D49B2407D4D8DACD551D08A5F9BB32BD7965313EC6C9DDCD685A62F7AFC8E71DF10F9E1FA25EB3DCD41D7DBDEFE5DB565BAE0CB62F192AA573A126FB92C9638457E73EB4C007268142D9506B17D20A4D73B51E21983D9AC86F7ABBDCE9B9D10BE307642C49382E27B45ADB32E9FF7A2203F395C71EAF7656DF83F57E527CCA37A2BE9AFBA89FB718DB95CC041BF4025FF1CB5F463C8A09FD374AF3F143EE53FF4B369117BDBE0743335B1B5650B68C5B4F64E42D4CF0B329316F4FCD5E66F4A1359F2B29684961CA04EC5AC787FD4BF990F3FBE698D69FAF946DE12A4215392928E29ACF24F940AE4046C74BC6E799EE1D85BA8264C6C7DFF62A244CA2D05C4352870E0E8EF71F884AEFA4A4CA704B6C6607D2E59D36253350AF73C1FBE9C5D61A26A9024B715B45ECF1487D23970C5E405B46029403DD95B2F5672E61863E48CBB280300B2CF87C749F0ACC52940819688C819250B71E54397C8792AAB31655BCE19FAD3A7C59BD64904CC806304AEB6DC8B534081CD2EFD2808977FAC9BAB540EC153DD98D8B33984EC40BCFBC0C5D5B95AB3E183961DB2EE8883B174A3CFEC21CBE7F200FDD2879C1BA808B65A03B02793688FBB1F753333A23A4139766DD3ECD30742E55C25474D068CAB008BA6957CB014E4D46C4BF3084C8343D61231B6B997A8BCEE761D907E4323B92EED55575A38048D686B04F6614B7F931BF1F7D2CF35912E3472F424B11FEBA41F6D569B1A13002A33D5660844A896436AA4D8BC74B6951C75F883D747690B6AD3501B84C6C5B4E29C4153A98C0F2DF38CAFDF00E15CFE8DB0939E5611518DB4547CB2880B5F2D431526082D608384FA3BDD78B75157F25C7A2448249E635C20051C39577AE777C75E7B424CB647B76C9880E905E401DA09DE7A6A5F3E59376B24DCAC613C6EF263741FA15E83B64C78C03016FD34AB608D77100FD8733F130F63A0725B8E7CCD344F5E9A460D2F4F5BE139A6B57A3955A47726A02D6425EF8D1440709517F2DE1D8BB1D054BF69B77E44B4C4427F26EC6303F91CF197298214820264AFACBD355F08E278734BDBF1E116ADF6C1C03ADF5E73212A7073BA1102A093 20160316165356 2 6 100 7679 5 EC435B7E292EBAAEC94B8E8A53ED9F3FF717BB820D4893F0BBE6589BD3AF344B765A6000950C6244B2E4262E7E500BF699AF0FF49605A15EB80C61429C9FB79F658C3E0F8DB516AF9703BCB5E84ABA314292808DC70D183C513609A6D345F5D8676256E25108EE70B210C0293B5C804CF21FD843D2F5F79F91F57CF2C2EFB7052CA5F73544F0568A68FA5583CA6EDD300817AAB25E650B0AB9523C6C60156726F4B5243A8BE580308BB6297E23785893119D49B2407D4D8DACD551D08A5F9BB32BD7965313EC6C9DDCD685A62F7AFC8E71DF10F9E1FA25EB3DCD41D7DBDEFE5DB565BAE0CB62F192AA573A126FB92C9638457E73EB4C007268142D9506B17D20A4D73B51E21983D9AC86F7ABBDCE9B9D10BE307642C49382E27B45ADB32E9FF7A2203F395C71EAF7656DF83F57E527CCA37A2BE9AFBA89FB718DB95CC041BF4025FF1CB5F463C8A09FD374AF3F143EE53FF4B369117BDBE0743335B1B5650B68C5B4F64E42D4CF0B329316F4FCD5E66F4A1359F2B29684961CA04EC5AC787FD4BF990F3FBE698D69FAF946DE12A4215392928E29ACF24F940AE4046C74BC6E799EE1D85BA8264C6C7DFF62A244CA2D05C4352870E0E8EF71F884AEFA4A4CA704B6C6607D2E59D36253350AF73C1FBE9C5D61A26A9024B715B45ECF1487D23970C5E405B46029403DD95B2F5672E61863E48CBB280300B2CF87C749F0ACC52940819688C819250B71E54397C8792AAB31655BCE19FAD3A7C59BD64904CC806304AEB6DC8B534081CD2EFD2808977FAC9BAB540EC153DD98D8B33984EC40BCFBC0C5D5B95AB3E183961DB2EE8883B174A3CFEC21CBE7F200FDD2879C1BA808B65A03B02793688FBB1F753333A23A4139766DD3ECD30742E55C25474D068CAB008BA6957CB014E4D46C4BF3084C8343D61231B6B997A8BCEE761D907E4323B92EED55575A38048D686B04F6614B7F931BF1F7D2CF35912E3472F424B11FEBA41F6D569B1A13002A33D5660844A896436AA4D8BC74B6951C75F883D747690B6AD3501B84C6C5B4E29C4153A98C0F2DF38CAFDF00E15CFE8DB0939E5611518DB4547CB2880B5F2D431526082D608384FA3BDD78B75157F25C7A2448249E635C20051C39577AE777C75E7B424CB647B76C9880E905E401DA09DE7A6A5F3E59376B24DCAC613C6EF263741FA15E83B64C78C03016FD34AB608D77100FD8733F130F63A0725B8E7CCD344F5E9A460D2F4F5BE139A6B57A3955A47726A02D6425EF8D1440709517F2DE1D8BB1D054BF69B77E44B4C4427F26EC6303F91CF197298214820264AFACBD355F08E278734BDBF1E116ADF6C1C03ADF5E73212A7073BA14B5C017 20160316191831 2 6 100 7679 2 EC435B7E292EBAAEC94B8E8A53ED9F3FF717BB820D4893F0BBE6589BD3AF344B765A6000950C6244B2E4262E7E500BF699AF0FF49605A15EB80C61429C9FB79F658C3E0F8DB516AF9703BCB5E84ABA314292808DC70D183C513609A6D345F5D8676256E25108EE70B210C0293B5C804CF21FD843D2F5F79F91F57CF2C2EFB7052CA5F73544F0568A68FA5583CA6EDD300817AAB25E650B0AB9523C6C60156726F4B5243A8BE580308BB6297E23785893119D49B2407D4D8DACD551D08A5F9BB32BD7965313EC6C9DDCD685A62F7AFC8E71DF10F9E1FA25EB3DCD41D7DBDEFE5DB565BAE0CB62F192AA573A126FB92C9638457E73EB4C007268142D9506B17D20A4D73B51E21983D9AC86F7ABBDCE9B9D10BE307642C49382E27B45ADB32E9FF7A2203F395C71EAF7656DF83F57E527CCA37A2BE9AFBA89FB718DB95CC041BF4025FF1CB5F463C8A09FD374AF3F143EE53FF4B369117BDBE0743335B1B5650B68C5B4F64E42D4CF0B329316F4FCD5E66F4A1359F2B29684961CA04EC5AC787FD4BF990F3FBE698D69FAF946DE12A4215392928E29ACF24F940AE4046C74BC6E799EE1D85BA8264C6C7DFF62A244CA2D05C4352870E0E8EF71F884AEFA4A4CA704B6C6607D2E59D36253350AF73C1FBE9C5D61A26A9024B715B45ECF1487D23970C5E405B46029403DD95B2F5672E61863E48CBB280300B2CF87C749F0ACC52940819688C819250B71E54397C8792AAB31655BCE19FAD3A7C59BD64904CC806304AEB6DC8B534081CD2EFD2808977FAC9BAB540EC153DD98D8B33984EC40BCFBC0C5D5B95AB3E183961DB2EE8883B174A3CFEC21CBE7F200FDD2879C1BA808B65A03B02793688FBB1F753333A23A4139766DD3ECD30742E55C25474D068CAB008BA6957CB014E4D46C4BF3084C8343D61231B6B997A8BCEE761D907E4323B92EED55575A38048D686B04F6614B7F931BF1F7D2CF35912E3472F424B11FEBA41F6D569B1A13002A33D5660844A896436AA4D8BC74B6951C75F883D747690B6AD3501B84C6C5B4E29C4153A98C0F2DF38CAFDF00E15CFE8DB0939E5611518DB4547CB2880B5F2D431526082D608384FA3BDD78B75157F25C7A2448249E635C20051C39577AE777C75E7B424CB647B76C9880E905E401DA09DE7A6A5F3E59376B24DCAC613C6EF263741FA15E83B64C78C03016FD34AB608D77100FD8733F130F63A0725B8E7CCD344F5E9A460D2F4F5BE139A6B57A3955A47726A02D6425EF8D1440709517F2DE1D8BB1D054BF69B77E44B4C4427F26EC6303F91CF197298214820264AFACBD355F08E278734BDBF1E116ADF6C1C03ADF5E73212A7073BA168B1623 20160316230539 2 6 100 7679 5 EC435B7E292EBAAEC94B8E8A53ED9F3FF717BB820D4893F0BBE6589BD3AF344B765A6000950C6244B2E4262E7E500BF699AF0FF49605A15EB80C61429C9FB79F658C3E0F8DB516AF9703BCB5E84ABA314292808DC70D183C513609A6D345F5D8676256E25108EE70B210C0293B5C804CF21FD843D2F5F79F91F57CF2C2EFB7052CA5F73544F0568A68FA5583CA6EDD300817AAB25E650B0AB9523C6C60156726F4B5243A8BE580308BB6297E23785893119D49B2407D4D8DACD551D08A5F9BB32BD7965313EC6C9DDCD685A62F7AFC8E71DF10F9E1FA25EB3DCD41D7DBDEFE5DB565BAE0CB62F192AA573A126FB92C9638457E73EB4C007268142D9506B17D20A4D73B51E21983D9AC86F7ABBDCE9B9D10BE307642C49382E27B45ADB32E9FF7A2203F395C71EAF7656DF83F57E527CCA37A2BE9AFBA89FB718DB95CC041BF4025FF1CB5F463C8A09FD374AF3F143EE53FF4B369117BDBE0743335B1B5650B68C5B4F64E42D4CF0B329316F4FCD5E66F4A1359F2B29684961CA04EC5AC787FD4BF990F3FBE698D69FAF946DE12A4215392928E29ACF24F940AE4046C74BC6E799EE1D85BA8264C6C7DFF62A244CA2D05C4352870E0E8EF71F884AEFA4A4CA704B6C6607D2E59D36253350AF73C1FBE9C5D61A26A9024B715B45ECF1487D23970C5E405B46029403DD95B2F5672E61863E48CBB280300B2CF87C749F0ACC52940819688C819250B71E54397C8792AAB31655BCE19FAD3A7C59BD64904CC806304AEB6DC8B534081CD2EFD2808977FAC9BAB540EC153DD98D8B33984EC40BCFBC0C5D5B95AB3E183961DB2EE8883B174A3CFEC21CBE7F200FDD2879C1BA808B65A03B02793688FBB1F753333A23A4139766DD3ECD30742E55C25474D068CAB008BA6957CB014E4D46C4BF3084C8343D61231B6B997A8BCEE761D907E4323B92EED55575A38048D686B04F6614B7F931BF1F7D2CF35912E3472F424B11FEBA41F6D569B1A13002A33D5660844A896436AA4D8BC74B6951C75F883D747690B6AD3501B84C6C5B4E29C4153A98C0F2DF38CAFDF00E15CFE8DB0939E5611518DB4547CB2880B5F2D431526082D608384FA3BDD78B75157F25C7A2448249E635C20051C39577AE777C75E7B424CB647B76C9880E905E401DA09DE7A6A5F3E59376B24DCAC613C6EF263741FA15E83B64C78C03016FD34AB608D77100FD8733F130F63A0725B8E7CCD344F5E9A460D2F4F5BE139A6B57A3955A47726A02D6425EF8D1440709517F2DE1D8BB1D054BF69B77E44B4C4427F26EC6303F91CF197298214820264AFACBD355F08E278734BDBF1E116ADF6C1C03ADF5E73212A7073BA1974D157 20160317204037 2 6 100 8191 5 D8320CDE33443FD11E472910A82D580EF614A690CF5313E998A695702508351835AF6D1DF2FA7AF2F1B234CB85E4174D67D9A32B8CC58DAF6DCFD555275B1D038D5EAAC00E0396BFF8A3686F1BB5DADDEB3C5F12B02358C7A1249A01CB1AA2AB3FAC5FC95CB7D16A38DBCD11804212872394D9A2E2F2797A3062AC5AF0C0C57F5ABEF3608546608EC08F197CE2CCF0490875BE4BCF1BD35358AF5694217F2E3DE713800F3C4071622FDBAD20CAEBE2BA60C80DF012DA576EE24A753749C0BAD8707A2382B6E909FF0B8F4A304EEDB1BF04CA0747166981279FE69248AF0DD177702DA2DC709E301D7D6FE985A7D3F7A1678A9BEF306D6036F143806563C42ADFFD8D70595F0C60BA39F0D392CE7EF7CA57547DB2E35B0464FEC6F59F6095F93BD0A241589CAEE15E2226873D31876900E534999F1D2E23E7239FF679377580065A861D3E29FA7215979BDE039ED1FFED26CC2F5541C5CD907E81434EED0479D8737262CCB2807A70504088F23E72A3D949F37C2C8E957DC2FE64BB9CE028013270F42E022BA671F1670EBD20413453A3CF19F53A1A6BDE5D744E39BBF9377384AAF0FBAF475DD1067A2906244CB87F919159DDC71256A251F1BBA789B18D97602C9C1254A4443849C16E0CE2A7A0B6AA6F117788A92C1CB3F60E2C8E539840E3AF49B9248D3E1CAACB08B43146F07CC53D2573086ED062D108C9AC924F58265CCEF3731D39FE5D4F983EADD0E9F9D8B68D953AA9342B8604AFE7916E544D88870F2ED0AFC2CD0C47DD1E5F361004D97B5108D13CD127DEC8609FA2C65FF1714FD45F3B2B3809BAC06DFCA198B71B3929E2A7B62538E5B1B8B5024D8BB78438883911A6FCA870DB16F8F2DA46D9C611F785428A356B40C07B2B8A72E157E3497DE2982AAAE4D2D9F4368469A7AD4061AEE188DA4317D826721B9F9B1A361FECF0C725E0AB6F17C147D2C62A4D11989DB1503F85763FA3E4A49BAB6BDD05C95199158D421B115F40B124EE448803E07496DE7C2682D4AF433662978CFDCFAC88C9100C46CC16929A10E3082BCAD4444D59FE57717FB4BE8DE45F4D84716D204AC97CBA5A7824765636C571AD6780AAA7510E832EECC54D571A780F90BC6A1B54DE8CC83ECB797A9065CC9807CC99DD7638AFC500D05FD2EDEB795227CAA37EBBC04A37DF07762E0319F27B523282D11DEFD85A1DBA40C87EA1EA4D1B9B2A2FC34F9F5395AE51E3A994FE25C680022E5ABD19D11703C2CB6EEE1780F76FEA8601FAE9E27BC16F832BC16776609DC2B0E3D605E635258A95907A148D583B44E202BA4A48211DA3358B7B391B6F3AD0F84D9D7F97DFFA9D819C3D316A59173E8CA970240349A89E09F0A9B1A4B4C6FFCDD878A977BC9EB254318574C40C49D2DCE56FF803601E1752BE3824F94D0D66C1C5FDADCC9670BFC85C422811D27F505984F7 20160317232704 2 6 100 8191 2 D8320CDE33443FD11E472910A82D580EF614A690CF5313E998A695702508351835AF6D1DF2FA7AF2F1B234CB85E4174D67D9A32B8CC58DAF6DCFD555275B1D038D5EAAC00E0396BFF8A3686F1BB5DADDEB3C5F12B02358C7A1249A01CB1AA2AB3FAC5FC95CB7D16A38DBCD11804212872394D9A2E2F2797A3062AC5AF0C0C57F5ABEF3608546608EC08F197CE2CCF0490875BE4BCF1BD35358AF5694217F2E3DE713800F3C4071622FDBAD20CAEBE2BA60C80DF012DA576EE24A753749C0BAD8707A2382B6E909FF0B8F4A304EEDB1BF04CA0747166981279FE69248AF0DD177702DA2DC709E301D7D6FE985A7D3F7A1678A9BEF306D6036F143806563C42ADFFD8D70595F0C60BA39F0D392CE7EF7CA57547DB2E35B0464FEC6F59F6095F93BD0A241589CAEE15E2226873D31876900E534999F1D2E23E7239FF679377580065A861D3E29FA7215979BDE039ED1FFED26CC2F5541C5CD907E81434EED0479D8737262CCB2807A70504088F23E72A3D949F37C2C8E957DC2FE64BB9CE028013270F42E022BA671F1670EBD20413453A3CF19F53A1A6BDE5D744E39BBF9377384AAF0FBAF475DD1067A2906244CB87F919159DDC71256A251F1BBA789B18D97602C9C1254A4443849C16E0CE2A7A0B6AA6F117788A92C1CB3F60E2C8E539840E3AF49B9248D3E1CAACB08B43146F07CC53D2573086ED062D108C9AC924F58265CCEF3731D39FE5D4F983EADD0E9F9D8B68D953AA9342B8604AFE7916E544D88870F2ED0AFC2CD0C47DD1E5F361004D97B5108D13CD127DEC8609FA2C65FF1714FD45F3B2B3809BAC06DFCA198B71B3929E2A7B62538E5B1B8B5024D8BB78438883911A6FCA870DB16F8F2DA46D9C611F785428A356B40C07B2B8A72E157E3497DE2982AAAE4D2D9F4368469A7AD4061AEE188DA4317D826721B9F9B1A361FECF0C725E0AB6F17C147D2C62A4D11989DB1503F85763FA3E4A49BAB6BDD05C95199158D421B115F40B124EE448803E07496DE7C2682D4AF433662978CFDCFAC88C9100C46CC16929A10E3082BCAD4444D59FE57717FB4BE8DE45F4D84716D204AC97CBA5A7824765636C571AD6780AAA7510E832EECC54D571A780F90BC6A1B54DE8CC83ECB797A9065CC9807CC99DD7638AFC500D05FD2EDEB795227CAA37EBBC04A37DF07762E0319F27B523282D11DEFD85A1DBA40C87EA1EA4D1B9B2A2FC34F9F5395AE51E3A994FE25C680022E5ABD19D11703C2CB6EEE1780F76FEA8601FAE9E27BC16F832BC16776609DC2B0E3D605E635258A95907A148D583B44E202BA4A48211DA3358B7B391B6F3AD0F84D9D7F97DFFA9D819C3D316A59173E8CA970240349A89E09F0A9B1A4B4C6FFCDD878A977BC9EB254318574C40C49D2DCE56FF803601E1752BE3824F94D0D66C1C5FDADCC9670BFC85C422811D27F52635AA3 20160318065706 2 6 100 8191 2 D8320CDE33443FD11E472910A82D580EF614A690CF5313E998A695702508351835AF6D1DF2FA7AF2F1B234CB85E4174D67D9A32B8CC58DAF6DCFD555275B1D038D5EAAC00E0396BFF8A3686F1BB5DADDEB3C5F12B02358C7A1249A01CB1AA2AB3FAC5FC95CB7D16A38DBCD11804212872394D9A2E2F2797A3062AC5AF0C0C57F5ABEF3608546608EC08F197CE2CCF0490875BE4BCF1BD35358AF5694217F2E3DE713800F3C4071622FDBAD20CAEBE2BA60C80DF012DA576EE24A753749C0BAD8707A2382B6E909FF0B8F4A304EEDB1BF04CA0747166981279FE69248AF0DD177702DA2DC709E301D7D6FE985A7D3F7A1678A9BEF306D6036F143806563C42ADFFD8D70595F0C60BA39F0D392CE7EF7CA57547DB2E35B0464FEC6F59F6095F93BD0A241589CAEE15E2226873D31876900E534999F1D2E23E7239FF679377580065A861D3E29FA7215979BDE039ED1FFED26CC2F5541C5CD907E81434EED0479D8737262CCB2807A70504088F23E72A3D949F37C2C8E957DC2FE64BB9CE028013270F42E022BA671F1670EBD20413453A3CF19F53A1A6BDE5D744E39BBF9377384AAF0FBAF475DD1067A2906244CB87F919159DDC71256A251F1BBA789B18D97602C9C1254A4443849C16E0CE2A7A0B6AA6F117788A92C1CB3F60E2C8E539840E3AF49B9248D3E1CAACB08B43146F07CC53D2573086ED062D108C9AC924F58265CCEF3731D39FE5D4F983EADD0E9F9D8B68D953AA9342B8604AFE7916E544D88870F2ED0AFC2CD0C47DD1E5F361004D97B5108D13CD127DEC8609FA2C65FF1714FD45F3B2B3809BAC06DFCA198B71B3929E2A7B62538E5B1B8B5024D8BB78438883911A6FCA870DB16F8F2DA46D9C611F785428A356B40C07B2B8A72E157E3497DE2982AAAE4D2D9F4368469A7AD4061AEE188DA4317D826721B9F9B1A361FECF0C725E0AB6F17C147D2C62A4D11989DB1503F85763FA3E4A49BAB6BDD05C95199158D421B115F40B124EE448803E07496DE7C2682D4AF433662978CFDCFAC88C9100C46CC16929A10E3082BCAD4444D59FE57717FB4BE8DE45F4D84716D204AC97CBA5A7824765636C571AD6780AAA7510E832EECC54D571A780F90BC6A1B54DE8CC83ECB797A9065CC9807CC99DD7638AFC500D05FD2EDEB795227CAA37EBBC04A37DF07762E0319F27B523282D11DEFD85A1DBA40C87EA1EA4D1B9B2A2FC34F9F5395AE51E3A994FE25C680022E5ABD19D11703C2CB6EEE1780F76FEA8601FAE9E27BC16F832BC16776609DC2B0E3D605E635258A95907A148D583B44E202BA4A48211DA3358B7B391B6F3AD0F84D9D7F97DFFA9D819C3D316A59173E8CA970240349A89E09F0A9B1A4B4C6FFCDD878A977BC9EB254318574C40C49D2DCE56FF803601E1752BE3824F94D0D66C1C5FDADCC9670BFC85C422811D27F57FAD16B 20160318115527 2 6 100 8191 5 D8320CDE33443FD11E472910A82D580EF614A690CF5313E998A695702508351835AF6D1DF2FA7AF2F1B234CB85E4174D67D9A32B8CC58DAF6DCFD555275B1D038D5EAAC00E0396BFF8A3686F1BB5DADDEB3C5F12B02358C7A1249A01CB1AA2AB3FAC5FC95CB7D16A38DBCD11804212872394D9A2E2F2797A3062AC5AF0C0C57F5ABEF3608546608EC08F197CE2CCF0490875BE4BCF1BD35358AF5694217F2E3DE713800F3C4071622FDBAD20CAEBE2BA60C80DF012DA576EE24A753749C0BAD8707A2382B6E909FF0B8F4A304EEDB1BF04CA0747166981279FE69248AF0DD177702DA2DC709E301D7D6FE985A7D3F7A1678A9BEF306D6036F143806563C42ADFFD8D70595F0C60BA39F0D392CE7EF7CA57547DB2E35B0464FEC6F59F6095F93BD0A241589CAEE15E2226873D31876900E534999F1D2E23E7239FF679377580065A861D3E29FA7215979BDE039ED1FFED26CC2F5541C5CD907E81434EED0479D8737262CCB2807A70504088F23E72A3D949F37C2C8E957DC2FE64BB9CE028013270F42E022BA671F1670EBD20413453A3CF19F53A1A6BDE5D744E39BBF9377384AAF0FBAF475DD1067A2906244CB87F919159DDC71256A251F1BBA789B18D97602C9C1254A4443849C16E0CE2A7A0B6AA6F117788A92C1CB3F60E2C8E539840E3AF49B9248D3E1CAACB08B43146F07CC53D2573086ED062D108C9AC924F58265CCEF3731D39FE5D4F983EADD0E9F9D8B68D953AA9342B8604AFE7916E544D88870F2ED0AFC2CD0C47DD1E5F361004D97B5108D13CD127DEC8609FA2C65FF1714FD45F3B2B3809BAC06DFCA198B71B3929E2A7B62538E5B1B8B5024D8BB78438883911A6FCA870DB16F8F2DA46D9C611F785428A356B40C07B2B8A72E157E3497DE2982AAAE4D2D9F4368469A7AD4061AEE188DA4317D826721B9F9B1A361FECF0C725E0AB6F17C147D2C62A4D11989DB1503F85763FA3E4A49BAB6BDD05C95199158D421B115F40B124EE448803E07496DE7C2682D4AF433662978CFDCFAC88C9100C46CC16929A10E3082BCAD4444D59FE57717FB4BE8DE45F4D84716D204AC97CBA5A7824765636C571AD6780AAA7510E832EECC54D571A780F90BC6A1B54DE8CC83ECB797A9065CC9807CC99DD7638AFC500D05FD2EDEB795227CAA37EBBC04A37DF07762E0319F27B523282D11DEFD85A1DBA40C87EA1EA4D1B9B2A2FC34F9F5395AE51E3A994FE25C680022E5ABD19D11703C2CB6EEE1780F76FEA8601FAE9E27BC16F832BC16776609DC2B0E3D605E635258A95907A148D583B44E202BA4A48211DA3358B7B391B6F3AD0F84D9D7F97DFFA9D819C3D316A59173E8CA970240349A89E09F0A9B1A4B4C6FFCDD878A977BC9EB254318574C40C49D2DCE56FF803601E1752BE3824F94D0D66C1C5FDADCC9670BFC85C422811D27F5BAEDEAF 20160318183751 2 6 100 8191 5 D8320CDE33443FD11E472910A82D580EF614A690CF5313E998A695702508351835AF6D1DF2FA7AF2F1B234CB85E4174D67D9A32B8CC58DAF6DCFD555275B1D038D5EAAC00E0396BFF8A3686F1BB5DADDEB3C5F12B02358C7A1249A01CB1AA2AB3FAC5FC95CB7D16A38DBCD11804212872394D9A2E2F2797A3062AC5AF0C0C57F5ABEF3608546608EC08F197CE2CCF0490875BE4BCF1BD35358AF5694217F2E3DE713800F3C4071622FDBAD20CAEBE2BA60C80DF012DA576EE24A753749C0BAD8707A2382B6E909FF0B8F4A304EEDB1BF04CA0747166981279FE69248AF0DD177702DA2DC709E301D7D6FE985A7D3F7A1678A9BEF306D6036F143806563C42ADFFD8D70595F0C60BA39F0D392CE7EF7CA57547DB2E35B0464FEC6F59F6095F93BD0A241589CAEE15E2226873D31876900E534999F1D2E23E7239FF679377580065A861D3E29FA7215979BDE039ED1FFED26CC2F5541C5CD907E81434EED0479D8737262CCB2807A70504088F23E72A3D949F37C2C8E957DC2FE64BB9CE028013270F42E022BA671F1670EBD20413453A3CF19F53A1A6BDE5D744E39BBF9377384AAF0FBAF475DD1067A2906244CB87F919159DDC71256A251F1BBA789B18D97602C9C1254A4443849C16E0CE2A7A0B6AA6F117788A92C1CB3F60E2C8E539840E3AF49B9248D3E1CAACB08B43146F07CC53D2573086ED062D108C9AC924F58265CCEF3731D39FE5D4F983EADD0E9F9D8B68D953AA9342B8604AFE7916E544D88870F2ED0AFC2CD0C47DD1E5F361004D97B5108D13CD127DEC8609FA2C65FF1714FD45F3B2B3809BAC06DFCA198B71B3929E2A7B62538E5B1B8B5024D8BB78438883911A6FCA870DB16F8F2DA46D9C611F785428A356B40C07B2B8A72E157E3497DE2982AAAE4D2D9F4368469A7AD4061AEE188DA4317D826721B9F9B1A361FECF0C725E0AB6F17C147D2C62A4D11989DB1503F85763FA3E4A49BAB6BDD05C95199158D421B115F40B124EE448803E07496DE7C2682D4AF433662978CFDCFAC88C9100C46CC16929A10E3082BCAD4444D59FE57717FB4BE8DE45F4D84716D204AC97CBA5A7824765636C571AD6780AAA7510E832EECC54D571A780F90BC6A1B54DE8CC83ECB797A9065CC9807CC99DD7638AFC500D05FD2EDEB795227CAA37EBBC04A37DF07762E0319F27B523282D11DEFD85A1DBA40C87EA1EA4D1B9B2A2FC34F9F5395AE51E3A994FE25C680022E5ABD19D11703C2CB6EEE1780F76FEA8601FAE9E27BC16F832BC16776609DC2B0E3D605E635258A95907A148D583B44E202BA4A48211DA3358B7B391B6F3AD0F84D9D7F97DFFA9D819C3D316A59173E8CA970240349A89E09F0A9B1A4B4C6FFCDD878A977BC9EB254318574C40C49D2DCE56FF803601E1752BE3824F94D0D66C1C5FDADCC9670BFC85C422811D27F608FC39F 20160318220732 2 6 100 8191 2 D8320CDE33443FD11E472910A82D580EF614A690CF5313E998A695702508351835AF6D1DF2FA7AF2F1B234CB85E4174D67D9A32B8CC58DAF6DCFD555275B1D038D5EAAC00E0396BFF8A3686F1BB5DADDEB3C5F12B02358C7A1249A01CB1AA2AB3FAC5FC95CB7D16A38DBCD11804212872394D9A2E2F2797A3062AC5AF0C0C57F5ABEF3608546608EC08F197CE2CCF0490875BE4BCF1BD35358AF5694217F2E3DE713800F3C4071622FDBAD20CAEBE2BA60C80DF012DA576EE24A753749C0BAD8707A2382B6E909FF0B8F4A304EEDB1BF04CA0747166981279FE69248AF0DD177702DA2DC709E301D7D6FE985A7D3F7A1678A9BEF306D6036F143806563C42ADFFD8D70595F0C60BA39F0D392CE7EF7CA57547DB2E35B0464FEC6F59F6095F93BD0A241589CAEE15E2226873D31876900E534999F1D2E23E7239FF679377580065A861D3E29FA7215979BDE039ED1FFED26CC2F5541C5CD907E81434EED0479D8737262CCB2807A70504088F23E72A3D949F37C2C8E957DC2FE64BB9CE028013270F42E022BA671F1670EBD20413453A3CF19F53A1A6BDE5D744E39BBF9377384AAF0FBAF475DD1067A2906244CB87F919159DDC71256A251F1BBA789B18D97602C9C1254A4443849C16E0CE2A7A0B6AA6F117788A92C1CB3F60E2C8E539840E3AF49B9248D3E1CAACB08B43146F07CC53D2573086ED062D108C9AC924F58265CCEF3731D39FE5D4F983EADD0E9F9D8B68D953AA9342B8604AFE7916E544D88870F2ED0AFC2CD0C47DD1E5F361004D97B5108D13CD127DEC8609FA2C65FF1714FD45F3B2B3809BAC06DFCA198B71B3929E2A7B62538E5B1B8B5024D8BB78438883911A6FCA870DB16F8F2DA46D9C611F785428A356B40C07B2B8A72E157E3497DE2982AAAE4D2D9F4368469A7AD4061AEE188DA4317D826721B9F9B1A361FECF0C725E0AB6F17C147D2C62A4D11989DB1503F85763FA3E4A49BAB6BDD05C95199158D421B115F40B124EE448803E07496DE7C2682D4AF433662978CFDCFAC88C9100C46CC16929A10E3082BCAD4444D59FE57717FB4BE8DE45F4D84716D204AC97CBA5A7824765636C571AD6780AAA7510E832EECC54D571A780F90BC6A1B54DE8CC83ECB797A9065CC9807CC99DD7638AFC500D05FD2EDEB795227CAA37EBBC04A37DF07762E0319F27B523282D11DEFD85A1DBA40C87EA1EA4D1B9B2A2FC34F9F5395AE51E3A994FE25C680022E5ABD19D11703C2CB6EEE1780F76FEA8601FAE9E27BC16F832BC16776609DC2B0E3D605E635258A95907A148D583B44E202BA4A48211DA3358B7B391B6F3AD0F84D9D7F97DFFA9D819C3D316A59173E8CA970240349A89E09F0A9B1A4B4C6FFCDD878A977BC9EB254318574C40C49D2DCE56FF803601E1752BE3824F94D0D66C1C5FDADCC9670BFC85C422811D27F6315D9EB 20160318231533 2 6 100 8191 5 D8320CDE33443FD11E472910A82D580EF614A690CF5313E998A695702508351835AF6D1DF2FA7AF2F1B234CB85E4174D67D9A32B8CC58DAF6DCFD555275B1D038D5EAAC00E0396BFF8A3686F1BB5DADDEB3C5F12B02358C7A1249A01CB1AA2AB3FAC5FC95CB7D16A38DBCD11804212872394D9A2E2F2797A3062AC5AF0C0C57F5ABEF3608546608EC08F197CE2CCF0490875BE4BCF1BD35358AF5694217F2E3DE713800F3C4071622FDBAD20CAEBE2BA60C80DF012DA576EE24A753749C0BAD8707A2382B6E909FF0B8F4A304EEDB1BF04CA0747166981279FE69248AF0DD177702DA2DC709E301D7D6FE985A7D3F7A1678A9BEF306D6036F143806563C42ADFFD8D70595F0C60BA39F0D392CE7EF7CA57547DB2E35B0464FEC6F59F6095F93BD0A241589CAEE15E2226873D31876900E534999F1D2E23E7239FF679377580065A861D3E29FA7215979BDE039ED1FFED26CC2F5541C5CD907E81434EED0479D8737262CCB2807A70504088F23E72A3D949F37C2C8E957DC2FE64BB9CE028013270F42E022BA671F1670EBD20413453A3CF19F53A1A6BDE5D744E39BBF9377384AAF0FBAF475DD1067A2906244CB87F919159DDC71256A251F1BBA789B18D97602C9C1254A4443849C16E0CE2A7A0B6AA6F117788A92C1CB3F60E2C8E539840E3AF49B9248D3E1CAACB08B43146F07CC53D2573086ED062D108C9AC924F58265CCEF3731D39FE5D4F983EADD0E9F9D8B68D953AA9342B8604AFE7916E544D88870F2ED0AFC2CD0C47DD1E5F361004D97B5108D13CD127DEC8609FA2C65FF1714FD45F3B2B3809BAC06DFCA198B71B3929E2A7B62538E5B1B8B5024D8BB78438883911A6FCA870DB16F8F2DA46D9C611F785428A356B40C07B2B8A72E157E3497DE2982AAAE4D2D9F4368469A7AD4061AEE188DA4317D826721B9F9B1A361FECF0C725E0AB6F17C147D2C62A4D11989DB1503F85763FA3E4A49BAB6BDD05C95199158D421B115F40B124EE448803E07496DE7C2682D4AF433662978CFDCFAC88C9100C46CC16929A10E3082BCAD4444D59FE57717FB4BE8DE45F4D84716D204AC97CBA5A7824765636C571AD6780AAA7510E832EECC54D571A780F90BC6A1B54DE8CC83ECB797A9065CC9807CC99DD7638AFC500D05FD2EDEB795227CAA37EBBC04A37DF07762E0319F27B523282D11DEFD85A1DBA40C87EA1EA4D1B9B2A2FC34F9F5395AE51E3A994FE25C680022E5ABD19D11703C2CB6EEE1780F76FEA8601FAE9E27BC16F832BC16776609DC2B0E3D605E635258A95907A148D583B44E202BA4A48211DA3358B7B391B6F3AD0F84D9D7F97DFFA9D819C3D316A59173E8CA970240349A89E09F0A9B1A4B4C6FFCDD878A977BC9EB254318574C40C49D2DCE56FF803601E1752BE3824F94D0D66C1C5FDADCC9670BFC85C422811D27F63E5739F 20160319161235 2 6 100 8191 2 D8320CDE33443FD11E472910A82D580EF614A690CF5313E998A695702508351835AF6D1DF2FA7AF2F1B234CB85E4174D67D9A32B8CC58DAF6DCFD555275B1D038D5EAAC00E0396BFF8A3686F1BB5DADDEB3C5F12B02358C7A1249A01CB1AA2AB3FAC5FC95CB7D16A38DBCD11804212872394D9A2E2F2797A3062AC5AF0C0C57F5ABEF3608546608EC08F197CE2CCF0490875BE4BCF1BD35358AF5694217F2E3DE713800F3C4071622FDBAD20CAEBE2BA60C80DF012DA576EE24A753749C0BAD8707A2382B6E909FF0B8F4A304EEDB1BF04CA0747166981279FE69248AF0DD177702DA2DC709E301D7D6FE985A7D3F7A1678A9BEF306D6036F143806563C42ADFFD8D70595F0C60BA39F0D392CE7EF7CA57547DB2E35B0464FEC6F59F6095F93BD0A241589CAEE15E2226873D31876900E534999F1D2E23E7239FF679377580065A861D3E29FA7215979BDE039ED1FFED26CC2F5541C5CD907E81434EED0479D8737262CCB2807A70504088F23E72A3D949F37C2C8E957DC2FE64BB9CE028013270F42E022BA671F1670EBD20413453A3CF19F53A1A6BDE5D744E39BBF9377384AAF0FBAF475DD1067A2906244CB87F919159DDC71256A251F1BBA789B18D97602C9C1254A4443849C16E0CE2A7A0B6AA6F117788A92C1CB3F60E2C8E539840E3AF49B9248D3E1CAACB08B43146F07CC53D2573086ED062D108C9AC924F58265CCEF3731D39FE5D4F983EADD0E9F9D8B68D953AA9342B8604AFE7916E544D88870F2ED0AFC2CD0C47DD1E5F361004D97B5108D13CD127DEC8609FA2C65FF1714FD45F3B2B3809BAC06DFCA198B71B3929E2A7B62538E5B1B8B5024D8BB78438883911A6FCA870DB16F8F2DA46D9C611F785428A356B40C07B2B8A72E157E3497DE2982AAAE4D2D9F4368469A7AD4061AEE188DA4317D826721B9F9B1A361FECF0C725E0AB6F17C147D2C62A4D11989DB1503F85763FA3E4A49BAB6BDD05C95199158D421B115F40B124EE448803E07496DE7C2682D4AF433662978CFDCFAC88C9100C46CC16929A10E3082BCAD4444D59FE57717FB4BE8DE45F4D84716D204AC97CBA5A7824765636C571AD6780AAA7510E832EECC54D571A780F90BC6A1B54DE8CC83ECB797A9065CC9807CC99DD7638AFC500D05FD2EDEB795227CAA37EBBC04A37DF07762E0319F27B523282D11DEFD85A1DBA40C87EA1EA4D1B9B2A2FC34F9F5395AE51E3A994FE25C680022E5ABD19D11703C2CB6EEE1780F76FEA8601FAE9E27BC16F832BC16776609DC2B0E3D605E635258A95907A148D583B44E202BA4A48211DA3358B7B391B6F3AD0F84D9D7F97DFFA9D819C3D316A59173E8CA970240349A89E09F0A9B1A4B4C6FFCDD878A977BC9EB254318574C40C49D2DCE56FF803601E1752BE3824F94D0D66C1C5FDADCC9670BFC85C422811D27F7037DD73 20160319230645 2 6 100 8191 2 D8320CDE33443FD11E472910A82D580EF614A690CF5313E998A695702508351835AF6D1DF2FA7AF2F1B234CB85E4174D67D9A32B8CC58DAF6DCFD555275B1D038D5EAAC00E0396BFF8A3686F1BB5DADDEB3C5F12B02358C7A1249A01CB1AA2AB3FAC5FC95CB7D16A38DBCD11804212872394D9A2E2F2797A3062AC5AF0C0C57F5ABEF3608546608EC08F197CE2CCF0490875BE4BCF1BD35358AF5694217F2E3DE713800F3C4071622FDBAD20CAEBE2BA60C80DF012DA576EE24A753749C0BAD8707A2382B6E909FF0B8F4A304EEDB1BF04CA0747166981279FE69248AF0DD177702DA2DC709E301D7D6FE985A7D3F7A1678A9BEF306D6036F143806563C42ADFFD8D70595F0C60BA39F0D392CE7EF7CA57547DB2E35B0464FEC6F59F6095F93BD0A241589CAEE15E2226873D31876900E534999F1D2E23E7239FF679377580065A861D3E29FA7215979BDE039ED1FFED26CC2F5541C5CD907E81434EED0479D8737262CCB2807A70504088F23E72A3D949F37C2C8E957DC2FE64BB9CE028013270F42E022BA671F1670EBD20413453A3CF19F53A1A6BDE5D744E39BBF9377384AAF0FBAF475DD1067A2906244CB87F919159DDC71256A251F1BBA789B18D97602C9C1254A4443849C16E0CE2A7A0B6AA6F117788A92C1CB3F60E2C8E539840E3AF49B9248D3E1CAACB08B43146F07CC53D2573086ED062D108C9AC924F58265CCEF3731D39FE5D4F983EADD0E9F9D8B68D953AA9342B8604AFE7916E544D88870F2ED0AFC2CD0C47DD1E5F361004D97B5108D13CD127DEC8609FA2C65FF1714FD45F3B2B3809BAC06DFCA198B71B3929E2A7B62538E5B1B8B5024D8BB78438883911A6FCA870DB16F8F2DA46D9C611F785428A356B40C07B2B8A72E157E3497DE2982AAAE4D2D9F4368469A7AD4061AEE188DA4317D826721B9F9B1A361FECF0C725E0AB6F17C147D2C62A4D11989DB1503F85763FA3E4A49BAB6BDD05C95199158D421B115F40B124EE448803E07496DE7C2682D4AF433662978CFDCFAC88C9100C46CC16929A10E3082BCAD4444D59FE57717FB4BE8DE45F4D84716D204AC97CBA5A7824765636C571AD6780AAA7510E832EECC54D571A780F90BC6A1B54DE8CC83ECB797A9065CC9807CC99DD7638AFC500D05FD2EDEB795227CAA37EBBC04A37DF07762E0319F27B523282D11DEFD85A1DBA40C87EA1EA4D1B9B2A2FC34F9F5395AE51E3A994FE25C680022E5ABD19D11703C2CB6EEE1780F76FEA8601FAE9E27BC16F832BC16776609DC2B0E3D605E635258A95907A148D583B44E202BA4A48211DA3358B7B391B6F3AD0F84D9D7F97DFFA9D819C3D316A59173E8CA970240349A89E09F0A9B1A4B4C6FFCDD878A977BC9EB254318574C40C49D2DCE56FF803601E1752BE3824F94D0D66C1C5FDADCC9670BFC85C422811D27F751E7BE3 20160320013744 2 6 100 8191 5 D8320CDE33443FD11E472910A82D580EF614A690CF5313E998A695702508351835AF6D1DF2FA7AF2F1B234CB85E4174D67D9A32B8CC58DAF6DCFD555275B1D038D5EAAC00E0396BFF8A3686F1BB5DADDEB3C5F12B02358C7A1249A01CB1AA2AB3FAC5FC95CB7D16A38DBCD11804212872394D9A2E2F2797A3062AC5AF0C0C57F5ABEF3608546608EC08F197CE2CCF0490875BE4BCF1BD35358AF5694217F2E3DE713800F3C4071622FDBAD20CAEBE2BA60C80DF012DA576EE24A753749C0BAD8707A2382B6E909FF0B8F4A304EEDB1BF04CA0747166981279FE69248AF0DD177702DA2DC709E301D7D6FE985A7D3F7A1678A9BEF306D6036F143806563C42ADFFD8D70595F0C60BA39F0D392CE7EF7CA57547DB2E35B0464FEC6F59F6095F93BD0A241589CAEE15E2226873D31876900E534999F1D2E23E7239FF679377580065A861D3E29FA7215979BDE039ED1FFED26CC2F5541C5CD907E81434EED0479D8737262CCB2807A70504088F23E72A3D949F37C2C8E957DC2FE64BB9CE028013270F42E022BA671F1670EBD20413453A3CF19F53A1A6BDE5D744E39BBF9377384AAF0FBAF475DD1067A2906244CB87F919159DDC71256A251F1BBA789B18D97602C9C1254A4443849C16E0CE2A7A0B6AA6F117788A92C1CB3F60E2C8E539840E3AF49B9248D3E1CAACB08B43146F07CC53D2573086ED062D108C9AC924F58265CCEF3731D39FE5D4F983EADD0E9F9D8B68D953AA9342B8604AFE7916E544D88870F2ED0AFC2CD0C47DD1E5F361004D97B5108D13CD127DEC8609FA2C65FF1714FD45F3B2B3809BAC06DFCA198B71B3929E2A7B62538E5B1B8B5024D8BB78438883911A6FCA870DB16F8F2DA46D9C611F785428A356B40C07B2B8A72E157E3497DE2982AAAE4D2D9F4368469A7AD4061AEE188DA4317D826721B9F9B1A361FECF0C725E0AB6F17C147D2C62A4D11989DB1503F85763FA3E4A49BAB6BDD05C95199158D421B115F40B124EE448803E07496DE7C2682D4AF433662978CFDCFAC88C9100C46CC16929A10E3082BCAD4444D59FE57717FB4BE8DE45F4D84716D204AC97CBA5A7824765636C571AD6780AAA7510E832EECC54D571A780F90BC6A1B54DE8CC83ECB797A9065CC9807CC99DD7638AFC500D05FD2EDEB795227CAA37EBBC04A37DF07762E0319F27B523282D11DEFD85A1DBA40C87EA1EA4D1B9B2A2FC34F9F5395AE51E3A994FE25C680022E5ABD19D11703C2CB6EEE1780F76FEA8601FAE9E27BC16F832BC16776609DC2B0E3D605E635258A95907A148D583B44E202BA4A48211DA3358B7B391B6F3AD0F84D9D7F97DFFA9D819C3D316A59173E8CA970240349A89E09F0A9B1A4B4C6FFCDD878A977BC9EB254318574C40C49D2DCE56FF803601E1752BE3824F94D0D66C1C5FDADCC9670BFC85C422811D27F76DF3D47 20160320040506 2 6 100 8191 5 D8320CDE33443FD11E472910A82D580EF614A690CF5313E998A695702508351835AF6D1DF2FA7AF2F1B234CB85E4174D67D9A32B8CC58DAF6DCFD555275B1D038D5EAAC00E0396BFF8A3686F1BB5DADDEB3C5F12B02358C7A1249A01CB1AA2AB3FAC5FC95CB7D16A38DBCD11804212872394D9A2E2F2797A3062AC5AF0C0C57F5ABEF3608546608EC08F197CE2CCF0490875BE4BCF1BD35358AF5694217F2E3DE713800F3C4071622FDBAD20CAEBE2BA60C80DF012DA576EE24A753749C0BAD8707A2382B6E909FF0B8F4A304EEDB1BF04CA0747166981279FE69248AF0DD177702DA2DC709E301D7D6FE985A7D3F7A1678A9BEF306D6036F143806563C42ADFFD8D70595F0C60BA39F0D392CE7EF7CA57547DB2E35B0464FEC6F59F6095F93BD0A241589CAEE15E2226873D31876900E534999F1D2E23E7239FF679377580065A861D3E29FA7215979BDE039ED1FFED26CC2F5541C5CD907E81434EED0479D8737262CCB2807A70504088F23E72A3D949F37C2C8E957DC2FE64BB9CE028013270F42E022BA671F1670EBD20413453A3CF19F53A1A6BDE5D744E39BBF9377384AAF0FBAF475DD1067A2906244CB87F919159DDC71256A251F1BBA789B18D97602C9C1254A4443849C16E0CE2A7A0B6AA6F117788A92C1CB3F60E2C8E539840E3AF49B9248D3E1CAACB08B43146F07CC53D2573086ED062D108C9AC924F58265CCEF3731D39FE5D4F983EADD0E9F9D8B68D953AA9342B8604AFE7916E544D88870F2ED0AFC2CD0C47DD1E5F361004D97B5108D13CD127DEC8609FA2C65FF1714FD45F3B2B3809BAC06DFCA198B71B3929E2A7B62538E5B1B8B5024D8BB78438883911A6FCA870DB16F8F2DA46D9C611F785428A356B40C07B2B8A72E157E3497DE2982AAAE4D2D9F4368469A7AD4061AEE188DA4317D826721B9F9B1A361FECF0C725E0AB6F17C147D2C62A4D11989DB1503F85763FA3E4A49BAB6BDD05C95199158D421B115F40B124EE448803E07496DE7C2682D4AF433662978CFDCFAC88C9100C46CC16929A10E3082BCAD4444D59FE57717FB4BE8DE45F4D84716D204AC97CBA5A7824765636C571AD6780AAA7510E832EECC54D571A780F90BC6A1B54DE8CC83ECB797A9065CC9807CC99DD7638AFC500D05FD2EDEB795227CAA37EBBC04A37DF07762E0319F27B523282D11DEFD85A1DBA40C87EA1EA4D1B9B2A2FC34F9F5395AE51E3A994FE25C680022E5ABD19D11703C2CB6EEE1780F76FEA8601FAE9E27BC16F832BC16776609DC2B0E3D605E635258A95907A148D583B44E202BA4A48211DA3358B7B391B6F3AD0F84D9D7F97DFFA9D819C3D316A59173E8CA970240349A89E09F0A9B1A4B4C6FFCDD878A977BC9EB254318574C40C49D2DCE56FF803601E1752BE3824F94D0D66C1C5FDADCC9670BFC85C422811D27F789CABBF 20160321132428 2 6 100 8191 2 D8320CDE33443FD11E472910A82D580EF614A690CF5313E998A695702508351835AF6D1DF2FA7AF2F1B234CB85E4174D67D9A32B8CC58DAF6DCFD555275B1D038D5EAAC00E0396BFF8A3686F1BB5DADDEB3C5F12B02358C7A1249A01CB1AA2AB3FAC5FC95CB7D16A38DBCD11804212872394D9A2E2F2797A3062AC5AF0C0C57F5ABEF3608546608EC08F197CE2CCF0490875BE4BCF1BD35358AF5694217F2E3DE713800F3C4071622FDBAD20CAEBE2BA60C80DF012DA576EE24A753749C0BAD8707A2382B6E909FF0B8F4A304EEDB1BF04CA0747166981279FE69248AF0DD177702DA2DC709E301D7D6FE985A7D3F7A1678A9BEF306D6036F143806563C42ADFFD8D70595F0C60BA39F0D392CE7EF7CA57547DB2E35B0464FEC6F59F6095F93BD0A241589CAEE15E2226873D31876900E534999F1D2E23E7239FF679377580065A861D3E29FA7215979BDE039ED1FFED26CC2F5541C5CD907E81434EED0479D8737262CCB2807A70504088F23E72A3D949F37C2C8E957DC2FE64BB9CE028013270F42E022BA671F1670EBD20413453A3CF19F53A1A6BDE5D744E39BBF9377384AAF0FBAF475DD1067A2906244CB87F919159DDC71256A251F1BBA789B18D97602C9C1254A4443849C16E0CE2A7A0B6AA6F117788A92C1CB3F60E2C8E539840E3AF49B9248D3E1CAACB08B43146F07CC53D2573086ED062D108C9AC924F58265CCEF3731D39FE5D4F983EADD0E9F9D8B68D953AA9342B8604AFE7916E544D88870F2ED0AFC2CD0C47DD1E5F361004D97B5108D13CD127DEC8609FA2C65FF1714FD45F3B2B3809BAC06DFCA198B71B3929E2A7B62538E5B1B8B5024D8BB78438883911A6FCA870DB16F8F2DA46D9C611F785428A356B40C07B2B8A72E157E3497DE2982AAAE4D2D9F4368469A7AD4061AEE188DA4317D826721B9F9B1A361FECF0C725E0AB6F17C147D2C62A4D11989DB1503F85763FA3E4A49BAB6BDD05C95199158D421B115F40B124EE448803E07496DE7C2682D4AF433662978CFDCFAC88C9100C46CC16929A10E3082BCAD4444D59FE57717FB4BE8DE45F4D84716D204AC97CBA5A7824765636C571AD6780AAA7510E832EECC54D571A780F90BC6A1B54DE8CC83ECB797A9065CC9807CC99DD7638AFC500D05FD2EDEB795227CAA37EBBC04A37DF07762E0319F27B523282D11DEFD85A1DBA40C87EA1EA4D1B9B2A2FC34F9F5395AE51E3A994FE25C680022E5ABD19D11703C2CB6EEE1780F76FEA8601FAE9E27BC16F832BC16776609DC2B0E3D605E635258A95907A148D583B44E202BA4A48211DA3358B7B391B6F3AD0F84D9D7F97DFFA9D819C3D316A59173E8CA970240349A89E09F0A9B1A4B4C6FFCDD878A977BC9EB254318574C40C49D2DCE56FF803601E1752BE3824F94D0D66C1C5FDADCC9670BFC85C422811D27F8FC5A85B 20160321160901 2 6 100 8191 5 D8320CDE33443FD11E472910A82D580EF614A690CF5313E998A695702508351835AF6D1DF2FA7AF2F1B234CB85E4174D67D9A32B8CC58DAF6DCFD555275B1D038D5EAAC00E0396BFF8A3686F1BB5DADDEB3C5F12B02358C7A1249A01CB1AA2AB3FAC5FC95CB7D16A38DBCD11804212872394D9A2E2F2797A3062AC5AF0C0C57F5ABEF3608546608EC08F197CE2CCF0490875BE4BCF1BD35358AF5694217F2E3DE713800F3C4071622FDBAD20CAEBE2BA60C80DF012DA576EE24A753749C0BAD8707A2382B6E909FF0B8F4A304EEDB1BF04CA0747166981279FE69248AF0DD177702DA2DC709E301D7D6FE985A7D3F7A1678A9BEF306D6036F143806563C42ADFFD8D70595F0C60BA39F0D392CE7EF7CA57547DB2E35B0464FEC6F59F6095F93BD0A241589CAEE15E2226873D31876900E534999F1D2E23E7239FF679377580065A861D3E29FA7215979BDE039ED1FFED26CC2F5541C5CD907E81434EED0479D8737262CCB2807A70504088F23E72A3D949F37C2C8E957DC2FE64BB9CE028013270F42E022BA671F1670EBD20413453A3CF19F53A1A6BDE5D744E39BBF9377384AAF0FBAF475DD1067A2906244CB87F919159DDC71256A251F1BBA789B18D97602C9C1254A4443849C16E0CE2A7A0B6AA6F117788A92C1CB3F60E2C8E539840E3AF49B9248D3E1CAACB08B43146F07CC53D2573086ED062D108C9AC924F58265CCEF3731D39FE5D4F983EADD0E9F9D8B68D953AA9342B8604AFE7916E544D88870F2ED0AFC2CD0C47DD1E5F361004D97B5108D13CD127DEC8609FA2C65FF1714FD45F3B2B3809BAC06DFCA198B71B3929E2A7B62538E5B1B8B5024D8BB78438883911A6FCA870DB16F8F2DA46D9C611F785428A356B40C07B2B8A72E157E3497DE2982AAAE4D2D9F4368469A7AD4061AEE188DA4317D826721B9F9B1A361FECF0C725E0AB6F17C147D2C62A4D11989DB1503F85763FA3E4A49BAB6BDD05C95199158D421B115F40B124EE448803E07496DE7C2682D4AF433662978CFDCFAC88C9100C46CC16929A10E3082BCAD4444D59FE57717FB4BE8DE45F4D84716D204AC97CBA5A7824765636C571AD6780AAA7510E832EECC54D571A780F90BC6A1B54DE8CC83ECB797A9065CC9807CC99DD7638AFC500D05FD2EDEB795227CAA37EBBC04A37DF07762E0319F27B523282D11DEFD85A1DBA40C87EA1EA4D1B9B2A2FC34F9F5395AE51E3A994FE25C680022E5ABD19D11703C2CB6EEE1780F76FEA8601FAE9E27BC16F832BC16776609DC2B0E3D605E635258A95907A148D583B44E202BA4A48211DA3358B7B391B6F3AD0F84D9D7F97DFFA9D819C3D316A59173E8CA970240349A89E09F0A9B1A4B4C6FFCDD878A977BC9EB254318574C40C49D2DCE56FF803601E1752BE3824F94D0D66C1C5FDADCC9670BFC85C422811D27F91961EDF 20160321181311 2 6 100 8191 2 D8320CDE33443FD11E472910A82D580EF614A690CF5313E998A695702508351835AF6D1DF2FA7AF2F1B234CB85E4174D67D9A32B8CC58DAF6DCFD555275B1D038D5EAAC00E0396BFF8A3686F1BB5DADDEB3C5F12B02358C7A1249A01CB1AA2AB3FAC5FC95CB7D16A38DBCD11804212872394D9A2E2F2797A3062AC5AF0C0C57F5ABEF3608546608EC08F197CE2CCF0490875BE4BCF1BD35358AF5694217F2E3DE713800F3C4071622FDBAD20CAEBE2BA60C80DF012DA576EE24A753749C0BAD8707A2382B6E909FF0B8F4A304EEDB1BF04CA0747166981279FE69248AF0DD177702DA2DC709E301D7D6FE985A7D3F7A1678A9BEF306D6036F143806563C42ADFFD8D70595F0C60BA39F0D392CE7EF7CA57547DB2E35B0464FEC6F59F6095F93BD0A241589CAEE15E2226873D31876900E534999F1D2E23E7239FF679377580065A861D3E29FA7215979BDE039ED1FFED26CC2F5541C5CD907E81434EED0479D8737262CCB2807A70504088F23E72A3D949F37C2C8E957DC2FE64BB9CE028013270F42E022BA671F1670EBD20413453A3CF19F53A1A6BDE5D744E39BBF9377384AAF0FBAF475DD1067A2906244CB87F919159DDC71256A251F1BBA789B18D97602C9C1254A4443849C16E0CE2A7A0B6AA6F117788A92C1CB3F60E2C8E539840E3AF49B9248D3E1CAACB08B43146F07CC53D2573086ED062D108C9AC924F58265CCEF3731D39FE5D4F983EADD0E9F9D8B68D953AA9342B8604AFE7916E544D88870F2ED0AFC2CD0C47DD1E5F361004D97B5108D13CD127DEC8609FA2C65FF1714FD45F3B2B3809BAC06DFCA198B71B3929E2A7B62538E5B1B8B5024D8BB78438883911A6FCA870DB16F8F2DA46D9C611F785428A356B40C07B2B8A72E157E3497DE2982AAAE4D2D9F4368469A7AD4061AEE188DA4317D826721B9F9B1A361FECF0C725E0AB6F17C147D2C62A4D11989DB1503F85763FA3E4A49BAB6BDD05C95199158D421B115F40B124EE448803E07496DE7C2682D4AF433662978CFDCFAC88C9100C46CC16929A10E3082BCAD4444D59FE57717FB4BE8DE45F4D84716D204AC97CBA5A7824765636C571AD6780AAA7510E832EECC54D571A780F90BC6A1B54DE8CC83ECB797A9065CC9807CC99DD7638AFC500D05FD2EDEB795227CAA37EBBC04A37DF07762E0319F27B523282D11DEFD85A1DBA40C87EA1EA4D1B9B2A2FC34F9F5395AE51E3A994FE25C680022E5ABD19D11703C2CB6EEE1780F76FEA8601FAE9E27BC16F832BC16776609DC2B0E3D605E635258A95907A148D583B44E202BA4A48211DA3358B7B391B6F3AD0F84D9D7F97DFFA9D819C3D316A59173E8CA970240349A89E09F0A9B1A4B4C6FFCDD878A977BC9EB254318574C40C49D2DCE56FF803601E1752BE3824F94D0D66C1C5FDADCC9670BFC85C422811D27F92F8EDBB 20160321224946 2 6 100 8191 5 D8320CDE33443FD11E472910A82D580EF614A690CF5313E998A695702508351835AF6D1DF2FA7AF2F1B234CB85E4174D67D9A32B8CC58DAF6DCFD555275B1D038D5EAAC00E0396BFF8A3686F1BB5DADDEB3C5F12B02358C7A1249A01CB1AA2AB3FAC5FC95CB7D16A38DBCD11804212872394D9A2E2F2797A3062AC5AF0C0C57F5ABEF3608546608EC08F197CE2CCF0490875BE4BCF1BD35358AF5694217F2E3DE713800F3C4071622FDBAD20CAEBE2BA60C80DF012DA576EE24A753749C0BAD8707A2382B6E909FF0B8F4A304EEDB1BF04CA0747166981279FE69248AF0DD177702DA2DC709E301D7D6FE985A7D3F7A1678A9BEF306D6036F143806563C42ADFFD8D70595F0C60BA39F0D392CE7EF7CA57547DB2E35B0464FEC6F59F6095F93BD0A241589CAEE15E2226873D31876900E534999F1D2E23E7239FF679377580065A861D3E29FA7215979BDE039ED1FFED26CC2F5541C5CD907E81434EED0479D8737262CCB2807A70504088F23E72A3D949F37C2C8E957DC2FE64BB9CE028013270F42E022BA671F1670EBD20413453A3CF19F53A1A6BDE5D744E39BBF9377384AAF0FBAF475DD1067A2906244CB87F919159DDC71256A251F1BBA789B18D97602C9C1254A4443849C16E0CE2A7A0B6AA6F117788A92C1CB3F60E2C8E539840E3AF49B9248D3E1CAACB08B43146F07CC53D2573086ED062D108C9AC924F58265CCEF3731D39FE5D4F983EADD0E9F9D8B68D953AA9342B8604AFE7916E544D88870F2ED0AFC2CD0C47DD1E5F361004D97B5108D13CD127DEC8609FA2C65FF1714FD45F3B2B3809BAC06DFCA198B71B3929E2A7B62538E5B1B8B5024D8BB78438883911A6FCA870DB16F8F2DA46D9C611F785428A356B40C07B2B8A72E157E3497DE2982AAAE4D2D9F4368469A7AD4061AEE188DA4317D826721B9F9B1A361FECF0C725E0AB6F17C147D2C62A4D11989DB1503F85763FA3E4A49BAB6BDD05C95199158D421B115F40B124EE448803E07496DE7C2682D4AF433662978CFDCFAC88C9100C46CC16929A10E3082BCAD4444D59FE57717FB4BE8DE45F4D84716D204AC97CBA5A7824765636C571AD6780AAA7510E832EECC54D571A780F90BC6A1B54DE8CC83ECB797A9065CC9807CC99DD7638AFC500D05FD2EDEB795227CAA37EBBC04A37DF07762E0319F27B523282D11DEFD85A1DBA40C87EA1EA4D1B9B2A2FC34F9F5395AE51E3A994FE25C680022E5ABD19D11703C2CB6EEE1780F76FEA8601FAE9E27BC16F832BC16776609DC2B0E3D605E635258A95907A148D583B44E202BA4A48211DA3358B7B391B6F3AD0F84D9D7F97DFFA9D819C3D316A59173E8CA970240349A89E09F0A9B1A4B4C6FFCDD878A977BC9EB254318574C40C49D2DCE56FF803601E1752BE3824F94D0D66C1C5FDADCC9670BFC85C422811D27F9615911F 20160321230806 2 6 100 8191 2 D8320CDE33443FD11E472910A82D580EF614A690CF5313E998A695702508351835AF6D1DF2FA7AF2F1B234CB85E4174D67D9A32B8CC58DAF6DCFD555275B1D038D5EAAC00E0396BFF8A3686F1BB5DADDEB3C5F12B02358C7A1249A01CB1AA2AB3FAC5FC95CB7D16A38DBCD11804212872394D9A2E2F2797A3062AC5AF0C0C57F5ABEF3608546608EC08F197CE2CCF0490875BE4BCF1BD35358AF5694217F2E3DE713800F3C4071622FDBAD20CAEBE2BA60C80DF012DA576EE24A753749C0BAD8707A2382B6E909FF0B8F4A304EEDB1BF04CA0747166981279FE69248AF0DD177702DA2DC709E301D7D6FE985A7D3F7A1678A9BEF306D6036F143806563C42ADFFD8D70595F0C60BA39F0D392CE7EF7CA57547DB2E35B0464FEC6F59F6095F93BD0A241589CAEE15E2226873D31876900E534999F1D2E23E7239FF679377580065A861D3E29FA7215979BDE039ED1FFED26CC2F5541C5CD907E81434EED0479D8737262CCB2807A70504088F23E72A3D949F37C2C8E957DC2FE64BB9CE028013270F42E022BA671F1670EBD20413453A3CF19F53A1A6BDE5D744E39BBF9377384AAF0FBAF475DD1067A2906244CB87F919159DDC71256A251F1BBA789B18D97602C9C1254A4443849C16E0CE2A7A0B6AA6F117788A92C1CB3F60E2C8E539840E3AF49B9248D3E1CAACB08B43146F07CC53D2573086ED062D108C9AC924F58265CCEF3731D39FE5D4F983EADD0E9F9D8B68D953AA9342B8604AFE7916E544D88870F2ED0AFC2CD0C47DD1E5F361004D97B5108D13CD127DEC8609FA2C65FF1714FD45F3B2B3809BAC06DFCA198B71B3929E2A7B62538E5B1B8B5024D8BB78438883911A6FCA870DB16F8F2DA46D9C611F785428A356B40C07B2B8A72E157E3497DE2982AAAE4D2D9F4368469A7AD4061AEE188DA4317D826721B9F9B1A361FECF0C725E0AB6F17C147D2C62A4D11989DB1503F85763FA3E4A49BAB6BDD05C95199158D421B115F40B124EE448803E07496DE7C2682D4AF433662978CFDCFAC88C9100C46CC16929A10E3082BCAD4444D59FE57717FB4BE8DE45F4D84716D204AC97CBA5A7824765636C571AD6780AAA7510E832EECC54D571A780F90BC6A1B54DE8CC83ECB797A9065CC9807CC99DD7638AFC500D05FD2EDEB795227CAA37EBBC04A37DF07762E0319F27B523282D11DEFD85A1DBA40C87EA1EA4D1B9B2A2FC34F9F5395AE51E3A994FE25C680022E5ABD19D11703C2CB6EEE1780F76FEA8601FAE9E27BC16F832BC16776609DC2B0E3D605E635258A95907A148D583B44E202BA4A48211DA3358B7B391B6F3AD0F84D9D7F97DFFA9D819C3D316A59173E8CA970240349A89E09F0A9B1A4B4C6FFCDD878A977BC9EB254318574C40C49D2DCE56FF803601E1752BE3824F94D0D66C1C5FDADCC9670BFC85C422811D27F963FE5D3 20160322064427 2 6 100 8191 2 D8320CDE33443FD11E472910A82D580EF614A690CF5313E998A695702508351835AF6D1DF2FA7AF2F1B234CB85E4174D67D9A32B8CC58DAF6DCFD555275B1D038D5EAAC00E0396BFF8A3686F1BB5DADDEB3C5F12B02358C7A1249A01CB1AA2AB3FAC5FC95CB7D16A38DBCD11804212872394D9A2E2F2797A3062AC5AF0C0C57F5ABEF3608546608EC08F197CE2CCF0490875BE4BCF1BD35358AF5694217F2E3DE713800F3C4071622FDBAD20CAEBE2BA60C80DF012DA576EE24A753749C0BAD8707A2382B6E909FF0B8F4A304EEDB1BF04CA0747166981279FE69248AF0DD177702DA2DC709E301D7D6FE985A7D3F7A1678A9BEF306D6036F143806563C42ADFFD8D70595F0C60BA39F0D392CE7EF7CA57547DB2E35B0464FEC6F59F6095F93BD0A241589CAEE15E2226873D31876900E534999F1D2E23E7239FF679377580065A861D3E29FA7215979BDE039ED1FFED26CC2F5541C5CD907E81434EED0479D8737262CCB2807A70504088F23E72A3D949F37C2C8E957DC2FE64BB9CE028013270F42E022BA671F1670EBD20413453A3CF19F53A1A6BDE5D744E39BBF9377384AAF0FBAF475DD1067A2906244CB87F919159DDC71256A251F1BBA789B18D97602C9C1254A4443849C16E0CE2A7A0B6AA6F117788A92C1CB3F60E2C8E539840E3AF49B9248D3E1CAACB08B43146F07CC53D2573086ED062D108C9AC924F58265CCEF3731D39FE5D4F983EADD0E9F9D8B68D953AA9342B8604AFE7916E544D88870F2ED0AFC2CD0C47DD1E5F361004D97B5108D13CD127DEC8609FA2C65FF1714FD45F3B2B3809BAC06DFCA198B71B3929E2A7B62538E5B1B8B5024D8BB78438883911A6FCA870DB16F8F2DA46D9C611F785428A356B40C07B2B8A72E157E3497DE2982AAAE4D2D9F4368469A7AD4061AEE188DA4317D826721B9F9B1A361FECF0C725E0AB6F17C147D2C62A4D11989DB1503F85763FA3E4A49BAB6BDD05C95199158D421B115F40B124EE448803E07496DE7C2682D4AF433662978CFDCFAC88C9100C46CC16929A10E3082BCAD4444D59FE57717FB4BE8DE45F4D84716D204AC97CBA5A7824765636C571AD6780AAA7510E832EECC54D571A780F90BC6A1B54DE8CC83ECB797A9065CC9807CC99DD7638AFC500D05FD2EDEB795227CAA37EBBC04A37DF07762E0319F27B523282D11DEFD85A1DBA40C87EA1EA4D1B9B2A2FC34F9F5395AE51E3A994FE25C680022E5ABD19D11703C2CB6EEE1780F76FEA8601FAE9E27BC16F832BC16776609DC2B0E3D605E635258A95907A148D583B44E202BA4A48211DA3358B7B391B6F3AD0F84D9D7F97DFFA9D819C3D316A59173E8CA970240349A89E09F0A9B1A4B4C6FFCDD878A977BC9EB254318574C40C49D2DCE56FF803601E1752BE3824F94D0D66C1C5FDADCC9670BFC85C422811D27F9B60592B 20160322090339 2 6 100 8191 2 D8320CDE33443FD11E472910A82D580EF614A690CF5313E998A695702508351835AF6D1DF2FA7AF2F1B234CB85E4174D67D9A32B8CC58DAF6DCFD555275B1D038D5EAAC00E0396BFF8A3686F1BB5DADDEB3C5F12B02358C7A1249A01CB1AA2AB3FAC5FC95CB7D16A38DBCD11804212872394D9A2E2F2797A3062AC5AF0C0C57F5ABEF3608546608EC08F197CE2CCF0490875BE4BCF1BD35358AF5694217F2E3DE713800F3C4071622FDBAD20CAEBE2BA60C80DF012DA576EE24A753749C0BAD8707A2382B6E909FF0B8F4A304EEDB1BF04CA0747166981279FE69248AF0DD177702DA2DC709E301D7D6FE985A7D3F7A1678A9BEF306D6036F143806563C42ADFFD8D70595F0C60BA39F0D392CE7EF7CA57547DB2E35B0464FEC6F59F6095F93BD0A241589CAEE15E2226873D31876900E534999F1D2E23E7239FF679377580065A861D3E29FA7215979BDE039ED1FFED26CC2F5541C5CD907E81434EED0479D8737262CCB2807A70504088F23E72A3D949F37C2C8E957DC2FE64BB9CE028013270F42E022BA671F1670EBD20413453A3CF19F53A1A6BDE5D744E39BBF9377384AAF0FBAF475DD1067A2906244CB87F919159DDC71256A251F1BBA789B18D97602C9C1254A4443849C16E0CE2A7A0B6AA6F117788A92C1CB3F60E2C8E539840E3AF49B9248D3E1CAACB08B43146F07CC53D2573086ED062D108C9AC924F58265CCEF3731D39FE5D4F983EADD0E9F9D8B68D953AA9342B8604AFE7916E544D88870F2ED0AFC2CD0C47DD1E5F361004D97B5108D13CD127DEC8609FA2C65FF1714FD45F3B2B3809BAC06DFCA198B71B3929E2A7B62538E5B1B8B5024D8BB78438883911A6FCA870DB16F8F2DA46D9C611F785428A356B40C07B2B8A72E157E3497DE2982AAAE4D2D9F4368469A7AD4061AEE188DA4317D826721B9F9B1A361FECF0C725E0AB6F17C147D2C62A4D11989DB1503F85763FA3E4A49BAB6BDD05C95199158D421B115F40B124EE448803E07496DE7C2682D4AF433662978CFDCFAC88C9100C46CC16929A10E3082BCAD4444D59FE57717FB4BE8DE45F4D84716D204AC97CBA5A7824765636C571AD6780AAA7510E832EECC54D571A780F90BC6A1B54DE8CC83ECB797A9065CC9807CC99DD7638AFC500D05FD2EDEB795227CAA37EBBC04A37DF07762E0319F27B523282D11DEFD85A1DBA40C87EA1EA4D1B9B2A2FC34F9F5395AE51E3A994FE25C680022E5ABD19D11703C2CB6EEE1780F76FEA8601FAE9E27BC16F832BC16776609DC2B0E3D605E635258A95907A148D583B44E202BA4A48211DA3358B7B391B6F3AD0F84D9D7F97DFFA9D819C3D316A59173E8CA970240349A89E09F0A9B1A4B4C6FFCDD878A977BC9EB254318574C40C49D2DCE56FF803601E1752BE3824F94D0D66C1C5FDADCC9670BFC85C422811D27F9CE9AD5B 20160322103202 2 6 100 8191 2 D8320CDE33443FD11E472910A82D580EF614A690CF5313E998A695702508351835AF6D1DF2FA7AF2F1B234CB85E4174D67D9A32B8CC58DAF6DCFD555275B1D038D5EAAC00E0396BFF8A3686F1BB5DADDEB3C5F12B02358C7A1249A01CB1AA2AB3FAC5FC95CB7D16A38DBCD11804212872394D9A2E2F2797A3062AC5AF0C0C57F5ABEF3608546608EC08F197CE2CCF0490875BE4BCF1BD35358AF5694217F2E3DE713800F3C4071622FDBAD20CAEBE2BA60C80DF012DA576EE24A753749C0BAD8707A2382B6E909FF0B8F4A304EEDB1BF04CA0747166981279FE69248AF0DD177702DA2DC709E301D7D6FE985A7D3F7A1678A9BEF306D6036F143806563C42ADFFD8D70595F0C60BA39F0D392CE7EF7CA57547DB2E35B0464FEC6F59F6095F93BD0A241589CAEE15E2226873D31876900E534999F1D2E23E7239FF679377580065A861D3E29FA7215979BDE039ED1FFED26CC2F5541C5CD907E81434EED0479D8737262CCB2807A70504088F23E72A3D949F37C2C8E957DC2FE64BB9CE028013270F42E022BA671F1670EBD20413453A3CF19F53A1A6BDE5D744E39BBF9377384AAF0FBAF475DD1067A2906244CB87F919159DDC71256A251F1BBA789B18D97602C9C1254A4443849C16E0CE2A7A0B6AA6F117788A92C1CB3F60E2C8E539840E3AF49B9248D3E1CAACB08B43146F07CC53D2573086ED062D108C9AC924F58265CCEF3731D39FE5D4F983EADD0E9F9D8B68D953AA9342B8604AFE7916E544D88870F2ED0AFC2CD0C47DD1E5F361004D97B5108D13CD127DEC8609FA2C65FF1714FD45F3B2B3809BAC06DFCA198B71B3929E2A7B62538E5B1B8B5024D8BB78438883911A6FCA870DB16F8F2DA46D9C611F785428A356B40C07B2B8A72E157E3497DE2982AAAE4D2D9F4368469A7AD4061AEE188DA4317D826721B9F9B1A361FECF0C725E0AB6F17C147D2C62A4D11989DB1503F85763FA3E4A49BAB6BDD05C95199158D421B115F40B124EE448803E07496DE7C2682D4AF433662978CFDCFAC88C9100C46CC16929A10E3082BCAD4444D59FE57717FB4BE8DE45F4D84716D204AC97CBA5A7824765636C571AD6780AAA7510E832EECC54D571A780F90BC6A1B54DE8CC83ECB797A9065CC9807CC99DD7638AFC500D05FD2EDEB795227CAA37EBBC04A37DF07762E0319F27B523282D11DEFD85A1DBA40C87EA1EA4D1B9B2A2FC34F9F5395AE51E3A994FE25C680022E5ABD19D11703C2CB6EEE1780F76FEA8601FAE9E27BC16F832BC16776609DC2B0E3D605E635258A95907A148D583B44E202BA4A48211DA3358B7B391B6F3AD0F84D9D7F97DFFA9D819C3D316A59173E8CA970240349A89E09F0A9B1A4B4C6FFCDD878A977BC9EB254318574C40C49D2DCE56FF803601E1752BE3824F94D0D66C1C5FDADCC9670BFC85C422811D27F9DDFC97B 20160322120630 2 6 100 8191 5 D8320CDE33443FD11E472910A82D580EF614A690CF5313E998A695702508351835AF6D1DF2FA7AF2F1B234CB85E4174D67D9A32B8CC58DAF6DCFD555275B1D038D5EAAC00E0396BFF8A3686F1BB5DADDEB3C5F12B02358C7A1249A01CB1AA2AB3FAC5FC95CB7D16A38DBCD11804212872394D9A2E2F2797A3062AC5AF0C0C57F5ABEF3608546608EC08F197CE2CCF0490875BE4BCF1BD35358AF5694217F2E3DE713800F3C4071622FDBAD20CAEBE2BA60C80DF012DA576EE24A753749C0BAD8707A2382B6E909FF0B8F4A304EEDB1BF04CA0747166981279FE69248AF0DD177702DA2DC709E301D7D6FE985A7D3F7A1678A9BEF306D6036F143806563C42ADFFD8D70595F0C60BA39F0D392CE7EF7CA57547DB2E35B0464FEC6F59F6095F93BD0A241589CAEE15E2226873D31876900E534999F1D2E23E7239FF679377580065A861D3E29FA7215979BDE039ED1FFED26CC2F5541C5CD907E81434EED0479D8737262CCB2807A70504088F23E72A3D949F37C2C8E957DC2FE64BB9CE028013270F42E022BA671F1670EBD20413453A3CF19F53A1A6BDE5D744E39BBF9377384AAF0FBAF475DD1067A2906244CB87F919159DDC71256A251F1BBA789B18D97602C9C1254A4443849C16E0CE2A7A0B6AA6F117788A92C1CB3F60E2C8E539840E3AF49B9248D3E1CAACB08B43146F07CC53D2573086ED062D108C9AC924F58265CCEF3731D39FE5D4F983EADD0E9F9D8B68D953AA9342B8604AFE7916E544D88870F2ED0AFC2CD0C47DD1E5F361004D97B5108D13CD127DEC8609FA2C65FF1714FD45F3B2B3809BAC06DFCA198B71B3929E2A7B62538E5B1B8B5024D8BB78438883911A6FCA870DB16F8F2DA46D9C611F785428A356B40C07B2B8A72E157E3497DE2982AAAE4D2D9F4368469A7AD4061AEE188DA4317D826721B9F9B1A361FECF0C725E0AB6F17C147D2C62A4D11989DB1503F85763FA3E4A49BAB6BDD05C95199158D421B115F40B124EE448803E07496DE7C2682D4AF433662978CFDCFAC88C9100C46CC16929A10E3082BCAD4444D59FE57717FB4BE8DE45F4D84716D204AC97CBA5A7824765636C571AD6780AAA7510E832EECC54D571A780F90BC6A1B54DE8CC83ECB797A9065CC9807CC99DD7638AFC500D05FD2EDEB795227CAA37EBBC04A37DF07762E0319F27B523282D11DEFD85A1DBA40C87EA1EA4D1B9B2A2FC34F9F5395AE51E3A994FE25C680022E5ABD19D11703C2CB6EEE1780F76FEA8601FAE9E27BC16F832BC16776609DC2B0E3D605E635258A95907A148D583B44E202BA4A48211DA3358B7B391B6F3AD0F84D9D7F97DFFA9D819C3D316A59173E8CA970240349A89E09F0A9B1A4B4C6FFCDD878A977BC9EB254318574C40C49D2DCE56FF803601E1752BE3824F94D0D66C1C5FDADCC9670BFC85C422811D27F9EE9F43F 20160322130823 2 6 100 8191 2 D8320CDE33443FD11E472910A82D580EF614A690CF5313E998A695702508351835AF6D1DF2FA7AF2F1B234CB85E4174D67D9A32B8CC58DAF6DCFD555275B1D038D5EAAC00E0396BFF8A3686F1BB5DADDEB3C5F12B02358C7A1249A01CB1AA2AB3FAC5FC95CB7D16A38DBCD11804212872394D9A2E2F2797A3062AC5AF0C0C57F5ABEF3608546608EC08F197CE2CCF0490875BE4BCF1BD35358AF5694217F2E3DE713800F3C4071622FDBAD20CAEBE2BA60C80DF012DA576EE24A753749C0BAD8707A2382B6E909FF0B8F4A304EEDB1BF04CA0747166981279FE69248AF0DD177702DA2DC709E301D7D6FE985A7D3F7A1678A9BEF306D6036F143806563C42ADFFD8D70595F0C60BA39F0D392CE7EF7CA57547DB2E35B0464FEC6F59F6095F93BD0A241589CAEE15E2226873D31876900E534999F1D2E23E7239FF679377580065A861D3E29FA7215979BDE039ED1FFED26CC2F5541C5CD907E81434EED0479D8737262CCB2807A70504088F23E72A3D949F37C2C8E957DC2FE64BB9CE028013270F42E022BA671F1670EBD20413453A3CF19F53A1A6BDE5D744E39BBF9377384AAF0FBAF475DD1067A2906244CB87F919159DDC71256A251F1BBA789B18D97602C9C1254A4443849C16E0CE2A7A0B6AA6F117788A92C1CB3F60E2C8E539840E3AF49B9248D3E1CAACB08B43146F07CC53D2573086ED062D108C9AC924F58265CCEF3731D39FE5D4F983EADD0E9F9D8B68D953AA9342B8604AFE7916E544D88870F2ED0AFC2CD0C47DD1E5F361004D97B5108D13CD127DEC8609FA2C65FF1714FD45F3B2B3809BAC06DFCA198B71B3929E2A7B62538E5B1B8B5024D8BB78438883911A6FCA870DB16F8F2DA46D9C611F785428A356B40C07B2B8A72E157E3497DE2982AAAE4D2D9F4368469A7AD4061AEE188DA4317D826721B9F9B1A361FECF0C725E0AB6F17C147D2C62A4D11989DB1503F85763FA3E4A49BAB6BDD05C95199158D421B115F40B124EE448803E07496DE7C2682D4AF433662978CFDCFAC88C9100C46CC16929A10E3082BCAD4444D59FE57717FB4BE8DE45F4D84716D204AC97CBA5A7824765636C571AD6780AAA7510E832EECC54D571A780F90BC6A1B54DE8CC83ECB797A9065CC9807CC99DD7638AFC500D05FD2EDEB795227CAA37EBBC04A37DF07762E0319F27B523282D11DEFD85A1DBA40C87EA1EA4D1B9B2A2FC34F9F5395AE51E3A994FE25C680022E5ABD19D11703C2CB6EEE1780F76FEA8601FAE9E27BC16F832BC16776609DC2B0E3D605E635258A95907A148D583B44E202BA4A48211DA3358B7B391B6F3AD0F84D9D7F97DFFA9D819C3D316A59173E8CA970240349A89E09F0A9B1A4B4C6FFCDD878A977BC9EB254318574C40C49D2DCE56FF803601E1752BE3824F94D0D66C1C5FDADCC9670BFC85C422811D27F9F927B4B 20160322151455 2 6 100 8191 2 D8320CDE33443FD11E472910A82D580EF614A690CF5313E998A695702508351835AF6D1DF2FA7AF2F1B234CB85E4174D67D9A32B8CC58DAF6DCFD555275B1D038D5EAAC00E0396BFF8A3686F1BB5DADDEB3C5F12B02358C7A1249A01CB1AA2AB3FAC5FC95CB7D16A38DBCD11804212872394D9A2E2F2797A3062AC5AF0C0C57F5ABEF3608546608EC08F197CE2CCF0490875BE4BCF1BD35358AF5694217F2E3DE713800F3C4071622FDBAD20CAEBE2BA60C80DF012DA576EE24A753749C0BAD8707A2382B6E909FF0B8F4A304EEDB1BF04CA0747166981279FE69248AF0DD177702DA2DC709E301D7D6FE985A7D3F7A1678A9BEF306D6036F143806563C42ADFFD8D70595F0C60BA39F0D392CE7EF7CA57547DB2E35B0464FEC6F59F6095F93BD0A241589CAEE15E2226873D31876900E534999F1D2E23E7239FF679377580065A861D3E29FA7215979BDE039ED1FFED26CC2F5541C5CD907E81434EED0479D8737262CCB2807A70504088F23E72A3D949F37C2C8E957DC2FE64BB9CE028013270F42E022BA671F1670EBD20413453A3CF19F53A1A6BDE5D744E39BBF9377384AAF0FBAF475DD1067A2906244CB87F919159DDC71256A251F1BBA789B18D97602C9C1254A4443849C16E0CE2A7A0B6AA6F117788A92C1CB3F60E2C8E539840E3AF49B9248D3E1CAACB08B43146F07CC53D2573086ED062D108C9AC924F58265CCEF3731D39FE5D4F983EADD0E9F9D8B68D953AA9342B8604AFE7916E544D88870F2ED0AFC2CD0C47DD1E5F361004D97B5108D13CD127DEC8609FA2C65FF1714FD45F3B2B3809BAC06DFCA198B71B3929E2A7B62538E5B1B8B5024D8BB78438883911A6FCA870DB16F8F2DA46D9C611F785428A356B40C07B2B8A72E157E3497DE2982AAAE4D2D9F4368469A7AD4061AEE188DA4317D826721B9F9B1A361FECF0C725E0AB6F17C147D2C62A4D11989DB1503F85763FA3E4A49BAB6BDD05C95199158D421B115F40B124EE448803E07496DE7C2682D4AF433662978CFDCFAC88C9100C46CC16929A10E3082BCAD4444D59FE57717FB4BE8DE45F4D84716D204AC97CBA5A7824765636C571AD6780AAA7510E832EECC54D571A780F90BC6A1B54DE8CC83ECB797A9065CC9807CC99DD7638AFC500D05FD2EDEB795227CAA37EBBC04A37DF07762E0319F27B523282D11DEFD85A1DBA40C87EA1EA4D1B9B2A2FC34F9F5395AE51E3A994FE25C680022E5ABD19D11703C2CB6EEE1780F76FEA8601FAE9E27BC16F832BC16776609DC2B0E3D605E635258A95907A148D583B44E202BA4A48211DA3358B7B391B6F3AD0F84D9D7F97DFFA9D819C3D316A59173E8CA970240349A89E09F0A9B1A4B4C6FFCDD878A977BC9EB254318574C40C49D2DCE56FF803601E1752BE3824F94D0D66C1C5FDADCC9670BFC85C422811D27FA0F6C9EB 20160322151924 2 6 100 8191 2 D8320CDE33443FD11E472910A82D580EF614A690CF5313E998A695702508351835AF6D1DF2FA7AF2F1B234CB85E4174D67D9A32B8CC58DAF6DCFD555275B1D038D5EAAC00E0396BFF8A3686F1BB5DADDEB3C5F12B02358C7A1249A01CB1AA2AB3FAC5FC95CB7D16A38DBCD11804212872394D9A2E2F2797A3062AC5AF0C0C57F5ABEF3608546608EC08F197CE2CCF0490875BE4BCF1BD35358AF5694217F2E3DE713800F3C4071622FDBAD20CAEBE2BA60C80DF012DA576EE24A753749C0BAD8707A2382B6E909FF0B8F4A304EEDB1BF04CA0747166981279FE69248AF0DD177702DA2DC709E301D7D6FE985A7D3F7A1678A9BEF306D6036F143806563C42ADFFD8D70595F0C60BA39F0D392CE7EF7CA57547DB2E35B0464FEC6F59F6095F93BD0A241589CAEE15E2226873D31876900E534999F1D2E23E7239FF679377580065A861D3E29FA7215979BDE039ED1FFED26CC2F5541C5CD907E81434EED0479D8737262CCB2807A70504088F23E72A3D949F37C2C8E957DC2FE64BB9CE028013270F42E022BA671F1670EBD20413453A3CF19F53A1A6BDE5D744E39BBF9377384AAF0FBAF475DD1067A2906244CB87F919159DDC71256A251F1BBA789B18D97602C9C1254A4443849C16E0CE2A7A0B6AA6F117788A92C1CB3F60E2C8E539840E3AF49B9248D3E1CAACB08B43146F07CC53D2573086ED062D108C9AC924F58265CCEF3731D39FE5D4F983EADD0E9F9D8B68D953AA9342B8604AFE7916E544D88870F2ED0AFC2CD0C47DD1E5F361004D97B5108D13CD127DEC8609FA2C65FF1714FD45F3B2B3809BAC06DFCA198B71B3929E2A7B62538E5B1B8B5024D8BB78438883911A6FCA870DB16F8F2DA46D9C611F785428A356B40C07B2B8A72E157E3497DE2982AAAE4D2D9F4368469A7AD4061AEE188DA4317D826721B9F9B1A361FECF0C725E0AB6F17C147D2C62A4D11989DB1503F85763FA3E4A49BAB6BDD05C95199158D421B115F40B124EE448803E07496DE7C2682D4AF433662978CFDCFAC88C9100C46CC16929A10E3082BCAD4444D59FE57717FB4BE8DE45F4D84716D204AC97CBA5A7824765636C571AD6780AAA7510E832EECC54D571A780F90BC6A1B54DE8CC83ECB797A9065CC9807CC99DD7638AFC500D05FD2EDEB795227CAA37EBBC04A37DF07762E0319F27B523282D11DEFD85A1DBA40C87EA1EA4D1B9B2A2FC34F9F5395AE51E3A994FE25C680022E5ABD19D11703C2CB6EEE1780F76FEA8601FAE9E27BC16F832BC16776609DC2B0E3D605E635258A95907A148D583B44E202BA4A48211DA3358B7B391B6F3AD0F84D9D7F97DFFA9D819C3D316A59173E8CA970240349A89E09F0A9B1A4B4C6FFCDD878A977BC9EB254318574C40C49D2DCE56FF803601E1752BE3824F94D0D66C1C5FDADCC9670BFC85C422811D27FA0FAAD73 20160323004347 2 6 100 8191 5 D8320CDE33443FD11E472910A82D580EF614A690CF5313E998A695702508351835AF6D1DF2FA7AF2F1B234CB85E4174D67D9A32B8CC58DAF6DCFD555275B1D038D5EAAC00E0396BFF8A3686F1BB5DADDEB3C5F12B02358C7A1249A01CB1AA2AB3FAC5FC95CB7D16A38DBCD11804212872394D9A2E2F2797A3062AC5AF0C0C57F5ABEF3608546608EC08F197CE2CCF0490875BE4BCF1BD35358AF5694217F2E3DE713800F3C4071622FDBAD20CAEBE2BA60C80DF012DA576EE24A753749C0BAD8707A2382B6E909FF0B8F4A304EEDB1BF04CA0747166981279FE69248AF0DD177702DA2DC709E301D7D6FE985A7D3F7A1678A9BEF306D6036F143806563C42ADFFD8D70595F0C60BA39F0D392CE7EF7CA57547DB2E35B0464FEC6F59F6095F93BD0A241589CAEE15E2226873D31876900E534999F1D2E23E7239FF679377580065A861D3E29FA7215979BDE039ED1FFED26CC2F5541C5CD907E81434EED0479D8737262CCB2807A70504088F23E72A3D949F37C2C8E957DC2FE64BB9CE028013270F42E022BA671F1670EBD20413453A3CF19F53A1A6BDE5D744E39BBF9377384AAF0FBAF475DD1067A2906244CB87F919159DDC71256A251F1BBA789B18D97602C9C1254A4443849C16E0CE2A7A0B6AA6F117788A92C1CB3F60E2C8E539840E3AF49B9248D3E1CAACB08B43146F07CC53D2573086ED062D108C9AC924F58265CCEF3731D39FE5D4F983EADD0E9F9D8B68D953AA9342B8604AFE7916E544D88870F2ED0AFC2CD0C47DD1E5F361004D97B5108D13CD127DEC8609FA2C65FF1714FD45F3B2B3809BAC06DFCA198B71B3929E2A7B62538E5B1B8B5024D8BB78438883911A6FCA870DB16F8F2DA46D9C611F785428A356B40C07B2B8A72E157E3497DE2982AAAE4D2D9F4368469A7AD4061AEE188DA4317D826721B9F9B1A361FECF0C725E0AB6F17C147D2C62A4D11989DB1503F85763FA3E4A49BAB6BDD05C95199158D421B115F40B124EE448803E07496DE7C2682D4AF433662978CFDCFAC88C9100C46CC16929A10E3082BCAD4444D59FE57717FB4BE8DE45F4D84716D204AC97CBA5A7824765636C571AD6780AAA7510E832EECC54D571A780F90BC6A1B54DE8CC83ECB797A9065CC9807CC99DD7638AFC500D05FD2EDEB795227CAA37EBBC04A37DF07762E0319F27B523282D11DEFD85A1DBA40C87EA1EA4D1B9B2A2FC34F9F5395AE51E3A994FE25C680022E5ABD19D11703C2CB6EEE1780F76FEA8601FAE9E27BC16F832BC16776609DC2B0E3D605E635258A95907A148D583B44E202BA4A48211DA3358B7B391B6F3AD0F84D9D7F97DFFA9D819C3D316A59173E8CA970240349A89E09F0A9B1A4B4C6FFCDD878A977BC9EB254318574C40C49D2DCE56FF803601E1752BE3824F94D0D66C1C5FDADCC9670BFC85C422811D27FA73E643F 20160323011842 2 6 100 8191 2 D8320CDE33443FD11E472910A82D580EF614A690CF5313E998A695702508351835AF6D1DF2FA7AF2F1B234CB85E4174D67D9A32B8CC58DAF6DCFD555275B1D038D5EAAC00E0396BFF8A3686F1BB5DADDEB3C5F12B02358C7A1249A01CB1AA2AB3FAC5FC95CB7D16A38DBCD11804212872394D9A2E2F2797A3062AC5AF0C0C57F5ABEF3608546608EC08F197CE2CCF0490875BE4BCF1BD35358AF5694217F2E3DE713800F3C4071622FDBAD20CAEBE2BA60C80DF012DA576EE24A753749C0BAD8707A2382B6E909FF0B8F4A304EEDB1BF04CA0747166981279FE69248AF0DD177702DA2DC709E301D7D6FE985A7D3F7A1678A9BEF306D6036F143806563C42ADFFD8D70595F0C60BA39F0D392CE7EF7CA57547DB2E35B0464FEC6F59F6095F93BD0A241589CAEE15E2226873D31876900E534999F1D2E23E7239FF679377580065A861D3E29FA7215979BDE039ED1FFED26CC2F5541C5CD907E81434EED0479D8737262CCB2807A70504088F23E72A3D949F37C2C8E957DC2FE64BB9CE028013270F42E022BA671F1670EBD20413453A3CF19F53A1A6BDE5D744E39BBF9377384AAF0FBAF475DD1067A2906244CB87F919159DDC71256A251F1BBA789B18D97602C9C1254A4443849C16E0CE2A7A0B6AA6F117788A92C1CB3F60E2C8E539840E3AF49B9248D3E1CAACB08B43146F07CC53D2573086ED062D108C9AC924F58265CCEF3731D39FE5D4F983EADD0E9F9D8B68D953AA9342B8604AFE7916E544D88870F2ED0AFC2CD0C47DD1E5F361004D97B5108D13CD127DEC8609FA2C65FF1714FD45F3B2B3809BAC06DFCA198B71B3929E2A7B62538E5B1B8B5024D8BB78438883911A6FCA870DB16F8F2DA46D9C611F785428A356B40C07B2B8A72E157E3497DE2982AAAE4D2D9F4368469A7AD4061AEE188DA4317D826721B9F9B1A361FECF0C725E0AB6F17C147D2C62A4D11989DB1503F85763FA3E4A49BAB6BDD05C95199158D421B115F40B124EE448803E07496DE7C2682D4AF433662978CFDCFAC88C9100C46CC16929A10E3082BCAD4444D59FE57717FB4BE8DE45F4D84716D204AC97CBA5A7824765636C571AD6780AAA7510E832EECC54D571A780F90BC6A1B54DE8CC83ECB797A9065CC9807CC99DD7638AFC500D05FD2EDEB795227CAA37EBBC04A37DF07762E0319F27B523282D11DEFD85A1DBA40C87EA1EA4D1B9B2A2FC34F9F5395AE51E3A994FE25C680022E5ABD19D11703C2CB6EEE1780F76FEA8601FAE9E27BC16F832BC16776609DC2B0E3D605E635258A95907A148D583B44E202BA4A48211DA3358B7B391B6F3AD0F84D9D7F97DFFA9D819C3D316A59173E8CA970240349A89E09F0A9B1A4B4C6FFCDD878A977BC9EB254318574C40C49D2DCE56FF803601E1752BE3824F94D0D66C1C5FDADCC9670BFC85C422811D27FA794B363 20160323041407 2 6 100 8191 5 D8320CDE33443FD11E472910A82D580EF614A690CF5313E998A695702508351835AF6D1DF2FA7AF2F1B234CB85E4174D67D9A32B8CC58DAF6DCFD555275B1D038D5EAAC00E0396BFF8A3686F1BB5DADDEB3C5F12B02358C7A1249A01CB1AA2AB3FAC5FC95CB7D16A38DBCD11804212872394D9A2E2F2797A3062AC5AF0C0C57F5ABEF3608546608EC08F197CE2CCF0490875BE4BCF1BD35358AF5694217F2E3DE713800F3C4071622FDBAD20CAEBE2BA60C80DF012DA576EE24A753749C0BAD8707A2382B6E909FF0B8F4A304EEDB1BF04CA0747166981279FE69248AF0DD177702DA2DC709E301D7D6FE985A7D3F7A1678A9BEF306D6036F143806563C42ADFFD8D70595F0C60BA39F0D392CE7EF7CA57547DB2E35B0464FEC6F59F6095F93BD0A241589CAEE15E2226873D31876900E534999F1D2E23E7239FF679377580065A861D3E29FA7215979BDE039ED1FFED26CC2F5541C5CD907E81434EED0479D8737262CCB2807A70504088F23E72A3D949F37C2C8E957DC2FE64BB9CE028013270F42E022BA671F1670EBD20413453A3CF19F53A1A6BDE5D744E39BBF9377384AAF0FBAF475DD1067A2906244CB87F919159DDC71256A251F1BBA789B18D97602C9C1254A4443849C16E0CE2A7A0B6AA6F117788A92C1CB3F60E2C8E539840E3AF49B9248D3E1CAACB08B43146F07CC53D2573086ED062D108C9AC924F58265CCEF3731D39FE5D4F983EADD0E9F9D8B68D953AA9342B8604AFE7916E544D88870F2ED0AFC2CD0C47DD1E5F361004D97B5108D13CD127DEC8609FA2C65FF1714FD45F3B2B3809BAC06DFCA198B71B3929E2A7B62538E5B1B8B5024D8BB78438883911A6FCA870DB16F8F2DA46D9C611F785428A356B40C07B2B8A72E157E3497DE2982AAAE4D2D9F4368469A7AD4061AEE188DA4317D826721B9F9B1A361FECF0C725E0AB6F17C147D2C62A4D11989DB1503F85763FA3E4A49BAB6BDD05C95199158D421B115F40B124EE448803E07496DE7C2682D4AF433662978CFDCFAC88C9100C46CC16929A10E3082BCAD4444D59FE57717FB4BE8DE45F4D84716D204AC97CBA5A7824765636C571AD6780AAA7510E832EECC54D571A780F90BC6A1B54DE8CC83ECB797A9065CC9807CC99DD7638AFC500D05FD2EDEB795227CAA37EBBC04A37DF07762E0319F27B523282D11DEFD85A1DBA40C87EA1EA4D1B9B2A2FC34F9F5395AE51E3A994FE25C680022E5ABD19D11703C2CB6EEE1780F76FEA8601FAE9E27BC16F832BC16776609DC2B0E3D605E635258A95907A148D583B44E202BA4A48211DA3358B7B391B6F3AD0F84D9D7F97DFFA9D819C3D316A59173E8CA970240349A89E09F0A9B1A4B4C6FFCDD878A977BC9EB254318574C40C49D2DCE56FF803601E1752BE3824F94D0D66C1C5FDADCC9670BFC85C422811D27FA98073AF 20160323042341 2 6 100 8191 2 D8320CDE33443FD11E472910A82D580EF614A690CF5313E998A695702508351835AF6D1DF2FA7AF2F1B234CB85E4174D67D9A32B8CC58DAF6DCFD555275B1D038D5EAAC00E0396BFF8A3686F1BB5DADDEB3C5F12B02358C7A1249A01CB1AA2AB3FAC5FC95CB7D16A38DBCD11804212872394D9A2E2F2797A3062AC5AF0C0C57F5ABEF3608546608EC08F197CE2CCF0490875BE4BCF1BD35358AF5694217F2E3DE713800F3C4071622FDBAD20CAEBE2BA60C80DF012DA576EE24A753749C0BAD8707A2382B6E909FF0B8F4A304EEDB1BF04CA0747166981279FE69248AF0DD177702DA2DC709E301D7D6FE985A7D3F7A1678A9BEF306D6036F143806563C42ADFFD8D70595F0C60BA39F0D392CE7EF7CA57547DB2E35B0464FEC6F59F6095F93BD0A241589CAEE15E2226873D31876900E534999F1D2E23E7239FF679377580065A861D3E29FA7215979BDE039ED1FFED26CC2F5541C5CD907E81434EED0479D8737262CCB2807A70504088F23E72A3D949F37C2C8E957DC2FE64BB9CE028013270F42E022BA671F1670EBD20413453A3CF19F53A1A6BDE5D744E39BBF9377384AAF0FBAF475DD1067A2906244CB87F919159DDC71256A251F1BBA789B18D97602C9C1254A4443849C16E0CE2A7A0B6AA6F117788A92C1CB3F60E2C8E539840E3AF49B9248D3E1CAACB08B43146F07CC53D2573086ED062D108C9AC924F58265CCEF3731D39FE5D4F983EADD0E9F9D8B68D953AA9342B8604AFE7916E544D88870F2ED0AFC2CD0C47DD1E5F361004D97B5108D13CD127DEC8609FA2C65FF1714FD45F3B2B3809BAC06DFCA198B71B3929E2A7B62538E5B1B8B5024D8BB78438883911A6FCA870DB16F8F2DA46D9C611F785428A356B40C07B2B8A72E157E3497DE2982AAAE4D2D9F4368469A7AD4061AEE188DA4317D826721B9F9B1A361FECF0C725E0AB6F17C147D2C62A4D11989DB1503F85763FA3E4A49BAB6BDD05C95199158D421B115F40B124EE448803E07496DE7C2682D4AF433662978CFDCFAC88C9100C46CC16929A10E3082BCAD4444D59FE57717FB4BE8DE45F4D84716D204AC97CBA5A7824765636C571AD6780AAA7510E832EECC54D571A780F90BC6A1B54DE8CC83ECB797A9065CC9807CC99DD7638AFC500D05FD2EDEB795227CAA37EBBC04A37DF07762E0319F27B523282D11DEFD85A1DBA40C87EA1EA4D1B9B2A2FC34F9F5395AE51E3A994FE25C680022E5ABD19D11703C2CB6EEE1780F76FEA8601FAE9E27BC16F832BC16776609DC2B0E3D605E635258A95907A148D583B44E202BA4A48211DA3358B7B391B6F3AD0F84D9D7F97DFFA9D819C3D316A59173E8CA970240349A89E09F0A9B1A4B4C6FFCDD878A977BC9EB254318574C40C49D2DCE56FF803601E1752BE3824F94D0D66C1C5FDADCC9670BFC85C422811D27FA992813B 20160324042502 2 6 100 8191 5 D8320CDE33443FD11E472910A82D580EF614A690CF5313E998A695702508351835AF6D1DF2FA7AF2F1B234CB85E4174D67D9A32B8CC58DAF6DCFD555275B1D038D5EAAC00E0396BFF8A3686F1BB5DADDEB3C5F12B02358C7A1249A01CB1AA2AB3FAC5FC95CB7D16A38DBCD11804212872394D9A2E2F2797A3062AC5AF0C0C57F5ABEF3608546608EC08F197CE2CCF0490875BE4BCF1BD35358AF5694217F2E3DE713800F3C4071622FDBAD20CAEBE2BA60C80DF012DA576EE24A753749C0BAD8707A2382B6E909FF0B8F4A304EEDB1BF04CA0747166981279FE69248AF0DD177702DA2DC709E301D7D6FE985A7D3F7A1678A9BEF306D6036F143806563C42ADFFD8D70595F0C60BA39F0D392CE7EF7CA57547DB2E35B0464FEC6F59F6095F93BD0A241589CAEE15E2226873D31876900E534999F1D2E23E7239FF679377580065A861D3E29FA7215979BDE039ED1FFED26CC2F5541C5CD907E81434EED0479D8737262CCB2807A70504088F23E72A3D949F37C2C8E957DC2FE64BB9CE028013270F42E022BA671F1670EBD20413453A3CF19F53A1A6BDE5D744E39BBF9377384AAF0FBAF475DD1067A2906244CB87F919159DDC71256A251F1BBA789B18D97602C9C1254A4443849C16E0CE2A7A0B6AA6F117788A92C1CB3F60E2C8E539840E3AF49B9248D3E1CAACB08B43146F07CC53D2573086ED062D108C9AC924F58265CCEF3731D39FE5D4F983EADD0E9F9D8B68D953AA9342B8604AFE7916E544D88870F2ED0AFC2CD0C47DD1E5F361004D97B5108D13CD127DEC8609FA2C65FF1714FD45F3B2B3809BAC06DFCA198B71B3929E2A7B62538E5B1B8B5024D8BB78438883911A6FCA870DB16F8F2DA46D9C611F785428A356B40C07B2B8A72E157E3497DE2982AAAE4D2D9F4368469A7AD4061AEE188DA4317D826721B9F9B1A361FECF0C725E0AB6F17C147D2C62A4D11989DB1503F85763FA3E4A49BAB6BDD05C95199158D421B115F40B124EE448803E07496DE7C2682D4AF433662978CFDCFAC88C9100C46CC16929A10E3082BCAD4444D59FE57717FB4BE8DE45F4D84716D204AC97CBA5A7824765636C571AD6780AAA7510E832EECC54D571A780F90BC6A1B54DE8CC83ECB797A9065CC9807CC99DD7638AFC500D05FD2EDEB795227CAA37EBBC04A37DF07762E0319F27B523282D11DEFD85A1DBA40C87EA1EA4D1B9B2A2FC34F9F5395AE51E3A994FE25C680022E5ABD19D11703C2CB6EEE1780F76FEA8601FAE9E27BC16F832BC16776609DC2B0E3D605E635258A95907A148D583B44E202BA4A48211DA3358B7B391B6F3AD0F84D9D7F97DFFA9D819C3D316A59173E8CA970240349A89E09F0A9B1A4B4C6FFCDD878A977BC9EB254318574C40C49D2DCE56FF803601E1752BE3824F94D0D66C1C5FDADCC9670BFC85C422811D27FB9535E6F 20160324084810 2 6 100 8191 2 D8320CDE33443FD11E472910A82D580EF614A690CF5313E998A695702508351835AF6D1DF2FA7AF2F1B234CB85E4174D67D9A32B8CC58DAF6DCFD555275B1D038D5EAAC00E0396BFF8A3686F1BB5DADDEB3C5F12B02358C7A1249A01CB1AA2AB3FAC5FC95CB7D16A38DBCD11804212872394D9A2E2F2797A3062AC5AF0C0C57F5ABEF3608546608EC08F197CE2CCF0490875BE4BCF1BD35358AF5694217F2E3DE713800F3C4071622FDBAD20CAEBE2BA60C80DF012DA576EE24A753749C0BAD8707A2382B6E909FF0B8F4A304EEDB1BF04CA0747166981279FE69248AF0DD177702DA2DC709E301D7D6FE985A7D3F7A1678A9BEF306D6036F143806563C42ADFFD8D70595F0C60BA39F0D392CE7EF7CA57547DB2E35B0464FEC6F59F6095F93BD0A241589CAEE15E2226873D31876900E534999F1D2E23E7239FF679377580065A861D3E29FA7215979BDE039ED1FFED26CC2F5541C5CD907E81434EED0479D8737262CCB2807A70504088F23E72A3D949F37C2C8E957DC2FE64BB9CE028013270F42E022BA671F1670EBD20413453A3CF19F53A1A6BDE5D744E39BBF9377384AAF0FBAF475DD1067A2906244CB87F919159DDC71256A251F1BBA789B18D97602C9C1254A4443849C16E0CE2A7A0B6AA6F117788A92C1CB3F60E2C8E539840E3AF49B9248D3E1CAACB08B43146F07CC53D2573086ED062D108C9AC924F58265CCEF3731D39FE5D4F983EADD0E9F9D8B68D953AA9342B8604AFE7916E544D88870F2ED0AFC2CD0C47DD1E5F361004D97B5108D13CD127DEC8609FA2C65FF1714FD45F3B2B3809BAC06DFCA198B71B3929E2A7B62538E5B1B8B5024D8BB78438883911A6FCA870DB16F8F2DA46D9C611F785428A356B40C07B2B8A72E157E3497DE2982AAAE4D2D9F4368469A7AD4061AEE188DA4317D826721B9F9B1A361FECF0C725E0AB6F17C147D2C62A4D11989DB1503F85763FA3E4A49BAB6BDD05C95199158D421B115F40B124EE448803E07496DE7C2682D4AF433662978CFDCFAC88C9100C46CC16929A10E3082BCAD4444D59FE57717FB4BE8DE45F4D84716D204AC97CBA5A7824765636C571AD6780AAA7510E832EECC54D571A780F90BC6A1B54DE8CC83ECB797A9065CC9807CC99DD7638AFC500D05FD2EDEB795227CAA37EBBC04A37DF07762E0319F27B523282D11DEFD85A1DBA40C87EA1EA4D1B9B2A2FC34F9F5395AE51E3A994FE25C680022E5ABD19D11703C2CB6EEE1780F76FEA8601FAE9E27BC16F832BC16776609DC2B0E3D605E635258A95907A148D583B44E202BA4A48211DA3358B7B391B6F3AD0F84D9D7F97DFFA9D819C3D316A59173E8CA970240349A89E09F0A9B1A4B4C6FFCDD878A977BC9EB254318574C40C49D2DCE56FF803601E1752BE3824F94D0D66C1C5FDADCC9670BFC85C422811D27FBC2024D3 20160324112528 2 6 100 8191 5 D8320CDE33443FD11E472910A82D580EF614A690CF5313E998A695702508351835AF6D1DF2FA7AF2F1B234CB85E4174D67D9A32B8CC58DAF6DCFD555275B1D038D5EAAC00E0396BFF8A3686F1BB5DADDEB3C5F12B02358C7A1249A01CB1AA2AB3FAC5FC95CB7D16A38DBCD11804212872394D9A2E2F2797A3062AC5AF0C0C57F5ABEF3608546608EC08F197CE2CCF0490875BE4BCF1BD35358AF5694217F2E3DE713800F3C4071622FDBAD20CAEBE2BA60C80DF012DA576EE24A753749C0BAD8707A2382B6E909FF0B8F4A304EEDB1BF04CA0747166981279FE69248AF0DD177702DA2DC709E301D7D6FE985A7D3F7A1678A9BEF306D6036F143806563C42ADFFD8D70595F0C60BA39F0D392CE7EF7CA57547DB2E35B0464FEC6F59F6095F93BD0A241589CAEE15E2226873D31876900E534999F1D2E23E7239FF679377580065A861D3E29FA7215979BDE039ED1FFED26CC2F5541C5CD907E81434EED0479D8737262CCB2807A70504088F23E72A3D949F37C2C8E957DC2FE64BB9CE028013270F42E022BA671F1670EBD20413453A3CF19F53A1A6BDE5D744E39BBF9377384AAF0FBAF475DD1067A2906244CB87F919159DDC71256A251F1BBA789B18D97602C9C1254A4443849C16E0CE2A7A0B6AA6F117788A92C1CB3F60E2C8E539840E3AF49B9248D3E1CAACB08B43146F07CC53D2573086ED062D108C9AC924F58265CCEF3731D39FE5D4F983EADD0E9F9D8B68D953AA9342B8604AFE7916E544D88870F2ED0AFC2CD0C47DD1E5F361004D97B5108D13CD127DEC8609FA2C65FF1714FD45F3B2B3809BAC06DFCA198B71B3929E2A7B62538E5B1B8B5024D8BB78438883911A6FCA870DB16F8F2DA46D9C611F785428A356B40C07B2B8A72E157E3497DE2982AAAE4D2D9F4368469A7AD4061AEE188DA4317D826721B9F9B1A361FECF0C725E0AB6F17C147D2C62A4D11989DB1503F85763FA3E4A49BAB6BDD05C95199158D421B115F40B124EE448803E07496DE7C2682D4AF433662978CFDCFAC88C9100C46CC16929A10E3082BCAD4444D59FE57717FB4BE8DE45F4D84716D204AC97CBA5A7824765636C571AD6780AAA7510E832EECC54D571A780F90BC6A1B54DE8CC83ECB797A9065CC9807CC99DD7638AFC500D05FD2EDEB795227CAA37EBBC04A37DF07762E0319F27B523282D11DEFD85A1DBA40C87EA1EA4D1B9B2A2FC34F9F5395AE51E3A994FE25C680022E5ABD19D11703C2CB6EEE1780F76FEA8601FAE9E27BC16F832BC16776609DC2B0E3D605E635258A95907A148D583B44E202BA4A48211DA3358B7B391B6F3AD0F84D9D7F97DFFA9D819C3D316A59173E8CA970240349A89E09F0A9B1A4B4C6FFCDD878A977BC9EB254318574C40C49D2DCE56FF803601E1752BE3824F94D0D66C1C5FDADCC9670BFC85C422811D27FBDCE47F7 20160324195325 2 6 100 8191 5 D8320CDE33443FD11E472910A82D580EF614A690CF5313E998A695702508351835AF6D1DF2FA7AF2F1B234CB85E4174D67D9A32B8CC58DAF6DCFD555275B1D038D5EAAC00E0396BFF8A3686F1BB5DADDEB3C5F12B02358C7A1249A01CB1AA2AB3FAC5FC95CB7D16A38DBCD11804212872394D9A2E2F2797A3062AC5AF0C0C57F5ABEF3608546608EC08F197CE2CCF0490875BE4BCF1BD35358AF5694217F2E3DE713800F3C4071622FDBAD20CAEBE2BA60C80DF012DA576EE24A753749C0BAD8707A2382B6E909FF0B8F4A304EEDB1BF04CA0747166981279FE69248AF0DD177702DA2DC709E301D7D6FE985A7D3F7A1678A9BEF306D6036F143806563C42ADFFD8D70595F0C60BA39F0D392CE7EF7CA57547DB2E35B0464FEC6F59F6095F93BD0A241589CAEE15E2226873D31876900E534999F1D2E23E7239FF679377580065A861D3E29FA7215979BDE039ED1FFED26CC2F5541C5CD907E81434EED0479D8737262CCB2807A70504088F23E72A3D949F37C2C8E957DC2FE64BB9CE028013270F42E022BA671F1670EBD20413453A3CF19F53A1A6BDE5D744E39BBF9377384AAF0FBAF475DD1067A2906244CB87F919159DDC71256A251F1BBA789B18D97602C9C1254A4443849C16E0CE2A7A0B6AA6F117788A92C1CB3F60E2C8E539840E3AF49B9248D3E1CAACB08B43146F07CC53D2573086ED062D108C9AC924F58265CCEF3731D39FE5D4F983EADD0E9F9D8B68D953AA9342B8604AFE7916E544D88870F2ED0AFC2CD0C47DD1E5F361004D97B5108D13CD127DEC8609FA2C65FF1714FD45F3B2B3809BAC06DFCA198B71B3929E2A7B62538E5B1B8B5024D8BB78438883911A6FCA870DB16F8F2DA46D9C611F785428A356B40C07B2B8A72E157E3497DE2982AAAE4D2D9F4368469A7AD4061AEE188DA4317D826721B9F9B1A361FECF0C725E0AB6F17C147D2C62A4D11989DB1503F85763FA3E4A49BAB6BDD05C95199158D421B115F40B124EE448803E07496DE7C2682D4AF433662978CFDCFAC88C9100C46CC16929A10E3082BCAD4444D59FE57717FB4BE8DE45F4D84716D204AC97CBA5A7824765636C571AD6780AAA7510E832EECC54D571A780F90BC6A1B54DE8CC83ECB797A9065CC9807CC99DD7638AFC500D05FD2EDEB795227CAA37EBBC04A37DF07762E0319F27B523282D11DEFD85A1DBA40C87EA1EA4D1B9B2A2FC34F9F5395AE51E3A994FE25C680022E5ABD19D11703C2CB6EEE1780F76FEA8601FAE9E27BC16F832BC16776609DC2B0E3D605E635258A95907A148D583B44E202BA4A48211DA3358B7B391B6F3AD0F84D9D7F97DFFA9D819C3D316A59173E8CA970240349A89E09F0A9B1A4B4C6FFCDD878A977BC9EB254318574C40C49D2DCE56FF803601E1752BE3824F94D0D66C1C5FDADCC9670BFC85C422811D27FC34000DF 20160325054405 2 6 100 8191 5 E8E5A3AF93DBD4FB99E4325B3B9308AE7731E7E27B532A2D0AF5306CB249EF6C63C7DFB66FC19B8E84A5672B378D77DD413933ACA7F62EABCD4012865D9336A47AD7E596B21EA5B6A2695C0F6C1C70D92CFF3CA18522B29993AA0A43A6849CEFFF53DF7E33C833B5B0037D8906528C80F98C2FC22F0C43B933795D153ECD05FC0D734F4EC61BBBD611F61CACA7CEC4FEF72A127074ACF73A11B1004A954C48D18E74B534E318069C5CE76C1D9BBB0326432B3C39F26058B6D6077B562CBE0DCA4E5B53F1CF9B80EB4F40DA6DAADF924DD2E7A689321F1558FFB55DA7B91009767791BDA252285D117D45A77FF044F467273CDEA8D4B5AC83DBF16DDB8F5FA4C1556129FFF4213D199DE4E0996BAA284FEC13A86A9F81E7FEAD84B4C59CC6DD641ADDE2E74DEAAD096E53F1F9509BF4A5405BAE67B7A1107E685D6CB934A422673ED632BD91BF84758C9B504DBFF7835E36B038C74400C983452CFEE72FACF76D3AE196BA44DF804657B92D6B646DA47910E53FAE8979C1DA9120C672CD4AAD18A7BDBA2AD397F7B0E01AA7AF4700F9A83EDBA90D25F74C1DCE0520BA9DE24636629D0140BB4BC6C2A703103E5A234BBB9154AEBA22D48F8EBC37368CCC68DC6BA310E2060EC37BCA2BF7DBD68F951BB23D7C018DB2CBC74752F5CED8ECA04EC743A8F4B503831DB09C387F6BD3A7DF1A25BCA452FFB852B134B67CCE4B0141E84B3D796BFDE7BFB2C34760C64200D40728560598B6FB965C0187495318A6EE97E6648F476939AE82F3D9D51761652672CFB3263385219E41D9A26ECFD975AB2005F67B9B6DB6D72ACE42C5079C2E11BEF3B2C0B334E9D4C2EFE518AD4BB8C0A9A995F99B4625D570E283D41EB4542BA37ADCEB772E45F77A72071874CBF8E9C2022DB9FAB62BB8BB11F72416193D10F4A493BDD9FB68A3BADF8130AE380D1987CD5ECCD6D9F5AD2F219D0076964D17F2232E5DAACB832D6E54A0CDAE72302C52604675053C5ED83680DB1D5A2FB9D4885B61E29465FDC016B9CE5DD93582A7221167E77C194C6E7A6D00E98A3E0FBE3987B1C5C1562AE878FC14AC7458003F949665D92F4F01B7A511C9C9126B79E32258AD5BFAB38B91B710AFDD222312DB543EA712C60CF8C8C0C9A7968A9AED867EA11E9718D25EF8A21F18A2F2B3FB28944F8E049705ADC399296AFBA30228CC7AF6D39F49689A16FF5FD64F09A2233970885EB76AEF2650D9A16CA594A3C67F0640095D10FB6E818BDC512F36446FB7277480BA1947D49A8AB5D78965DB16F2E50BFD09910DB0DD99654A32E07C86CF1601D618E7B9D2745C4CFC983E3D48FFE5A08AA471B29DD0E7BBE6DC1DE82FF8988E76835D0E03C177945886DC273C9C91B8B0950E7619490125AFC453772CB66D45D3CEBA3AFA919AE4AEF42D36AF7EDC4C5F030B5720C82FB229E9DD3C9827F7 20160325073844 2 6 100 8191 2 E8E5A3AF93DBD4FB99E4325B3B9308AE7731E7E27B532A2D0AF5306CB249EF6C63C7DFB66FC19B8E84A5672B378D77DD413933ACA7F62EABCD4012865D9336A47AD7E596B21EA5B6A2695C0F6C1C70D92CFF3CA18522B29993AA0A43A6849CEFFF53DF7E33C833B5B0037D8906528C80F98C2FC22F0C43B933795D153ECD05FC0D734F4EC61BBBD611F61CACA7CEC4FEF72A127074ACF73A11B1004A954C48D18E74B534E318069C5CE76C1D9BBB0326432B3C39F26058B6D6077B562CBE0DCA4E5B53F1CF9B80EB4F40DA6DAADF924DD2E7A689321F1558FFB55DA7B91009767791BDA252285D117D45A77FF044F467273CDEA8D4B5AC83DBF16DDB8F5FA4C1556129FFF4213D199DE4E0996BAA284FEC13A86A9F81E7FEAD84B4C59CC6DD641ADDE2E74DEAAD096E53F1F9509BF4A5405BAE67B7A1107E685D6CB934A422673ED632BD91BF84758C9B504DBFF7835E36B038C74400C983452CFEE72FACF76D3AE196BA44DF804657B92D6B646DA47910E53FAE8979C1DA9120C672CD4AAD18A7BDBA2AD397F7B0E01AA7AF4700F9A83EDBA90D25F74C1DCE0520BA9DE24636629D0140BB4BC6C2A703103E5A234BBB9154AEBA22D48F8EBC37368CCC68DC6BA310E2060EC37BCA2BF7DBD68F951BB23D7C018DB2CBC74752F5CED8ECA04EC743A8F4B503831DB09C387F6BD3A7DF1A25BCA452FFB852B134B67CCE4B0141E84B3D796BFDE7BFB2C34760C64200D40728560598B6FB965C0187495318A6EE97E6648F476939AE82F3D9D51761652672CFB3263385219E41D9A26ECFD975AB2005F67B9B6DB6D72ACE42C5079C2E11BEF3B2C0B334E9D4C2EFE518AD4BB8C0A9A995F99B4625D570E283D41EB4542BA37ADCEB772E45F77A72071874CBF8E9C2022DB9FAB62BB8BB11F72416193D10F4A493BDD9FB68A3BADF8130AE380D1987CD5ECCD6D9F5AD2F219D0076964D17F2232E5DAACB832D6E54A0CDAE72302C52604675053C5ED83680DB1D5A2FB9D4885B61E29465FDC016B9CE5DD93582A7221167E77C194C6E7A6D00E98A3E0FBE3987B1C5C1562AE878FC14AC7458003F949665D92F4F01B7A511C9C9126B79E32258AD5BFAB38B91B710AFDD222312DB543EA712C60CF8C8C0C9A7968A9AED867EA11E9718D25EF8A21F18A2F2B3FB28944F8E049705ADC399296AFBA30228CC7AF6D39F49689A16FF5FD64F09A2233970885EB76AEF2650D9A16CA594A3C67F0640095D10FB6E818BDC512F36446FB7277480BA1947D49A8AB5D78965DB16F2E50BFD09910DB0DD99654A32E07C86CF1601D618E7B9D2745C4CFC983E3D48FFE5A08AA471B29DD0E7BBE6DC1DE82FF8988E76835D0E03C177945886DC273C9C91B8B0950E7619490125AFC453772CB66D45D3CEBA3AFA919AE4AEF42D36AF7EDC4C5F030B5720C82FB229E9DD3DFD683B 20160326035547 2 6 100 8191 2 E8E5A3AF93DBD4FB99E4325B3B9308AE7731E7E27B532A2D0AF5306CB249EF6C63C7DFB66FC19B8E84A5672B378D77DD413933ACA7F62EABCD4012865D9336A47AD7E596B21EA5B6A2695C0F6C1C70D92CFF3CA18522B29993AA0A43A6849CEFFF53DF7E33C833B5B0037D8906528C80F98C2FC22F0C43B933795D153ECD05FC0D734F4EC61BBBD611F61CACA7CEC4FEF72A127074ACF73A11B1004A954C48D18E74B534E318069C5CE76C1D9BBB0326432B3C39F26058B6D6077B562CBE0DCA4E5B53F1CF9B80EB4F40DA6DAADF924DD2E7A689321F1558FFB55DA7B91009767791BDA252285D117D45A77FF044F467273CDEA8D4B5AC83DBF16DDB8F5FA4C1556129FFF4213D199DE4E0996BAA284FEC13A86A9F81E7FEAD84B4C59CC6DD641ADDE2E74DEAAD096E53F1F9509BF4A5405BAE67B7A1107E685D6CB934A422673ED632BD91BF84758C9B504DBFF7835E36B038C74400C983452CFEE72FACF76D3AE196BA44DF804657B92D6B646DA47910E53FAE8979C1DA9120C672CD4AAD18A7BDBA2AD397F7B0E01AA7AF4700F9A83EDBA90D25F74C1DCE0520BA9DE24636629D0140BB4BC6C2A703103E5A234BBB9154AEBA22D48F8EBC37368CCC68DC6BA310E2060EC37BCA2BF7DBD68F951BB23D7C018DB2CBC74752F5CED8ECA04EC743A8F4B503831DB09C387F6BD3A7DF1A25BCA452FFB852B134B67CCE4B0141E84B3D796BFDE7BFB2C34760C64200D40728560598B6FB965C0187495318A6EE97E6648F476939AE82F3D9D51761652672CFB3263385219E41D9A26ECFD975AB2005F67B9B6DB6D72ACE42C5079C2E11BEF3B2C0B334E9D4C2EFE518AD4BB8C0A9A995F99B4625D570E283D41EB4542BA37ADCEB772E45F77A72071874CBF8E9C2022DB9FAB62BB8BB11F72416193D10F4A493BDD9FB68A3BADF8130AE380D1987CD5ECCD6D9F5AD2F219D0076964D17F2232E5DAACB832D6E54A0CDAE72302C52604675053C5ED83680DB1D5A2FB9D4885B61E29465FDC016B9CE5DD93582A7221167E77C194C6E7A6D00E98A3E0FBE3987B1C5C1562AE878FC14AC7458003F949665D92F4F01B7A511C9C9126B79E32258AD5BFAB38B91B710AFDD222312DB543EA712C60CF8C8C0C9A7968A9AED867EA11E9718D25EF8A21F18A2F2B3FB28944F8E049705ADC399296AFBA30228CC7AF6D39F49689A16FF5FD64F09A2233970885EB76AEF2650D9A16CA594A3C67F0640095D10FB6E818BDC512F36446FB7277480BA1947D49A8AB5D78965DB16F2E50BFD09910DB0DD99654A32E07C86CF1601D618E7B9D2745C4CFC983E3D48FFE5A08AA471B29DD0E7BBE6DC1DE82FF8988E76835D0E03C177945886DC273C9C91B8B0950E7619490125AFC453772CB66D45D3CEBA3AFA919AE4AEF42D36AF7EDC4C5F030B5720C82FB229E9DD4D2BE973 20160326072058 2 6 100 8191 2 E8E5A3AF93DBD4FB99E4325B3B9308AE7731E7E27B532A2D0AF5306CB249EF6C63C7DFB66FC19B8E84A5672B378D77DD413933ACA7F62EABCD4012865D9336A47AD7E596B21EA5B6A2695C0F6C1C70D92CFF3CA18522B29993AA0A43A6849CEFFF53DF7E33C833B5B0037D8906528C80F98C2FC22F0C43B933795D153ECD05FC0D734F4EC61BBBD611F61CACA7CEC4FEF72A127074ACF73A11B1004A954C48D18E74B534E318069C5CE76C1D9BBB0326432B3C39F26058B6D6077B562CBE0DCA4E5B53F1CF9B80EB4F40DA6DAADF924DD2E7A689321F1558FFB55DA7B91009767791BDA252285D117D45A77FF044F467273CDEA8D4B5AC83DBF16DDB8F5FA4C1556129FFF4213D199DE4E0996BAA284FEC13A86A9F81E7FEAD84B4C59CC6DD641ADDE2E74DEAAD096E53F1F9509BF4A5405BAE67B7A1107E685D6CB934A422673ED632BD91BF84758C9B504DBFF7835E36B038C74400C983452CFEE72FACF76D3AE196BA44DF804657B92D6B646DA47910E53FAE8979C1DA9120C672CD4AAD18A7BDBA2AD397F7B0E01AA7AF4700F9A83EDBA90D25F74C1DCE0520BA9DE24636629D0140BB4BC6C2A703103E5A234BBB9154AEBA22D48F8EBC37368CCC68DC6BA310E2060EC37BCA2BF7DBD68F951BB23D7C018DB2CBC74752F5CED8ECA04EC743A8F4B503831DB09C387F6BD3A7DF1A25BCA452FFB852B134B67CCE4B0141E84B3D796BFDE7BFB2C34760C64200D40728560598B6FB965C0187495318A6EE97E6648F476939AE82F3D9D51761652672CFB3263385219E41D9A26ECFD975AB2005F67B9B6DB6D72ACE42C5079C2E11BEF3B2C0B334E9D4C2EFE518AD4BB8C0A9A995F99B4625D570E283D41EB4542BA37ADCEB772E45F77A72071874CBF8E9C2022DB9FAB62BB8BB11F72416193D10F4A493BDD9FB68A3BADF8130AE380D1987CD5ECCD6D9F5AD2F219D0076964D17F2232E5DAACB832D6E54A0CDAE72302C52604675053C5ED83680DB1D5A2FB9D4885B61E29465FDC016B9CE5DD93582A7221167E77C194C6E7A6D00E98A3E0FBE3987B1C5C1562AE878FC14AC7458003F949665D92F4F01B7A511C9C9126B79E32258AD5BFAB38B91B710AFDD222312DB543EA712C60CF8C8C0C9A7968A9AED867EA11E9718D25EF8A21F18A2F2B3FB28944F8E049705ADC399296AFBA30228CC7AF6D39F49689A16FF5FD64F09A2233970885EB76AEF2650D9A16CA594A3C67F0640095D10FB6E818BDC512F36446FB7277480BA1947D49A8AB5D78965DB16F2E50BFD09910DB0DD99654A32E07C86CF1601D618E7B9D2745C4CFC983E3D48FFE5A08AA471B29DD0E7BBE6DC1DE82FF8988E76835D0E03C177945886DC273C9C91B8B0950E7619490125AFC453772CB66D45D3CEBA3AFA919AE4AEF42D36AF7EDC4C5F030B5720C82FB229E9DD4FA14E4B 20160326092507 2 6 100 8191 2 E8E5A3AF93DBD4FB99E4325B3B9308AE7731E7E27B532A2D0AF5306CB249EF6C63C7DFB66FC19B8E84A5672B378D77DD413933ACA7F62EABCD4012865D9336A47AD7E596B21EA5B6A2695C0F6C1C70D92CFF3CA18522B29993AA0A43A6849CEFFF53DF7E33C833B5B0037D8906528C80F98C2FC22F0C43B933795D153ECD05FC0D734F4EC61BBBD611F61CACA7CEC4FEF72A127074ACF73A11B1004A954C48D18E74B534E318069C5CE76C1D9BBB0326432B3C39F26058B6D6077B562CBE0DCA4E5B53F1CF9B80EB4F40DA6DAADF924DD2E7A689321F1558FFB55DA7B91009767791BDA252285D117D45A77FF044F467273CDEA8D4B5AC83DBF16DDB8F5FA4C1556129FFF4213D199DE4E0996BAA284FEC13A86A9F81E7FEAD84B4C59CC6DD641ADDE2E74DEAAD096E53F1F9509BF4A5405BAE67B7A1107E685D6CB934A422673ED632BD91BF84758C9B504DBFF7835E36B038C74400C983452CFEE72FACF76D3AE196BA44DF804657B92D6B646DA47910E53FAE8979C1DA9120C672CD4AAD18A7BDBA2AD397F7B0E01AA7AF4700F9A83EDBA90D25F74C1DCE0520BA9DE24636629D0140BB4BC6C2A703103E5A234BBB9154AEBA22D48F8EBC37368CCC68DC6BA310E2060EC37BCA2BF7DBD68F951BB23D7C018DB2CBC74752F5CED8ECA04EC743A8F4B503831DB09C387F6BD3A7DF1A25BCA452FFB852B134B67CCE4B0141E84B3D796BFDE7BFB2C34760C64200D40728560598B6FB965C0187495318A6EE97E6648F476939AE82F3D9D51761652672CFB3263385219E41D9A26ECFD975AB2005F67B9B6DB6D72ACE42C5079C2E11BEF3B2C0B334E9D4C2EFE518AD4BB8C0A9A995F99B4625D570E283D41EB4542BA37ADCEB772E45F77A72071874CBF8E9C2022DB9FAB62BB8BB11F72416193D10F4A493BDD9FB68A3BADF8130AE380D1987CD5ECCD6D9F5AD2F219D0076964D17F2232E5DAACB832D6E54A0CDAE72302C52604675053C5ED83680DB1D5A2FB9D4885B61E29465FDC016B9CE5DD93582A7221167E77C194C6E7A6D00E98A3E0FBE3987B1C5C1562AE878FC14AC7458003F949665D92F4F01B7A511C9C9126B79E32258AD5BFAB38B91B710AFDD222312DB543EA712C60CF8C8C0C9A7968A9AED867EA11E9718D25EF8A21F18A2F2B3FB28944F8E049705ADC399296AFBA30228CC7AF6D39F49689A16FF5FD64F09A2233970885EB76AEF2650D9A16CA594A3C67F0640095D10FB6E818BDC512F36446FB7277480BA1947D49A8AB5D78965DB16F2E50BFD09910DB0DD99654A32E07C86CF1601D618E7B9D2745C4CFC983E3D48FFE5A08AA471B29DD0E7BBE6DC1DE82FF8988E76835D0E03C177945886DC273C9C91B8B0950E7619490125AFC453772CB66D45D3CEBA3AFA919AE4AEF42D36AF7EDC4C5F030B5720C82FB229E9DD511CC0FB 20160326124028 2 6 100 8191 5 E8E5A3AF93DBD4FB99E4325B3B9308AE7731E7E27B532A2D0AF5306CB249EF6C63C7DFB66FC19B8E84A5672B378D77DD413933ACA7F62EABCD4012865D9336A47AD7E596B21EA5B6A2695C0F6C1C70D92CFF3CA18522B29993AA0A43A6849CEFFF53DF7E33C833B5B0037D8906528C80F98C2FC22F0C43B933795D153ECD05FC0D734F4EC61BBBD611F61CACA7CEC4FEF72A127074ACF73A11B1004A954C48D18E74B534E318069C5CE76C1D9BBB0326432B3C39F26058B6D6077B562CBE0DCA4E5B53F1CF9B80EB4F40DA6DAADF924DD2E7A689321F1558FFB55DA7B91009767791BDA252285D117D45A77FF044F467273CDEA8D4B5AC83DBF16DDB8F5FA4C1556129FFF4213D199DE4E0996BAA284FEC13A86A9F81E7FEAD84B4C59CC6DD641ADDE2E74DEAAD096E53F1F9509BF4A5405BAE67B7A1107E685D6CB934A422673ED632BD91BF84758C9B504DBFF7835E36B038C74400C983452CFEE72FACF76D3AE196BA44DF804657B92D6B646DA47910E53FAE8979C1DA9120C672CD4AAD18A7BDBA2AD397F7B0E01AA7AF4700F9A83EDBA90D25F74C1DCE0520BA9DE24636629D0140BB4BC6C2A703103E5A234BBB9154AEBA22D48F8EBC37368CCC68DC6BA310E2060EC37BCA2BF7DBD68F951BB23D7C018DB2CBC74752F5CED8ECA04EC743A8F4B503831DB09C387F6BD3A7DF1A25BCA452FFB852B134B67CCE4B0141E84B3D796BFDE7BFB2C34760C64200D40728560598B6FB965C0187495318A6EE97E6648F476939AE82F3D9D51761652672CFB3263385219E41D9A26ECFD975AB2005F67B9B6DB6D72ACE42C5079C2E11BEF3B2C0B334E9D4C2EFE518AD4BB8C0A9A995F99B4625D570E283D41EB4542BA37ADCEB772E45F77A72071874CBF8E9C2022DB9FAB62BB8BB11F72416193D10F4A493BDD9FB68A3BADF8130AE380D1987CD5ECCD6D9F5AD2F219D0076964D17F2232E5DAACB832D6E54A0CDAE72302C52604675053C5ED83680DB1D5A2FB9D4885B61E29465FDC016B9CE5DD93582A7221167E77C194C6E7A6D00E98A3E0FBE3987B1C5C1562AE878FC14AC7458003F949665D92F4F01B7A511C9C9126B79E32258AD5BFAB38B91B710AFDD222312DB543EA712C60CF8C8C0C9A7968A9AED867EA11E9718D25EF8A21F18A2F2B3FB28944F8E049705ADC399296AFBA30228CC7AF6D39F49689A16FF5FD64F09A2233970885EB76AEF2650D9A16CA594A3C67F0640095D10FB6E818BDC512F36446FB7277480BA1947D49A8AB5D78965DB16F2E50BFD09910DB0DD99654A32E07C86CF1601D618E7B9D2745C4CFC983E3D48FFE5A08AA471B29DD0E7BBE6DC1DE82FF8988E76835D0E03C177945886DC273C9C91B8B0950E7619490125AFC453772CB66D45D3CEBA3AFA919AE4AEF42D36AF7EDC4C5F030B5720C82FB229E9DD537EA3E7 20160326204702 2 6 100 8191 2 E8E5A3AF93DBD4FB99E4325B3B9308AE7731E7E27B532A2D0AF5306CB249EF6C63C7DFB66FC19B8E84A5672B378D77DD413933ACA7F62EABCD4012865D9336A47AD7E596B21EA5B6A2695C0F6C1C70D92CFF3CA18522B29993AA0A43A6849CEFFF53DF7E33C833B5B0037D8906528C80F98C2FC22F0C43B933795D153ECD05FC0D734F4EC61BBBD611F61CACA7CEC4FEF72A127074ACF73A11B1004A954C48D18E74B534E318069C5CE76C1D9BBB0326432B3C39F26058B6D6077B562CBE0DCA4E5B53F1CF9B80EB4F40DA6DAADF924DD2E7A689321F1558FFB55DA7B91009767791BDA252285D117D45A77FF044F467273CDEA8D4B5AC83DBF16DDB8F5FA4C1556129FFF4213D199DE4E0996BAA284FEC13A86A9F81E7FEAD84B4C59CC6DD641ADDE2E74DEAAD096E53F1F9509BF4A5405BAE67B7A1107E685D6CB934A422673ED632BD91BF84758C9B504DBFF7835E36B038C74400C983452CFEE72FACF76D3AE196BA44DF804657B92D6B646DA47910E53FAE8979C1DA9120C672CD4AAD18A7BDBA2AD397F7B0E01AA7AF4700F9A83EDBA90D25F74C1DCE0520BA9DE24636629D0140BB4BC6C2A703103E5A234BBB9154AEBA22D48F8EBC37368CCC68DC6BA310E2060EC37BCA2BF7DBD68F951BB23D7C018DB2CBC74752F5CED8ECA04EC743A8F4B503831DB09C387F6BD3A7DF1A25BCA452FFB852B134B67CCE4B0141E84B3D796BFDE7BFB2C34760C64200D40728560598B6FB965C0187495318A6EE97E6648F476939AE82F3D9D51761652672CFB3263385219E41D9A26ECFD975AB2005F67B9B6DB6D72ACE42C5079C2E11BEF3B2C0B334E9D4C2EFE518AD4BB8C0A9A995F99B4625D570E283D41EB4542BA37ADCEB772E45F77A72071874CBF8E9C2022DB9FAB62BB8BB11F72416193D10F4A493BDD9FB68A3BADF8130AE380D1987CD5ECCD6D9F5AD2F219D0076964D17F2232E5DAACB832D6E54A0CDAE72302C52604675053C5ED83680DB1D5A2FB9D4885B61E29465FDC016B9CE5DD93582A7221167E77C194C6E7A6D00E98A3E0FBE3987B1C5C1562AE878FC14AC7458003F949665D92F4F01B7A511C9C9126B79E32258AD5BFAB38B91B710AFDD222312DB543EA712C60CF8C8C0C9A7968A9AED867EA11E9718D25EF8A21F18A2F2B3FB28944F8E049705ADC399296AFBA30228CC7AF6D39F49689A16FF5FD64F09A2233970885EB76AEF2650D9A16CA594A3C67F0640095D10FB6E818BDC512F36446FB7277480BA1947D49A8AB5D78965DB16F2E50BFD09910DB0DD99654A32E07C86CF1601D618E7B9D2745C4CFC983E3D48FFE5A08AA471B29DD0E7BBE6DC1DE82FF8988E76835D0E03C177945886DC273C9C91B8B0950E7619490125AFC453772CB66D45D3CEBA3AFA919AE4AEF42D36AF7EDC4C5F030B5720C82FB229E9DD595EF333 20160327004038 2 6 100 8191 2 E8E5A3AF93DBD4FB99E4325B3B9308AE7731E7E27B532A2D0AF5306CB249EF6C63C7DFB66FC19B8E84A5672B378D77DD413933ACA7F62EABCD4012865D9336A47AD7E596B21EA5B6A2695C0F6C1C70D92CFF3CA18522B29993AA0A43A6849CEFFF53DF7E33C833B5B0037D8906528C80F98C2FC22F0C43B933795D153ECD05FC0D734F4EC61BBBD611F61CACA7CEC4FEF72A127074ACF73A11B1004A954C48D18E74B534E318069C5CE76C1D9BBB0326432B3C39F26058B6D6077B562CBE0DCA4E5B53F1CF9B80EB4F40DA6DAADF924DD2E7A689321F1558FFB55DA7B91009767791BDA252285D117D45A77FF044F467273CDEA8D4B5AC83DBF16DDB8F5FA4C1556129FFF4213D199DE4E0996BAA284FEC13A86A9F81E7FEAD84B4C59CC6DD641ADDE2E74DEAAD096E53F1F9509BF4A5405BAE67B7A1107E685D6CB934A422673ED632BD91BF84758C9B504DBFF7835E36B038C74400C983452CFEE72FACF76D3AE196BA44DF804657B92D6B646DA47910E53FAE8979C1DA9120C672CD4AAD18A7BDBA2AD397F7B0E01AA7AF4700F9A83EDBA90D25F74C1DCE0520BA9DE24636629D0140BB4BC6C2A703103E5A234BBB9154AEBA22D48F8EBC37368CCC68DC6BA310E2060EC37BCA2BF7DBD68F951BB23D7C018DB2CBC74752F5CED8ECA04EC743A8F4B503831DB09C387F6BD3A7DF1A25BCA452FFB852B134B67CCE4B0141E84B3D796BFDE7BFB2C34760C64200D40728560598B6FB965C0187495318A6EE97E6648F476939AE82F3D9D51761652672CFB3263385219E41D9A26ECFD975AB2005F67B9B6DB6D72ACE42C5079C2E11BEF3B2C0B334E9D4C2EFE518AD4BB8C0A9A995F99B4625D570E283D41EB4542BA37ADCEB772E45F77A72071874CBF8E9C2022DB9FAB62BB8BB11F72416193D10F4A493BDD9FB68A3BADF8130AE380D1987CD5ECCD6D9F5AD2F219D0076964D17F2232E5DAACB832D6E54A0CDAE72302C52604675053C5ED83680DB1D5A2FB9D4885B61E29465FDC016B9CE5DD93582A7221167E77C194C6E7A6D00E98A3E0FBE3987B1C5C1562AE878FC14AC7458003F949665D92F4F01B7A511C9C9126B79E32258AD5BFAB38B91B710AFDD222312DB543EA712C60CF8C8C0C9A7968A9AED867EA11E9718D25EF8A21F18A2F2B3FB28944F8E049705ADC399296AFBA30228CC7AF6D39F49689A16FF5FD64F09A2233970885EB76AEF2650D9A16CA594A3C67F0640095D10FB6E818BDC512F36446FB7277480BA1947D49A8AB5D78965DB16F2E50BFD09910DB0DD99654A32E07C86CF1601D618E7B9D2745C4CFC983E3D48FFE5A08AA471B29DD0E7BBE6DC1DE82FF8988E76835D0E03C177945886DC273C9C91B8B0950E7619490125AFC453772CB66D45D3CEBA3AFA919AE4AEF42D36AF7EDC4C5F030B5720C82FB229E9DD5C324F5B 20160327062851 2 6 100 8191 5 E8E5A3AF93DBD4FB99E4325B3B9308AE7731E7E27B532A2D0AF5306CB249EF6C63C7DFB66FC19B8E84A5672B378D77DD413933ACA7F62EABCD4012865D9336A47AD7E596B21EA5B6A2695C0F6C1C70D92CFF3CA18522B29993AA0A43A6849CEFFF53DF7E33C833B5B0037D8906528C80F98C2FC22F0C43B933795D153ECD05FC0D734F4EC61BBBD611F61CACA7CEC4FEF72A127074ACF73A11B1004A954C48D18E74B534E318069C5CE76C1D9BBB0326432B3C39F26058B6D6077B562CBE0DCA4E5B53F1CF9B80EB4F40DA6DAADF924DD2E7A689321F1558FFB55DA7B91009767791BDA252285D117D45A77FF044F467273CDEA8D4B5AC83DBF16DDB8F5FA4C1556129FFF4213D199DE4E0996BAA284FEC13A86A9F81E7FEAD84B4C59CC6DD641ADDE2E74DEAAD096E53F1F9509BF4A5405BAE67B7A1107E685D6CB934A422673ED632BD91BF84758C9B504DBFF7835E36B038C74400C983452CFEE72FACF76D3AE196BA44DF804657B92D6B646DA47910E53FAE8979C1DA9120C672CD4AAD18A7BDBA2AD397F7B0E01AA7AF4700F9A83EDBA90D25F74C1DCE0520BA9DE24636629D0140BB4BC6C2A703103E5A234BBB9154AEBA22D48F8EBC37368CCC68DC6BA310E2060EC37BCA2BF7DBD68F951BB23D7C018DB2CBC74752F5CED8ECA04EC743A8F4B503831DB09C387F6BD3A7DF1A25BCA452FFB852B134B67CCE4B0141E84B3D796BFDE7BFB2C34760C64200D40728560598B6FB965C0187495318A6EE97E6648F476939AE82F3D9D51761652672CFB3263385219E41D9A26ECFD975AB2005F67B9B6DB6D72ACE42C5079C2E11BEF3B2C0B334E9D4C2EFE518AD4BB8C0A9A995F99B4625D570E283D41EB4542BA37ADCEB772E45F77A72071874CBF8E9C2022DB9FAB62BB8BB11F72416193D10F4A493BDD9FB68A3BADF8130AE380D1987CD5ECCD6D9F5AD2F219D0076964D17F2232E5DAACB832D6E54A0CDAE72302C52604675053C5ED83680DB1D5A2FB9D4885B61E29465FDC016B9CE5DD93582A7221167E77C194C6E7A6D00E98A3E0FBE3987B1C5C1562AE878FC14AC7458003F949665D92F4F01B7A511C9C9126B79E32258AD5BFAB38B91B710AFDD222312DB543EA712C60CF8C8C0C9A7968A9AED867EA11E9718D25EF8A21F18A2F2B3FB28944F8E049705ADC399296AFBA30228CC7AF6D39F49689A16FF5FD64F09A2233970885EB76AEF2650D9A16CA594A3C67F0640095D10FB6E818BDC512F36446FB7277480BA1947D49A8AB5D78965DB16F2E50BFD09910DB0DD99654A32E07C86CF1601D618E7B9D2745C4CFC983E3D48FFE5A08AA471B29DD0E7BBE6DC1DE82FF8988E76835D0E03C177945886DC273C9C91B8B0950E7619490125AFC453772CB66D45D3CEBA3AFA919AE4AEF42D36AF7EDC4C5F030B5720C82FB229E9DD606E1A47 20160327081155 2 6 100 8191 5 E8E5A3AF93DBD4FB99E4325B3B9308AE7731E7E27B532A2D0AF5306CB249EF6C63C7DFB66FC19B8E84A5672B378D77DD413933ACA7F62EABCD4012865D9336A47AD7E596B21EA5B6A2695C0F6C1C70D92CFF3CA18522B29993AA0A43A6849CEFFF53DF7E33C833B5B0037D8906528C80F98C2FC22F0C43B933795D153ECD05FC0D734F4EC61BBBD611F61CACA7CEC4FEF72A127074ACF73A11B1004A954C48D18E74B534E318069C5CE76C1D9BBB0326432B3C39F26058B6D6077B562CBE0DCA4E5B53F1CF9B80EB4F40DA6DAADF924DD2E7A689321F1558FFB55DA7B91009767791BDA252285D117D45A77FF044F467273CDEA8D4B5AC83DBF16DDB8F5FA4C1556129FFF4213D199DE4E0996BAA284FEC13A86A9F81E7FEAD84B4C59CC6DD641ADDE2E74DEAAD096E53F1F9509BF4A5405BAE67B7A1107E685D6CB934A422673ED632BD91BF84758C9B504DBFF7835E36B038C74400C983452CFEE72FACF76D3AE196BA44DF804657B92D6B646DA47910E53FAE8979C1DA9120C672CD4AAD18A7BDBA2AD397F7B0E01AA7AF4700F9A83EDBA90D25F74C1DCE0520BA9DE24636629D0140BB4BC6C2A703103E5A234BBB9154AEBA22D48F8EBC37368CCC68DC6BA310E2060EC37BCA2BF7DBD68F951BB23D7C018DB2CBC74752F5CED8ECA04EC743A8F4B503831DB09C387F6BD3A7DF1A25BCA452FFB852B134B67CCE4B0141E84B3D796BFDE7BFB2C34760C64200D40728560598B6FB965C0187495318A6EE97E6648F476939AE82F3D9D51761652672CFB3263385219E41D9A26ECFD975AB2005F67B9B6DB6D72ACE42C5079C2E11BEF3B2C0B334E9D4C2EFE518AD4BB8C0A9A995F99B4625D570E283D41EB4542BA37ADCEB772E45F77A72071874CBF8E9C2022DB9FAB62BB8BB11F72416193D10F4A493BDD9FB68A3BADF8130AE380D1987CD5ECCD6D9F5AD2F219D0076964D17F2232E5DAACB832D6E54A0CDAE72302C52604675053C5ED83680DB1D5A2FB9D4885B61E29465FDC016B9CE5DD93582A7221167E77C194C6E7A6D00E98A3E0FBE3987B1C5C1562AE878FC14AC7458003F949665D92F4F01B7A511C9C9126B79E32258AD5BFAB38B91B710AFDD222312DB543EA712C60CF8C8C0C9A7968A9AED867EA11E9718D25EF8A21F18A2F2B3FB28944F8E049705ADC399296AFBA30228CC7AF6D39F49689A16FF5FD64F09A2233970885EB76AEF2650D9A16CA594A3C67F0640095D10FB6E818BDC512F36446FB7277480BA1947D49A8AB5D78965DB16F2E50BFD09910DB0DD99654A32E07C86CF1601D618E7B9D2745C4CFC983E3D48FFE5A08AA471B29DD0E7BBE6DC1DE82FF8988E76835D0E03C177945886DC273C9C91B8B0950E7619490125AFC453772CB66D45D3CEBA3AFA919AE4AEF42D36AF7EDC4C5F030B5720C82FB229E9DD61A5005F 20160327123555 2 6 100 8191 5 E8E5A3AF93DBD4FB99E4325B3B9308AE7731E7E27B532A2D0AF5306CB249EF6C63C7DFB66FC19B8E84A5672B378D77DD413933ACA7F62EABCD4012865D9336A47AD7E596B21EA5B6A2695C0F6C1C70D92CFF3CA18522B29993AA0A43A6849CEFFF53DF7E33C833B5B0037D8906528C80F98C2FC22F0C43B933795D153ECD05FC0D734F4EC61BBBD611F61CACA7CEC4FEF72A127074ACF73A11B1004A954C48D18E74B534E318069C5CE76C1D9BBB0326432B3C39F26058B6D6077B562CBE0DCA4E5B53F1CF9B80EB4F40DA6DAADF924DD2E7A689321F1558FFB55DA7B91009767791BDA252285D117D45A77FF044F467273CDEA8D4B5AC83DBF16DDB8F5FA4C1556129FFF4213D199DE4E0996BAA284FEC13A86A9F81E7FEAD84B4C59CC6DD641ADDE2E74DEAAD096E53F1F9509BF4A5405BAE67B7A1107E685D6CB934A422673ED632BD91BF84758C9B504DBFF7835E36B038C74400C983452CFEE72FACF76D3AE196BA44DF804657B92D6B646DA47910E53FAE8979C1DA9120C672CD4AAD18A7BDBA2AD397F7B0E01AA7AF4700F9A83EDBA90D25F74C1DCE0520BA9DE24636629D0140BB4BC6C2A703103E5A234BBB9154AEBA22D48F8EBC37368CCC68DC6BA310E2060EC37BCA2BF7DBD68F951BB23D7C018DB2CBC74752F5CED8ECA04EC743A8F4B503831DB09C387F6BD3A7DF1A25BCA452FFB852B134B67CCE4B0141E84B3D796BFDE7BFB2C34760C64200D40728560598B6FB965C0187495318A6EE97E6648F476939AE82F3D9D51761652672CFB3263385219E41D9A26ECFD975AB2005F67B9B6DB6D72ACE42C5079C2E11BEF3B2C0B334E9D4C2EFE518AD4BB8C0A9A995F99B4625D570E283D41EB4542BA37ADCEB772E45F77A72071874CBF8E9C2022DB9FAB62BB8BB11F72416193D10F4A493BDD9FB68A3BADF8130AE380D1987CD5ECCD6D9F5AD2F219D0076964D17F2232E5DAACB832D6E54A0CDAE72302C52604675053C5ED83680DB1D5A2FB9D4885B61E29465FDC016B9CE5DD93582A7221167E77C194C6E7A6D00E98A3E0FBE3987B1C5C1562AE878FC14AC7458003F949665D92F4F01B7A511C9C9126B79E32258AD5BFAB38B91B710AFDD222312DB543EA712C60CF8C8C0C9A7968A9AED867EA11E9718D25EF8A21F18A2F2B3FB28944F8E049705ADC399296AFBA30228CC7AF6D39F49689A16FF5FD64F09A2233970885EB76AEF2650D9A16CA594A3C67F0640095D10FB6E818BDC512F36446FB7277480BA1947D49A8AB5D78965DB16F2E50BFD09910DB0DD99654A32E07C86CF1601D618E7B9D2745C4CFC983E3D48FFE5A08AA471B29DD0E7BBE6DC1DE82FF8988E76835D0E03C177945886DC273C9C91B8B0950E7619490125AFC453772CB66D45D3CEBA3AFA919AE4AEF42D36AF7EDC4C5F030B5720C82FB229E9DD64D2A70F 20160327223323 2 6 100 8191 2 E8E5A3AF93DBD4FB99E4325B3B9308AE7731E7E27B532A2D0AF5306CB249EF6C63C7DFB66FC19B8E84A5672B378D77DD413933ACA7F62EABCD4012865D9336A47AD7E596B21EA5B6A2695C0F6C1C70D92CFF3CA18522B29993AA0A43A6849CEFFF53DF7E33C833B5B0037D8906528C80F98C2FC22F0C43B933795D153ECD05FC0D734F4EC61BBBD611F61CACA7CEC4FEF72A127074ACF73A11B1004A954C48D18E74B534E318069C5CE76C1D9BBB0326432B3C39F26058B6D6077B562CBE0DCA4E5B53F1CF9B80EB4F40DA6DAADF924DD2E7A689321F1558FFB55DA7B91009767791BDA252285D117D45A77FF044F467273CDEA8D4B5AC83DBF16DDB8F5FA4C1556129FFF4213D199DE4E0996BAA284FEC13A86A9F81E7FEAD84B4C59CC6DD641ADDE2E74DEAAD096E53F1F9509BF4A5405BAE67B7A1107E685D6CB934A422673ED632BD91BF84758C9B504DBFF7835E36B038C74400C983452CFEE72FACF76D3AE196BA44DF804657B92D6B646DA47910E53FAE8979C1DA9120C672CD4AAD18A7BDBA2AD397F7B0E01AA7AF4700F9A83EDBA90D25F74C1DCE0520BA9DE24636629D0140BB4BC6C2A703103E5A234BBB9154AEBA22D48F8EBC37368CCC68DC6BA310E2060EC37BCA2BF7DBD68F951BB23D7C018DB2CBC74752F5CED8ECA04EC743A8F4B503831DB09C387F6BD3A7DF1A25BCA452FFB852B134B67CCE4B0141E84B3D796BFDE7BFB2C34760C64200D40728560598B6FB965C0187495318A6EE97E6648F476939AE82F3D9D51761652672CFB3263385219E41D9A26ECFD975AB2005F67B9B6DB6D72ACE42C5079C2E11BEF3B2C0B334E9D4C2EFE518AD4BB8C0A9A995F99B4625D570E283D41EB4542BA37ADCEB772E45F77A72071874CBF8E9C2022DB9FAB62BB8BB11F72416193D10F4A493BDD9FB68A3BADF8130AE380D1987CD5ECCD6D9F5AD2F219D0076964D17F2232E5DAACB832D6E54A0CDAE72302C52604675053C5ED83680DB1D5A2FB9D4885B61E29465FDC016B9CE5DD93582A7221167E77C194C6E7A6D00E98A3E0FBE3987B1C5C1562AE878FC14AC7458003F949665D92F4F01B7A511C9C9126B79E32258AD5BFAB38B91B710AFDD222312DB543EA712C60CF8C8C0C9A7968A9AED867EA11E9718D25EF8A21F18A2F2B3FB28944F8E049705ADC399296AFBA30228CC7AF6D39F49689A16FF5FD64F09A2233970885EB76AEF2650D9A16CA594A3C67F0640095D10FB6E818BDC512F36446FB7277480BA1947D49A8AB5D78965DB16F2E50BFD09910DB0DD99654A32E07C86CF1601D618E7B9D2745C4CFC983E3D48FFE5A08AA471B29DD0E7BBE6DC1DE82FF8988E76835D0E03C177945886DC273C9C91B8B0950E7619490125AFC453772CB66D45D3CEBA3AFA919AE4AEF42D36AF7EDC4C5F030B5720C82FB229E9DD6BD47A7B 20160328011117 2 6 100 8191 5 E8E5A3AF93DBD4FB99E4325B3B9308AE7731E7E27B532A2D0AF5306CB249EF6C63C7DFB66FC19B8E84A5672B378D77DD413933ACA7F62EABCD4012865D9336A47AD7E596B21EA5B6A2695C0F6C1C70D92CFF3CA18522B29993AA0A43A6849CEFFF53DF7E33C833B5B0037D8906528C80F98C2FC22F0C43B933795D153ECD05FC0D734F4EC61BBBD611F61CACA7CEC4FEF72A127074ACF73A11B1004A954C48D18E74B534E318069C5CE76C1D9BBB0326432B3C39F26058B6D6077B562CBE0DCA4E5B53F1CF9B80EB4F40DA6DAADF924DD2E7A689321F1558FFB55DA7B91009767791BDA252285D117D45A77FF044F467273CDEA8D4B5AC83DBF16DDB8F5FA4C1556129FFF4213D199DE4E0996BAA284FEC13A86A9F81E7FEAD84B4C59CC6DD641ADDE2E74DEAAD096E53F1F9509BF4A5405BAE67B7A1107E685D6CB934A422673ED632BD91BF84758C9B504DBFF7835E36B038C74400C983452CFEE72FACF76D3AE196BA44DF804657B92D6B646DA47910E53FAE8979C1DA9120C672CD4AAD18A7BDBA2AD397F7B0E01AA7AF4700F9A83EDBA90D25F74C1DCE0520BA9DE24636629D0140BB4BC6C2A703103E5A234BBB9154AEBA22D48F8EBC37368CCC68DC6BA310E2060EC37BCA2BF7DBD68F951BB23D7C018DB2CBC74752F5CED8ECA04EC743A8F4B503831DB09C387F6BD3A7DF1A25BCA452FFB852B134B67CCE4B0141E84B3D796BFDE7BFB2C34760C64200D40728560598B6FB965C0187495318A6EE97E6648F476939AE82F3D9D51761652672CFB3263385219E41D9A26ECFD975AB2005F67B9B6DB6D72ACE42C5079C2E11BEF3B2C0B334E9D4C2EFE518AD4BB8C0A9A995F99B4625D570E283D41EB4542BA37ADCEB772E45F77A72071874CBF8E9C2022DB9FAB62BB8BB11F72416193D10F4A493BDD9FB68A3BADF8130AE380D1987CD5ECCD6D9F5AD2F219D0076964D17F2232E5DAACB832D6E54A0CDAE72302C52604675053C5ED83680DB1D5A2FB9D4885B61E29465FDC016B9CE5DD93582A7221167E77C194C6E7A6D00E98A3E0FBE3987B1C5C1562AE878FC14AC7458003F949665D92F4F01B7A511C9C9126B79E32258AD5BFAB38B91B710AFDD222312DB543EA712C60CF8C8C0C9A7968A9AED867EA11E9718D25EF8A21F18A2F2B3FB28944F8E049705ADC399296AFBA30228CC7AF6D39F49689A16FF5FD64F09A2233970885EB76AEF2650D9A16CA594A3C67F0640095D10FB6E818BDC512F36446FB7277480BA1947D49A8AB5D78965DB16F2E50BFD09910DB0DD99654A32E07C86CF1601D618E7B9D2745C4CFC983E3D48FFE5A08AA471B29DD0E7BBE6DC1DE82FF8988E76835D0E03C177945886DC273C9C91B8B0950E7619490125AFC453772CB66D45D3CEBA3AFA919AE4AEF42D36AF7EDC4C5F030B5720C82FB229E9DD6DAD19BF 20160328031621 2 6 100 8191 2 E8E5A3AF93DBD4FB99E4325B3B9308AE7731E7E27B532A2D0AF5306CB249EF6C63C7DFB66FC19B8E84A5672B378D77DD413933ACA7F62EABCD4012865D9336A47AD7E596B21EA5B6A2695C0F6C1C70D92CFF3CA18522B29993AA0A43A6849CEFFF53DF7E33C833B5B0037D8906528C80F98C2FC22F0C43B933795D153ECD05FC0D734F4EC61BBBD611F61CACA7CEC4FEF72A127074ACF73A11B1004A954C48D18E74B534E318069C5CE76C1D9BBB0326432B3C39F26058B6D6077B562CBE0DCA4E5B53F1CF9B80EB4F40DA6DAADF924DD2E7A689321F1558FFB55DA7B91009767791BDA252285D117D45A77FF044F467273CDEA8D4B5AC83DBF16DDB8F5FA4C1556129FFF4213D199DE4E0996BAA284FEC13A86A9F81E7FEAD84B4C59CC6DD641ADDE2E74DEAAD096E53F1F9509BF4A5405BAE67B7A1107E685D6CB934A422673ED632BD91BF84758C9B504DBFF7835E36B038C74400C983452CFEE72FACF76D3AE196BA44DF804657B92D6B646DA47910E53FAE8979C1DA9120C672CD4AAD18A7BDBA2AD397F7B0E01AA7AF4700F9A83EDBA90D25F74C1DCE0520BA9DE24636629D0140BB4BC6C2A703103E5A234BBB9154AEBA22D48F8EBC37368CCC68DC6BA310E2060EC37BCA2BF7DBD68F951BB23D7C018DB2CBC74752F5CED8ECA04EC743A8F4B503831DB09C387F6BD3A7DF1A25BCA452FFB852B134B67CCE4B0141E84B3D796BFDE7BFB2C34760C64200D40728560598B6FB965C0187495318A6EE97E6648F476939AE82F3D9D51761652672CFB3263385219E41D9A26ECFD975AB2005F67B9B6DB6D72ACE42C5079C2E11BEF3B2C0B334E9D4C2EFE518AD4BB8C0A9A995F99B4625D570E283D41EB4542BA37ADCEB772E45F77A72071874CBF8E9C2022DB9FAB62BB8BB11F72416193D10F4A493BDD9FB68A3BADF8130AE380D1987CD5ECCD6D9F5AD2F219D0076964D17F2232E5DAACB832D6E54A0CDAE72302C52604675053C5ED83680DB1D5A2FB9D4885B61E29465FDC016B9CE5DD93582A7221167E77C194C6E7A6D00E98A3E0FBE3987B1C5C1562AE878FC14AC7458003F949665D92F4F01B7A511C9C9126B79E32258AD5BFAB38B91B710AFDD222312DB543EA712C60CF8C8C0C9A7968A9AED867EA11E9718D25EF8A21F18A2F2B3FB28944F8E049705ADC399296AFBA30228CC7AF6D39F49689A16FF5FD64F09A2233970885EB76AEF2650D9A16CA594A3C67F0640095D10FB6E818BDC512F36446FB7277480BA1947D49A8AB5D78965DB16F2E50BFD09910DB0DD99654A32E07C86CF1601D618E7B9D2745C4CFC983E3D48FFE5A08AA471B29DD0E7BBE6DC1DE82FF8988E76835D0E03C177945886DC273C9C91B8B0950E7619490125AFC453772CB66D45D3CEBA3AFA919AE4AEF42D36AF7EDC4C5F030B5720C82FB229E9DD6F1E5643 20160328081352 2 6 100 8191 2 E8E5A3AF93DBD4FB99E4325B3B9308AE7731E7E27B532A2D0AF5306CB249EF6C63C7DFB66FC19B8E84A5672B378D77DD413933ACA7F62EABCD4012865D9336A47AD7E596B21EA5B6A2695C0F6C1C70D92CFF3CA18522B29993AA0A43A6849CEFFF53DF7E33C833B5B0037D8906528C80F98C2FC22F0C43B933795D153ECD05FC0D734F4EC61BBBD611F61CACA7CEC4FEF72A127074ACF73A11B1004A954C48D18E74B534E318069C5CE76C1D9BBB0326432B3C39F26058B6D6077B562CBE0DCA4E5B53F1CF9B80EB4F40DA6DAADF924DD2E7A689321F1558FFB55DA7B91009767791BDA252285D117D45A77FF044F467273CDEA8D4B5AC83DBF16DDB8F5FA4C1556129FFF4213D199DE4E0996BAA284FEC13A86A9F81E7FEAD84B4C59CC6DD641ADDE2E74DEAAD096E53F1F9509BF4A5405BAE67B7A1107E685D6CB934A422673ED632BD91BF84758C9B504DBFF7835E36B038C74400C983452CFEE72FACF76D3AE196BA44DF804657B92D6B646DA47910E53FAE8979C1DA9120C672CD4AAD18A7BDBA2AD397F7B0E01AA7AF4700F9A83EDBA90D25F74C1DCE0520BA9DE24636629D0140BB4BC6C2A703103E5A234BBB9154AEBA22D48F8EBC37368CCC68DC6BA310E2060EC37BCA2BF7DBD68F951BB23D7C018DB2CBC74752F5CED8ECA04EC743A8F4B503831DB09C387F6BD3A7DF1A25BCA452FFB852B134B67CCE4B0141E84B3D796BFDE7BFB2C34760C64200D40728560598B6FB965C0187495318A6EE97E6648F476939AE82F3D9D51761652672CFB3263385219E41D9A26ECFD975AB2005F67B9B6DB6D72ACE42C5079C2E11BEF3B2C0B334E9D4C2EFE518AD4BB8C0A9A995F99B4625D570E283D41EB4542BA37ADCEB772E45F77A72071874CBF8E9C2022DB9FAB62BB8BB11F72416193D10F4A493BDD9FB68A3BADF8130AE380D1987CD5ECCD6D9F5AD2F219D0076964D17F2232E5DAACB832D6E54A0CDAE72302C52604675053C5ED83680DB1D5A2FB9D4885B61E29465FDC016B9CE5DD93582A7221167E77C194C6E7A6D00E98A3E0FBE3987B1C5C1562AE878FC14AC7458003F949665D92F4F01B7A511C9C9126B79E32258AD5BFAB38B91B710AFDD222312DB543EA712C60CF8C8C0C9A7968A9AED867EA11E9718D25EF8A21F18A2F2B3FB28944F8E049705ADC399296AFBA30228CC7AF6D39F49689A16FF5FD64F09A2233970885EB76AEF2650D9A16CA594A3C67F0640095D10FB6E818BDC512F36446FB7277480BA1947D49A8AB5D78965DB16F2E50BFD09910DB0DD99654A32E07C86CF1601D618E7B9D2745C4CFC983E3D48FFE5A08AA471B29DD0E7BBE6DC1DE82FF8988E76835D0E03C177945886DC273C9C91B8B0950E7619490125AFC453772CB66D45D3CEBA3AFA919AE4AEF42D36AF7EDC4C5F030B5720C82FB229E9DD7291B183 20160328130100 2 6 100 8191 2 E8E5A3AF93DBD4FB99E4325B3B9308AE7731E7E27B532A2D0AF5306CB249EF6C63C7DFB66FC19B8E84A5672B378D77DD413933ACA7F62EABCD4012865D9336A47AD7E596B21EA5B6A2695C0F6C1C70D92CFF3CA18522B29993AA0A43A6849CEFFF53DF7E33C833B5B0037D8906528C80F98C2FC22F0C43B933795D153ECD05FC0D734F4EC61BBBD611F61CACA7CEC4FEF72A127074ACF73A11B1004A954C48D18E74B534E318069C5CE76C1D9BBB0326432B3C39F26058B6D6077B562CBE0DCA4E5B53F1CF9B80EB4F40DA6DAADF924DD2E7A689321F1558FFB55DA7B91009767791BDA252285D117D45A77FF044F467273CDEA8D4B5AC83DBF16DDB8F5FA4C1556129FFF4213D199DE4E0996BAA284FEC13A86A9F81E7FEAD84B4C59CC6DD641ADDE2E74DEAAD096E53F1F9509BF4A5405BAE67B7A1107E685D6CB934A422673ED632BD91BF84758C9B504DBFF7835E36B038C74400C983452CFEE72FACF76D3AE196BA44DF804657B92D6B646DA47910E53FAE8979C1DA9120C672CD4AAD18A7BDBA2AD397F7B0E01AA7AF4700F9A83EDBA90D25F74C1DCE0520BA9DE24636629D0140BB4BC6C2A703103E5A234BBB9154AEBA22D48F8EBC37368CCC68DC6BA310E2060EC37BCA2BF7DBD68F951BB23D7C018DB2CBC74752F5CED8ECA04EC743A8F4B503831DB09C387F6BD3A7DF1A25BCA452FFB852B134B67CCE4B0141E84B3D796BFDE7BFB2C34760C64200D40728560598B6FB965C0187495318A6EE97E6648F476939AE82F3D9D51761652672CFB3263385219E41D9A26ECFD975AB2005F67B9B6DB6D72ACE42C5079C2E11BEF3B2C0B334E9D4C2EFE518AD4BB8C0A9A995F99B4625D570E283D41EB4542BA37ADCEB772E45F77A72071874CBF8E9C2022DB9FAB62BB8BB11F72416193D10F4A493BDD9FB68A3BADF8130AE380D1987CD5ECCD6D9F5AD2F219D0076964D17F2232E5DAACB832D6E54A0CDAE72302C52604675053C5ED83680DB1D5A2FB9D4885B61E29465FDC016B9CE5DD93582A7221167E77C194C6E7A6D00E98A3E0FBE3987B1C5C1562AE878FC14AC7458003F949665D92F4F01B7A511C9C9126B79E32258AD5BFAB38B91B710AFDD222312DB543EA712C60CF8C8C0C9A7968A9AED867EA11E9718D25EF8A21F18A2F2B3FB28944F8E049705ADC399296AFBA30228CC7AF6D39F49689A16FF5FD64F09A2233970885EB76AEF2650D9A16CA594A3C67F0640095D10FB6E818BDC512F36446FB7277480BA1947D49A8AB5D78965DB16F2E50BFD09910DB0DD99654A32E07C86CF1601D618E7B9D2745C4CFC983E3D48FFE5A08AA471B29DD0E7BBE6DC1DE82FF8988E76835D0E03C177945886DC273C9C91B8B0950E7619490125AFC453772CB66D45D3CEBA3AFA919AE4AEF42D36AF7EDC4C5F030B5720C82FB229E9DD75E7418B 20160328200420 2 6 100 8191 2 E8E5A3AF93DBD4FB99E4325B3B9308AE7731E7E27B532A2D0AF5306CB249EF6C63C7DFB66FC19B8E84A5672B378D77DD413933ACA7F62EABCD4012865D9336A47AD7E596B21EA5B6A2695C0F6C1C70D92CFF3CA18522B29993AA0A43A6849CEFFF53DF7E33C833B5B0037D8906528C80F98C2FC22F0C43B933795D153ECD05FC0D734F4EC61BBBD611F61CACA7CEC4FEF72A127074ACF73A11B1004A954C48D18E74B534E318069C5CE76C1D9BBB0326432B3C39F26058B6D6077B562CBE0DCA4E5B53F1CF9B80EB4F40DA6DAADF924DD2E7A689321F1558FFB55DA7B91009767791BDA252285D117D45A77FF044F467273CDEA8D4B5AC83DBF16DDB8F5FA4C1556129FFF4213D199DE4E0996BAA284FEC13A86A9F81E7FEAD84B4C59CC6DD641ADDE2E74DEAAD096E53F1F9509BF4A5405BAE67B7A1107E685D6CB934A422673ED632BD91BF84758C9B504DBFF7835E36B038C74400C983452CFEE72FACF76D3AE196BA44DF804657B92D6B646DA47910E53FAE8979C1DA9120C672CD4AAD18A7BDBA2AD397F7B0E01AA7AF4700F9A83EDBA90D25F74C1DCE0520BA9DE24636629D0140BB4BC6C2A703103E5A234BBB9154AEBA22D48F8EBC37368CCC68DC6BA310E2060EC37BCA2BF7DBD68F951BB23D7C018DB2CBC74752F5CED8ECA04EC743A8F4B503831DB09C387F6BD3A7DF1A25BCA452FFB852B134B67CCE4B0141E84B3D796BFDE7BFB2C34760C64200D40728560598B6FB965C0187495318A6EE97E6648F476939AE82F3D9D51761652672CFB3263385219E41D9A26ECFD975AB2005F67B9B6DB6D72ACE42C5079C2E11BEF3B2C0B334E9D4C2EFE518AD4BB8C0A9A995F99B4625D570E283D41EB4542BA37ADCEB772E45F77A72071874CBF8E9C2022DB9FAB62BB8BB11F72416193D10F4A493BDD9FB68A3BADF8130AE380D1987CD5ECCD6D9F5AD2F219D0076964D17F2232E5DAACB832D6E54A0CDAE72302C52604675053C5ED83680DB1D5A2FB9D4885B61E29465FDC016B9CE5DD93582A7221167E77C194C6E7A6D00E98A3E0FBE3987B1C5C1562AE878FC14AC7458003F949665D92F4F01B7A511C9C9126B79E32258AD5BFAB38B91B710AFDD222312DB543EA712C60CF8C8C0C9A7968A9AED867EA11E9718D25EF8A21F18A2F2B3FB28944F8E049705ADC399296AFBA30228CC7AF6D39F49689A16FF5FD64F09A2233970885EB76AEF2650D9A16CA594A3C67F0640095D10FB6E818BDC512F36446FB7277480BA1947D49A8AB5D78965DB16F2E50BFD09910DB0DD99654A32E07C86CF1601D618E7B9D2745C4CFC983E3D48FFE5A08AA471B29DD0E7BBE6DC1DE82FF8988E76835D0E03C177945886DC273C9C91B8B0950E7619490125AFC453772CB66D45D3CEBA3AFA919AE4AEF42D36AF7EDC4C5F030B5720C82FB229E9DD7AC63CBB 20160328203420 2 6 100 8191 2 E8E5A3AF93DBD4FB99E4325B3B9308AE7731E7E27B532A2D0AF5306CB249EF6C63C7DFB66FC19B8E84A5672B378D77DD413933ACA7F62EABCD4012865D9336A47AD7E596B21EA5B6A2695C0F6C1C70D92CFF3CA18522B29993AA0A43A6849CEFFF53DF7E33C833B5B0037D8906528C80F98C2FC22F0C43B933795D153ECD05FC0D734F4EC61BBBD611F61CACA7CEC4FEF72A127074ACF73A11B1004A954C48D18E74B534E318069C5CE76C1D9BBB0326432B3C39F26058B6D6077B562CBE0DCA4E5B53F1CF9B80EB4F40DA6DAADF924DD2E7A689321F1558FFB55DA7B91009767791BDA252285D117D45A77FF044F467273CDEA8D4B5AC83DBF16DDB8F5FA4C1556129FFF4213D199DE4E0996BAA284FEC13A86A9F81E7FEAD84B4C59CC6DD641ADDE2E74DEAAD096E53F1F9509BF4A5405BAE67B7A1107E685D6CB934A422673ED632BD91BF84758C9B504DBFF7835E36B038C74400C983452CFEE72FACF76D3AE196BA44DF804657B92D6B646DA47910E53FAE8979C1DA9120C672CD4AAD18A7BDBA2AD397F7B0E01AA7AF4700F9A83EDBA90D25F74C1DCE0520BA9DE24636629D0140BB4BC6C2A703103E5A234BBB9154AEBA22D48F8EBC37368CCC68DC6BA310E2060EC37BCA2BF7DBD68F951BB23D7C018DB2CBC74752F5CED8ECA04EC743A8F4B503831DB09C387F6BD3A7DF1A25BCA452FFB852B134B67CCE4B0141E84B3D796BFDE7BFB2C34760C64200D40728560598B6FB965C0187495318A6EE97E6648F476939AE82F3D9D51761652672CFB3263385219E41D9A26ECFD975AB2005F67B9B6DB6D72ACE42C5079C2E11BEF3B2C0B334E9D4C2EFE518AD4BB8C0A9A995F99B4625D570E283D41EB4542BA37ADCEB772E45F77A72071874CBF8E9C2022DB9FAB62BB8BB11F72416193D10F4A493BDD9FB68A3BADF8130AE380D1987CD5ECCD6D9F5AD2F219D0076964D17F2232E5DAACB832D6E54A0CDAE72302C52604675053C5ED83680DB1D5A2FB9D4885B61E29465FDC016B9CE5DD93582A7221167E77C194C6E7A6D00E98A3E0FBE3987B1C5C1562AE878FC14AC7458003F949665D92F4F01B7A511C9C9126B79E32258AD5BFAB38B91B710AFDD222312DB543EA712C60CF8C8C0C9A7968A9AED867EA11E9718D25EF8A21F18A2F2B3FB28944F8E049705ADC399296AFBA30228CC7AF6D39F49689A16FF5FD64F09A2233970885EB76AEF2650D9A16CA594A3C67F0640095D10FB6E818BDC512F36446FB7277480BA1947D49A8AB5D78965DB16F2E50BFD09910DB0DD99654A32E07C86CF1601D618E7B9D2745C4CFC983E3D48FFE5A08AA471B29DD0E7BBE6DC1DE82FF8988E76835D0E03C177945886DC273C9C91B8B0950E7619490125AFC453772CB66D45D3CEBA3AFA919AE4AEF42D36AF7EDC4C5F030B5720C82FB229E9DD7B12C7E3 20160329051003 2 6 100 8191 2 E8E5A3AF93DBD4FB99E4325B3B9308AE7731E7E27B532A2D0AF5306CB249EF6C63C7DFB66FC19B8E84A5672B378D77DD413933ACA7F62EABCD4012865D9336A47AD7E596B21EA5B6A2695C0F6C1C70D92CFF3CA18522B29993AA0A43A6849CEFFF53DF7E33C833B5B0037D8906528C80F98C2FC22F0C43B933795D153ECD05FC0D734F4EC61BBBD611F61CACA7CEC4FEF72A127074ACF73A11B1004A954C48D18E74B534E318069C5CE76C1D9BBB0326432B3C39F26058B6D6077B562CBE0DCA4E5B53F1CF9B80EB4F40DA6DAADF924DD2E7A689321F1558FFB55DA7B91009767791BDA252285D117D45A77FF044F467273CDEA8D4B5AC83DBF16DDB8F5FA4C1556129FFF4213D199DE4E0996BAA284FEC13A86A9F81E7FEAD84B4C59CC6DD641ADDE2E74DEAAD096E53F1F9509BF4A5405BAE67B7A1107E685D6CB934A422673ED632BD91BF84758C9B504DBFF7835E36B038C74400C983452CFEE72FACF76D3AE196BA44DF804657B92D6B646DA47910E53FAE8979C1DA9120C672CD4AAD18A7BDBA2AD397F7B0E01AA7AF4700F9A83EDBA90D25F74C1DCE0520BA9DE24636629D0140BB4BC6C2A703103E5A234BBB9154AEBA22D48F8EBC37368CCC68DC6BA310E2060EC37BCA2BF7DBD68F951BB23D7C018DB2CBC74752F5CED8ECA04EC743A8F4B503831DB09C387F6BD3A7DF1A25BCA452FFB852B134B67CCE4B0141E84B3D796BFDE7BFB2C34760C64200D40728560598B6FB965C0187495318A6EE97E6648F476939AE82F3D9D51761652672CFB3263385219E41D9A26ECFD975AB2005F67B9B6DB6D72ACE42C5079C2E11BEF3B2C0B334E9D4C2EFE518AD4BB8C0A9A995F99B4625D570E283D41EB4542BA37ADCEB772E45F77A72071874CBF8E9C2022DB9FAB62BB8BB11F72416193D10F4A493BDD9FB68A3BADF8130AE380D1987CD5ECCD6D9F5AD2F219D0076964D17F2232E5DAACB832D6E54A0CDAE72302C52604675053C5ED83680DB1D5A2FB9D4885B61E29465FDC016B9CE5DD93582A7221167E77C194C6E7A6D00E98A3E0FBE3987B1C5C1562AE878FC14AC7458003F949665D92F4F01B7A511C9C9126B79E32258AD5BFAB38B91B710AFDD222312DB543EA712C60CF8C8C0C9A7968A9AED867EA11E9718D25EF8A21F18A2F2B3FB28944F8E049705ADC399296AFBA30228CC7AF6D39F49689A16FF5FD64F09A2233970885EB76AEF2650D9A16CA594A3C67F0640095D10FB6E818BDC512F36446FB7277480BA1947D49A8AB5D78965DB16F2E50BFD09910DB0DD99654A32E07C86CF1601D618E7B9D2745C4CFC983E3D48FFE5A08AA471B29DD0E7BBE6DC1DE82FF8988E76835D0E03C177945886DC273C9C91B8B0950E7619490125AFC453772CB66D45D3CEBA3AFA919AE4AEF42D36AF7EDC4C5F030B5720C82FB229E9DD80FE5033 20160329150013 2 6 100 8191 2 E8E5A3AF93DBD4FB99E4325B3B9308AE7731E7E27B532A2D0AF5306CB249EF6C63C7DFB66FC19B8E84A5672B378D77DD413933ACA7F62EABCD4012865D9336A47AD7E596B21EA5B6A2695C0F6C1C70D92CFF3CA18522B29993AA0A43A6849CEFFF53DF7E33C833B5B0037D8906528C80F98C2FC22F0C43B933795D153ECD05FC0D734F4EC61BBBD611F61CACA7CEC4FEF72A127074ACF73A11B1004A954C48D18E74B534E318069C5CE76C1D9BBB0326432B3C39F26058B6D6077B562CBE0DCA4E5B53F1CF9B80EB4F40DA6DAADF924DD2E7A689321F1558FFB55DA7B91009767791BDA252285D117D45A77FF044F467273CDEA8D4B5AC83DBF16DDB8F5FA4C1556129FFF4213D199DE4E0996BAA284FEC13A86A9F81E7FEAD84B4C59CC6DD641ADDE2E74DEAAD096E53F1F9509BF4A5405BAE67B7A1107E685D6CB934A422673ED632BD91BF84758C9B504DBFF7835E36B038C74400C983452CFEE72FACF76D3AE196BA44DF804657B92D6B646DA47910E53FAE8979C1DA9120C672CD4AAD18A7BDBA2AD397F7B0E01AA7AF4700F9A83EDBA90D25F74C1DCE0520BA9DE24636629D0140BB4BC6C2A703103E5A234BBB9154AEBA22D48F8EBC37368CCC68DC6BA310E2060EC37BCA2BF7DBD68F951BB23D7C018DB2CBC74752F5CED8ECA04EC743A8F4B503831DB09C387F6BD3A7DF1A25BCA452FFB852B134B67CCE4B0141E84B3D796BFDE7BFB2C34760C64200D40728560598B6FB965C0187495318A6EE97E6648F476939AE82F3D9D51761652672CFB3263385219E41D9A26ECFD975AB2005F67B9B6DB6D72ACE42C5079C2E11BEF3B2C0B334E9D4C2EFE518AD4BB8C0A9A995F99B4625D570E283D41EB4542BA37ADCEB772E45F77A72071874CBF8E9C2022DB9FAB62BB8BB11F72416193D10F4A493BDD9FB68A3BADF8130AE380D1987CD5ECCD6D9F5AD2F219D0076964D17F2232E5DAACB832D6E54A0CDAE72302C52604675053C5ED83680DB1D5A2FB9D4885B61E29465FDC016B9CE5DD93582A7221167E77C194C6E7A6D00E98A3E0FBE3987B1C5C1562AE878FC14AC7458003F949665D92F4F01B7A511C9C9126B79E32258AD5BFAB38B91B710AFDD222312DB543EA712C60CF8C8C0C9A7968A9AED867EA11E9718D25EF8A21F18A2F2B3FB28944F8E049705ADC399296AFBA30228CC7AF6D39F49689A16FF5FD64F09A2233970885EB76AEF2650D9A16CA594A3C67F0640095D10FB6E818BDC512F36446FB7277480BA1947D49A8AB5D78965DB16F2E50BFD09910DB0DD99654A32E07C86CF1601D618E7B9D2745C4CFC983E3D48FFE5A08AA471B29DD0E7BBE6DC1DE82FF8988E76835D0E03C177945886DC273C9C91B8B0950E7619490125AFC453772CB66D45D3CEBA3AFA919AE4AEF42D36AF7EDC4C5F030B5720C82FB229E9DD87A1FCEB 20160329205744 2 6 100 8191 2 E8E5A3AF93DBD4FB99E4325B3B9308AE7731E7E27B532A2D0AF5306CB249EF6C63C7DFB66FC19B8E84A5672B378D77DD413933ACA7F62EABCD4012865D9336A47AD7E596B21EA5B6A2695C0F6C1C70D92CFF3CA18522B29993AA0A43A6849CEFFF53DF7E33C833B5B0037D8906528C80F98C2FC22F0C43B933795D153ECD05FC0D734F4EC61BBBD611F61CACA7CEC4FEF72A127074ACF73A11B1004A954C48D18E74B534E318069C5CE76C1D9BBB0326432B3C39F26058B6D6077B562CBE0DCA4E5B53F1CF9B80EB4F40DA6DAADF924DD2E7A689321F1558FFB55DA7B91009767791BDA252285D117D45A77FF044F467273CDEA8D4B5AC83DBF16DDB8F5FA4C1556129FFF4213D199DE4E0996BAA284FEC13A86A9F81E7FEAD84B4C59CC6DD641ADDE2E74DEAAD096E53F1F9509BF4A5405BAE67B7A1107E685D6CB934A422673ED632BD91BF84758C9B504DBFF7835E36B038C74400C983452CFEE72FACF76D3AE196BA44DF804657B92D6B646DA47910E53FAE8979C1DA9120C672CD4AAD18A7BDBA2AD397F7B0E01AA7AF4700F9A83EDBA90D25F74C1DCE0520BA9DE24636629D0140BB4BC6C2A703103E5A234BBB9154AEBA22D48F8EBC37368CCC68DC6BA310E2060EC37BCA2BF7DBD68F951BB23D7C018DB2CBC74752F5CED8ECA04EC743A8F4B503831DB09C387F6BD3A7DF1A25BCA452FFB852B134B67CCE4B0141E84B3D796BFDE7BFB2C34760C64200D40728560598B6FB965C0187495318A6EE97E6648F476939AE82F3D9D51761652672CFB3263385219E41D9A26ECFD975AB2005F67B9B6DB6D72ACE42C5079C2E11BEF3B2C0B334E9D4C2EFE518AD4BB8C0A9A995F99B4625D570E283D41EB4542BA37ADCEB772E45F77A72071874CBF8E9C2022DB9FAB62BB8BB11F72416193D10F4A493BDD9FB68A3BADF8130AE380D1987CD5ECCD6D9F5AD2F219D0076964D17F2232E5DAACB832D6E54A0CDAE72302C52604675053C5ED83680DB1D5A2FB9D4885B61E29465FDC016B9CE5DD93582A7221167E77C194C6E7A6D00E98A3E0FBE3987B1C5C1562AE878FC14AC7458003F949665D92F4F01B7A511C9C9126B79E32258AD5BFAB38B91B710AFDD222312DB543EA712C60CF8C8C0C9A7968A9AED867EA11E9718D25EF8A21F18A2F2B3FB28944F8E049705ADC399296AFBA30228CC7AF6D39F49689A16FF5FD64F09A2233970885EB76AEF2650D9A16CA594A3C67F0640095D10FB6E818BDC512F36446FB7277480BA1947D49A8AB5D78965DB16F2E50BFD09910DB0DD99654A32E07C86CF1601D618E7B9D2745C4CFC983E3D48FFE5A08AA471B29DD0E7BBE6DC1DE82FF8988E76835D0E03C177945886DC273C9C91B8B0950E7619490125AFC453772CB66D45D3CEBA3AFA919AE4AEF42D36AF7EDC4C5F030B5720C82FB229E9DD8BA2A65B 20160330010039 2 6 100 8191 2 E8E5A3AF93DBD4FB99E4325B3B9308AE7731E7E27B532A2D0AF5306CB249EF6C63C7DFB66FC19B8E84A5672B378D77DD413933ACA7F62EABCD4012865D9336A47AD7E596B21EA5B6A2695C0F6C1C70D92CFF3CA18522B29993AA0A43A6849CEFFF53DF7E33C833B5B0037D8906528C80F98C2FC22F0C43B933795D153ECD05FC0D734F4EC61BBBD611F61CACA7CEC4FEF72A127074ACF73A11B1004A954C48D18E74B534E318069C5CE76C1D9BBB0326432B3C39F26058B6D6077B562CBE0DCA4E5B53F1CF9B80EB4F40DA6DAADF924DD2E7A689321F1558FFB55DA7B91009767791BDA252285D117D45A77FF044F467273CDEA8D4B5AC83DBF16DDB8F5FA4C1556129FFF4213D199DE4E0996BAA284FEC13A86A9F81E7FEAD84B4C59CC6DD641ADDE2E74DEAAD096E53F1F9509BF4A5405BAE67B7A1107E685D6CB934A422673ED632BD91BF84758C9B504DBFF7835E36B038C74400C983452CFEE72FACF76D3AE196BA44DF804657B92D6B646DA47910E53FAE8979C1DA9120C672CD4AAD18A7BDBA2AD397F7B0E01AA7AF4700F9A83EDBA90D25F74C1DCE0520BA9DE24636629D0140BB4BC6C2A703103E5A234BBB9154AEBA22D48F8EBC37368CCC68DC6BA310E2060EC37BCA2BF7DBD68F951BB23D7C018DB2CBC74752F5CED8ECA04EC743A8F4B503831DB09C387F6BD3A7DF1A25BCA452FFB852B134B67CCE4B0141E84B3D796BFDE7BFB2C34760C64200D40728560598B6FB965C0187495318A6EE97E6648F476939AE82F3D9D51761652672CFB3263385219E41D9A26ECFD975AB2005F67B9B6DB6D72ACE42C5079C2E11BEF3B2C0B334E9D4C2EFE518AD4BB8C0A9A995F99B4625D570E283D41EB4542BA37ADCEB772E45F77A72071874CBF8E9C2022DB9FAB62BB8BB11F72416193D10F4A493BDD9FB68A3BADF8130AE380D1987CD5ECCD6D9F5AD2F219D0076964D17F2232E5DAACB832D6E54A0CDAE72302C52604675053C5ED83680DB1D5A2FB9D4885B61E29465FDC016B9CE5DD93582A7221167E77C194C6E7A6D00E98A3E0FBE3987B1C5C1562AE878FC14AC7458003F949665D92F4F01B7A511C9C9126B79E32258AD5BFAB38B91B710AFDD222312DB543EA712C60CF8C8C0C9A7968A9AED867EA11E9718D25EF8A21F18A2F2B3FB28944F8E049705ADC399296AFBA30228CC7AF6D39F49689A16FF5FD64F09A2233970885EB76AEF2650D9A16CA594A3C67F0640095D10FB6E818BDC512F36446FB7277480BA1947D49A8AB5D78965DB16F2E50BFD09910DB0DD99654A32E07C86CF1601D618E7B9D2745C4CFC983E3D48FFE5A08AA471B29DD0E7BBE6DC1DE82FF8988E76835D0E03C177945886DC273C9C91B8B0950E7619490125AFC453772CB66D45D3CEBA3AFA919AE4AEF42D36AF7EDC4C5F030B5720C82FB229E9DD8E545E13 20160330064620 2 6 100 8191 2 E8E5A3AF93DBD4FB99E4325B3B9308AE7731E7E27B532A2D0AF5306CB249EF6C63C7DFB66FC19B8E84A5672B378D77DD413933ACA7F62EABCD4012865D9336A47AD7E596B21EA5B6A2695C0F6C1C70D92CFF3CA18522B29993AA0A43A6849CEFFF53DF7E33C833B5B0037D8906528C80F98C2FC22F0C43B933795D153ECD05FC0D734F4EC61BBBD611F61CACA7CEC4FEF72A127074ACF73A11B1004A954C48D18E74B534E318069C5CE76C1D9BBB0326432B3C39F26058B6D6077B562CBE0DCA4E5B53F1CF9B80EB4F40DA6DAADF924DD2E7A689321F1558FFB55DA7B91009767791BDA252285D117D45A77FF044F467273CDEA8D4B5AC83DBF16DDB8F5FA4C1556129FFF4213D199DE4E0996BAA284FEC13A86A9F81E7FEAD84B4C59CC6DD641ADDE2E74DEAAD096E53F1F9509BF4A5405BAE67B7A1107E685D6CB934A422673ED632BD91BF84758C9B504DBFF7835E36B038C74400C983452CFEE72FACF76D3AE196BA44DF804657B92D6B646DA47910E53FAE8979C1DA9120C672CD4AAD18A7BDBA2AD397F7B0E01AA7AF4700F9A83EDBA90D25F74C1DCE0520BA9DE24636629D0140BB4BC6C2A703103E5A234BBB9154AEBA22D48F8EBC37368CCC68DC6BA310E2060EC37BCA2BF7DBD68F951BB23D7C018DB2CBC74752F5CED8ECA04EC743A8F4B503831DB09C387F6BD3A7DF1A25BCA452FFB852B134B67CCE4B0141E84B3D796BFDE7BFB2C34760C64200D40728560598B6FB965C0187495318A6EE97E6648F476939AE82F3D9D51761652672CFB3263385219E41D9A26ECFD975AB2005F67B9B6DB6D72ACE42C5079C2E11BEF3B2C0B334E9D4C2EFE518AD4BB8C0A9A995F99B4625D570E283D41EB4542BA37ADCEB772E45F77A72071874CBF8E9C2022DB9FAB62BB8BB11F72416193D10F4A493BDD9FB68A3BADF8130AE380D1987CD5ECCD6D9F5AD2F219D0076964D17F2232E5DAACB832D6E54A0CDAE72302C52604675053C5ED83680DB1D5A2FB9D4885B61E29465FDC016B9CE5DD93582A7221167E77C194C6E7A6D00E98A3E0FBE3987B1C5C1562AE878FC14AC7458003F949665D92F4F01B7A511C9C9126B79E32258AD5BFAB38B91B710AFDD222312DB543EA712C60CF8C8C0C9A7968A9AED867EA11E9718D25EF8A21F18A2F2B3FB28944F8E049705ADC399296AFBA30228CC7AF6D39F49689A16FF5FD64F09A2233970885EB76AEF2650D9A16CA594A3C67F0640095D10FB6E818BDC512F36446FB7277480BA1947D49A8AB5D78965DB16F2E50BFD09910DB0DD99654A32E07C86CF1601D618E7B9D2745C4CFC983E3D48FFE5A08AA471B29DD0E7BBE6DC1DE82FF8988E76835D0E03C177945886DC273C9C91B8B0950E7619490125AFC453772CB66D45D3CEBA3AFA919AE4AEF42D36AF7EDC4C5F030B5720C82FB229E9DD922B39AB 20160330195544 2 6 100 8191 5 E8E5A3AF93DBD4FB99E4325B3B9308AE7731E7E27B532A2D0AF5306CB249EF6C63C7DFB66FC19B8E84A5672B378D77DD413933ACA7F62EABCD4012865D9336A47AD7E596B21EA5B6A2695C0F6C1C70D92CFF3CA18522B29993AA0A43A6849CEFFF53DF7E33C833B5B0037D8906528C80F98C2FC22F0C43B933795D153ECD05FC0D734F4EC61BBBD611F61CACA7CEC4FEF72A127074ACF73A11B1004A954C48D18E74B534E318069C5CE76C1D9BBB0326432B3C39F26058B6D6077B562CBE0DCA4E5B53F1CF9B80EB4F40DA6DAADF924DD2E7A689321F1558FFB55DA7B91009767791BDA252285D117D45A77FF044F467273CDEA8D4B5AC83DBF16DDB8F5FA4C1556129FFF4213D199DE4E0996BAA284FEC13A86A9F81E7FEAD84B4C59CC6DD641ADDE2E74DEAAD096E53F1F9509BF4A5405BAE67B7A1107E685D6CB934A422673ED632BD91BF84758C9B504DBFF7835E36B038C74400C983452CFEE72FACF76D3AE196BA44DF804657B92D6B646DA47910E53FAE8979C1DA9120C672CD4AAD18A7BDBA2AD397F7B0E01AA7AF4700F9A83EDBA90D25F74C1DCE0520BA9DE24636629D0140BB4BC6C2A703103E5A234BBB9154AEBA22D48F8EBC37368CCC68DC6BA310E2060EC37BCA2BF7DBD68F951BB23D7C018DB2CBC74752F5CED8ECA04EC743A8F4B503831DB09C387F6BD3A7DF1A25BCA452FFB852B134B67CCE4B0141E84B3D796BFDE7BFB2C34760C64200D40728560598B6FB965C0187495318A6EE97E6648F476939AE82F3D9D51761652672CFB3263385219E41D9A26ECFD975AB2005F67B9B6DB6D72ACE42C5079C2E11BEF3B2C0B334E9D4C2EFE518AD4BB8C0A9A995F99B4625D570E283D41EB4542BA37ADCEB772E45F77A72071874CBF8E9C2022DB9FAB62BB8BB11F72416193D10F4A493BDD9FB68A3BADF8130AE380D1987CD5ECCD6D9F5AD2F219D0076964D17F2232E5DAACB832D6E54A0CDAE72302C52604675053C5ED83680DB1D5A2FB9D4885B61E29465FDC016B9CE5DD93582A7221167E77C194C6E7A6D00E98A3E0FBE3987B1C5C1562AE878FC14AC7458003F949665D92F4F01B7A511C9C9126B79E32258AD5BFAB38B91B710AFDD222312DB543EA712C60CF8C8C0C9A7968A9AED867EA11E9718D25EF8A21F18A2F2B3FB28944F8E049705ADC399296AFBA30228CC7AF6D39F49689A16FF5FD64F09A2233970885EB76AEF2650D9A16CA594A3C67F0640095D10FB6E818BDC512F36446FB7277480BA1947D49A8AB5D78965DB16F2E50BFD09910DB0DD99654A32E07C86CF1601D618E7B9D2745C4CFC983E3D48FFE5A08AA471B29DD0E7BBE6DC1DE82FF8988E76835D0E03C177945886DC273C9C91B8B0950E7619490125AFC453772CB66D45D3CEBA3AFA919AE4AEF42D36AF7EDC4C5F030B5720C82FB229E9DD9AE926F7 20160330202118 2 6 100 8191 2 E8E5A3AF93DBD4FB99E4325B3B9308AE7731E7E27B532A2D0AF5306CB249EF6C63C7DFB66FC19B8E84A5672B378D77DD413933ACA7F62EABCD4012865D9336A47AD7E596B21EA5B6A2695C0F6C1C70D92CFF3CA18522B29993AA0A43A6849CEFFF53DF7E33C833B5B0037D8906528C80F98C2FC22F0C43B933795D153ECD05FC0D734F4EC61BBBD611F61CACA7CEC4FEF72A127074ACF73A11B1004A954C48D18E74B534E318069C5CE76C1D9BBB0326432B3C39F26058B6D6077B562CBE0DCA4E5B53F1CF9B80EB4F40DA6DAADF924DD2E7A689321F1558FFB55DA7B91009767791BDA252285D117D45A77FF044F467273CDEA8D4B5AC83DBF16DDB8F5FA4C1556129FFF4213D199DE4E0996BAA284FEC13A86A9F81E7FEAD84B4C59CC6DD641ADDE2E74DEAAD096E53F1F9509BF4A5405BAE67B7A1107E685D6CB934A422673ED632BD91BF84758C9B504DBFF7835E36B038C74400C983452CFEE72FACF76D3AE196BA44DF804657B92D6B646DA47910E53FAE8979C1DA9120C672CD4AAD18A7BDBA2AD397F7B0E01AA7AF4700F9A83EDBA90D25F74C1DCE0520BA9DE24636629D0140BB4BC6C2A703103E5A234BBB9154AEBA22D48F8EBC37368CCC68DC6BA310E2060EC37BCA2BF7DBD68F951BB23D7C018DB2CBC74752F5CED8ECA04EC743A8F4B503831DB09C387F6BD3A7DF1A25BCA452FFB852B134B67CCE4B0141E84B3D796BFDE7BFB2C34760C64200D40728560598B6FB965C0187495318A6EE97E6648F476939AE82F3D9D51761652672CFB3263385219E41D9A26ECFD975AB2005F67B9B6DB6D72ACE42C5079C2E11BEF3B2C0B334E9D4C2EFE518AD4BB8C0A9A995F99B4625D570E283D41EB4542BA37ADCEB772E45F77A72071874CBF8E9C2022DB9FAB62BB8BB11F72416193D10F4A493BDD9FB68A3BADF8130AE380D1987CD5ECCD6D9F5AD2F219D0076964D17F2232E5DAACB832D6E54A0CDAE72302C52604675053C5ED83680DB1D5A2FB9D4885B61E29465FDC016B9CE5DD93582A7221167E77C194C6E7A6D00E98A3E0FBE3987B1C5C1562AE878FC14AC7458003F949665D92F4F01B7A511C9C9126B79E32258AD5BFAB38B91B710AFDD222312DB543EA712C60CF8C8C0C9A7968A9AED867EA11E9718D25EF8A21F18A2F2B3FB28944F8E049705ADC399296AFBA30228CC7AF6D39F49689A16FF5FD64F09A2233970885EB76AEF2650D9A16CA594A3C67F0640095D10FB6E818BDC512F36446FB7277480BA1947D49A8AB5D78965DB16F2E50BFD09910DB0DD99654A32E07C86CF1601D618E7B9D2745C4CFC983E3D48FFE5A08AA471B29DD0E7BBE6DC1DE82FF8988E76835D0E03C177945886DC273C9C91B8B0950E7619490125AFC453772CB66D45D3CEBA3AFA919AE4AEF42D36AF7EDC4C5F030B5720C82FB229E9DD9B2841A3 20160331010824 2 6 100 8191 5 E8E5A3AF93DBD4FB99E4325B3B9308AE7731E7E27B532A2D0AF5306CB249EF6C63C7DFB66FC19B8E84A5672B378D77DD413933ACA7F62EABCD4012865D9336A47AD7E596B21EA5B6A2695C0F6C1C70D92CFF3CA18522B29993AA0A43A6849CEFFF53DF7E33C833B5B0037D8906528C80F98C2FC22F0C43B933795D153ECD05FC0D734F4EC61BBBD611F61CACA7CEC4FEF72A127074ACF73A11B1004A954C48D18E74B534E318069C5CE76C1D9BBB0326432B3C39F26058B6D6077B562CBE0DCA4E5B53F1CF9B80EB4F40DA6DAADF924DD2E7A689321F1558FFB55DA7B91009767791BDA252285D117D45A77FF044F467273CDEA8D4B5AC83DBF16DDB8F5FA4C1556129FFF4213D199DE4E0996BAA284FEC13A86A9F81E7FEAD84B4C59CC6DD641ADDE2E74DEAAD096E53F1F9509BF4A5405BAE67B7A1107E685D6CB934A422673ED632BD91BF84758C9B504DBFF7835E36B038C74400C983452CFEE72FACF76D3AE196BA44DF804657B92D6B646DA47910E53FAE8979C1DA9120C672CD4AAD18A7BDBA2AD397F7B0E01AA7AF4700F9A83EDBA90D25F74C1DCE0520BA9DE24636629D0140BB4BC6C2A703103E5A234BBB9154AEBA22D48F8EBC37368CCC68DC6BA310E2060EC37BCA2BF7DBD68F951BB23D7C018DB2CBC74752F5CED8ECA04EC743A8F4B503831DB09C387F6BD3A7DF1A25BCA452FFB852B134B67CCE4B0141E84B3D796BFDE7BFB2C34760C64200D40728560598B6FB965C0187495318A6EE97E6648F476939AE82F3D9D51761652672CFB3263385219E41D9A26ECFD975AB2005F67B9B6DB6D72ACE42C5079C2E11BEF3B2C0B334E9D4C2EFE518AD4BB8C0A9A995F99B4625D570E283D41EB4542BA37ADCEB772E45F77A72071874CBF8E9C2022DB9FAB62BB8BB11F72416193D10F4A493BDD9FB68A3BADF8130AE380D1987CD5ECCD6D9F5AD2F219D0076964D17F2232E5DAACB832D6E54A0CDAE72302C52604675053C5ED83680DB1D5A2FB9D4885B61E29465FDC016B9CE5DD93582A7221167E77C194C6E7A6D00E98A3E0FBE3987B1C5C1562AE878FC14AC7458003F949665D92F4F01B7A511C9C9126B79E32258AD5BFAB38B91B710AFDD222312DB543EA712C60CF8C8C0C9A7968A9AED867EA11E9718D25EF8A21F18A2F2B3FB28944F8E049705ADC399296AFBA30228CC7AF6D39F49689A16FF5FD64F09A2233970885EB76AEF2650D9A16CA594A3C67F0640095D10FB6E818BDC512F36446FB7277480BA1947D49A8AB5D78965DB16F2E50BFD09910DB0DD99654A32E07C86CF1601D618E7B9D2745C4CFC983E3D48FFE5A08AA471B29DD0E7BBE6DC1DE82FF8988E76835D0E03C177945886DC273C9C91B8B0950E7619490125AFC453772CB66D45D3CEBA3AFA919AE4AEF42D36AF7EDC4C5F030B5720C82FB229E9DD9E522A6F 20160331155606 2 6 100 8191 2 E8E5A3AF93DBD4FB99E4325B3B9308AE7731E7E27B532A2D0AF5306CB249EF6C63C7DFB66FC19B8E84A5672B378D77DD413933ACA7F62EABCD4012865D9336A47AD7E596B21EA5B6A2695C0F6C1C70D92CFF3CA18522B29993AA0A43A6849CEFFF53DF7E33C833B5B0037D8906528C80F98C2FC22F0C43B933795D153ECD05FC0D734F4EC61BBBD611F61CACA7CEC4FEF72A127074ACF73A11B1004A954C48D18E74B534E318069C5CE76C1D9BBB0326432B3C39F26058B6D6077B562CBE0DCA4E5B53F1CF9B80EB4F40DA6DAADF924DD2E7A689321F1558FFB55DA7B91009767791BDA252285D117D45A77FF044F467273CDEA8D4B5AC83DBF16DDB8F5FA4C1556129FFF4213D199DE4E0996BAA284FEC13A86A9F81E7FEAD84B4C59CC6DD641ADDE2E74DEAAD096E53F1F9509BF4A5405BAE67B7A1107E685D6CB934A422673ED632BD91BF84758C9B504DBFF7835E36B038C74400C983452CFEE72FACF76D3AE196BA44DF804657B92D6B646DA47910E53FAE8979C1DA9120C672CD4AAD18A7BDBA2AD397F7B0E01AA7AF4700F9A83EDBA90D25F74C1DCE0520BA9DE24636629D0140BB4BC6C2A703103E5A234BBB9154AEBA22D48F8EBC37368CCC68DC6BA310E2060EC37BCA2BF7DBD68F951BB23D7C018DB2CBC74752F5CED8ECA04EC743A8F4B503831DB09C387F6BD3A7DF1A25BCA452FFB852B134B67CCE4B0141E84B3D796BFDE7BFB2C34760C64200D40728560598B6FB965C0187495318A6EE97E6648F476939AE82F3D9D51761652672CFB3263385219E41D9A26ECFD975AB2005F67B9B6DB6D72ACE42C5079C2E11BEF3B2C0B334E9D4C2EFE518AD4BB8C0A9A995F99B4625D570E283D41EB4542BA37ADCEB772E45F77A72071874CBF8E9C2022DB9FAB62BB8BB11F72416193D10F4A493BDD9FB68A3BADF8130AE380D1987CD5ECCD6D9F5AD2F219D0076964D17F2232E5DAACB832D6E54A0CDAE72302C52604675053C5ED83680DB1D5A2FB9D4885B61E29465FDC016B9CE5DD93582A7221167E77C194C6E7A6D00E98A3E0FBE3987B1C5C1562AE878FC14AC7458003F949665D92F4F01B7A511C9C9126B79E32258AD5BFAB38B91B710AFDD222312DB543EA712C60CF8C8C0C9A7968A9AED867EA11E9718D25EF8A21F18A2F2B3FB28944F8E049705ADC399296AFBA30228CC7AF6D39F49689A16FF5FD64F09A2233970885EB76AEF2650D9A16CA594A3C67F0640095D10FB6E818BDC512F36446FB7277480BA1947D49A8AB5D78965DB16F2E50BFD09910DB0DD99654A32E07C86CF1601D618E7B9D2745C4CFC983E3D48FFE5A08AA471B29DD0E7BBE6DC1DE82FF8988E76835D0E03C177945886DC273C9C91B8B0950E7619490125AFC453772CB66D45D3CEBA3AFA919AE4AEF42D36AF7EDC4C5F030B5720C82FB229E9DDA80BFF2B 20160401003202 2 6 100 8191 5 E8E5A3AF93DBD4FB99E4325B3B9308AE7731E7E27B532A2D0AF5306CB249EF6C63C7DFB66FC19B8E84A5672B378D77DD413933ACA7F62EABCD4012865D9336A47AD7E596B21EA5B6A2695C0F6C1C70D92CFF3CA18522B29993AA0A43A6849CEFFF53DF7E33C833B5B0037D8906528C80F98C2FC22F0C43B933795D153ECD05FC0D734F4EC61BBBD611F61CACA7CEC4FEF72A127074ACF73A11B1004A954C48D18E74B534E318069C5CE76C1D9BBB0326432B3C39F26058B6D6077B562CBE0DCA4E5B53F1CF9B80EB4F40DA6DAADF924DD2E7A689321F1558FFB55DA7B91009767791BDA252285D117D45A77FF044F467273CDEA8D4B5AC83DBF16DDB8F5FA4C1556129FFF4213D199DE4E0996BAA284FEC13A86A9F81E7FEAD84B4C59CC6DD641ADDE2E74DEAAD096E53F1F9509BF4A5405BAE67B7A1107E685D6CB934A422673ED632BD91BF84758C9B504DBFF7835E36B038C74400C983452CFEE72FACF76D3AE196BA44DF804657B92D6B646DA47910E53FAE8979C1DA9120C672CD4AAD18A7BDBA2AD397F7B0E01AA7AF4700F9A83EDBA90D25F74C1DCE0520BA9DE24636629D0140BB4BC6C2A703103E5A234BBB9154AEBA22D48F8EBC37368CCC68DC6BA310E2060EC37BCA2BF7DBD68F951BB23D7C018DB2CBC74752F5CED8ECA04EC743A8F4B503831DB09C387F6BD3A7DF1A25BCA452FFB852B134B67CCE4B0141E84B3D796BFDE7BFB2C34760C64200D40728560598B6FB965C0187495318A6EE97E6648F476939AE82F3D9D51761652672CFB3263385219E41D9A26ECFD975AB2005F67B9B6DB6D72ACE42C5079C2E11BEF3B2C0B334E9D4C2EFE518AD4BB8C0A9A995F99B4625D570E283D41EB4542BA37ADCEB772E45F77A72071874CBF8E9C2022DB9FAB62BB8BB11F72416193D10F4A493BDD9FB68A3BADF8130AE380D1987CD5ECCD6D9F5AD2F219D0076964D17F2232E5DAACB832D6E54A0CDAE72302C52604675053C5ED83680DB1D5A2FB9D4885B61E29465FDC016B9CE5DD93582A7221167E77C194C6E7A6D00E98A3E0FBE3987B1C5C1562AE878FC14AC7458003F949665D92F4F01B7A511C9C9126B79E32258AD5BFAB38B91B710AFDD222312DB543EA712C60CF8C8C0C9A7968A9AED867EA11E9718D25EF8A21F18A2F2B3FB28944F8E049705ADC399296AFBA30228CC7AF6D39F49689A16FF5FD64F09A2233970885EB76AEF2650D9A16CA594A3C67F0640095D10FB6E818BDC512F36446FB7277480BA1947D49A8AB5D78965DB16F2E50BFD09910DB0DD99654A32E07C86CF1601D618E7B9D2745C4CFC983E3D48FFE5A08AA471B29DD0E7BBE6DC1DE82FF8988E76835D0E03C177945886DC273C9C91B8B0950E7619490125AFC453772CB66D45D3CEBA3AFA919AE4AEF42D36AF7EDC4C5F030B5720C82FB229E9DDADA756E7 20160401083841 2 6 100 8191 5 E8E5A3AF93DBD4FB99E4325B3B9308AE7731E7E27B532A2D0AF5306CB249EF6C63C7DFB66FC19B8E84A5672B378D77DD413933ACA7F62EABCD4012865D9336A47AD7E596B21EA5B6A2695C0F6C1C70D92CFF3CA18522B29993AA0A43A6849CEFFF53DF7E33C833B5B0037D8906528C80F98C2FC22F0C43B933795D153ECD05FC0D734F4EC61BBBD611F61CACA7CEC4FEF72A127074ACF73A11B1004A954C48D18E74B534E318069C5CE76C1D9BBB0326432B3C39F26058B6D6077B562CBE0DCA4E5B53F1CF9B80EB4F40DA6DAADF924DD2E7A689321F1558FFB55DA7B91009767791BDA252285D117D45A77FF044F467273CDEA8D4B5AC83DBF16DDB8F5FA4C1556129FFF4213D199DE4E0996BAA284FEC13A86A9F81E7FEAD84B4C59CC6DD641ADDE2E74DEAAD096E53F1F9509BF4A5405BAE67B7A1107E685D6CB934A422673ED632BD91BF84758C9B504DBFF7835E36B038C74400C983452CFEE72FACF76D3AE196BA44DF804657B92D6B646DA47910E53FAE8979C1DA9120C672CD4AAD18A7BDBA2AD397F7B0E01AA7AF4700F9A83EDBA90D25F74C1DCE0520BA9DE24636629D0140BB4BC6C2A703103E5A234BBB9154AEBA22D48F8EBC37368CCC68DC6BA310E2060EC37BCA2BF7DBD68F951BB23D7C018DB2CBC74752F5CED8ECA04EC743A8F4B503831DB09C387F6BD3A7DF1A25BCA452FFB852B134B67CCE4B0141E84B3D796BFDE7BFB2C34760C64200D40728560598B6FB965C0187495318A6EE97E6648F476939AE82F3D9D51761652672CFB3263385219E41D9A26ECFD975AB2005F67B9B6DB6D72ACE42C5079C2E11BEF3B2C0B334E9D4C2EFE518AD4BB8C0A9A995F99B4625D570E283D41EB4542BA37ADCEB772E45F77A72071874CBF8E9C2022DB9FAB62BB8BB11F72416193D10F4A493BDD9FB68A3BADF8130AE380D1987CD5ECCD6D9F5AD2F219D0076964D17F2232E5DAACB832D6E54A0CDAE72302C52604675053C5ED83680DB1D5A2FB9D4885B61E29465FDC016B9CE5DD93582A7221167E77C194C6E7A6D00E98A3E0FBE3987B1C5C1562AE878FC14AC7458003F949665D92F4F01B7A511C9C9126B79E32258AD5BFAB38B91B710AFDD222312DB543EA712C60CF8C8C0C9A7968A9AED867EA11E9718D25EF8A21F18A2F2B3FB28944F8E049705ADC399296AFBA30228CC7AF6D39F49689A16FF5FD64F09A2233970885EB76AEF2650D9A16CA594A3C67F0640095D10FB6E818BDC512F36446FB7277480BA1947D49A8AB5D78965DB16F2E50BFD09910DB0DD99654A32E07C86CF1601D618E7B9D2745C4CFC983E3D48FFE5A08AA471B29DD0E7BBE6DC1DE82FF8988E76835D0E03C177945886DC273C9C91B8B0950E7619490125AFC453772CB66D45D3CEBA3AFA919AE4AEF42D36AF7EDC4C5F030B5720C82FB229E9DDB2E0BFC7 20160401133333 2 6 100 8191 5 E8E5A3AF93DBD4FB99E4325B3B9308AE7731E7E27B532A2D0AF5306CB249EF6C63C7DFB66FC19B8E84A5672B378D77DD413933ACA7F62EABCD4012865D9336A47AD7E596B21EA5B6A2695C0F6C1C70D92CFF3CA18522B29993AA0A43A6849CEFFF53DF7E33C833B5B0037D8906528C80F98C2FC22F0C43B933795D153ECD05FC0D734F4EC61BBBD611F61CACA7CEC4FEF72A127074ACF73A11B1004A954C48D18E74B534E318069C5CE76C1D9BBB0326432B3C39F26058B6D6077B562CBE0DCA4E5B53F1CF9B80EB4F40DA6DAADF924DD2E7A689321F1558FFB55DA7B91009767791BDA252285D117D45A77FF044F467273CDEA8D4B5AC83DBF16DDB8F5FA4C1556129FFF4213D199DE4E0996BAA284FEC13A86A9F81E7FEAD84B4C59CC6DD641ADDE2E74DEAAD096E53F1F9509BF4A5405BAE67B7A1107E685D6CB934A422673ED632BD91BF84758C9B504DBFF7835E36B038C74400C983452CFEE72FACF76D3AE196BA44DF804657B92D6B646DA47910E53FAE8979C1DA9120C672CD4AAD18A7BDBA2AD397F7B0E01AA7AF4700F9A83EDBA90D25F74C1DCE0520BA9DE24636629D0140BB4BC6C2A703103E5A234BBB9154AEBA22D48F8EBC37368CCC68DC6BA310E2060EC37BCA2BF7DBD68F951BB23D7C018DB2CBC74752F5CED8ECA04EC743A8F4B503831DB09C387F6BD3A7DF1A25BCA452FFB852B134B67CCE4B0141E84B3D796BFDE7BFB2C34760C64200D40728560598B6FB965C0187495318A6EE97E6648F476939AE82F3D9D51761652672CFB3263385219E41D9A26ECFD975AB2005F67B9B6DB6D72ACE42C5079C2E11BEF3B2C0B334E9D4C2EFE518AD4BB8C0A9A995F99B4625D570E283D41EB4542BA37ADCEB772E45F77A72071874CBF8E9C2022DB9FAB62BB8BB11F72416193D10F4A493BDD9FB68A3BADF8130AE380D1987CD5ECCD6D9F5AD2F219D0076964D17F2232E5DAACB832D6E54A0CDAE72302C52604675053C5ED83680DB1D5A2FB9D4885B61E29465FDC016B9CE5DD93582A7221167E77C194C6E7A6D00E98A3E0FBE3987B1C5C1562AE878FC14AC7458003F949665D92F4F01B7A511C9C9126B79E32258AD5BFAB38B91B710AFDD222312DB543EA712C60CF8C8C0C9A7968A9AED867EA11E9718D25EF8A21F18A2F2B3FB28944F8E049705ADC399296AFBA30228CC7AF6D39F49689A16FF5FD64F09A2233970885EB76AEF2650D9A16CA594A3C67F0640095D10FB6E818BDC512F36446FB7277480BA1947D49A8AB5D78965DB16F2E50BFD09910DB0DD99654A32E07C86CF1601D618E7B9D2745C4CFC983E3D48FFE5A08AA471B29DD0E7BBE6DC1DE82FF8988E76835D0E03C177945886DC273C9C91B8B0950E7619490125AFC453772CB66D45D3CEBA3AFA919AE4AEF42D36AF7EDC4C5F030B5720C82FB229E9DDB612067F 20160401171656 2 6 100 8191 2 E8E5A3AF93DBD4FB99E4325B3B9308AE7731E7E27B532A2D0AF5306CB249EF6C63C7DFB66FC19B8E84A5672B378D77DD413933ACA7F62EABCD4012865D9336A47AD7E596B21EA5B6A2695C0F6C1C70D92CFF3CA18522B29993AA0A43A6849CEFFF53DF7E33C833B5B0037D8906528C80F98C2FC22F0C43B933795D153ECD05FC0D734F4EC61BBBD611F61CACA7CEC4FEF72A127074ACF73A11B1004A954C48D18E74B534E318069C5CE76C1D9BBB0326432B3C39F26058B6D6077B562CBE0DCA4E5B53F1CF9B80EB4F40DA6DAADF924DD2E7A689321F1558FFB55DA7B91009767791BDA252285D117D45A77FF044F467273CDEA8D4B5AC83DBF16DDB8F5FA4C1556129FFF4213D199DE4E0996BAA284FEC13A86A9F81E7FEAD84B4C59CC6DD641ADDE2E74DEAAD096E53F1F9509BF4A5405BAE67B7A1107E685D6CB934A422673ED632BD91BF84758C9B504DBFF7835E36B038C74400C983452CFEE72FACF76D3AE196BA44DF804657B92D6B646DA47910E53FAE8979C1DA9120C672CD4AAD18A7BDBA2AD397F7B0E01AA7AF4700F9A83EDBA90D25F74C1DCE0520BA9DE24636629D0140BB4BC6C2A703103E5A234BBB9154AEBA22D48F8EBC37368CCC68DC6BA310E2060EC37BCA2BF7DBD68F951BB23D7C018DB2CBC74752F5CED8ECA04EC743A8F4B503831DB09C387F6BD3A7DF1A25BCA452FFB852B134B67CCE4B0141E84B3D796BFDE7BFB2C34760C64200D40728560598B6FB965C0187495318A6EE97E6648F476939AE82F3D9D51761652672CFB3263385219E41D9A26ECFD975AB2005F67B9B6DB6D72ACE42C5079C2E11BEF3B2C0B334E9D4C2EFE518AD4BB8C0A9A995F99B4625D570E283D41EB4542BA37ADCEB772E45F77A72071874CBF8E9C2022DB9FAB62BB8BB11F72416193D10F4A493BDD9FB68A3BADF8130AE380D1987CD5ECCD6D9F5AD2F219D0076964D17F2232E5DAACB832D6E54A0CDAE72302C52604675053C5ED83680DB1D5A2FB9D4885B61E29465FDC016B9CE5DD93582A7221167E77C194C6E7A6D00E98A3E0FBE3987B1C5C1562AE878FC14AC7458003F949665D92F4F01B7A511C9C9126B79E32258AD5BFAB38B91B710AFDD222312DB543EA712C60CF8C8C0C9A7968A9AED867EA11E9718D25EF8A21F18A2F2B3FB28944F8E049705ADC399296AFBA30228CC7AF6D39F49689A16FF5FD64F09A2233970885EB76AEF2650D9A16CA594A3C67F0640095D10FB6E818BDC512F36446FB7277480BA1947D49A8AB5D78965DB16F2E50BFD09910DB0DD99654A32E07C86CF1601D618E7B9D2745C4CFC983E3D48FFE5A08AA471B29DD0E7BBE6DC1DE82FF8988E76835D0E03C177945886DC273C9C91B8B0950E7619490125AFC453772CB66D45D3CEBA3AFA919AE4AEF42D36AF7EDC4C5F030B5720C82FB229E9DDB86F198B openssh-7.5p1/moduli.5010064400017500001750000000071451306364033700130470ustar00djmdjm.\" $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.5p1/moduli.c010064400017500001750000000507251306364033700131270ustar00djmdjm/* $OpenBSD: moduli.c,v 1.31 2016/09/12 01:22:38 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 #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 = MAXIMUM(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.5p1/monitor.c010064400017500001750000001275231306364033700133260ustar00djmdjm/* $OpenBSD: monitor.c,v 1.167 2017/02/03 23:05:57 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 #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" #include "auth-pam.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" #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; /* 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_ONCE, mm_answer_pam_init_ctx}, {MONITOR_REQ_PAM_QUERY, 0, mm_answer_pam_query}, {MONITOR_REQ_PAM_RESPOND, MON_ONCE, 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, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok}, {MONITOR_REQ_GSSCHECKMIC, MON_ONCE, 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; /* 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 ssh *ssh = active_state; /* XXX */ 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; 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); /* 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 (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); ssh_packet_set_log_preamble(ssh, "user %s", 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 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); 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); } 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, is_proof = 0; u_int keyid; 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)); if (keyid > INT_MAX) fatal("%s: invalid key ID", __func__); /* * 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) { struct ssh *ssh = active_state; /* XXX */ 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: ssh_packet_set_log_preamble(ssh, "%suser %s", authctxt->valid ? "authenticating" : "invalid ", authctxt->user); 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 (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); /* 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; if (!options.password_authentication) fatal("%s: password authentication not enabled", __func__); 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); #ifdef USE_PAM buffer_put_int(m, sshpam_get_maxtries_reached()); #endif 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; if (!options.kbd_interactive_authentication) fatal("%s: kbd-int authentication not enabled", __func__); 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 (!options.kbd_interactive_authentication) fatal("%s: kbd-int authentication not enabled", __func__); 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); auth_method = "keyboard-interactive"; auth_submethod = "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); if (options.kbd_interactive_authentication) monitor_permit(mon_dispatch, MONITOR_REQ_PAM_INIT_CTX, 1); return (0); } int mm_answer_pam_account(int sock, Buffer *m) { u_int ret; if (!options.use_pam) fatal("%s: PAM not enabled", __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__); if (!options.kbd_interactive_authentication) fatal("%s: kbd-int authentication not enabled", __func__); if (sshpam_ctxt != NULL) fatal("%s: already called", __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); monitor_permit(mon_dispatch, MONITOR_REQ_PAM_QUERY, 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; if (sshpam_ctxt == NULL) fatal("%s: no context", __func__); 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) fatal("sshpam_device.query failed"); monitor_permit(mon_dispatch, MONITOR_REQ_PAM_RESPOND, 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, sshpam_get_maxtries_reached()); 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__); if (sshpam_ctxt == NULL) fatal("%s: no context", __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__); if (sshpam_ctxt == NULL) fatal("%s: no context", __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); /* Allow another attempt */ monitor_permit(mon_dispatch, MONITOR_REQ_PAM_INIT_CTX, 1); 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); 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; default: fatal("%s: unknown key type %d", __func__, type); break; } } debug3("%s: key %p is %s", __func__, key, allowed ? "allowed" : "not allowed"); 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); } buffer_clear(m); buffer_put_int(m, allowed); buffer_put_int(m, forced_command != NULL); mm_request_send(sock, MONITOR_ANS_KEYALLOWED, m); return (0); } static int monitor_valid_userblob(u_char *data, u_int datalen) { Buffer b; u_char *p; char *userstyle, *cp; 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++; cp = buffer_get_cstring(&b, NULL); xasprintf(&userstyle, "%s%s%s", authctxt->user, authctxt->style ? ":" : "", authctxt->style ? authctxt->style : ""); if (strcmp(userstyle, cp) != 0) { logit("wrong user name passed to monitor: " "expected %s != %.100s", userstyle, cp); fail++; } free(userstyle); free(cp); buffer_skip_string(&b); if (datafellows & SSH_BUG_PKAUTH) { if (!buffer_get_char(&b)) fail++; } else { cp = buffer_get_cstring(&b, NULL); if (strcmp("publickey", cp) != 0) fail++; free(cp); 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) { struct ssh *ssh = active_state; /* XXX */ socklen_t fromlen; struct sockaddr_storage from; /* * 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, session_get_remote_name_or_ip(ssh, 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); } 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_GRP14_SHA256] = kexdh_server; kex->kex[KEX_DH_GRP16_SHA512] = kexdh_server; kex->kex[KEX_DH_GRP18_SHA512] = 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; } } /* 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 monitor *mon; mon = xcalloc(1, sizeof(*mon)); monitor_openfds(mon, 1); 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; if (!options.gss_authentication) fatal("%s: GSSAPI authentication not enabled", __func__); 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; if (!options.gss_authentication) fatal("%s: GSSAPI authentication not enabled", __func__); 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; if (!options.gss_authentication) fatal("%s: GSSAPI authentication not enabled", __func__); 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; if (!options.gss_authentication) fatal("%s: GSSAPI authentication not enabled", __func__); 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.5p1/monitor.h010064400017500001750000000075651306364033700133360ustar00djmdjm/* $OpenBSD: monitor.h,v 1.20 2016/09/28 16:33:07 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 _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 monitor { int m_recvfd; int m_sendfd; int m_log_recvfd; int m_log_sendfd; struct kex **m_pkex; pid_t m_pid; }; struct monitor *monitor_init(void); void monitor_reinit(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.5p1/monitor_fdpass.c010064400017500001750000000113331306364033700146550ustar00djmdjm/* $OpenBSD: monitor_fdpass.c,v 1.21 2016/02/29 20:22:36 jca 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 %zd", __func__, 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 %zd", __func__, 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.5p1/monitor_fdpass.h010064400017500001750000000027721306364033700146710ustar00djmdjm/* $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.5p1/monitor_wrap.c010064400017500001750000000536331306364033700143570ustar00djmdjm/* $OpenBSD: monitor_wrap.c,v 1.89 2016/08/13 17:47:41 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" #include "auth-pam.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 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); #ifdef USE_PAM sshpam_set_maxtries_reached(buffer_get_int(&m)); #endif 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, const char *user, const char *host, Key *key) { return (mm_key_allowed(MM_HOSTKEY, user, host, key, 0)); } int mm_key_allowed(enum mm_keytype type, const char *user, const 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); sshpam_set_maxtries_reached(buffer_get_int(&m)); *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); } 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 */ #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.5p1/monitor_wrap.h010064400017500001750000000071351306364033700143600ustar00djmdjm/* $OpenBSD: monitor_wrap.h,v 1.32 2016/09/28 16:33:07 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_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 }; 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, const char *, const char *, Key *, int); int mm_user_key_allowed(struct passwd *, Key *, int); int mm_hostbased_key_allowed(struct passwd *, const char *, const char *, Key *); int mm_key_verify(Key *, u_char *, u_int, u_char *, u_int); #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 *); /* 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 **); #endif /* _MM_WRAP_H_ */ openssh-7.5p1/msg.c010064400017500001750000000054021306364033700124140ustar00djmdjm/* $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.5p1/msg.h010064400017500001750000000027641306364033700124310ustar00djmdjm/* $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.5p1/mux.c010064400017500001750000001667331306364033700124560ustar00djmdjm/* $OpenBSD: mux.c,v 1.64 2017/01/21 11:32:04 guenther 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" #include "ssherr.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; /* 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_C_PROXY 0x1000000f #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_S_PROXY 0x8000000f /* 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 int process_mux_proxy(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 }, { MUX_C_PROXY, process_mux_proxy }, { 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; } static int process_mux_proxy(u_int rid, Channel *c, Buffer *m, Buffer *r) { debug("%s: channel %d: proxy request", __func__, c->self); c->mux_rcb = channel_proxy_downstream; buffer_put_int(r, MUX_S_PROXY); 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_proxy(int fd) { Buffer m; char *e; u_int type, rid; buffer_init(&m); buffer_put_int(&m, MUX_C_PROXY); 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_PROXY) { 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); buffer_free(&m); debug3("%s: done", __func__); muxclient_request_id++; return 0; } 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, options.stdio_forward_host); buffer_put_int(&m, options.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. */ int muxclient(const char *path) { struct sockaddr_un addr; int sock; u_int pid; if (muxclient_command == 0) { if (options.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 -1; } memset(&addr, '\0', sizeof(addr)); addr.sun_family = AF_UNIX; if (strlcpy(addr.sun_path, path, sizeof(addr.sun_path)) >= sizeof(addr.sun_path)) fatal("ControlPath too long ('%s' >= %u bytes)", path, (unsigned int)sizeof(addr.sun_path)); if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) fatal("%s socket(): %s", __func__, strerror(errno)); if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == -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 -1; } set_nonblock(sock); if (mux_client_hello_exchange(sock) != 0) { error("%s: master hello exchange failed", __func__); close(sock); return -1; } 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); if (options.log_level != SYSLOG_LEVEL_QUIET) 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 -1; } mux_client_request_session(sock); return -1; case SSHMUX_COMMAND_STDIO_FWD: mux_client_request_stdio_fwd(sock); exit(0); case SSHMUX_COMMAND_STOP: mux_client_request_stop_listening(sock); if (options.log_level != SYSLOG_LEVEL_QUIET) 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); case SSHMUX_COMMAND_PROXY: mux_client_proxy(sock); return (sock); default: fatal("unrecognised muxclient_command %d", muxclient_command); } } openssh-7.5p1/myproposal.h010064400017500001750000000124471306364033700140470ustar00djmdjm/* $OpenBSD: myproposal.h,v 1.54 2016/09/28 16:33:07 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_SHA2_METHODS \ "diffie-hellman-group-exchange-sha256," \ "diffie-hellman-group16-sha512," \ "diffie-hellman-group18-sha512," # define KEX_SHA2_GROUP14 \ "diffie-hellman-group14-sha256," #define SHA2_HMAC_MODES \ "hmac-sha2-256," \ "hmac-sha2-512," #else # define KEX_SHA2_METHODS # define KEX_SHA2_GROUP14 # define SHA2_HMAC_MODES #endif #ifdef WITH_OPENSSL # ifdef HAVE_EVP_SHA256 # define KEX_CURVE25519_METHODS \ "curve25519-sha256," \ "curve25519-sha256@libssh.org," # else # define KEX_CURVE25519_METHODS "" # endif #define KEX_COMMON_KEX \ KEX_CURVE25519_METHODS \ KEX_ECDH_METHODS \ KEX_SHA2_METHODS #define KEX_SERVER_KEX KEX_COMMON_KEX \ KEX_SHA2_GROUP14 \ "diffie-hellman-group14-sha1" \ #define KEX_CLIENT_KEX KEX_COMMON_KEX \ "diffie-hellman-group-exchange-sha1," \ KEX_SHA2_GROUP14 \ "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" #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," \ "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" #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.5p1/nchan.c010064400017500001750000000315231306364033700127200ustar00djmdjm/* $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.5p1/nchan.ms010064400017500001750000000075561306364033700131260ustar00djmdjm.\" $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.5p1/nchan2.ms010064400017500001750000000066021306364033700131770ustar00djmdjm.\" $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.5p1/opacket.c010064400017500001750000000135311306364033700132560ustar00djmdjm/* 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.5p1/opacket.h010064400017500001750000000145511306364033700132660ustar00djmdjm#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_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) #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) #define packet_set_mux() \ ssh_packet_set_mux(active_state) #define packet_get_mux() \ ssh_packet_get_mux(active_state) #endif /* _OPACKET_H */ openssh-7.5p1/openbsd-compat004075500017500001750000000000001306364033700143205ustar00djmdjmopenssh-7.5p1/openbsd-compat/Makefile.in010064400017500001750000000027731306364033700164520ustar00djmdjm# $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 strcasestr.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-err.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 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.5p1/openbsd-compat/arc4random.c010064400017500001750000000155621306364033700166030ustar00djmdjm/* 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 0x%lx)", (unsigned long)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.5p1/openbsd-compat/base64.c010064400017500001750000000243761306364033700156400ustar00djmdjm/* $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.5p1/openbsd-compat/base64.h010064400017500001750000000053071306364033700156360ustar00djmdjm/* * 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.5p1/openbsd-compat/basename.c010064400017500001750000000034341306364033700163170ustar00djmdjm/* $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.5p1/openbsd-compat/bcrypt_pbkdf.c010064400017500001750000000126061306364033700172160ustar00djmdjm/* $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.5p1/openbsd-compat/bindresvport.c010064400017500001750000000063711306364033700172700ustar00djmdjm/* 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; salen = sizeof(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.5p1/openbsd-compat/blf.h010064400017500001750000000067661306364033700153270ustar00djmdjm/* $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.5p1/openbsd-compat/blowfish.c010064400017500001750000000561571306364033700163730ustar00djmdjm/* $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.5p1/openbsd-compat/bsd-asprintf.c010064400017500001750000000041531306364033700171370ustar00djmdjm/* * 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 #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.5p1/openbsd-compat/bsd-closefrom.c010064400017500001750000000055321306364033700173040ustar00djmdjm/* * 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.5p1/openbsd-compat/bsd-cray.c010064400017500001750000000477331306364033700162620ustar00djmdjm/* * * 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.5p1/openbsd-compat/bsd-cray.h010064400017500001750000000040301306364033700162460ustar00djmdjm/* * 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.5p1/openbsd-compat/bsd-cygwin_util.c010064400017500001750000000062071306364033700176500ustar00djmdjm/* * 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.5p1/openbsd-compat/bsd-cygwin_util.h010064400017500001750000000045421306364033700176550ustar00djmdjm/* * 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.5p1/openbsd-compat/bsd-err.c010064400017500001750000000040701306364033700160770ustar00djmdjm/* * Copyright (c) 2015 Tim Rice * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must 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. */ #include "includes.h" #ifndef HAVE_ERR 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); } #endif #ifndef HAVE_ERRX 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); } #endif #ifndef HAVE_WARN 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); } #endif openssh-7.5p1/openbsd-compat/bsd-getpeereid.c010064400017500001750000000032651306364033700174310ustar00djmdjm/* * 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.5p1/openbsd-compat/bsd-misc.c010064400017500001750000000136061306364033700162470ustar00djmdjm /* * 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 #ifndef HAVE_MBTOWC /* a mbtowc that only supports ASCII */ int mbtowc(wchar_t *pwc, const char *s, size_t n) { if (s == NULL || *s == '\0') return 0; /* ASCII is not state-dependent */ if (*s < 0 || *s > 0x7f || n < 1) { errno = EOPNOTSUPP; return -1; } if (pwc != NULL) *pwc = *s; return 1; } #endif #ifndef HAVE_LLABS long long llabs(long long j) { return (j < 0 ? -j : j); } #endif openssh-7.5p1/openbsd-compat/bsd-misc.h010064400017500001750000000065561306364033700162620ustar00djmdjm/* * 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 /* bsd-err.h */ #ifndef HAVE_ERR void err(int, const char *, ...) __attribute__((format(printf, 2, 3))); #endif #ifndef HAVE_ERRX void errx(int, const char *, ...) __attribute__((format(printf, 2, 3))); #endif #ifndef HAVE_WARN void warn(const char *, ...) __attribute__((format(printf, 1, 2))); #endif #ifndef HAVE_LLABS long long llabs(long long); #endif #endif /* _BSD_MISC_H */ openssh-7.5p1/openbsd-compat/bsd-nextstep.c010064400017500001750000000050001306364033700171530ustar00djmdjm/* * 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.5p1/openbsd-compat/bsd-nextstep.h010064400017500001750000000043441306364033700171720ustar00djmdjm/* * 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.5p1/openbsd-compat/bsd-poll.c010064400017500001750000000056441306364033700162650ustar00djmdjm/* * 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.5p1/openbsd-compat/bsd-openpty.c010064400017500001750000000127441306364033700170140ustar00djmdjm/* * 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.5p1/openbsd-compat/bsd-poll.h010064400017500001750000000041011306364033700162550ustar00djmdjm/* $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.5p1/openbsd-compat/bsd-setres_id.c010064400017500001750000000045361306364033700172770ustar00djmdjm/* * 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.5p1/openbsd-compat/bsd-setres_id.h010064400017500001750000000016421306364033700172770ustar00djmdjm/* * 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.5p1/openbsd-compat/bsd-snprintf.c010064400017500001750000000511241306364033700171540ustar00djmdjm/* * 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 #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.5p1/openbsd-compat/bsd-statvfs.c010064400017500001750000000037621306364033700170100ustar00djmdjm/* * 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.5p1/openbsd-compat/bsd-statvfs.h010064400017500001750000000043051306364033700170070ustar00djmdjm/* * 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.5p1/openbsd-compat/bsd-waitpid.c010064400017500001750000000034271306364033700167550ustar00djmdjm/* * 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.5p1/openbsd-compat/bsd-waitpid.h010064400017500001750000000040271306364033700167570ustar00djmdjm/* * 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.5p1/openbsd-compat/chacha_private.h010064400017500001750000000124151306364033700175110ustar00djmdjm/* 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.5p1/openbsd-compat/charclass.h010064400017500001750000000012761306364033700165160ustar00djmdjm/* * 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.5p1/openbsd-compat/daemon.c010064400017500001750000000045131306364033700160060ustar00djmdjm/* $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.5p1/openbsd-compat/dirname.c010064400017500001750000000035701306364033700161640ustar00djmdjm/* $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.5p1/openbsd-compat/explicit_bzero.c010064400017500001750000000020541306364033700175630ustar00djmdjm/* 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" #include /* * 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) { /* * clang -fsanitize=memory needs to intercept memset-like functions * to correctly detect memory initialisation. Make sure one is called * directly since our indirection trick above sucessfully confuses it. */ #if defined(__has_feature) # if __has_feature(memory_sanitizer) memset(p, 0, n); # endif #endif ssh_bzero(p, n); } #endif /* HAVE_MEMSET_S */ #endif /* HAVE_EXPLICIT_BZERO */ openssh-7.5p1/openbsd-compat/fake-rfc2553.c010064400017500001750000000142271306364033700165430ustar00djmdjm/* * 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.5p1/openbsd-compat/fake-rfc2553.h010064400017500001750000000123151306364033700165440ustar00djmdjm/* * 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.5p1/openbsd-compat/fmt_scaled.c010064400017500001750000000166261306364033700166540ustar00djmdjm/* $OpenBSD: fmt_scaled.c,v 1.13 2017/03/11 23:37:23 djm 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((unsigned char)*p) && isspace((unsigned char)*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((unsigned char)*p) && (isdigit((unsigned char)*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 */ if (fpart >= LLONG_MAX / 10) { errno = ERANGE; return -1; } fpart *= 10; fpart += i; } else { /* normal digit */ if (++ndigits >= MAX_DIGITS) { errno = ERANGE; return -1; } if (whole >= LLONG_MAX / 10) { 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((unsigned char)scale_chars[i])) { /* If it ends with alphanumerics after the scale char, bad. */ if (isalnum((unsigned char)*(p+1))) { errno = EINVAL; return -1; } scale_fact = scale_factors[i]; if (whole >= LLONG_MAX / scale_fact) { errno = ERANGE; return -1; } /* 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; } } /* Invalid unit or character */ errno = EINVAL; 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 = llabs(number); /* 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.5p1/openbsd-compat/getcwd.c010064400017500001750000000137101306364033700160170ustar00djmdjm/* $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.5p1/openbsd-compat/getgrouplist.c010064400017500001750000000053171306364033700172760ustar00djmdjm/* $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.5p1/openbsd-compat/getopt.h010064400017500001750000000053221306364033700160510ustar00djmdjm/* $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.5p1/openbsd-compat/getopt_long.c010064400017500001750000000347331306364033700170730ustar00djmdjm/* $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.5p1/openbsd-compat/glob.c010064400017500001750000000630331306364033700154700ustar00djmdjm/* $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.5p1/openbsd-compat/getrrsetbyname-ldns.c010064400017500001750000000174761306364033700205500ustar00djmdjm/* $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.5p1/openbsd-compat/getrrsetbyname.c010064400017500001750000000330741306364033700176020ustar00djmdjm/* $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.5p1/openbsd-compat/getrrsetbyname.h010064400017500001750000000071741306364033700176110ustar00djmdjm/* 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.5p1/openbsd-compat/glob.h010064400017500001750000000110521306364033700154670ustar00djmdjm/* $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.5p1/openbsd-compat/inet_aton.c010064400017500001750000000123501306364033700165210ustar00djmdjm/* $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.5p1/openbsd-compat/inet_ntoa.c010064400017500001750000000043271306364033700165260ustar00djmdjm/* $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.5p1/openbsd-compat/inet_ntop.c010064400017500001750000000126621306364033700165460ustar00djmdjm/* $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.5p1/openbsd-compat/kludge-fd_set.c010064400017500001750000000015621306364033700172610ustar00djmdjm/* 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.5p1/openbsd-compat/md5.c010064400017500001750000000175161306364033700152370ustar00djmdjm/* $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.5p1/openbsd-compat/md5.h010064400017500001750000000035431306364033700152370ustar00djmdjm/* $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.5p1/openbsd-compat/mktemp.c010064400017500001750000000062201306364033700160350ustar00djmdjm/* 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.5p1/openbsd-compat/openbsd-compat.h010064400017500001750000000202721306364033700174630ustar00djmdjm/* * 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 #include /* for wchar_t */ /* 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 size_t strlcpy(char *dst, const char *src, size_t siz); #endif #ifndef HAVE_STRLCAT size_t strlcat(char *dst, const char *src, size_t siz); #endif #ifndef HAVE_STRCASESTR char *strcasestr(const char *, const char *); #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 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 */ #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 #ifndef HAVE_WCWIDTH # define wcwidth(x) (((x) >= 0x20 && (x) <= 0x7e) ? 1 : -1) /* force our no-op nl_langinfo and mbtowc */ # undef HAVE_NL_LANGINFO # undef HAVE_MBTOWC # undef HAVE_LANGINFO_H #endif #ifndef HAVE_NL_LANGINFO # define nl_langinfo(x) "" #endif #ifndef HAVE_MBTOWC int mbtowc(wchar_t *, const char*, size_t); #endif #if !defined(HAVE_VASPRINTF) || !defined(HAVE_VSNPRINTF) # include #endif /* * Some platforms unconditionally undefine va_copy() so we define VA_COPY() * instead. This is known to be the case on at least some configurations of * AIX with the xlc compiler. */ #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 #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 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.5p1/openbsd-compat/openssl-compat.c010064400017500001750000000044151306364033700175100ustar00djmdjm/* * 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.5p1/openbsd-compat/openssl-compat.h010064400017500001750000000060731306364033700175170ustar00djmdjm/* * 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 #if defined(HAVE_EVP_RIPEMD160) # if defined(OPENSSL_NO_RIPEMD) || defined(OPENSSL_NO_RMD160) # undef HAVE_EVP_RIPEMD160 # 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.5p1/openbsd-compat/port-aix.c010064400017500001750000000305641306364033700163130ustar00djmdjm/* * * 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.5p1/openbsd-compat/port-aix.h010064400017500001750000000103231306364033700163070ustar00djmdjm/* * * 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.5p1/openbsd-compat/port-irix.c010064400017500001750000000057051306364033700165040ustar00djmdjm/* * 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.5p1/openbsd-compat/port-irix.h010064400017500001750000000032271306364033700165060ustar00djmdjm/* * 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.5p1/openbsd-compat/port-linux.c010064400017500001750000000170101306364033700166600ustar00djmdjm/* * 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.5p1/openbsd-compat/port-linux.h010064400017500001750000000022651306364033700166730ustar00djmdjm/* * 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.5p1/openbsd-compat/port-solaris.c010064400017500001750000000230761306364033700172060ustar00djmdjm/* * 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))) != NULL) { /* 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.5p1/openbsd-compat/port-solaris.h010064400017500001750000000024221306364033700172030ustar00djmdjm/* * 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 #include 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.5p1/openbsd-compat/port-tun.c010064400017500001750000000143451306364033700163370ustar00djmdjm/* * 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.5p1/openbsd-compat/port-tun.h010064400017500001750000000022471306364033700163420ustar00djmdjm/* * 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.5p1/openbsd-compat/port-uw.c010064400017500001750000000101551306364033700161570ustar00djmdjm/* * 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.5p1/openbsd-compat/port-uw.h010064400017500001750000000025751306364033700161730ustar00djmdjm/* * 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.5p1/openbsd-compat/pwcache.c010064400017500001750000000063421306364033700161570ustar00djmdjm/* $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.5p1/openbsd-compat/readpassphrase.c010064400017500001750000000136111306364033700175470ustar00djmdjm/* $OpenBSD: readpassphrase.c,v 1.26 2016/10/18 12:47:18 millert Exp $ */ /* * Copyright (c) 2000-2002, 2007, 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. * * 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 #ifndef TCSASOFT /* If we don't have TCSASOFT define it so that ORing it it below is a no-op. */ # define TCSASOFT 0 #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; } /* * Turn off echo if possible. * If we are using a tty but are not the foreground pgrp this will * generate SIGTTOU, so do it *before* installing the signal handlers. */ 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, TCSAFLUSH|TCSASOFT, &term); } else { memset(&term, 0, sizeof(term)); term.c_lflag |= ECHO; memset(&oterm, 0, sizeof(oterm)); oterm.c_lflag |= ECHO; } /* * 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); 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((unsigned char)ch)) { if ((flags & RPP_FORCELOWER)) ch = (char)tolower((unsigned char)ch); if ((flags & RPP_FORCEUPPER)) ch = (char)toupper((unsigned char)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) { const int sigttou = signo[SIGTTOU]; /* Ignore SIGTTOU generated when we are not the fg pgrp. */ while (tcsetattr(input, TCSAFLUSH|TCSASOFT, &oterm) == -1 && errno == EINTR && !signo[SIGTTOU]) continue; signo[SIGTTOU] = sigttou; } (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); } DEF_WEAK(readpassphrase); #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.5p1/openbsd-compat/readpassphrase.h010064400017500001750000000034031306364033700175520ustar00djmdjm/* $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.5p1/openbsd-compat/reallocarray.c010064400017500001750000000027641306364033700172310ustar00djmdjm/* $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.5p1/openbsd-compat/realpath.c010064400017500001750000000141171306364033700163440ustar00djmdjm/* $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.5p1/openbsd-compat/regress004075500017500001750000000000001306364033700157725ustar00djmdjmopenssh-7.5p1/openbsd-compat/regress/Makefile.in010064400017500001750000000015661306364033700201230ustar00djmdjm# $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.5p1/openbsd-compat/regress/closefromtest.c010064400017500001750000000032131306364033700211020ustar00djmdjm/* * 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.5p1/openbsd-compat/regress/opensslvertest.c010064400017500001750000000047301306364033700213160ustar00djmdjm/* * 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.5p1/openbsd-compat/regress/snprintftest.c010064400017500001750000000036241306364033700207620ustar00djmdjm/* * 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.5p1/openbsd-compat/regress/strduptest.c010064400017500001750000000020751306364033700204370ustar00djmdjm/* * 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.5p1/openbsd-compat/regress/strtonumtest.c010064400017500001750000000047141306364033700210130ustar00djmdjm/* $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.5p1/openbsd-compat/rmd160.c010064400017500001750000000273361306364033700155640ustar00djmdjm/* * 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.5p1/openbsd-compat/rmd160.h010064400017500001750000000054711306364033700155650ustar00djmdjm/* $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.5p1/openbsd-compat/rresvport.c010064400017500001750000000057441306364033700166200ustar00djmdjm/* $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.5p1/openbsd-compat/setenv.c010064400017500001750000000134141306364033700160470ustar00djmdjm/* $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.5p1/openbsd-compat/setproctitle.c010064400017500001750000000110531306364033700172610ustar00djmdjm/* 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.5p1/openbsd-compat/sha1.c010064400017500001750000000122641306364033700154010ustar00djmdjm/* $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.5p1/openbsd-compat/sha1.h010064400017500001750000000043561306364033700154110ustar00djmdjm/* $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.5p1/openbsd-compat/sha2.c010064400017500001750000000616001306364033700154000ustar00djmdjm/* $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.5p1/openbsd-compat/sha2.h010064400017500001750000000132371306364033700154100ustar00djmdjm/* $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.5p1/openbsd-compat/sigact.c010064400017500001750000000075131306364033700160200ustar00djmdjm/* $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.5p1/openbsd-compat/sigact.h010064400017500001750000000072501306364033700160230ustar00djmdjm/* $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.5p1/openbsd-compat/strcasestr.c010064400017500001750000000045531306364033700167440ustar00djmdjm/* $OpenBSD: strcasestr.c,v 1.4 2015/08/31 02:53:57 guenther Exp $ */ /* $NetBSD: strcasestr.c,v 1.2 2005/02/09 21:35:47 kleink Exp $ */ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must 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/strcasestr.c */ #include "includes.h" #ifndef HAVE_STRCASESTR #include #include /* * Find the first occurrence of find in s, ignore case. */ char * strcasestr(const char *s, const char *find) { char c, sc; size_t len; if ((c = *find++) != 0) { c = (char)tolower((unsigned char)c); len = strlen(find); do { do { if ((sc = *s++) == 0) return (NULL); } while ((char)tolower((unsigned char)sc) != c); } while (strncasecmp(s, find, len) != 0); s--; } return ((char *)s); } DEF_WEAK(strcasestr); #endif openssh-7.5p1/openbsd-compat/strlcat.c010064400017500001750000000034161306364033700162200ustar00djmdjm/* $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.5p1/openbsd-compat/strlcpy.c010064400017500001750000000032241306364033700162410ustar00djmdjm/* $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.5p1/openbsd-compat/strmode.c010064400017500001750000000066031306364033700162220ustar00djmdjm/* $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.5p1/openbsd-compat/strnlen.c010064400017500001750000000022271306364033700162300ustar00djmdjm/* $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.5p1/openbsd-compat/strptime.c010064400017500001750000000224411306364033700164120ustar00djmdjm/* $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.5p1/openbsd-compat/strsep.c010064400017500001750000000051351306364033700160640ustar00djmdjm/* $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.5p1/openbsd-compat/strtoll.c010064400017500001750000000104461306364033700162500ustar00djmdjm/* $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.5p1/openbsd-compat/strtonum.c010064400017500001750000000035461306364033700164430ustar00djmdjm/* $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.5p1/openbsd-compat/strtoul.c010064400017500001750000000061071306364033700162600ustar00djmdjm/* $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.5p1/openbsd-compat/strtoull.c010064400017500001750000000062051306364033700164330ustar00djmdjm/* $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.5p1/openbsd-compat/sys-queue.h010064400017500001750000000516361306364033700165200ustar00djmdjm/* $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.5p1/openbsd-compat/sys-tree.h010064400017500001750000000612651306364033700163320ustar00djmdjm/* $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.5p1/openbsd-compat/timingsafe_bcmp.c010064400017500001750000000022551306364033700176730ustar00djmdjm/* $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.5p1/openbsd-compat/vis.c010064400017500001750000000137431306364033700153510ustar00djmdjm/* $OpenBSD: vis.c,v 1.25 2015/09/13 11:32:51 guenther 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 #include #include #include #include "vis.h" #define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') #define isvisible(c,flag) \ (((c) == '\\' || (flag & VIS_ALL) == 0) && \ (((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, flag)) { if ((c == '"' && (flag & VIS_DQ) != 0) || (c == '\\' && (flag & VIS_NOSLASH) == 0)) *dst++ = '\\'; *dst++ = c; *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); } DEF_WEAK(vis); /* * 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); } DEF_WEAK(strvis); 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, flag)) { if ((c == '"' && (flag & VIS_DQ) != 0) || (c == '\\' && (flag & VIS_NOSLASH) == 0)) { /* need space for the extra '\\' */ if (dst + 1 >= end) { i = 2; break; } *dst++ = '\\'; } i = 1; *dst++ = c; 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 stravis(char **outp, const char *src, int flag) { char *buf; int len, serrno; buf = reallocarray(NULL, 4, strlen(src) + 1); if (buf == NULL) return -1; len = strvis(buf, src, flag); serrno = errno; *outp = realloc(buf, len + 1); if (*outp == NULL) { *outp = buf; errno = serrno; } return (len); } 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.5p1/openbsd-compat/vis.h010064400017500001750000000071131306364033700153500ustar00djmdjm/* $OpenBSD: vis.h,v 1.15 2015/07/20 01:52:27 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 */ #define VIS_DQ 0x200 /* backslash-escape double quotes */ #define VIS_ALL 0x400 /* encode all 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 stravis(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.5p1/openbsd-compat/xcrypt.c010064400017500001750000000103571306364033700160770ustar00djmdjm/* * 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 #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 /* * Pick an appropriate password encryption type and salt for the running * system by searching through accounts until we find one that has a valid * salt. Usually this will be root unless the root account is locked out. * If we don't find one we return a traditional DES-based salt. */ static const char * pick_salt(void) { struct passwd *pw; char *passwd, *p; size_t typelen; static char salt[32]; if (salt[0] != '\0') return salt; strlcpy(salt, "xx", sizeof(salt)); setpwent(); while ((pw = getpwent()) != NULL) { passwd = shadow_pw(pw); if (passwd[0] == '$' && (p = strrchr(passwd+1, '$')) != NULL) { typelen = p - passwd + 1; strlcpy(salt, passwd, MIN(typelen, sizeof(salt))); explicit_bzero(passwd, strlen(passwd)); goto out; } } out: endpwent(); return salt; } char * xcrypt(const char *password, const char *salt) { char *crypted; /* * If we don't have a salt we are encrypting a fake password for * for timing purposes. Pick an appropriate salt. */ if (salt == NULL) salt = pick_salt(); # 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.5p1/openssh.xml.in010064400017500001750000000054271306364033700142770ustar00djmdjm openssh-7.5p1/opensshd.init.in010075500017500001750000000040471306364033700146060ustar00djmdjm#!@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() { @COMMENT_OUT_RSA1@ if [ ! -f $HOST_KEY_RSA1 ]; then @COMMENT_OUT_RSA1@ ${SSH_KEYGEN} -t rsa1 -f ${HOST_KEY_RSA1} -N "" @COMMENT_OUT_RSA1@ 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.5p1/packet.c010064400017500001750000002445021306364033700131030ustar00djmdjm/* $OpenBSD: packet.c,v 1.247 2017/03/11 13:07:35 markus 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 #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 #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; size_t packet_discard_mac_already; struct sshmac *packet_discard_mac; /* Used in packet_read_poll2() */ u_int packlen; /* Used in packet_send2 */ int rekeying; /* Used in ssh_packet_send_mux() */ int mux; /* 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; /* Hook for fuzzing inbound packets */ ssh_packet_hook_fn *hook_in; void *hook_in_ctx; 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; } void ssh_packet_set_input_hook(struct ssh *ssh, ssh_packet_hook_fn *hook, void *ctx) { ssh->state->hook_in = hook; ssh->state->hook_in_ctx = ctx; } /* 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); /* XXX need ssh_free_session_state? */ 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; } void ssh_packet_set_mux(struct ssh *ssh) { ssh->state->mux = 1; ssh->state->rekeying = 0; } int ssh_packet_get_mux(struct ssh *ssh) { return ssh->state->mux; } int ssh_packet_set_log_preamble(struct ssh *ssh, const char *fmt, ...) { va_list args; int r; free(ssh->log_preamble); if (fmt == NULL) ssh->log_preamble = NULL; else { va_start(args, fmt); r = vasprintf(&ssh->log_preamble, fmt, args); va_end(args); if (r < 0 || ssh->log_preamble == NULL) return SSH_ERR_ALLOC_FAIL; } return 0; } int ssh_packet_stop_discard(struct ssh *ssh) { struct session_state *state = ssh->state; int r; if (state->packet_discard_mac) { char buf[1024]; size_t dlen = PACKET_MAX_SIZE; if (dlen > state->packet_discard_mac_already) dlen -= state->packet_discard_mac_already; memset(buf, 'a', sizeof(buf)); while (sshbuf_len(state->incoming_packet) < dlen) 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), dlen, 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, size_t mac_already, 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; } /* * Record number of bytes over which the mac has already * been computed in order to minimize timing attacks. */ if (mac && mac->enabled) { state->packet_discard_mac = mac; state->packet_discard_mac_already = mac_already; } if (sshbuf_len(state->input) >= discard) return ssh_packet_stop_discard(ssh); 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; if (state->connection_in == -1 || state->connection_out == -1) return 0; /* 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_peer_port(sock); ssh->local_ipaddr = get_local_ipaddr(sock); ssh->local_port = get_local_port(sock); } else { ssh->remote_ipaddr = strdup("UNKNOWN"); ssh->remote_port = 65535; ssh->local_ipaddr = strdup("UNKNOWN"); ssh->local_port = 65535; } } 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; } /* * Returns the IP-address of the local host as a string. The returned * string must not be freed. */ const char * ssh_local_ipaddr(struct ssh *ssh) { (void)ssh_remote_ipaddr(ssh); /* Will lookup and cache. */ return ssh->local_ipaddr; } /* Returns the port number of the local host. */ int ssh_local_port(struct ssh *ssh) { (void)ssh_remote_ipaddr(ssh); /* Will lookup and cache. */ return ssh->local_port; } /* Closes the connection and clears and frees internal data structures. */ void ssh_packet_close(struct ssh *ssh) { struct session_state *state = ssh->state; 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); } } cipher_free(state->send_context); cipher_free(state->receive_context); state->send_context = state->receive_context = NULL; 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 */ } /* * 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 (!cipher_ctx_is_plaintext(state->send_context)) { 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 **ccp; struct packet_state *ps; u_int64_t *max_blocks; const char *wmsg, *dir; int r, crypt_type; debug2("set_newkeys: mode %d", mode); if (mode == MODE_OUT) { dir = "output"; ccp = &state->send_context; crypt_type = CIPHER_ENCRYPT; ps = &state->p_send; max_blocks = &state->max_blocks_out; } else { dir = "input"; ccp = &state->receive_context; crypt_type = CIPHER_DECRYPT; ps = &state->p_read; max_blocks = &state->max_blocks_in; } if (state->newkeys[mode] != NULL) { debug("%s: rekeying after %llu %s blocks" " (%llu bytes total)", __func__, (unsigned long long)ps->blocks, dir, (unsigned long long)ps->bytes); cipher_free(*ccp); *ccp = NULL; 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]); } /* note that both bytes and the seqnr are not reset */ ps->packets = ps->blocks = 0; /* 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(ccp, 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(*ccp)) != 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 = MINIMUM(*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 && (int64_t)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 */ 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 tmp, 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) { tmp = state->extra_pad; state->extra_pad = ROUNDUP(state->extra_pad, block_size); /* check if roundup overflowed */ if (state->extra_pad < tmp) return SSH_ERR_INVALID_ARGUMENT; tmp = (len + padlen) % state->extra_pad; /* Check whether pad calculation below will underflow */ if (tmp > state->extra_pad) return SSH_ERR_INVALID_ARGUMENT; pad = state->extra_pad - tmp; DBG(debug3("%s: adding %d (len %d padlen %d extra_pad %d)", __func__, pad, len, padlen, state->extra_pad)); tmp = padlen; padlen += pad; /* Check whether padlen calculation overflowed */ if (padlen < tmp) return SSH_ERR_INVALID_ARGUMENT; /* overflow */ state->extra_pad = 0; } if ((r = sshbuf_reserve(state->outgoing_packet, padlen, &cp)) != 0) goto out; if (enc && !cipher_ctx_is_plaintext(state->send_context)) { /* 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) { r = SSH_ERR_CONN_TIMEOUT; goto out; } /* 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 (!cipher_ctx_is_plaintext(state->receive_context)) { 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; } static int ssh_packet_read_poll2_mux(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) { struct session_state *state = ssh->state; const u_char *cp; size_t need; int r; if (ssh->kex) return SSH_ERR_INTERNAL_ERROR; *typep = SSH_MSG_NONE; cp = sshbuf_ptr(state->input); if (state->packlen == 0) { if (sshbuf_len(state->input) < 4 + 1) return 0; /* packet is incomplete */ state->packlen = PEEK_U32(cp); if (state->packlen < 4 + 1 || state->packlen > PACKET_MAX_SIZE) return SSH_ERR_MESSAGE_INCOMPLETE; } need = state->packlen + 4; if (sshbuf_len(state->input) < need) return 0; /* packet is incomplete */ sshbuf_reset(state->incoming_packet); if ((r = sshbuf_put(state->incoming_packet, cp + 4, state->packlen)) != 0 || (r = sshbuf_consume(state->input, need)) != 0 || (r = sshbuf_get_u8(state->incoming_packet, NULL)) != 0 || (r = sshbuf_get_u8(state->incoming_packet, typep)) != 0) return r; if (ssh_packet_log_type(*typep)) debug3("%s: type %u", __func__, *typep); /* sshbuf_dump(state->incoming_packet, stderr); */ /* reset for next packet */ state->packlen = 0; 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; u_int maclen, aadlen = 0, authlen = 0, block_size; struct sshenc *enc = NULL; struct sshmac *mac = NULL; struct sshcomp *comp = NULL; int r; if (state->mux) return ssh_packet_read_poll2_mux(ssh, typep, seqnr_p); *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, 0, 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, 0, 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; /* packet is incomplete */ #ifdef PACKET_DEBUG fprintf(stderr, "read_poll enc/full: "); sshbuf_dump(state->input, stderr); #endif /* EtM: check mac over encrypted input */ if (mac && mac->enabled && mac->etm) { if ((r = mac_check(mac, state->p_read.seqnr, sshbuf_ptr(state->input), aadlen + need, sshbuf_ptr(state->input) + aadlen + need + authlen, maclen)) != 0) { if (r == SSH_ERR_MAC_INVALID) logit("Corrupted MAC on input."); 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; if (mac && mac->enabled) { /* Not EtM: check MAC over cleartext */ if (!mac->etm && (r = mac_check(mac, state->p_read.seqnr, sshbuf_ptr(state->incoming_packet), sshbuf_len(state->incoming_packet), sshbuf_ptr(state->input), maclen)) != 0) { if (r != SSH_ERR_MAC_INVALID) goto out; logit("Corrupted MAC on input."); if (need + block_size > PACKET_MAX_SIZE) return SSH_ERR_INTERNAL_ERROR; return ssh_packet_start_discard(ssh, enc, mac, sshbuf_len(state->incoming_packet), PACKET_MAX_SIZE - need - block_size); } /* Remove MAC from input buffer */ 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 (state->hook_in != NULL && (r = state->hook_in(ssh, state->incoming_packet, typep, state->hook_in_ctx)) != 0) return r; 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)); } static void fmt_connection_id(struct ssh *ssh, char *s, size_t l) { snprintf(s, l, "%.200s%s%s port %d", ssh->log_preamble ? ssh->log_preamble : "", ssh->log_preamble ? " " : "", ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); } /* * Pretty-print connection-terminating errors and exit. */ void sshpkt_fatal(struct ssh *ssh, const char *tag, int r) { char remote_id[512]; fmt_connection_id(ssh, remote_id, sizeof(remote_id)); switch (r) { case SSH_ERR_CONN_CLOSED: logdie("Connection closed by %s", remote_id); case SSH_ERR_CONN_TIMEOUT: logdie("Connection %s %s timed out", ssh->state->server_side ? "from" : "to", remote_id); case SSH_ERR_DISCONNECTED: logdie("Disconnected from %s", remote_id); case SSH_ERR_SYSTEM_ERROR: if (errno == ECONNRESET) logdie("Connection reset by %s", remote_id); /* 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) { logdie("Unable to negotiate with %s: %s. " "Their offer: %s", remote_id, ssh_err(r), ssh->kex->failed_choice); } /* FALLTHROUGH */ default: logdie("%s%sConnection %s %s: %s", tag != NULL ? tag : "", tag != NULL ? ": " : "", ssh->state->server_side ? "from" : "to", remote_id, 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], remote_id[512]; 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. */ fmt_connection_id(ssh, remote_id, sizeof(remote_id)); va_start(args, fmt); vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); /* Display the error locally */ logit("Disconnecting %s: %.100s", remote_id, 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, u_int32_t seconds) { debug3("rekey after %llu bytes, %u seconds", (unsigned long long)bytes, (unsigned 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) { int r; 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; if ((r = ssh_packet_enable_delayed_compress(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_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_ctx_get_number(state->receive_context); 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 = 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_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_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); } static int ssh_packet_send_mux(struct ssh *ssh) { struct session_state *state = ssh->state; u_char type, *cp; size_t len; int r; if (ssh->kex) return SSH_ERR_INTERNAL_ERROR; len = sshbuf_len(state->outgoing_packet); if (len < 6) return SSH_ERR_INTERNAL_ERROR; cp = sshbuf_mutable_ptr(state->outgoing_packet); type = cp[5]; if (ssh_packet_log_type(type)) debug3("%s: type %u", __func__, type); /* drop everything, but the connection protocol */ if (type >= SSH2_MSG_CONNECTION_MIN && type <= SSH2_MSG_CONNECTION_MAX) { POKE_U32(cp, len - 4); if ((r = sshbuf_putb(state->output, state->outgoing_packet)) != 0) return r; /* sshbuf_dump(state->output, stderr); */ } sshbuf_reset(state->outgoing_packet); return 0; } /* send it */ int sshpkt_send(struct ssh *ssh) { if (ssh->state && ssh->state->mux) return ssh_packet_send_mux(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.5p1/packet.h010064400017500001750000000164311306364033700131060ustar00djmdjm/* $OpenBSD: packet.h,v 1.76 2017/02/03 23:03:33 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 local and remote ip addresses and ports */ char *remote_ipaddr; int remote_port; char *local_ipaddr; int local_port; /* Optional preamble for log messages (e.g. username) */ char *log_preamble; /* 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; }; typedef int (ssh_packet_hook_fn)(struct ssh *, struct sshbuf *, u_char *, void *); 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); void ssh_packet_set_input_hook(struct ssh *, ssh_packet_hook_fn *, void *); 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 *); void ssh_packet_set_mux(struct ssh *); int ssh_packet_get_mux(struct ssh *); int ssh_packet_set_log_preamble(struct ssh *, const char *, ...) __attribute__((format(printf, 2, 3))); int ssh_packet_log_type(u_char); 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 *); 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 *); const char *ssh_local_ipaddr(struct ssh *); int ssh_local_port(struct ssh *); void ssh_packet_set_rekey_limits(struct ssh *, u_int64_t, u_int32_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.5p1/pathnames.h010064400017500001750000000132601306364033700136140ustar00djmdjm/* $OpenBSD: pathnames.h,v 1.25 2016/03/31 05:24:06 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". */ #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" #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 /* Askpass program define */ #ifndef ASKPASS_PROGRAM #define ASKPASS_PROGRAM "/usr/lib/ssh/ssh-askpass" #endif /* ASKPASS_PROGRAM */ openssh-7.5p1/pkcs11.h010064400017500001750000001225761306364033700127510ustar00djmdjm/* $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.5p1/platform-pledge.c010064400017500001750000000035651306364033700147200ustar00djmdjm/* * 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.5p1/platform-tracing.c010064400017500001750000000033051306364033700150770ustar00djmdjm/* * Copyright (c) 2016 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 #if defined(HAVE_SYS_PRCTL_H) #include /* For prctl() and PR_SET_DUMPABLE */ #endif #ifdef HAVE_SYS_PTRACE_H #include #endif #ifdef HAVE_PRIV_H #include /* For setpflags() and __PROC_PROTECT */ #endif #include #include "log.h" void platform_disable_tracing(int strict) { #if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE) /* Disable ptrace on Linux without sgid bit */ if (prctl(PR_SET_DUMPABLE, 0) != 0 && strict) fatal("unable to make the process undumpable"); #endif #if defined(HAVE_SETPFLAGS) && defined(__PROC_PROTECT) /* On Solaris, we should make this process untraceable */ if (setpflags(__PROC_PROTECT, 1) != 0 && strict) fatal("unable to make the process untraceable"); #endif #ifdef PT_DENY_ATTACH /* Mac OS X */ if (ptrace(PT_DENY_ATTACH, 0, 0, 0) == -1 && strict) fatal("unable to set PT_DENY_ATTACH"); #endif } openssh-7.5p1/platform.c010064400017500001750000000117521306364033700134570ustar00djmdjm/* * 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 "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, unless * we are using PAM in which case it is the responsibility of the * PAM stack. */ if (!options.use_pam && (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.5p1/platform.h010064400017500001750000000026741306364033700134670ustar00djmdjm/* * 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); void platform_disable_tracing(int); /* in platform-pledge.c */ void platform_pledge_agent(void); void platform_pledge_sftp_server(void); void platform_pledge_mux(void); openssh-7.5p1/poly1305.c010064400017500001750000000110551306364033700131230ustar00djmdjm/* * 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.5p1/poly1305.h010064400017500001750000000012051306364033700131240ustar00djmdjm/* $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.5p1/progressmeter.c010064400017500001750000000167501306364033700145370ustar00djmdjm/* $OpenBSD: progressmeter.c,v 1.45 2016/06/30 05:17:05 dtucker 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 double start; /* start progress */ static double 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]; off_t transferred; double elapsed, now; 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_double(); 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 || cur_pos == end_pos) percent = 100; else percent = ((float)cur_pos / end_pos) * 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_double(); 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.5p1/progressmeter.h010064400017500001750000000027011306364033700145330ustar00djmdjm/* $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.5p1/readconf.c010064400017500001750000002331571306364033700134210ustar00djmdjm/* $OpenBSD: readconf.c,v 1.270 2017/03/10 04:27:32 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 USE_SYSTEM_GLOB # include #else # include "openbsd-compat/glob.h" #endif #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 Ciphers 3des-cbc 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 Ciphers aes128-ctr 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 ~ */ static int read_config_file_depth(const char *filename, struct passwd *pw, const char *host, const char *original_host, Options *options, int flags, int *activep, int depth); static int process_config_line_depth(Options *options, struct passwd *pw, const char *host, const char *original_host, char *line, const char *filename, int linenum, int *activep, int flags, int depth); /* Keyword tokens. */ typedef enum { oBadOption, oHost, oMatch, oInclude, oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout, oGatewayPorts, oExitOnForwardFailure, oPasswordAuthentication, oRSAAuthentication, oChallengeResponseAuthentication, oXAuthLocation, oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward, oCertificateFile, oAddKeysToAgent, oIdentityAgent, 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, oProxyJump, oIgnoredUnknownOption, oDeprecated, oUnsupported } OpCodes; /* Textual representations of the tokens. */ static struct { const char *name; OpCodes opcode; } keywords[] = { /* Deprecated options */ { "fallbacktorsh", oDeprecated }, { "globalknownhostsfile2", oDeprecated }, { "rhostsauthentication", oDeprecated }, { "userknownhostsfile2", oDeprecated }, { "useroaming", oDeprecated }, { "usersh", oDeprecated }, /* Unsupported options */ { "afstokenpassing", oUnsupported }, { "kerberosauthentication", oUnsupported }, { "kerberostgtpassing", oUnsupported }, /* Sometimes-unsupported options */ #if defined(GSSAPI) { "gssapiauthentication", oGssAuthentication }, { "gssapidelegatecredentials", oGssDelegateCreds }, # else { "gssapiauthentication", oUnsupported }, { "gssapidelegatecredentials", oUnsupported }, #endif #ifdef ENABLE_PKCS11 { "smartcarddevice", oPKCS11Provider }, { "pkcs11provider", oPKCS11Provider }, # else { "smartcarddevice", oUnsupported }, { "pkcs11provider", oUnsupported }, #endif #ifdef WITH_SSH1 { "rsaauthentication", oRSAAuthentication }, { "rhostsrsaauthentication", oRhostsRSAAuthentication }, { "compressionlevel", oCompressionLevel }, # else { "rsaauthentication", oUnsupported }, { "rhostsrsaauthentication", oUnsupported }, { "compressionlevel", oUnsupported }, #endif { "forwardagent", oForwardAgent }, { "forwardx11", oForwardX11 }, { "forwardx11trusted", oForwardX11Trusted }, { "forwardx11timeout", oForwardX11Timeout }, { "exitonforwardfailure", oExitOnForwardFailure }, { "xauthlocation", oXAuthLocation }, { "gatewayports", oGatewayPorts }, { "useprivilegedport", oUsePrivilegedPort }, { "passwordauthentication", oPasswordAuthentication }, { "kbdinteractiveauthentication", oKbdInteractiveAuthentication }, { "kbdinteractivedevices", oKbdInteractiveDevices }, { "pubkeyauthentication", oPubkeyAuthentication }, { "dsaauthentication", oPubkeyAuthentication }, /* alias */ { "hostbasedauthentication", oHostbasedAuthentication }, { "challengeresponseauthentication", oChallengeResponseAuthentication }, { "skeyauthentication", oChallengeResponseAuthentication }, /* alias */ { "tisauthentication", oChallengeResponseAuthentication }, /* alias */ { "identityfile", oIdentityFile }, { "identityfile2", oIdentityFile }, /* obsolete */ { "identitiesonly", oIdentitiesOnly }, { "certificatefile", oCertificateFile }, { "addkeystoagent", oAddKeysToAgent }, { "identityagent", oIdentityAgent }, { "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 }, { "userknownhostsfile", oUserKnownHostsFile }, { "connectionattempts", oConnectionAttempts }, { "batchmode", oBatchMode }, { "checkhostip", oCheckHostIP }, { "stricthostkeychecking", oStrictHostKeyChecking }, { "compression", oCompression }, { "tcpkeepalive", oTCPKeepAlive }, { "keepalive", oTCPKeepAlive }, /* obsolete */ { "numberofpasswordprompts", oNumberOfPasswordPrompts }, { "loglevel", oLogLevel }, { "dynamicforward", oDynamicForward }, { "preferredauthentications", oPreferredAuthentications }, { "hostkeyalgorithms", oHostKeyAlgorithms }, { "bindaddress", oBindAddress }, { "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 }, { "include", oInclude }, { "tunnel", oTunnel }, { "tunneldevice", oTunnelDevice }, { "localcommand", oLocalCommand }, { "permitlocalcommand", oPermitLocalCommand }, { "visualhostkey", oVisualHostKey }, { "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 }, { "proxyjump", oProxyJump }, { 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; extern uid_t original_real_uid; int i; if (!bind_permitted(newfwd->listen_port, original_real_uid) && newfwd->listen_path == NULL) fatal("Privileged ports can only be forwarded by root."); /* Don't add duplicates */ for (i = 0; i < options->num_local_forwards; i++) { if (forward_equals(newfwd, options->local_forwards + i)) return; } 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; int i; /* Don't add duplicates */ for (i = 0; i < options->num_remote_forwards; i++) { if (forward_equals(newfwd, options->remote_forwards + i)) return; } 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. */ 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) { return process_config_line_depth(options, pw, host, original_host, line, filename, linenum, activep, flags, 0); } #define WHITESPACE " \t\r\n" static int process_config_line_depth(Options *options, struct passwd *pw, const char *host, const char *original_host, char *line, const char *filename, int linenum, int *activep, int flags, int depth) { char *s, **charptr, *endofnumber, *keyword, *arg, *arg2; char **cpptr, fwdarg[256]; u_int i, *uintptr, max_entries = 0; int r, oactive, 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; glob_t gl; if (activep == NULL) { /* We are processing a command line directive */ cmdline = 1; activep = &cmdline; } /* Strip trailing whitespace. Allow \f (form feed) at EOL only */ if ((len = strlen(line)) == 0) return 0; for (len--; len > 0; len--) { if (strchr(WHITESPACE "\f", 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; 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; /* Ignore ProxyCommand if ProxyJump already specified */ if (options->jump_host != NULL) charptr = &options->jump_host; /* Skip below */ 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 oProxyJump: if (s == NULL) { fatal("%.200s line %d: Missing argument.", filename, linenum); } len = strspn(s, WHITESPACE "="); if (parse_jump(s + len, options, *activep) == -1) { fatal("%.200s line %d: Invalid ProxyJump \"%s\"", filename, linenum, 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 (*arg != '-' && !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 (*arg != '-' && !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 (*arg != '-' && !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 (*arg != '-' && !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') { if ((flags & SSHCONF_NEVERMATCH) != 0) break; 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 = (flags & SSHCONF_NEVERMATCH) ? 0 : 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 oInclude: if (cmdline) fatal("Include directive not supported as a " "command-line option"); value = 0; while ((arg = strdelim(&s)) != NULL && *arg != '\0') { /* * Ensure all paths are anchored. User configuration * files may begin with '~/' but system configurations * must not. If the path is relative, then treat it * as living in ~/.ssh for user configurations or * /etc/ssh for system ones. */ if (*arg == '~' && (flags & SSHCONF_USERCONF) == 0) fatal("%.200s line %d: bad include path %s.", filename, linenum, arg); if (*arg != '/' && *arg != '~') { xasprintf(&arg2, "%s/%s", (flags & SSHCONF_USERCONF) ? "~/" _PATH_SSH_USER_DIR : SSHDIR, arg); } else arg2 = xstrdup(arg); memset(&gl, 0, sizeof(gl)); r = glob(arg2, GLOB_TILDE, NULL, &gl); if (r == GLOB_NOMATCH) { debug("%.200s line %d: include %s matched no " "files",filename, linenum, arg2); free(arg2); continue; } else if (r != 0 || gl.gl_pathc < 0) fatal("%.200s line %d: glob failed for %s.", filename, linenum, arg2); free(arg2); oactive = *activep; for (i = 0; i < (u_int)gl.gl_pathc; i++) { debug3("%.200s line %d: Including file %s " "depth %d%s", filename, linenum, gl.gl_pathv[i], depth, oactive ? "" : " (parse only)"); r = read_config_file_depth(gl.gl_pathv[i], pw, host, original_host, options, flags | SSHCONF_CHECKPERM | (oactive ? 0 : SSHCONF_NEVERMATCH), activep, depth + 1); if (r != 1 && errno != ENOENT) { fatal("Can't open user config file " "%.100s: %.100s", gl.gl_pathv[i], strerror(errno)); } /* * don't let Match in includes clobber the * containing file's Match state. */ *activep = oactive; if (r != 1) value = -1; } globfree(&gl); } if (value != 0) return value; break; 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 oIdentityAgent: charptr = &options->identity_agent; goto parse_string; 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) { int active = 1; return read_config_file_depth(filename, pw, host, original_host, options, flags, &active, 0); } #define READCONF_MAX_DEPTH 16 static int read_config_file_depth(const char *filename, struct passwd *pw, const char *host, const char *original_host, Options *options, int flags, int *activep, int depth) { FILE *f; char line[4096]; int linenum; int bad_options = 0; if (depth < 0 || depth > READCONF_MAX_DEPTH) fatal("Too many recursive configuration includes"); 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. */ linenum = 0; while (fgets(line, sizeof(line), f)) { /* Update line number counter. */ linenum++; if (strlen(line) == sizeof(line) - 1) fatal("%s line %d too long", filename, linenum); if (process_config_line_depth(options, pw, host, original_host, line, filename, linenum, activep, flags, depth) != 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->stdio_forward_host = NULL; options->stdio_forward_port = 0; options->clear_forwardings = -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->jump_user = NULL; options->jump_host = NULL; options->jump_port = -1; options->jump_extra = 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->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->identity_agent = NULL; 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; /* * stdio forwarding (-W) changes the default for these but we defer * setting the values so they can be overridden. */ if (options->exit_on_forward_failure == -1) options->exit_on_forward_failure = options->stdio_forward_host != NULL ? 1 : 0; if (options->clear_forwardings == -1) options->clear_forwardings = options->stdio_forward_host != NULL ? 1 : 0; if (options->clear_forwardings == 1) clear_forwardings(options); 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->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->identity_agent distinguishes NULL from 'none' */ /* 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); } int parse_jump(const char *s, Options *o, int active) { char *orig, *sdup, *cp; char *host = NULL, *user = NULL; int ret = -1, port = -1, first; active &= o->proxy_command == NULL && o->jump_host == NULL; orig = sdup = xstrdup(s); first = active; do { if ((cp = strrchr(sdup, ',')) == NULL) cp = sdup; /* last */ else *cp++ = '\0'; if (first) { /* First argument and configuration is active */ if (parse_user_host_port(cp, &user, &host, &port) != 0) goto out; } else { /* Subsequent argument or inactive configuration */ if (parse_user_host_port(cp, NULL, NULL, NULL) != 0) goto out; } first = 0; /* only check syntax for subsequent hosts */ } while (cp != sdup); /* success */ if (active) { o->jump_user = user; o->jump_host = host; o->jump_port = port; o->proxy_command = xstrdup("none"); user = host = NULL; if ((cp = strrchr(s, ',')) != NULL && cp != s) { o->jump_extra = xstrdup(s); o->jump_extra[cp - s] = '\0'; } } ret = 0; out: free(orig); free(user); free(host); return ret; } /* 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 && fwd->connect_host != NULL && strcmp(fwd->connect_host, "socks") != 0) continue; if (code == oLocalForward && fwd->connect_host != NULL && 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 buf[8]; /* 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(oClearAllForwardings, o->clear_forwardings); 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); #ifdef WITH_RSA1 dump_cfg_fmtint(oRhostsRSAAuthentication, o->rhosts_rsa_authentication); dump_cfg_fmtint(oRSAAuthentication, o->rsa_authentication); #endif 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); #ifdef WITH_SSH1 dump_cfg_int(oCompressionLevel, o->compression_level); #endif 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(oIdentityAgent, o->identity_agent); 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); #ifdef ENABLE_PKCS11 dump_cfg_string(oPKCS11Provider, o->pkcs11_provider); #endif dump_cfg_string(oPreferredAuthentications, o->preferred_authentications); 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(buf, o->escape_char, VIS_WHITE, 0); printf("escapechar %s\n", buf); } /* 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); /* oProxyCommand / oProxyJump */ if (o->jump_host == NULL) dump_cfg_string(oProxyCommand, o->proxy_command); else { /* Check for numeric addresses */ i = strchr(o->jump_host, ':') != NULL || strspn(o->jump_host, "1234567890.") == strlen(o->jump_host); snprintf(buf, sizeof(buf), "%d", o->jump_port); printf("proxyjump %s%s%s%s%s%s%s%s%s\n", /* optional additional jump spec */ o->jump_extra == NULL ? "" : o->jump_extra, o->jump_extra == NULL ? "" : ",", /* optional user */ o->jump_user == NULL ? "" : o->jump_user, o->jump_user == NULL ? "" : "@", /* opening [ if hostname is numeric */ i ? "[" : "", /* mandatory hostname */ o->jump_host, /* closing ] if hostname is numeric */ i ? "]" : "", /* optional port number */ o->jump_port <= 0 ? "" : ":", o->jump_port <= 0 ? "" : buf); } } openssh-7.5p1/readconf.h010064400017500001750000000173701306364033700134230ustar00djmdjm/* $OpenBSD: readconf.h,v 1.117 2016/07/15 00:24:30 djm 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; char *identity_agent; /* Optional path to ssh-agent socket */ /* 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; /* stdio forwarding (-W) host and port */ char *stdio_forward_host; int stdio_forward_port; 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 *jump_user; char *jump_host; int jump_port; char *jump_extra; 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 SSHCONF_NEVERMATCH 8 /* Match/Host never matches; internal only */ #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 parse_jump(const char *, Options *, 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.5p1/readpass.c010064400017500001750000000120251306364033700134270ustar00djmdjm/* $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.5p1/regress004075500017500001750000000000001306364033700130575ustar00djmdjmopenssh-7.5p1/regress/Makefile010064400017500001750000000152241306364033700145770ustar00djmdjm# $OpenBSD: Makefile,v 1.94 2016/12/16 03:51:19 dtucker 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 \ keygen-moduli \ key-options \ scp \ sftp \ sftp-chroot \ sftp-cmds \ sftp-badcmds \ sftp-batch \ sftp-glob \ sftp-perm \ reconfigure \ dynamic-forward \ forwarding \ multiplex \ reexec \ brokenkeys \ sshcfgparse \ 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 \ cfginclude \ allow-deny-users # 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 USERNAME!= id -un CLEANFILES= *.core actual agent-key.* authorized_keys_${USERNAME} \ authorized_keys_${USERNAME}.* \ authorized_principals_${USERNAME} \ banner.in banner.out cert_host_key* cert_user_key* \ copy.1 copy.2 data ed25519-agent ed25519-agent* \ ed25519-agent.pub empty.in expect failed-regress.log \ failed-ssh.log failed-sshd.log hkr.* host.rsa host.rsa1 \ host_* host_ca_key* host_krl_* host_revoked_* key.* \ key.dsa-* key.ecdsa-* key.ed25519-512 key.ed25519-512.pub \ key.rsa-* keys-command-args kh.* known_hosts \ known_hosts-cert known_hosts.* krl-* ls.copy modpipe \ netcat pidfile putty.rsa2 ready regress.log remote_pid \ revoked-* rsa rsa-agent rsa-agent.pub rsa.pub rsa1 \ rsa1-agent rsa1-agent.pub rsa1.pub rsa_ssh2_cr.prv \ rsa_ssh2_crnl.prv scp-ssh-wrapper.exe \ scp-ssh-wrapper.scp setuid-allowed sftp-server.log \ sftp-server.sh sftp.log ssh-log-wrapper.sh ssh.log \ ssh_config ssh_config.* ssh_proxy ssh_proxy_bak \ ssh_proxy_envpass sshd.log sshd_config sshd_config.orig \ sshd_proxy sshd_proxy.* sshd_proxy_bak sshd_proxy_orig \ t10.out t10.out.pub t12.out t12.out.pub t2.out t3.out \ t6.out1 t6.out2 t7.out t7.out.pub t8.out t8.out.pub \ t9.out t9.out.pub testdata user_*key* user_ca* user_key* SUDO_CLEAN+= /var/run/testdata_${USERNAME} /var/run/keycommand_${USERNAME} # Enable all malloc(3) randomisations and checks TEST_ENV= "MALLOC_OPTIONS=CFGJRSUX" 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/conversion/test_conversion ; \ $$V ${.OBJDIR}/unittests/kex/test_kex ; \ $$V ${.OBJDIR}/unittests/hostkeys/test_hostkeys \ -d ${.CURDIR}/unittests/hostkeys/testdata ; \ $$V ${.OBJDIR}/unittests/match/test_match ; \ if test "x${TEST_SSH_UTF8}" = "xyes" ; then \ $$V ${.OBJDIR}/unittests/utf8/test_utf8 ; \ fi \ fi openssh-7.5p1/regress/README.regress010064400017500001750000000072631306364033700154740ustar00djmdjmOverview. $ ./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.5p1/regress/addrmatch.sh010064400017500001750000000041001306364033700154110ustar00djmdjm# $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} ${SSHADD} -l > /dev/null 2>&1 r=$? if [ $r -ne 1 ]; then fail "ssh-add failed with $r != 1" fi if test -z "$sudo" ; then # doas ${SUDO} -n -u ${UNPRIV} ${SSHADD} -l 2>/dev/null else # sudo < /dev/null ${SUDO} -S -u ${UNPRIV} ${SSHADD} -l 2>/dev/null fi 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.5p1/regress/agent-pkcs11.sh010064400017500001750000000035641306364033700156750ustar00djmdjm# $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.5p1/regress/agent-ptrace.sh010064400017500001750000000024721306364033700160460ustar00djmdjm# $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.5p1/regress/agent-timeout.sh010064400017500001750000000016401306364033700162520ustar00djmdjm# $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.5p1/regress/agent.sh010064400017500001750000000040041306364033700145630ustar00djmdjm# $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.5p1/regress/allow-deny-users.sh010064400017500001750000000023461306364033700167060ustar00djmdjm# Public Domain # Zev Weiss, 2016 tid="AllowUsers/DenyUsers" me="$LOGNAME" if [ "x$me" = "x" ]; then me=`whoami` fi other="nobody" test_auth() { deny="$1" allow="$2" should_succeed="$3" failmsg="$4" start_sshd -oDenyUsers="$deny" -oAllowUsers="$allow" ${SSH} -F $OBJ/ssh_config "$me@somehost" true status=$? if (test $status -eq 0 && ! $should_succeed) \ || (test $status -ne 0 && $should_succeed); then fail "$failmsg" fi stop_sshd } # DenyUsers AllowUsers should_succeed failure_message test_auth "" "" true "user in neither DenyUsers nor AllowUsers denied" test_auth "$other $me" "" false "user in DenyUsers allowed" test_auth "$me $other" "" false "user in DenyUsers allowed" test_auth "" "$other" false "user not in AllowUsers allowed" test_auth "" "$other $me" true "user in AllowUsers denied" test_auth "" "$me $other" true "user in AllowUsers denied" test_auth "$me $other" "$me $other" false "user in both DenyUsers and AllowUsers allowed" test_auth "$other $me" "$other $me" false "user in both DenyUsers and AllowUsers allowed" openssh-7.5p1/regress/banner.sh010064400017500001750000000024001306364033700147300ustar00djmdjm# $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.5p1/regress/broken-pipe.sh010064400017500001750000000005571306364033700157110ustar00djmdjm# $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.5p1/regress/brokenkeys.sh010064400017500001750000000007351306364033700156500ustar00djmdjm# $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.5p1/regress/cert-file.sh010064400017500001750000000131461306364033700153460ustar00djmdjm# $OpenBSD: cert-file.sh,v 1.5 2017/03/11 23:44:16 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" ${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_key3 || \ fatal "ssh-keygen failed" ${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_key4 || \ fatal "ssh-keygen failed" ${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/user_key5 || \ 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 || fatal "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 || fatal "couldn't sign user_key1 with user_ca_key2" mv $OBJ/user_key1-cert.pub $OBJ/cert_user_key1_2.pub ${SSHKEYGEN} -q -s $OBJ/user_ca_key1 -I "regress user key for $USER" \ -z $$ -n ${USER} $OBJ/user_key3 || fatal "couldn't sign user_key3 with user_ca_key1" rm $OBJ/user_key3.pub # to test use of private key w/o public half. ${SSHKEYGEN} -q -s $OBJ/user_ca_key1 -I "regress user key for $USER" \ -z $$ -n ${USER} $OBJ/user_key4 || fatal "couldn't sign user_key4 with user_ca_key1" rm $OBJ/user_key4 $OBJ/user_key4.pub # to test no matching pub/private key case. 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 # Make a clean config that doesn't have any pre-added identities. cat $OBJ/ssh_proxy | grep -v IdentityFile > $OBJ/no_identity_config # XXX: verify that certificate used was what we expect. Needs exposure of # keys via enviornment variable or similar. for p in ${SSH_PROTOCOLS}; do # Key with no .pub should work - finding the equivalent *-cert.pub. verbose "protocol $p: identity cert with no plain public file" ${SSH} -F $OBJ/no_identity_config -oIdentitiesOnly=yes \ -i $OBJ/user_key3 somehost exit 5$p [ $? -ne 5$p ] && fail "ssh failed" # CertificateFile matching private key with no .pub file should work. verbose "protocol $p: CertificateFile with no plain public file" ${SSH} -F $OBJ/no_identity_config -oIdentitiesOnly=yes \ -oCertificateFile=$OBJ/user_key3-cert.pub \ -i $OBJ/user_key3 somehost exit 5$p [ $? -ne 5$p ] && fail "ssh failed" # Just keys should fail verbose "protocol $p: plain keys" ${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. verbose "protocol $p: untrusted cert" 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. verbose "protocol $p: good cert, bad key" 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. verbose "protocol $p: single trusted" 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. verbose "protocol $p: multiple trusted" 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 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.5p1/regress/cert-hostkey.sh010064400017500001750000000241641306364033700161170ustar00djmdjm# $OpenBSD: cert-hostkey.sh,v 1.14 2016/05/02 09:52:00 djm 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' kh_ca() { for k in "$@" ; do printf "@cert-authority $HOSTS " cat $OBJ/$k || fatal "couldn't cat $k" done } kh_revoke() { for k in "$@" ; do printf "@revoked * " cat $OBJ/$k || fatal "couldn't cat $k" done } # Create a CA key and add it to known hosts. Ed25519 chosen for speed. # RSA for testing RSA/SHA2 signatures. ${SSHKEYGEN} -q -N '' -t ed25519 -f $OBJ/host_ca_key ||\ fail "ssh-keygen of host_ca_key failed" ${SSHKEYGEN} -q -N '' -t rsa -f $OBJ/host_ca_key2 ||\ fail "ssh-keygen of host_ca_key failed" kh_ca host_ca_key.pub host_ca_key2.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 cat $OBJ/host_ca_key.pub $OBJ/host_ca_key2.pub > $OBJ/host_revoked_ca PLAIN_TYPES=`$SSH -Q key-plain | sed 's/^ssh-dss/ssh-dsa/g;s/^ssh-//'` if echo "$PLAIN_TYPES" | grep '^rsa$' >/dev/null 2>&1 ; then PLAIN_TYPES="$PLAIN_TYPES rsa-sha2-256 rsa-sha2-512" fi # 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 $OBJ/host_ca_key2.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 case $ktype in rsa-sha2-*) tflag="-t $ktype"; ca="$OBJ/host_ca_key2" ;; *) tflag=""; ca="$OBJ/host_ca_key" ;; esac ${SSHKEYGEN} -h -q -s $ca -z $serial $tflag \ -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 kh_ca host_ca_key.pub host_ca_key2.pub > $OBJ/known_hosts-cert.orig for ktype in $PLAIN_TYPES ; do test -f "$OBJ/cert_host_key_${ktype}.pub" || fatal "no pubkey" kh_revoke cert_host_key_${ktype}.pub >> $OBJ/known_hosts-cert.orig done 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 kh_ca host_ca_key.pub host_ca_key2.pub > $OBJ/known_hosts-cert.orig kh_revoke host_ca_key.pub host_ca_key2.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 kh_ca host_ca_key.pub host_ca_key2.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 case $ktype in rsa-sha2-*) tflag="-t $ktype"; ca="$OBJ/host_ca_key2" ;; *) tflag=""; ca="$OBJ/host_ca_key" ;; esac ${SSHKEYGEN} -q -s $ca $tflag -I "regress host key for $USER" \ $sign_opts $OBJ/cert_host_key_${kt} || fatal "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" case $ktype in rsa-sha2-*) tflag="-t $ktype"; ca="$OBJ/host_ca_key2" ;; *) tflag=""; ca="$OBJ/host_ca_key" ;; esac ${SSHKEYGEN} -h -q $tflag -s $ca $tflag \ -I "regress host key for $USER" \ -n $HOSTS $OBJ/cert_host_key_${ktype} || fatal "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 kh_ca host_ca_key.pub host_ca_key2.pub > $OBJ/known_hosts-cert.orig cp $OBJ/known_hosts-cert.orig $OBJ/known_hosts-cert for kt in $PLAIN_TYPES ; do verbose "$tid: host ${kt} connect wrong cert" 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" case $kt in rsa-sha2-*) tflag="-t $kt" ;; *) tflag="" ;; esac ${SSHKEYGEN} $tflag -h -q -s $OBJ/cert_host_key_${kt} \ -I "regress host key for $USER" \ -n $HOSTS $OBJ/cert_host_key_${kt} || fatal "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 -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.5p1/regress/cert-userkey.sh010064400017500001750000000277071306364033700161260ustar00djmdjm# $OpenBSD: cert-userkey.sh,v 1.17 2016/11/30 03:01:33 djm 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-//'` if echo "$PLAIN_TYPES" | grep '^rsa$' >/dev/null 2>&1 ; then PLAIN_TYPES="$PLAIN_TYPES rsa-sha2-256 rsa-sha2-512" fi kname() { case $ktype in rsa-sha2-*) ;; # subshell because some seds will add a newline *) n=$(echo $1 | sed 's/^dsa/ssh-dss/;s/^rsa/ssh-rsa/;s/^ed/ssh-ed/') ;; esac 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 $EXTRA_TYPES ; do verbose "$tid: sign user ${ktype} cert" ${SSHKEYGEN} -q -N '' -t ${ktype} \ -f $OBJ/cert_user_key_${ktype} || \ fatal "ssh-keygen of cert_user_key_${ktype} failed" # Generate RSA/SHA2 certs for rsa-sha2* keys. case $ktype in rsa-sha2-*) tflag="-t $ktype" ;; *) tflag="" ;; esac ${SSHKEYGEN} -q -s $OBJ/user_ca_key -z $$ \ -I "regress user key for $USER" \ -n ${USER},mekmitasdigoat $tflag $OBJ/cert_user_key_${ktype} || \ fatal "couldn't sign cert_user_key_${ktype}" done # Test explicitly-specified principals for ktype in $EXTRA_TYPES $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"' # command= options vs. force-command in key test_one "force-command match true" success \ "-n ${USER} -Oforce-command=true" \ authorized_keys ',command="true"' test_one "force-command match true" failure \ "-n ${USER} -Oforce-command=false" \ authorized_keys ',command="false"' test_one "force-command mismatch 1" failure \ "-n ${USER} -Oforce-command=false" \ authorized_keys ',command="true"' test_one "force-command mismatch 2" failure \ "-n ${USER} -Oforce-command=true" \ authorized_keys ',command="false"' # 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} || fatal "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.5p1/regress/cfginclude.sh010064400017500001750000000106151306364033700155750ustar00djmdjm# $OpenBSD: cfginclude.sh,v 1.2 2016/05/03 15:30:46 dtucker Exp $ # Placed in the Public Domain. tid="config include" # to appease StrictModes umask 022 cat > $OBJ/ssh_config.i << _EOF Match host a Hostname aa Match host b Hostname bb Include $OBJ/ssh_config.i.* Match host c Include $OBJ/ssh_config.i.* Hostname cc Match host m Include $OBJ/ssh_config.i.* Host d Hostname dd Host e Hostname ee Include $OBJ/ssh_config.i.* Host f Include $OBJ/ssh_config.i.* Hostname ff Host n Include $OBJ/ssh_config.i.* _EOF cat > $OBJ/ssh_config.i.0 << _EOF Match host xxxxxx _EOF cat > $OBJ/ssh_config.i.1 << _EOF Match host a Hostname aaa Match host b Hostname bbb Match host c Hostname ccc Host d Hostname ddd Host e Hostname eee Host f Hostname fff _EOF cat > $OBJ/ssh_config.i.2 << _EOF Match host a Hostname aaaa Match host b Hostname bbbb Match host c Hostname cccc Host d Hostname dddd Host e Hostname eeee Host f Hostname ffff Match all Hostname xxxx _EOF trial() { _host="$1" _exp="$2" ${REAL_SSH} -F $OBJ/ssh_config.i -G "$_host" > $OBJ/ssh_config.out || fatal "ssh config parse failed" _got=`grep -i '^hostname ' $OBJ/ssh_config.out | awk '{print $2}'` if test "x$_exp" != "x$_got" ; then fail "host $_host include fail: expected $_exp got $_got" fi } trial a aa trial b bb trial c ccc trial d dd trial e ee trial f fff trial m xxxx trial n xxxx trial x x # Prepare an included config with an error. cat > $OBJ/ssh_config.i.3 << _EOF Hostname xxxx Junk _EOF ${REAL_SSH} -F $OBJ/ssh_config.i -G a 2>/dev/null && \ fail "ssh include allowed invalid config" ${REAL_SSH} -F $OBJ/ssh_config.i -G x 2>/dev/null && \ fail "ssh include allowed invalid config" rm -f $OBJ/ssh_config.i.* # Ensure that a missing include is not fatal. cat > $OBJ/ssh_config.i << _EOF Include $OBJ/ssh_config.i.* Hostname aa _EOF trial a aa # Ensure that Match/Host in an included config does not affect parent. cat > $OBJ/ssh_config.i.x << _EOF Match host x _EOF trial a aa cat > $OBJ/ssh_config.i.x << _EOF Host x _EOF trial a aa # cleanup rm -f $OBJ/ssh_config.i $OBJ/ssh_config.i.* $OBJ/ssh_config.out # $OpenBSD: cfginclude.sh,v 1.2 2016/05/03 15:30:46 dtucker Exp $ # Placed in the Public Domain. tid="config include" cat > $OBJ/ssh_config.i << _EOF Match host a Hostname aa Match host b Hostname bb Include $OBJ/ssh_config.i.* Match host c Include $OBJ/ssh_config.i.* Hostname cc Match host m Include $OBJ/ssh_config.i.* Host d Hostname dd Host e Hostname ee Include $OBJ/ssh_config.i.* Host f Include $OBJ/ssh_config.i.* Hostname ff Host n Include $OBJ/ssh_config.i.* _EOF cat > $OBJ/ssh_config.i.0 << _EOF Match host xxxxxx _EOF cat > $OBJ/ssh_config.i.1 << _EOF Match host a Hostname aaa Match host b Hostname bbb Match host c Hostname ccc Host d Hostname ddd Host e Hostname eee Host f Hostname fff _EOF cat > $OBJ/ssh_config.i.2 << _EOF Match host a Hostname aaaa Match host b Hostname bbbb Match host c Hostname cccc Host d Hostname dddd Host e Hostname eeee Host f Hostname ffff Match all Hostname xxxx _EOF trial() { _host="$1" _exp="$2" ${REAL_SSH} -F $OBJ/ssh_config.i -G "$_host" > $OBJ/ssh_config.out || fatal "ssh config parse failed" _got=`grep -i '^hostname ' $OBJ/ssh_config.out | awk '{print $2}'` if test "x$_exp" != "x$_got" ; then fail "host $_host include fail: expected $_exp got $_got" fi } trial a aa trial b bb trial c ccc trial d dd trial e ee trial f fff trial m xxxx trial n xxxx trial x x # Prepare an included config with an error. cat > $OBJ/ssh_config.i.3 << _EOF Hostname xxxx Junk _EOF ${REAL_SSH} -F $OBJ/ssh_config.i -G a 2>/dev/null && \ fail "ssh include allowed invalid config" ${REAL_SSH} -F $OBJ/ssh_config.i -G x 2>/dev/null && \ fail "ssh include allowed invalid config" rm -f $OBJ/ssh_config.i.* # Ensure that a missing include is not fatal. cat > $OBJ/ssh_config.i << _EOF Include $OBJ/ssh_config.i.* Hostname aa _EOF trial a aa # Ensure that Match/Host in an included config does not affect parent. cat > $OBJ/ssh_config.i.x << _EOF Match host x _EOF trial a aa cat > $OBJ/ssh_config.i.x << _EOF Host x _EOF trial a aa # Ensure that recursive includes are bounded. cat > $OBJ/ssh_config.i << _EOF Include $OBJ/ssh_config.i _EOF ${REAL_SSH} -F $OBJ/ssh_config.i -G a 2>/dev/null && \ fail "ssh include allowed infinite recursion?" # or hang... # cleanup rm -f $OBJ/ssh_config.i $OBJ/ssh_config.i.* $OBJ/ssh_config.out openssh-7.5p1/regress/cfgmatch.sh010064400017500001750000000075131306364033700152510ustar00djmdjm# $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.5p1/regress/cfgparse.sh010064400017500001750000000042431306364033700152640ustar00djmdjm# $OpenBSD: cfgparse.sh,v 1.6 2016/06/03 03:47:59 dtucker Exp $ # Placed in the Public Domain. tid="sshd 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.5p1/regress/check-perm.c010064400017500001750000000105231306364033700153160ustar00djmdjm/* * 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.5p1/regress/cipher-speed.sh010064400017500001750000000022671306364033700160460ustar00djmdjm# $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.5p1/regress/krl.sh010064400017500001750000000132551306364033700142650ustar00djmdjm# $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.5p1/regress/conch-ciphers.sh010064400017500001750000000014341306364033700162160ustar00djmdjm# $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.5p1/regress/connect-privsep.sh010064400017500001750000000023021306364033700166030ustar00djmdjm# $OpenBSD: connect-privsep.sh,v 1.8 2016/11/01 13:43:27 tb 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). if [ -z "TEST_MALLOC_OPTIONS" ]; then mopts="C F G J R S U X < >" else mopts=`echo $TEST_MALLOC_OPTIONS | sed 's/./& /g'` fi for m in '' $mopts ; 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.5p1/regress/connect.sh010064400017500001750000000004451306364033700151230ustar00djmdjm# $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.5p1/regress/dhgex.sh010064400017500001750000000030051306364033700145640ustar00djmdjm# $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.5p1/regress/dsa_ssh2.prv010064400017500001750000000015371306364033700154000ustar00djmdjm---- 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.5p1/regress/dsa_ssh2.pub010064400017500001750000000013341306364033700153520ustar00djmdjm---- 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.5p1/regress/dynamic-forward.sh010064400017500001750000000030331306364033700165540ustar00djmdjm# $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.5p1/regress/envpass.sh010064400017500001750000000030531306364033700151470ustar00djmdjm# $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.5p1/regress/exit-status.sh010064400017500001750000000012451306364033700157630ustar00djmdjm# $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.5p1/regress/forcecommand.sh010064400017500001750000000024531306364033700161300ustar00djmdjm# $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.5p1/regress/forward-control.sh010064400017500001750000000126331306364033700166160ustar00djmdjm# $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.5p1/regress/forwarding.sh010064400017500001750000000111511306364033700156300ustar00djmdjm# $OpenBSD: forwarding.sh,v 1.19 2017/01/30 05:22:14 djm Exp $ # Placed in the Public Domain. tid="local and remote forwarding" DATA=/bin/ls${EXEEXT} start_sshd base=33 last=$PORT fwd="" CTL=/tmp/openssh.regress.ctl-sock.$$ 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" rm -f $CTL ${SSH} -S $CTL -M -$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}" ${SSH} -F $OBJ/ssh_config -S $CTL -O exit somehost 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 fatal "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:localhost:$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" rm -f $CTL ${SSH} -S $CTL -M -$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 somehost true \ >>$TEST_REGRESS_LOGFILE 2>&1 && \ fail "local forwarding not cleared" fi ${SSH} -F $OBJ/ssh_config -S $CTL -O exit somehost trace "clear remote forward proto $p" rm -f $CTL ${SSH} -S $CTL -M -$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 somehost true \ >>$TEST_REGRESS_LOGFILE 2>&1 && \ fail "remote forwarding not cleared" fi ${SSH} -F $OBJ/ssh_config -S $CTL -O exit somehost 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" rm -f $CTL ${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} -F $OBJ/ssh_config -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 rm -f $CTL $CTL.[123] ${SSH} -S $CTL -M -f -F $OBJ/ssh_config -R${base}01:[$OBJ/unix-1.fwd] somehost sleep 10 ${SSH} -S $CTL.1 -M -f -F $OBJ/ssh_config -L[$OBJ/unix-1.fwd]:[$OBJ/unix-2.fwd] somehost sleep 10 ${SSH} -S $CTL.2 -M -f -F $OBJ/ssh_config -R[$OBJ/unix-2.fwd]:[$OBJ/unix-3.fwd] somehost sleep 10 ${SSH} -S $CTL.3 -M -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}" ${SSH} -F $OBJ/ssh_config -S $CTL -O exit somehost ${SSH} -F $OBJ/ssh_config -S $CTL.1 -O exit somehost ${SSH} -F $OBJ/ssh_config -S $CTL.2 -O exit somehost ${SSH} -F $OBJ/ssh_config -S $CTL.3 -O exit somehost done openssh-7.5p1/regress/host-expand.sh010064400017500001750000000007241306364033700157240ustar00djmdjm# $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.5p1/regress/hostkey-agent.sh010064400017500001750000000031631306364033700162540ustar00djmdjm# $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.5p1/regress/hostkey-rotate.sh010064400017500001750000000075631306364033700164640ustar00djmdjm# $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.5p1/regress/integrity.sh010064400017500001750000000044121306364033700155060ustar00djmdjm# $OpenBSD: integrity.sh,v 1.20 2017/01/06 02:26:10 dtucker 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 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 etmo=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=$(egrep -v "^debug" $TEST_SSH_LOGFILE | tail -2 | \ 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.5p1/regress/kextype.sh010064400017500001750000000011131306364033700151540ustar00djmdjm# $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.5p1/regress/key-options.sh010064400017500001750000000036511306364033700157550ustar00djmdjm# $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.5p1/regress/keygen-change.sh010064400017500001750000000011771306364033700162020ustar00djmdjm# $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.5p1/regress/keygen-convert.sh010064400017500001750000000021271306364033700164310ustar00djmdjm# $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.5p1/regress/misc004075500017500001750000000000001306364033700140125ustar00djmdjmopenssh-7.5p1/regress/misc/Makefile010064400017500001750000000000531306364033700155240ustar00djmdjmSUBDIR= kexfuzz .include openssh-7.5p1/regress/misc/kexfuzz004075500017500001750000000000001306364033700155205ustar00djmdjmopenssh-7.5p1/regress/misc/kexfuzz/Makefile010064400017500001750000000030461306364033700172370ustar00djmdjm# $OpenBSD: Makefile,v 1.1 2016/03/04 02:30:37 djm Exp $ .include .include # XXX detect from ssh binary? SSH1?= no OPENSSL?= yes PROG= kexfuzz SRCS= kexfuzz.c NOMAN= 1 .if (${OPENSSL:L} == "yes") CFLAGS+= -DWITH_OPENSSL .else # SSH v.1 requires OpenSSL. SSH1= no .endif .if (${SSH1:L} == "yes") CFLAGS+= -DWITH_SSH1 .endif # 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}/${SSHREL} .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+= -lutil -lz DPADD+= ${LIBUTIL} ${LIBZ} .if (${OPENSSL:L} == "yes") LDADD+= -lcrypto DPADD+= ${LIBCRYPTO} .endif .include openssh-7.5p1/regress/misc/kexfuzz/README010064400017500001750000000020111306364033700164460ustar00djmdjmThis is a harness to help with fuzzing KEX. To use it, you first set it to count packets in each direction: ./kexfuzz -K diffie-hellman-group1-sha1 -k host_ed25519_key -c S2C: 29 C2S: 31 Then get it to record a particular packet (in this case the 4th packet from client->server): ./kexfuzz -K diffie-hellman-group1-sha1 -k host_ed25519_key \ -d -D C2S -i 3 -f packet_3 Fuzz the packet somehow: dd if=/dev/urandom of=packet_3 bs=32 count=1 # Just for example Then re-run the key exchange substituting the modified packet in its original sequence: ./kexfuzz -K diffie-hellman-group1-sha1 -k host_ed25519_key \ -r -D C2S -i 3 -f packet_3 A comprehensive KEX fuzz run would fuzz every packet in both directions for each key exchange type and every hostkey type. This will take some time. Limitations: kexfuzz can't change the ordering of packets at present. It is limited to replacing individual packets with fuzzed variants with the same type. It really should allow insertion, deletion on replacement of packets too. openssh-7.5p1/regress/misc/kexfuzz/kexfuzz.c010064400017500001750000000302101306364033700174420ustar00djmdjm/* $OpenBSD: kexfuzz.c,v 1.3 2016/10/11 21:49:54 djm Exp $ */ /* * Fuzz harness for KEX code * * Placed in the public domain */ #include "includes.h" #include #include #include #ifdef HAVE_STDINT_H # include #endif #include #include #include #include #ifdef HAVE_ERR_H # include #endif #include "ssherr.h" #include "ssh_api.h" #include "sshbuf.h" #include "packet.h" #include "myproposal.h" #include "authfile.h" #include "log.h" struct ssh *active_state = NULL; /* XXX - needed for linking */ void kex_tests(void); static int do_debug = 0; enum direction { S2C, C2S }; struct hook_ctx { struct ssh *client, *server, *server2; int *c2s, *s2c; int trigger_direction, packet_index; const char *dump_path; struct sshbuf *replace_data; }; static int packet_hook(struct ssh *ssh, struct sshbuf *packet, u_char *typep, void *_ctx) { struct hook_ctx *ctx = (struct hook_ctx *)_ctx; int mydirection = ssh == ctx->client ? S2C : C2S; int *packet_count = mydirection == S2C ? ctx->s2c : ctx->c2s; FILE *dumpfile; int r; if (do_debug) { printf("%s packet %d type %u:\n", mydirection == S2C ? "s2c" : "c2s", *packet_count, *typep); sshbuf_dump(packet, stdout); } if (mydirection == ctx->trigger_direction && ctx->packet_index == *packet_count) { if (ctx->replace_data != NULL) { sshbuf_reset(packet); /* Type is first byte of packet */ if ((r = sshbuf_get_u8(ctx->replace_data, typep)) != 0 || (r = sshbuf_putb(packet, ctx->replace_data)) != 0) return r; if (do_debug) { printf("***** replaced packet type %u\n", *typep); sshbuf_dump(packet, stdout); } } else if (ctx->dump_path != NULL) { if ((dumpfile = fopen(ctx->dump_path, "w+")) == NULL) err(1, "fopen %s", ctx->dump_path); /* Write { type, packet } */ if (fwrite(typep, 1, 1, dumpfile) != 1) err(1, "fwrite type %s", ctx->dump_path); if (sshbuf_len(packet) != 0 && fwrite(sshbuf_ptr(packet), sshbuf_len(packet), 1, dumpfile) != 1) err(1, "fwrite body %s", ctx->dump_path); if (do_debug) { printf("***** dumped packet type %u len %zu\n", *typep, sshbuf_len(packet)); } fclose(dumpfile); /* No point in continuing */ exit(0); } } (*packet_count)++; return 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 (len == 0) return 0; if ((r = ssh_input_append(to, buf, len)) != 0) { debug("ssh_input_append: %s", ssh_err(r)); return r; } if ((r = ssh_output_consume(from, len)) != 0) { debug("ssh_output_consume: %s", ssh_err(r)); return r; } } } /* Minimal test_helper.c scaffholding to make this standalone */ const char *in_test = NULL; #define TEST_START(a) \ do { \ in_test = (a); \ if (do_debug) \ fprintf(stderr, "test %s starting\n", in_test); \ } while (0) #define TEST_DONE() \ do { \ if (do_debug) \ fprintf(stderr, "test %s done\n", \ in_test ? in_test : "???"); \ in_test = NULL; \ } while(0) #define ASSERT_INT_EQ(a, b) \ do { \ if ((int)(a) != (int)(b)) { \ fprintf(stderr, "%s %s:%d " \ "%s (%d) != expected %s (%d)\n", \ in_test ? in_test : "(none)", \ __func__, __LINE__, #a, (int)(a), #b, (int)(b)); \ exit(2); \ } \ } while (0) #define ASSERT_INT_GE(a, b) \ do { \ if ((int)(a) < (int)(b)) { \ fprintf(stderr, "%s %s:%d " \ "%s (%d) < expected %s (%d)\n", \ in_test ? in_test : "(none)", \ __func__, __LINE__, #a, (int)(a), #b, (int)(b)); \ exit(2); \ } \ } while (0) #define ASSERT_PTR_NE(a, b) \ do { \ if ((a) == (b)) { \ fprintf(stderr, "%s %s:%d " \ "%s (%p) != expected %s (%p)\n", \ in_test ? in_test : "(none)", \ __func__, __LINE__, #a, (a), #b, (b)); \ exit(2); \ } \ } while (0) static void run_kex(struct ssh *client, struct ssh *server) { int r = 0; while (!server->kex->done || !client->kex->done) { if ((r = do_send_and_receive(server, client)) != 0) { debug("do_send_and_receive S2C: %s", ssh_err(r)); break; } if ((r = do_send_and_receive(client, server)) != 0) { debug("do_send_and_receive C2S: %s", ssh_err(r)); 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(const char *kex, struct sshkey *prvkey, int *c2s, int *s2c, int direction, int packet_index, const char *dump_path, struct sshbuf *replace_data) { struct ssh *client = NULL, *server = NULL, *server2 = NULL; struct sshkey *pubkey = NULL; struct sshbuf *state; struct kex_params kex_params; char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT }; char *keyname = NULL; struct hook_ctx hook_ctx; TEST_START("sshkey_from_private"); ASSERT_INT_EQ(sshkey_from_private(prvkey, &pubkey), 0); TEST_DONE(); TEST_START("ssh_init"); memcpy(kex_params.proposal, myproposal, sizeof(myproposal)); if (kex != NULL) kex_params.proposal[PROPOSAL_KEX_ALGS] = strdup(kex); keyname = strdup(sshkey_ssh_name(prvkey)); 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_INT_EQ(ssh_init(&server2, 1, NULL), 0); ASSERT_PTR_NE(client, NULL); ASSERT_PTR_NE(server, NULL); ASSERT_PTR_NE(server2, NULL); TEST_DONE(); hook_ctx.c2s = c2s; hook_ctx.s2c = s2c; hook_ctx.trigger_direction = direction; hook_ctx.packet_index = packet_index; hook_ctx.dump_path = dump_path; hook_ctx.replace_data = replace_data; hook_ctx.client = client; hook_ctx.server = server; hook_ctx.server2 = server2; ssh_packet_set_input_hook(client, packet_hook, &hook_ctx); ssh_packet_set_input_hook(server, packet_hook, &hook_ctx); ssh_packet_set_input_hook(server2, packet_hook, &hook_ctx); TEST_START("ssh_add_hostkey"); ASSERT_INT_EQ(ssh_add_hostkey(server, prvkey), 0); ASSERT_INT_EQ(ssh_add_hostkey(client, pubkey), 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"); ASSERT_INT_EQ(ssh_add_hostkey(server2, prvkey), 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 */ #ifdef WITH_OPENSSL server2->kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; server2->kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server; server2->kex->kex[KEX_DH_GRP14_SHA256] = kexdh_server; server2->kex->kex[KEX_DH_GRP16_SHA512] = kexdh_server; server2->kex->kex[KEX_DH_GRP18_SHA512] = 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 #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(pubkey); ssh_free(client); ssh_free(server); ssh_free(server2); free(keyname); TEST_DONE(); } static void usage(void) { fprintf(stderr, "Usage: kexfuzz [-hcdrv] [-D direction] [-f data_file]\n" " [-K kex_alg] [-k private_key] [-i packet_index]\n" "\n" "Options:\n" " -h Display this help\n" " -c Count packets sent during KEX\n" " -d Dump mode: record KEX packet to data file\n" " -r Replace mode: replace packet with data file\n" " -v Turn on verbose logging\n" " -D S2C|C2S Packet direction for replacement or dump\n" " -f data_file Path to data file for replacement or dump\n" " -K kex_alg Name of KEX algorithm to test (see below)\n" " -k private_key Path to private key file\n" " -i packet_index Index of packet to replace or dump (from 0)\n" "\n" "Available KEX algorithms: %s\n", kex_alg_list(' ')); } static void badusage(const char *bad) { fprintf(stderr, "Invalid options\n"); fprintf(stderr, "%s\n", bad); usage(); exit(1); } int main(int argc, char **argv) { int ch, fd, r; int count_flag = 0, dump_flag = 0, replace_flag = 0; int packet_index = -1, direction = -1; int s2c = 0, c2s = 0; /* packet counts */ const char *kex = NULL, *kpath = NULL, *data_path = NULL; struct sshkey *key = NULL; struct sshbuf *replace_data = NULL; setvbuf(stdout, NULL, _IONBF, 0); while ((ch = getopt(argc, argv, "hcdrvD:f:K:k:i:")) != -1) { switch (ch) { case 'h': usage(); return 0; case 'c': count_flag = 1; break; case 'd': dump_flag = 1; break; case 'r': replace_flag = 1; break; case 'v': do_debug = 1; break; case 'D': if (strcasecmp(optarg, "s2c") == 0) direction = S2C; else if (strcasecmp(optarg, "c2s") == 0) direction = C2S; else badusage("Invalid direction (-D)"); break; case 'f': data_path = optarg; break; case 'K': kex = optarg; break; case 'k': kpath = optarg; break; case 'i': packet_index = atoi(optarg); if (packet_index < 0) badusage("Invalid packet index"); break; default: badusage("unsupported flag"); } } argc -= optind; argv += optind; log_init(argv[0], do_debug ? SYSLOG_LEVEL_DEBUG3 : SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1); /* Must select a single mode */ if ((count_flag + dump_flag + replace_flag) != 1) badusage("Must select one mode: -c, -d or -r"); /* KEX type is mandatory */ if (kex == NULL || !kex_names_valid(kex) || strchr(kex, ',') != NULL) badusage("Missing or invalid kex type (-K flag)"); /* Valid key is mandatory */ if (kpath == NULL) badusage("Missing private key (-k flag)"); if ((fd = open(kpath, O_RDONLY)) == -1) err(1, "open %s", kpath); if ((r = sshkey_load_private_type_fd(fd, KEY_UNSPEC, NULL, &key, NULL)) != 0) errx(1, "Unable to load key %s: %s", kpath, ssh_err(r)); close(fd); /* XXX check that it is a private key */ /* XXX support certificates */ if (key == NULL || key->type == KEY_UNSPEC || key->type == KEY_RSA1) badusage("Invalid key file (-k flag)"); /* Replace (fuzz) mode */ if (replace_flag) { if (packet_index == -1 || direction == -1 || data_path == NULL) badusage("Replace (-r) mode must specify direction " "(-D) packet index (-i) and data path (-f)"); if ((fd = open(data_path, O_RDONLY)) == -1) err(1, "open %s", data_path); replace_data = sshbuf_new(); if ((r = sshkey_load_file(fd, replace_data)) != 0) errx(1, "read %s: %s", data_path, ssh_err(r)); close(fd); } /* Dump mode */ if (dump_flag) { if (packet_index == -1 || direction == -1 || data_path == NULL) badusage("Dump (-d) mode must specify direction " "(-D), packet index (-i) and data path (-f)"); } /* Count mode needs no further flags */ do_kex_with_key(kex, key, &c2s, &s2c, direction, packet_index, dump_flag ? data_path : NULL, replace_flag ? replace_data : NULL); sshkey_free(key); sshbuf_free(replace_data); if (count_flag) { printf("S2C: %d\n", s2c); printf("C2S: %d\n", c2s); } return 0; } openssh-7.5p1/regress/keygen-knownhosts.sh010064400017500001750000000135251306364033700171720ustar00djmdjm# $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.5p1/regress/keygen-moduli.sh010064400017500001750000000012761306364033700162460ustar00djmdjm# $OpenBSD: keygen-moduli.sh,v 1.2 2016/09/14 00:45:31 dtucker Exp $ # Placed in the Public Domain. tid="keygen moduli" # Try "start at the beginning and stop after 1", "skip 1 then stop after 1" # and "skip 2 and run to the end with checkpointing". Since our test data # file has 3 lines, these should always result in 1 line of output. for i in "-J1" "-j1 -J1" "-j2 -K $OBJ/moduli.ckpt"; do trace "keygen $i" rm -f $OBJ/moduli.out $OBJ/moduli.ckpt ${SSHKEYGEN} -T $OBJ/moduli.out -f ${SRC}/moduli.in $i 2>/dev/null || \ fail "keygen screen failed $i" lines=`wc -l <$OBJ/moduli.out` test "$lines" -eq "1" || fail "expected 1 line, got $lines" done rm -f $OBJ/moduli.out $OBJ/moduli.ckpt openssh-7.5p1/regress/keys-command.sh010064400017500001750000000046141306364033700160630ustar00djmdjm# $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 [ -z "$SUDO" -a ! -w /var/run ]; 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.5p1/regress/keyscan.sh010064400017500001750000000007131306364033700151250ustar00djmdjm# $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.5p1/regress/keytype.sh010064400017500001750000000036441306364033700151700ustar00djmdjm# $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.5p1/regress/limit-keytype.sh010064400017500001750000000071501306364033700163000ustar00djmdjm# $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.5p1/regress/localcommand.sh010064400017500001750000000006161306364033700161230ustar00djmdjm# $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.5p1/regress/login-timeout.sh010064400017500001750000000016631306364033700162710ustar00djmdjm# $OpenBSD: login-timeout.sh,v 1.8 2016/12/16 01:06:27 dtucker 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 stop_sshd 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.5p1/regress/modpipe.c010075500017500001750000000074751306364033700147540ustar00djmdjm/* * 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 #ifdef HAVE_ERR_H # include #endif #include "openbsd-compat/getopt_long.c" 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.5p1/regress/moduli.in010064400017500001750000000031351306364033700147560ustar00djmdjm20160301052556 2 6 100 2047 5 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D19F4647 20160301052601 2 6 100 2047 2 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D1A5C13B 20160301052612 2 6 100 2047 5 DA57B18976E9C55CEAC3BFFF70419A1550258EA7359400BD4FAC8F4203B73E0BC54D62C0A2D9AA9B543FACA0290514EA426DE6FEF897CB858243511DCE5170420C799D888DCFDC4502FF49B66F34E75C00E98A55408A791FF5CFEA7C288F8E6664226A6A90BE237D2E40C207B5AD0CAEDFDA4946E63AEA351A09EF462515FED4098694241CD07E2CB7727B39B8B1B9467D72DFB908D8169F5DB3CD5A6BEBE1344C585A882508B760402E86EB9B5548A7B98635ECFCDC02FF62B29C53847142FC598ADC66F622F6E9F73BDF02B3D795C0DF23D00E5A3A7748F3E1D5B06F46D4568CE3F4CC57E67D4C36DF5C12800620698C727CC5F5BCACF3B7E17E37D1B7A3EF openssh-7.5p1/regress/multiplex.sh010064400017500001750000000161651306364033700155230ustar00djmdjm# $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.5p1/regress/multipubkey.sh010064400017500001750000000044771306364033700160550ustar00djmdjm# $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.5p1/regress/netcat.c010064400017500001750000001174241306364033700145660ustar00djmdjm/* $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 #ifdef HAVE_ERR_H # include #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 *); 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.5p1/regress/portnum.sh010064400017500001750000000011601306364033700151710ustar00djmdjm# $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.5p1/regress/principals-command.sh010064400017500001750000000127711306364033700172570ustar00djmdjm# $OpenBSD: principals-command.sh,v 1.3 2016/09/26 21:34:38 bluhm 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 [ -z "$SUDO" -a ! -w /var/run ]; then echo "skipped (SUDO not set)" echo "need SUDO to create file in /var/run, test won't work without" exit 0 fi SERIAL=$$ # 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 rsa -f $OBJ/cert_user_key || \ fatal "ssh-keygen of cert_user_key failed" ${SSHKEYGEN} -q -s $OBJ/user_ca_key -I "Joanne User" \ -z $$ -n ${USER},mekmitasdigoat $OBJ/cert_user_key || \ fatal "couldn't sign cert_user_key" CERT_BODY=`cat $OBJ/cert_user_key-cert.pub | awk '{ print $2 }'` CA_BODY=`cat $OBJ/user_ca_key.pub | awk '{ print $2 }'` CERT_FP=`${SSHKEYGEN} -lf $OBJ/cert_user_key-cert.pub | awk '{ print $2 }'` CA_FP=`${SSHKEYGEN} -lf $OBJ/user_ca_key.pub | awk '{ print $2 }'` # Establish a AuthorizedPrincipalsCommand in /var/run where it will have # acceptable directory permissions. PRINCIPALS_COMMAND="/var/run/principals_command_${LOGNAME}" cat << _EOF | $SUDO sh -c "cat > '$PRINCIPALS_COMMAND'" #!/bin/sh test "x\$1" != "x${LOGNAME}" && exit 1 test "x\$2" != "xssh-rsa-cert-v01@openssh.com" && exit 1 test "x\$3" != "xssh-ed25519" && exit 1 test "x\$4" != "xJoanne User" && exit 1 test "x\$5" != "x${SERIAL}" && exit 1 test "x\$6" != "x${CA_FP}" && exit 1 test "x\$7" != "x${CERT_FP}" && exit 1 test "x\$8" != "x${CERT_BODY}" && exit 1 test "x\$9" != "x${CA_BODY}" && 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_COMMAND" if ! $OBJ/check-perm -m keys-command $PRINCIPALS_COMMAND ; then echo "skipping: $PRINCIPALS_COMMAND is unsuitable as " \ "AuthorizedPrincipalsCommand" $SUDO rm -f $PRINCIPALS_COMMAND exit 0 fi if [ -x $PRINCIPALS_COMMAND ]; 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_COMMAND" \ "%u %t %T %i %s %F %f %k %K" 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.5p1/regress/proto-mismatch.sh010064400017500001750000000007311306364033700164360ustar00djmdjm# $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.5p1/regress/proto-version.sh010064400017500001750000000012441306364033700163160ustar00djmdjm# $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.5p1/regress/proxy-connect.sh010064400017500001750000000017151306364033700163030ustar00djmdjm# $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.5p1/regress/putty-ciphers.sh010064400017500001750000000012641306364033700163120ustar00djmdjm# $OpenBSD: putty-ciphers.sh,v 1.5 2016/11/25 03:02:01 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 \ 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.5p1/regress/putty-kex.sh010064400017500001750000000010421306364033700154360ustar00djmdjm# $OpenBSD: putty-kex.sh,v 1.4 2016/11/25 03:02:01 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 true if [ $? -ne 0 ]; then fail "KEX $k failed" fi done openssh-7.5p1/regress/putty-transfer.sh010064400017500001750000000021211306364033700164720ustar00djmdjm# $OpenBSD: putty-transfer.sh,v 1.4 2016/11/25 03:02:01 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 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 \ "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.5p1/regress/reconfigure.sh010064400017500001750000000017441306364033700160050ustar00djmdjm# $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.5p1/regress/reexec.sh010064400017500001750000000022171306364033700147440ustar00djmdjm# $OpenBSD: reexec.sh,v 1.10 2016/12/16 01:06:27 dtucker 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 stop_sshd 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 stop_sshd 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 stop_sshd fi openssh-7.5p1/regress/rekey.sh010064400017500001750000000101721306364033700146070ustar00djmdjm# $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.5p1/regress/rsa_openssh.prv010064400017500001750000000015631306364033700162150ustar00djmdjm-----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.5p1/regress/rsa_openssh.pub010064400017500001750000000003251306364033700161670ustar00djmdjmssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDsilwKcaKN6wSMNd1WgQ9+HRqQEkD0kCTVttrazGu0OhBU3Uko+dFD1Ip0CxdXmN25JQWxOYF7h/Ocu8P3jzv3RTX87xKR0YzlXTLX+SLtF/ySebS3xWPrlfRUDhh03hR5V+8xxvvy9widPYKw/oItwGSueOsEq1LTczCDv2dAjQ== openssh-7.5p1/regress/rsa_ssh2.prv010064400017500001750000000016341306364033700154140ustar00djmdjm---- 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.5p1/regress/scp-ssh-wrapper.sh010064400017500001750000000016221306364033700165260ustar00djmdjm#!/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.5p1/regress/scp.sh010064400017500001750000000070001306364033700142510ustar00djmdjm# $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.5p1/regress/setuid-allowed.c010064400017500001750000000026721306364033700162300ustar00djmdjm/* * 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.5p1/regress/sftp-badcmds.sh010064400017500001750000000043451306364033700160440ustar00djmdjm# $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.5p1/regress/sftp-batch.sh010064400017500001750000000022451306364033700155250ustar00djmdjm# $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.5p1/regress/sftp-chroot.sh010064400017500001750000000015101306364033700157340ustar00djmdjm# $OpenBSD: sftp-chroot.sh,v 1.5 2016/09/26 21:34:38 bluhm Exp $ # Placed in the Public Domain. tid="sftp in chroot" CHROOT=/var/run FILENAME=testdata_${USER} PRIVDATA=${CHROOT}/${FILENAME} if [ -z "$SUDO" -a ! -w /var/run ]; 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.5p1/regress/sftp-cmds.sh010064400017500001750000000164511306364033700153760ustar00djmdjm# $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.5p1/regress/sftp-glob.sh010064400017500001750000000047401306364033700153710ustar00djmdjm# $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.5p1/regress/sftp-perm.sh010064400017500001750000000123561306364033700154130ustar00djmdjm# $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.5p1/regress/sftp.sh010064400017500001750000000013661306364033700144510ustar00djmdjm# $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.5p1/regress/ssh-com-client.sh010064400017500001750000000060271306364033700163210ustar00djmdjm# $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.5p1/regress/ssh-com-keygen.sh010064400017500001750000000026051306364033700163230ustar00djmdjm# $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.5p1/regress/ssh-com-sftp.sh010064400017500001750000000023061306364033700160130ustar00djmdjm# $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.5p1/regress/ssh-com.sh010064400017500001750000000053541306364033700150470ustar00djmdjm# $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.5p1/regress/t11.ok010064400017500001750000000000631306364033700140720ustar00djmdjmSHA256:4w1rnrek3klTJOTVhwuCIFd5k+pq9Bfo5KTxxb8BqbY openssh-7.5p1/regress/ssh2putty.sh010075500017500001750000000012651306364033700154630ustar00djmdjm#!/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.5p1/regress/sshcfgparse.sh010064400017500001750000000024161306364033700160020ustar00djmdjm# $OpenBSD: sshcfgparse.sh,v 1.2 2016/07/14 01:24:21 dtucker Exp $ # Placed in the Public Domain. tid="ssh config parse" verbose "reparse minimal config" (${SSH} -G -F $OBJ/ssh_config somehost >$OBJ/ssh_config.1 && ${SSH} -G -F $OBJ/ssh_config.1 somehost >$OBJ/ssh_config.2 && diff $OBJ/ssh_config.1 $OBJ/ssh_config.2) || fail "reparse minimal config" verbose "ssh -W opts" f=`${SSH} -GF $OBJ/ssh_config host | awk '/exitonforwardfailure/{print $2}'` test "$f" = "no" || fail "exitonforwardfailure default" f=`${SSH} -GF $OBJ/ssh_config -W a:1 h | awk '/exitonforwardfailure/{print $2}'` test "$f" = "yes" || fail "exitonforwardfailure enable" f=`${SSH} -GF $OBJ/ssh_config -W a:1 -o exitonforwardfailure=no h | \ awk '/exitonforwardfailure/{print $2}'` test "$f" = "no" || fail "exitonforwardfailure override" f=`${SSH} -GF $OBJ/ssh_config host | awk '/clearallforwardings/{print $2}'` test "$f" = "no" || fail "clearallforwardings default" f=`${SSH} -GF $OBJ/ssh_config -W a:1 h | awk '/clearallforwardings/{print $2}'` test "$f" = "yes" || fail "clearallforwardings enable" f=`${SSH} -GF $OBJ/ssh_config -W a:1 -o clearallforwardings=no h | \ awk '/clearallforwardings/{print $2}'` test "$f" = "no" || fail "clearallforwardings override" # cleanup rm -f $OBJ/ssh_config.[012] openssh-7.5p1/regress/sshd-log-wrapper.sh010064400017500001750000000004351306364033700166670ustar00djmdjm#!/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.5p1/regress/stderr-after-eof.sh010064400017500001750000000011421306364033700166360ustar00djmdjm# $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.5p1/regress/stderr-data.sh010064400017500001750000000013661306364033700157070ustar00djmdjm# $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.5p1/regress/t4.ok010064400017500001750000000000641306364033700140150ustar00djmdjmMD5:3b:dd:44:e9:49:18:84:95:f1:e7:33:6b:9d:93:b1:36 openssh-7.5p1/regress/t5.ok010064400017500001750000000001021306364033700140070ustar00djmdjmxokes-lylis-byleh-zebib-kalus-bihas-tevah-haroz-suhar-foved-noxex openssh-7.5p1/regress/test-exec.sh010064400017500001750000000311701306364033700153720ustar00djmdjm# $OpenBSD: test-exec.sh,v 1.59 2017/02/07 23:03:11 dtucker 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=2 #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 REAL_SSH="$SSH" 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 stop_sshd () { 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 } # 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 stop_sshd } 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 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 # This may be necessary if /usr/src and/or /usr/obj are group-writable, # but if you aren't careful with permissions then the unit tests could # be abused to locally escalate privileges. if [ ! -z "$TEST_SSH_UNSAFE_PERMISSIONS" ]; then echo "StrictModes no" >> $OBJ/sshd_config fi 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 * Hostname 127.0.0.1 HostKeyAlias localhost-with-alias Port $PORT User $USER GlobalKnownHostsFile $OBJ/known_hosts UserKnownHostsFile $OBJ/known_hosts PubkeyAuthentication yes ChallengeResponseAuthentication no HostbasedAuthentication no PasswordAuthentication 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 if ! puttygen -t rsa -o ${OBJ}/putty.rsa2 \ --new-passphrase /dev/null < /dev/null > /dev/null; then echo "Your installed version of PuTTY is too old to support --new-passphrase; trying without (may require manual interaction) ..." >&2 puttygen -t rsa -o ${OBJ}/putty.rsa2 < /dev/null > /dev/null fi 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 "Protocol=ssh" >> ${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 echo "ProxyLocalhost=1" >> ${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.5p1/regress/transfer.sh010064400017500001750000000012501306364033700153110ustar00djmdjm# $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.5p1/regress/try-ciphers.sh010064400017500001750000000017711306364033700157460ustar00djmdjm# $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.5p1/regress/unittests004075500017500001750000000000001306364033700151215ustar00djmdjmopenssh-7.5p1/regress/unittests/Makefile010064400017500001750000000002751306364033700166410ustar00djmdjm# $OpenBSD: Makefile,v 1.9 2017/03/14 01:20:29 dtucker Exp $ REGRESS_FAIL_EARLY?= yes SUBDIR= test_helper sshbuf sshkey bitmap kex hostkeys utf8 match conversion .include openssh-7.5p1/regress/unittests/Makefile.inc010064400017500001750000000031211306364033700174020ustar00djmdjm# $OpenBSD: Makefile.inc,v 1.9 2016/11/01 13:43:27 tb 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 LIBSSH=${.CURDIR}/${SSHREL}/lib/${__objdir}/libssh.a .else LDADD+=-L${.CURDIR}/${SSHREL}/lib -lssh LIBSSH=${.CURDIR}/${SSHREL}/lib/libssh.a .endif DPADD+=${LIBSSH} ${PROG}: ${LIBSSH} ${LIBSSH}: cd ${.CURDIR}/${SSHREL} && ${MAKE} lib LDADD+= -lcrypto DPADD+= ${LIBCRYPTO} openssh-7.5p1/regress/unittests/bitmap004075500017500001750000000000001306364033700163755ustar00djmdjmopenssh-7.5p1/regress/unittests/bitmap/Makefile010064400017500001750000000003171306364033700201120ustar00djmdjm# $OpenBSD: Makefile,v 1.3 2016/11/01 13:43:27 tb Exp $ PROG=test_bitmap SRCS=tests.c REGRESS_TARGETS=run-regress-${PROG} run-regress-${PROG}: ${PROG} env ${TEST_ENV} ./${PROG} .include openssh-7.5p1/regress/unittests/bitmap/tests.c010064400017500001750000000057701306364033700177700ustar00djmdjm/* $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.5p1/regress/unittests/conversion004075500017500001750000000000001306364033700173065ustar00djmdjmopenssh-7.5p1/regress/unittests/conversion/Makefile010064400017500001750000000003301306364033700210160ustar00djmdjm# $OpenBSD: Makefile,v 1.1 2017/03/14 01:20:29 dtucker Exp $ PROG=test_conversion SRCS=tests.c REGRESS_TARGETS=run-regress-${PROG} run-regress-${PROG}: ${PROG} env ${TEST_ENV} ./${PROG} .include openssh-7.5p1/regress/unittests/conversion/tests.c010064400017500001750000000023171306364033700206730ustar00djmdjm/* $OpenBSD: tests.c,v 1.1 2017/03/14 01:20:29 dtucker Exp $ */ /* * Regress test for conversions * * 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 "misc.h" void tests(void) { char buf[1024]; TEST_START("conversion_convtime"); ASSERT_LONG_EQ(convtime("0"), 0); ASSERT_LONG_EQ(convtime("1"), 1); ASSERT_LONG_EQ(convtime("1S"), 1); /* from the examples in the comment above the function */ ASSERT_LONG_EQ(convtime("90m"), 5400); ASSERT_LONG_EQ(convtime("1h30m"), 5400); ASSERT_LONG_EQ(convtime("2d"), 172800); ASSERT_LONG_EQ(convtime("1w"), 604800); /* negative time is not allowed */ ASSERT_LONG_EQ(convtime("-7"), -1); ASSERT_LONG_EQ(convtime("-9d"), -1); /* overflow */ snprintf(buf, sizeof buf, "%llu", (unsigned long long)LONG_MAX + 1); ASSERT_LONG_EQ(convtime(buf), -1); /* overflow with multiplier */ snprintf(buf, sizeof buf, "%lluM", (unsigned long long)LONG_MAX/60 + 1); ASSERT_LONG_EQ(convtime(buf), -1); ASSERT_LONG_EQ(convtime("1000000000000000000000w"), -1); TEST_DONE(); } openssh-7.5p1/regress/unittests/hostkeys004075500017500001750000000000001306364033700167725ustar00djmdjmopenssh-7.5p1/regress/unittests/hostkeys/Makefile010064400017500001750000000003671306364033700205140ustar00djmdjm# $OpenBSD: Makefile,v 1.3 2016/11/01 13:43:27 tb Exp $ 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.5p1/regress/unittests/hostkeys/mktestdata.sh010064400017500001750000000053651306364033700215540ustar00djmdjm#!/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.5p1/regress/unittests/hostkeys/test_iterate.c010064400017500001750000000615741306364033700217230ustar00djmdjm/* $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.5p1/regress/unittests/hostkeys/testdata004075500017500001750000000000001306364033700206035ustar00djmdjmopenssh-7.5p1/regress/unittests/hostkeys/testdata/dsa_1.pub010064400017500001750000000011241306364033700223540ustar00djmdjmssh-dss AAAAB3NzaC1kc3MAAACBAOqffHxEW4c+Z9q/r3l4sYK8F7qrBsU8XF9upGsW62T9InROFFq9IO0x3pQ6mDA0Wtw0sqcDmkPCHPyP4Ok/fU3/drLaZusHoVYu8pBBrWsIDrKgkeX9TEodBsSrYdl4Sqtqq9EZv9+DttV6LStZrgYyUTOKwOF95wGantpLynX5AAAAFQDdt+zjRNlETDsgmxcSYFgREirJrQAAAIBQlrPaiPhR24FhnMLcHH4016vL7AqDDID6Qw7PhbXGa4/XlxWMIigjBKrIPKvnZ6p712LSnCKtcbfdx0MtmJlNa01CYqPaRhgRaf+uGdvTkTUcdaq8R5lLJL+JMNwUhcC8ijm3NqEjXjffuebGe1EzIeiITbA7Nndcd+GytwRDegAAAIEAkRYPjSVcUxfUHhHdpP6V8CuY1+CYSs9EPJ7iiWTDuXWVIBTU32oJLAnrmAcOwtIzEfPvm+rff5FI/Yhon2pB3VTXhPPEBjYzE5qANanAT4e6tzAVc5f3DUhHaDknwRYfDz86GFvuLtDjeE/UZ9t6OofYoEsCBpYozLAprBvNIQY= DSA #1 openssh-7.5p1/regress/unittests/hostkeys/testdata/dsa_2.pub010064400017500001750000000011241306364033700223550ustar00djmdjmssh-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.5p1/regress/unittests/hostkeys/testdata/dsa_3.pub010064400017500001750000000011241306364033700223560ustar00djmdjmssh-dss AAAAB3NzaC1kc3MAAACBAI6lz2Ip9bzE7TGuDD4SjO9S4Ac90gq0h6ai1O06eI8t/Ot2uJ5Jk2QyVr2jvIZHDl/5bwBx7+5oyjlwRoUrAPPD814wf5tU2tSnmdu1Wbf0cBswif5q0r4tevzmopp/AtgH11QHo3u0/pfyJd10qBDLV2FaYSKMmZvyPfZJ0s9pAAAAFQD5Eqjl6Rx2qVePodD9OwAPT0bU6wAAAIAfnDm6csZF0sFaJR3NIJvaYgSGr8s7cqlsk2gLltB/1wOOO2yX+NeEC+B0H93hlMfaUsPa08bwgmYxnavSMqEBpmtPceefJiEd68zwYqXd38f88wyWZ9Z5iwaI/6OVZPHzCbDxOa4ewVTevRNYUKP1xUTZNT8/gSMfZLYPk4T2AQAAAIAUKroozRMyV+3V/rxt0gFnNxRXBKk+9cl3vgsQ7ktkI9cYg7V1T2K0XF21AVMK9gODszy6PBJjV6ruXBV6TRiqIbQauivp3bHHKYsG6wiJNqwdbVwIjfvv8nn1qFoZQLXG3sdONr9NwN8KzrX89OV0BlR2dVM5qqp+YxOXymP9yg== DSA #3 openssh-7.5p1/regress/unittests/hostkeys/testdata/dsa_4.pub010064400017500001750000000011241306364033700223570ustar00djmdjmssh-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.5p1/regress/unittests/hostkeys/testdata/dsa_5.pub010064400017500001750000000011241306364033700223600ustar00djmdjmssh-dss AAAAB3NzaC1kc3MAAACBALrFy7w5ihlaOG+qR+6fj+vm5EQaO3qwxgACLcgH+VfShuOG4mkx8qFJmf+OZ3fh5iKngjNZfKtfcqI7zHWdk6378TQfQC52/kbZukjNXOLCpyNkogahcjA00onIoTK1RUDuMW28edAHwPFbpttXDTaqis+8JPMY8hZwsZGENCzTAAAAFQD6+It5vozwGgaN9ROYPMlByhi6jwAAAIBz2mcAC694vNzz9b6614gkX9d9E99PzJYfU1MPkXDziKg7MrjBw7Opd5y1jL09S3iL6lSTlHkKwVKvQ3pOwWRwXXRrKVus4I0STveoApm526jmp6mY0YEtqR98vMJ0v97h1ydt8FikKlihefCsnXVicb8887PXs2Y8C6GuFT3tfQAAAIBbmHtV5tPcrMRDkULhaQ/Whap2VKvT2DUhIHA7lx6oy/KpkltOpxDZOIGUHKqffGbiR7Jh01/y090AY5L2eCf0S2Ytx93+eADwVVpJbFJo6zSwfeey2Gm6L2oA+rCz9zTdmtZoekpD3/RAOQjnJIAPwbs7mXwabZTw4xRtiYIRrw== DSA #5 openssh-7.5p1/regress/unittests/hostkeys/testdata/dsa_6.pub010064400017500001750000000011241306364033700223610ustar00djmdjmssh-dss AAAAB3NzaC1kc3MAAACBAIutigAse65TCW6hHDOEGXenE9L4L0talHbs65hj3UUNtWflKdQeXLofqXgW8AwaDKmnuRPrxRoxVNXj84n45wtBEdt4ztmdAZteAbXSnHqpcxME3jDxh3EtxzGPXLs+RUmKPVguraSgo7W2oN7KFx6VM+AcAtxANSTlvDid3s47AAAAFQCd9Q3kkHSLWe77sW0eRaayI45ovwAAAIAw6srGF6xvFasI44Y3r9JJ2K+3ezozl3ldL3p2+p2HG3iWafC4SdV8pB6ZIxKlYAywiiFb3LzH/JweGFq1jtoFDRM3MlYORBevydU4zPz7b5QLDVB0sY4evYtWmg2BFJvoWRfhLnlZVW7h5N8v4fNIwdVmVsw4Ljes7iF2HRGhHgAAAIBDFT3fww2Oby1xUA6G9pDAcVikrQFqp1sJRylNTUyeyQ37SNAGzYxwHJFgQr8gZLdRQ1UW+idYpqVbVNcYFMOiw/zSqK2OfVwPZ9U+TTKdc992ChSup6vJEKM/ZVIyDWDbJr7igQ4ahy7jo9mFvm8ljN926EnspQzCvs0Dxk6tHA== DSA #6 openssh-7.5p1/regress/unittests/hostkeys/testdata/ecdsa_1.pub010064400017500001750000000003261306364033700226670ustar00djmdjmecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBF6yQEtD9yBw9gmDRf477WBBzvWhAa0ioBI3nbA4emKykj0RbuQd5C4XdQAEOZGzE7v//FcCjwB2wi+JH5eKkxCtN6CjohDASZ1huoIV2UVyYIicZJEEOg1IWjjphvaxtw== ECDSA #1 openssh-7.5p1/regress/unittests/hostkeys/testdata/ecdsa_2.pub010064400017500001750000000004061306364033700226670ustar00djmdjmecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAB8qVcXwgBM92NCmReQlPrZAoui4Bz/mW0VUBFOpHXXW1n+15b/Y7Pc6UBd/ITTZmaBciXY+PWaSBGdwc5GdqGdLgFyJ/QAGrFMPNpVutm/82gNQzlxpNwjbMcKyiZEXzSgnjS6DzMQ0WuSMdzIBXq8OW/Kafxg4ZkU6YqALUXxlQMZuQ== ECDSA #2 openssh-7.5p1/regress/unittests/hostkeys/testdata/ecdsa_3.pub010064400017500001750000000002521306364033700226670ustar00djmdjmecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIb3BhJZk+vUQPg5TQc1koIzuGqloCq7wjr9LjlhG24IBeiFHLsdWw74HDlH4DrOmlxToVYk2lTdnjARleRByjk= ECDSA #3 openssh-7.5p1/regress/unittests/hostkeys/testdata/ecdsa_4.pub010064400017500001750000000002521306364033700226700ustar00djmdjmecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHZd0OXHIWwK3xnjAdMZ1tojxWycdu38pORO/UX5cqsKMgGCKQVBWWO3TFk1ePkGIE9VMWT1hCGqWRRwYlH+dSE= ECDSA #4 openssh-7.5p1/regress/unittests/hostkeys/testdata/ecdsa_5.pub010064400017500001750000000002521306364033700226710ustar00djmdjmecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPIudcagzq4QPtP1jkpje34+0POLB0jwT64hqrbCqhTH2T800KDZ0h2vwlJYa3OP3Oqru9AB5pnuHsKw7mAhUGY= ECDSA #5 openssh-7.5p1/regress/unittests/hostkeys/testdata/ecdsa_6.pub010064400017500001750000000002521306364033700226720ustar00djmdjmecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK1wRLyKtvK3Mmhd0XPkKwW4ev1KBVf8J4aG8lESq1TsaqqfOXYGyxMq5pN8fCGiD5UPOqyTYz/ZNzClRhJRHao= ECDSA #6 openssh-7.5p1/regress/unittests/hostkeys/testdata/ed25519_1.pub010064400017500001750000000001341306364033700226030ustar00djmdjmssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK9ks7jkua5YWIwByRnnnc6UPJQWI75O0e/UJdPYU1JI ED25519 #1 openssh-7.5p1/regress/unittests/hostkeys/testdata/ed25519_2.pub010064400017500001750000000001341306364033700226040ustar00djmdjmssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIBp6PVW0z2o9C4Ukv/JOgmK7QMFe1pD1s3ADFF7IQob ED25519 #2 openssh-7.5p1/regress/unittests/hostkeys/testdata/ed25519_3.pub010064400017500001750000000001341306364033700226050ustar00djmdjmssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBlYfExtYZAPqYvYdrlpGlSWhh/XNHcH3v3c2JzsVNbB ED25519 #3 openssh-7.5p1/regress/unittests/hostkeys/testdata/ed25519_4.pub010064400017500001750000000001341306364033700226060ustar00djmdjmssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDFP8L9REfN/iYy1KIRtFqSCn3V2+vOCpoZYENFGLdOF ED25519 #4 openssh-7.5p1/regress/unittests/hostkeys/testdata/ed25519_5.pub010064400017500001750000000001341306364033700226070ustar00djmdjmssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINf63qSV8rD57N+digID8t28WVhd3Yf2K2UhaoG8TsWQ ED25519 #5 openssh-7.5p1/regress/unittests/hostkeys/testdata/ed25519_6.pub010064400017500001750000000001341306364033700226100ustar00djmdjmssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPLW0ZwCkRQldpLa4I5BpwGa/om+WE6OgC8jdVqakt0Z ED25519 #6 openssh-7.5p1/regress/unittests/hostkeys/testdata/known_hosts010064400017500001750000000340471306364033700231660ustar00djmdjm# 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.5p1/regress/unittests/hostkeys/testdata/rsa1_1.pub010064400017500001750000000005111306364033700224520ustar00djmdjm1024 65537 153895431603677073925890314548566704948446776958334195280085080329934839226701954473292358821568047724356487621573742372399387931887004184139835510820577359977148363519970774657801798872789118894962853659233045778161859413980935372685480527355016624825696983269800574755126132814333241868538220824608980319407 RSA1 #1 openssh-7.5p1/regress/unittests/hostkeys/testdata/rsa1_2.pub010064400017500001750000000005111306364033700224530ustar00djmdjm1024 65537 135970715082947442639683969597180728933388298633245835186618852623800675939308729462220235058285909679252157995530180587329132927339620517781785310829060832352381015614725360278571924286986474946772141568893116432268565829418506866604294073334978275702221949783314402806080929601995102334442541344606109853641 RSA1 #2 openssh-7.5p1/regress/unittests/hostkeys/testdata/rsa1_3.pub010064400017500001750000000005111306364033700224540ustar00djmdjm1024 65537 125895605498029643697051635076028105429632810811904702876152645261610759866299221305725069141163240694267669117205342283569102183636228981857946763978553664895308762890072813014496700601576921921752482059207749978374872713540759920335553799711267170948655579130584031555334229966603000896364091459595522912269 RSA1 #3 openssh-7.5p1/regress/unittests/hostkeys/testdata/rsa1_4.pub010064400017500001750000000005111306364033700224550ustar00djmdjm1024 65537 174143366122697048196335388217056770310345753698079464367148030836533360510864881734142526411160017107552815906024399248049666856133771656680462456979369587903909343046704480897527203474513676654933090991684252819423129896444427656841613263783484827101210734799449281639493127615902427443211183258155381810593 RSA1 #4 openssh-7.5p1/regress/unittests/hostkeys/testdata/rsa1_5.pub010064400017500001750000000005111306364033700224560ustar00djmdjm1024 65537 127931411493401587586867047972295564331543694182352197506125410692673654572057908999642645524647232712160516076508316152810117209181150078352725299319149726341058893406440426414316276977768958023952319602422835879783057966985348561111880658922724668687074412548487722084792283453716871417610020757212399252171 RSA1 #5 openssh-7.5p1/regress/unittests/hostkeys/testdata/rsa1_6.pub010064400017500001750000000005111306364033700224570ustar00djmdjm1024 65537 140883028436203600354693376066567741282115117509696517282419557936340193768851493584179972504103033755515036493433917203732876685813283050574208967197963391667532902202382549275760997891673884333346000558018002659506756213191532156293935482587878596032743105911487673274674568768638010598205190227631909167257 RSA1 #6 openssh-7.5p1/regress/unittests/hostkeys/testdata/rsa_1.pub010064400017500001750000000003341306364033700223740ustar00djmdjmssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDg4hB4vAZHJ0PVRiJajOv/GlytFWNpv5/9xgB9+5BIbvp8LOrFZ5D9K0Gsmwpd4G4rfaAz8j896DhMArg0vtkilIPPGt/6VzWMERgvaIQPJ/IE99X3+fjcAG56oAWwy29JX10lQMzBPU6XJIaN/zqpkb6qUBiAHBdLpxrFBBU0/w== RSA #1 openssh-7.5p1/regress/unittests/hostkeys/testdata/rsa_2.pub010064400017500001750000000003341306364033700223750ustar00djmdjmssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDmbUhNabB5AmBDX6GNHZ3lbn7pRxqfpW+f53QqNGlK0sLV+0gkMIrOfUp1kdE2ZLE6tfzdicatj/RlH6/wuo4yyYb+Pyx3G0vxdmAIiA4aANq38XweDucBC0TZkRWVHK+Gs5V/uV0z7N0axJvkkJujMLvST3CRiiWwlficBc6yVQ== RSA #2 openssh-7.5p1/regress/unittests/hostkeys/testdata/rsa_3.pub010064400017500001750000000003341306364033700223760ustar00djmdjmssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDX8F93W3SH4ZSus4XUQ2cw9dqcuyUETTlKEeGv3zlknV3YCoe2Mp04naDhiuwj8sOsytrZSESzLY1ZEyzrjxE6ZFVv8NKgck/AbRjcwlRFOcx9oKUxOrXRa0IoXlTq0kyjKCJfaHBKnGitZThknCPTbVmpATkm5xx6J0WEDozfoQ== RSA #3 openssh-7.5p1/regress/unittests/hostkeys/testdata/rsa_4.pub010064400017500001750000000003341306364033700223770ustar00djmdjmssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDI8AdjBAozcdRnIikVlt69iyDHKyrtxmpdkbRy9bWaL86OH+PTmLUk5e+T/ufiakpeE2pm0hkE3e4Sh/FsY+rsQdRoraWVNFfchcMeVlKvuy5RZN0ElvmaQebOJUeNeBn2LLw8aL8bJ4CP/bQRKrmrSSqjz3+4H9YNVyyk1OGBPQ== RSA #4 openssh-7.5p1/regress/unittests/hostkeys/testdata/rsa_5.pub010064400017500001750000000003341306364033700224000ustar00djmdjmssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC/C15Q4sfnk7BZff1er8bscay+5s51oD4eWArlHWMK/ZfYeeTAccTy+7B7Jv+MS4nKCpflrvJI2RQz4kS8vF0ATdBbi4jeWefStlHNg0HLhnCY7NAfDIlRdaN9lm3Pqm2vmr+CkqwcJaSpycDg8nPN9yNAuD6pv7NDuUnECezojQ== RSA #5 openssh-7.5p1/regress/unittests/hostkeys/testdata/rsa_6.pub010064400017500001750000000003341306364033700224010ustar00djmdjmssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQClu/3I6GG1Ai89Imnw0vXmWJ2OW0ftQwRrsbIAD0qzLFYpkJ76QWnzpCehvK9u0L5hcw7z2Y6mRLcSBsqONc+HVU73Qi7M4zHRvtjprPs3SOyLpf0J9sL1WiHBDwg2P0miHMCdqHDd5nVXkJB2d4eeecmgezGLa29NOHZjbza5yw== RSA #6 openssh-7.5p1/regress/unittests/hostkeys/tests.c010064400017500001750000000003741306364033700203600ustar00djmdjm/* $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.5p1/regress/unittests/kex004075500017500001750000000000001306364033700157105ustar00djmdjmopenssh-7.5p1/regress/unittests/kex/Makefile010064400017500001750000000003431306364033700174240ustar00djmdjm# $OpenBSD: Makefile,v 1.4 2016/11/01 13:43:27 tb Exp $ 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.5p1/regress/unittests/kex/test_kex.c010064400017500001750000000117731306364033700177670ustar00djmdjm/* $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.5p1/regress/unittests/kex/tests.c010064400017500001750000000003121306364033700172660ustar00djmdjm/* $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.5p1/regress/unittests/match004075500017500001750000000000001306364033700162155ustar00djmdjmopenssh-7.5p1/regress/unittests/match/Makefile010064400017500001750000000003161306364033700177310ustar00djmdjm# $OpenBSD: Makefile,v 1.3 2016/11/01 13:43:27 tb Exp $ PROG=test_match SRCS=tests.c REGRESS_TARGETS=run-regress-${PROG} run-regress-${PROG}: ${PROG} env ${TEST_ENV} ./${PROG} .include openssh-7.5p1/regress/unittests/match/tests.c010064400017500001750000000122111306364033700175740ustar00djmdjm/* $OpenBSD: tests.c,v 1.4 2017/02/03 23:01:42 djm Exp $ */ /* * Regress test for matching functions * * 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 "match.h" void tests(void) { TEST_START("match_pattern"); ASSERT_INT_EQ(match_pattern("", ""), 1); ASSERT_INT_EQ(match_pattern("", "aaa"), 0); ASSERT_INT_EQ(match_pattern("aaa", ""), 0); ASSERT_INT_EQ(match_pattern("aaa", "aaaa"), 0); ASSERT_INT_EQ(match_pattern("aaaa", "aaa"), 0); TEST_DONE(); TEST_START("match_pattern wildcard"); ASSERT_INT_EQ(match_pattern("", "*"), 1); ASSERT_INT_EQ(match_pattern("a", "?"), 1); ASSERT_INT_EQ(match_pattern("aa", "a?"), 1); ASSERT_INT_EQ(match_pattern("a", "*"), 1); ASSERT_INT_EQ(match_pattern("aa", "a*"), 1); ASSERT_INT_EQ(match_pattern("aa", "?*"), 1); ASSERT_INT_EQ(match_pattern("aa", "**"), 1); ASSERT_INT_EQ(match_pattern("aa", "?a"), 1); ASSERT_INT_EQ(match_pattern("aa", "*a"), 1); ASSERT_INT_EQ(match_pattern("ba", "a?"), 0); ASSERT_INT_EQ(match_pattern("ba", "a*"), 0); ASSERT_INT_EQ(match_pattern("ab", "?a"), 0); ASSERT_INT_EQ(match_pattern("ab", "*a"), 0); TEST_DONE(); TEST_START("match_pattern_list"); ASSERT_INT_EQ(match_pattern_list("", "", 0), 0); /* no patterns */ ASSERT_INT_EQ(match_pattern_list("", "*", 0), 1); ASSERT_INT_EQ(match_pattern_list("", "!*", 0), -1); ASSERT_INT_EQ(match_pattern_list("", "!a,*", 0), 1); ASSERT_INT_EQ(match_pattern_list("", "*,!a", 0), 1); ASSERT_INT_EQ(match_pattern_list("", "a,!*", 0), -1); ASSERT_INT_EQ(match_pattern_list("", "!*,a", 0), -1); ASSERT_INT_EQ(match_pattern_list("a", "", 0), 0); ASSERT_INT_EQ(match_pattern_list("a", "*", 0), 1); ASSERT_INT_EQ(match_pattern_list("a", "!*", 0), -1); ASSERT_INT_EQ(match_pattern_list("a", "!a", 0), -1); /* XXX negated ASSERT_INT_EQ(match_pattern_list("a", "!b", 0), 1); */ ASSERT_INT_EQ(match_pattern_list("a", "!a,*", 0), -1); ASSERT_INT_EQ(match_pattern_list("b", "!a,*", 0), 1); ASSERT_INT_EQ(match_pattern_list("a", "*,!a", 0), -1); ASSERT_INT_EQ(match_pattern_list("b", "*,!a", 0), 1); ASSERT_INT_EQ(match_pattern_list("a", "a,!*", 0), -1); ASSERT_INT_EQ(match_pattern_list("b", "a,!*", 0), -1); ASSERT_INT_EQ(match_pattern_list("a", "a,!a", 0), -1); /* XXX negated ASSERT_INT_EQ(match_pattern_list("b", "a,!a", 0), 1); */ ASSERT_INT_EQ(match_pattern_list("a", "!*,a", 0), -1); ASSERT_INT_EQ(match_pattern_list("b", "!*,a", 0), -1); TEST_DONE(); TEST_START("match_pattern_list lowercase"); ASSERT_INT_EQ(match_pattern_list("abc", "ABC", 0), 0); ASSERT_INT_EQ(match_pattern_list("ABC", "abc", 0), 0); ASSERT_INT_EQ(match_pattern_list("abc", "ABC", 1), 1); ASSERT_INT_EQ(match_pattern_list("ABC", "abc", 1), 0); TEST_DONE(); TEST_START("addr_match_list"); ASSERT_INT_EQ(addr_match_list("127.0.0.1", "127.0.0.1/44"), -2); ASSERT_INT_EQ(addr_match_list(NULL, "127.0.0.1/44"), -2); ASSERT_INT_EQ(addr_match_list("a", "*"), 0); ASSERT_INT_EQ(addr_match_list("127.0.0.1", "*"), 1); ASSERT_INT_EQ(addr_match_list(NULL, "*"), 0); ASSERT_INT_EQ(addr_match_list("127.0.0.1", "127.0.0.1"), 1); ASSERT_INT_EQ(addr_match_list("127.0.0.1", "127.0.0.2"), 0); ASSERT_INT_EQ(addr_match_list("127.0.0.1", "!127.0.0.1"), -1); /* XXX negated ASSERT_INT_EQ(addr_match_list("127.0.0.1", "!127.0.0.2"), 1); */ ASSERT_INT_EQ(addr_match_list("127.0.0.255", "127.0.0.0/24"), 1); ASSERT_INT_EQ(addr_match_list("127.0.1.1", "127.0.0.0/24"), 0); ASSERT_INT_EQ(addr_match_list("127.0.0.1", "127.0.0.0/24"), 1); ASSERT_INT_EQ(addr_match_list("127.0.0.1", "127.0.1.0/24"), 0); ASSERT_INT_EQ(addr_match_list("127.0.0.1", "!127.0.0.0/24"), -1); /* XXX negated ASSERT_INT_EQ(addr_match_list("127.0.0.1", "!127.0.1.0/24"), 1); */ ASSERT_INT_EQ(addr_match_list("127.0.0.1", "10.0.0.1,!127.0.0.1"), -1); ASSERT_INT_EQ(addr_match_list("127.0.0.1", "!127.0.0.1,10.0.0.1"), -1); ASSERT_INT_EQ(addr_match_list("127.0.0.1", "10.0.0.1,127.0.0.2"), 0); ASSERT_INT_EQ(addr_match_list("127.0.0.1", "127.0.0.2,10.0.0.1"), 0); /* XXX negated ASSERT_INT_EQ(addr_match_list("127.0.0.1", "10.0.0.1,!127.0.0.2"), 1); */ /* XXX negated ASSERT_INT_EQ(addr_match_list("127.0.0.1", "!127.0.0.2,10.0.0.1"), 1); */ TEST_DONE(); #define CHECK_FILTER(string,filter,expected) \ do { \ char *result = match_filter_list((string), (filter)); \ ASSERT_STRING_EQ(result, expected); \ free(result); \ } while (0) TEST_START("match_filter_list"); CHECK_FILTER("a,b,c", "", "a,b,c"); CHECK_FILTER("a,b,c", "a", "b,c"); CHECK_FILTER("a,b,c", "b", "a,c"); CHECK_FILTER("a,b,c", "c", "a,b"); CHECK_FILTER("a,b,c", "a,b", "c"); CHECK_FILTER("a,b,c", "a,c", "b"); CHECK_FILTER("a,b,c", "b,c", "a"); CHECK_FILTER("a,b,c", "a,b,c", ""); CHECK_FILTER("a,b,c", "b,c", "a"); CHECK_FILTER("", "a,b,c", ""); TEST_DONE(); /* * XXX TODO * 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 *); * int addr_match_cidr_list(const char *, const char *); */ } openssh-7.5p1/regress/unittests/sshbuf004075500017500001750000000000001306364033700164135ustar00djmdjmopenssh-7.5p1/regress/unittests/sshbuf/Makefile010064400017500001750000000004661306364033700201350ustar00djmdjm# $OpenBSD: Makefile,v 1.5 2016/11/01 13:43:27 tb 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.5p1/regress/unittests/sshbuf/test_sshbuf.c010064400017500001750000000144771306364033700212010ustar00djmdjm/* $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.5p1/regress/unittests/sshbuf/test_sshbuf_fixed.c010064400017500001750000000074571306364033700223600ustar00djmdjm/* $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.5p1/regress/unittests/sshbuf/test_sshbuf_fuzz.c010064400017500001750000000064141306364033700222470ustar00djmdjm/* $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.5p1/regress/unittests/sshbuf/test_sshbuf_getput_basic.c010064400017500001750000000334001306364033700237150ustar00djmdjm/* $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.5p1/regress/unittests/sshbuf/test_sshbuf_getput_crypto.c010064400017500001750000000275461306364033700241720ustar00djmdjm/* $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.5p1/regress/unittests/sshbuf/test_sshbuf_getput_fuzz.c010064400017500001750000000057151306364033700236420ustar00djmdjm/* $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.5p1/regress/unittests/sshbuf/test_sshbuf_misc.c010064400017500001750000000077111306364033700222050ustar00djmdjm/* $OpenBSD: test_sshbuf_misc.c,v 1.2 2016/05/03 13:48:33 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(); TEST_START("sshbuf_dup_string"); p1 = sshbuf_new(); ASSERT_PTR_NE(p1, NULL); /* Check empty buffer */ p = sshbuf_dup_string(p1); ASSERT_PTR_NE(p, NULL); ASSERT_SIZE_T_EQ(strlen(p), 0); free(p); /* Check buffer with string */ ASSERT_INT_EQ(sshbuf_put(p1, "quad1", strlen("quad1")), 0); p = sshbuf_dup_string(p1); ASSERT_PTR_NE(p, NULL); ASSERT_SIZE_T_EQ(strlen(p), strlen("quad1")); ASSERT_STRING_EQ(p, "quad1"); free(p); /* Check buffer with terminating nul */ ASSERT_INT_EQ(sshbuf_put(p1, "\0", 1), 0); p = sshbuf_dup_string(p1); ASSERT_PTR_NE(p, NULL); ASSERT_SIZE_T_EQ(strlen(p), strlen("quad1")); ASSERT_STRING_EQ(p, "quad1"); free(p); /* Check buffer with data after nul (expect failure) */ ASSERT_INT_EQ(sshbuf_put(p1, "quad2", strlen("quad2")), 0); p = sshbuf_dup_string(p1); ASSERT_PTR_EQ(p, NULL); sshbuf_free(p1); TEST_DONE(); } openssh-7.5p1/regress/unittests/sshbuf/tests.c010064400017500001750000000011261306364033700177750ustar00djmdjm/* $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.5p1/regress/unittests/sshkey004075500017500001750000000000001306364033700164275ustar00djmdjmopenssh-7.5p1/regress/unittests/sshkey/Makefile010064400017500001750000000004261306364033700201450ustar00djmdjm# $OpenBSD: Makefile,v 1.4 2016/11/01 13:43:27 tb Exp $ 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.5p1/regress/unittests/sshkey/common.c010064400017500001750000000031551306364033700201430ustar00djmdjm/* $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.5p1/regress/unittests/sshkey/common.h010064400017500001750000000005701306364033700201460ustar00djmdjm/* $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.5p1/regress/unittests/sshkey/mktestdata.sh010075500017500001750000000145141306364033700212100ustar00djmdjm#!/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.5p1/regress/unittests/sshkey/test_file.c010064400017500001750000000305531306364033700206330ustar00djmdjm/* $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.5p1/regress/unittests/sshkey/test_fuzz.c010064400017500001750000000254601306364033700207130ustar00djmdjm/* $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.5p1/regress/unittests/sshkey/test_sshkey.c010064400017500001750000000357631306364033700212320ustar00djmdjm/* $OpenBSD: test_sshkey.c,v 1.10 2016/05/02 09:52:00 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, NULL), 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.5p1/regress/unittests/sshkey/testdata004075500017500001750000000000001306364033700202405ustar00djmdjmopenssh-7.5p1/regress/unittests/sshkey/testdata/dsa_1010064400017500001750000000012401306364033700212230ustar00djmdjm-----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.5p1/regress/unittests/sshkey/testdata/dsa_1-cert.fp010064400017500001750000000000631306364033700225640ustar00djmdjmSHA256:kOLgXSoAT8O5T6r36n5NJUYigbux1d7gdH/rmWiJm6s openssh-7.5p1/regress/unittests/sshkey/testdata/dsa_1-cert.pub010064400017500001750000000017361306364033700227550ustar00djmdjmssh-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.5p1/regress/unittests/sshkey/testdata/dsa_1.fp010064400017500001750000000000631306364033700216310ustar00djmdjmSHA256:kOLgXSoAT8O5T6r36n5NJUYigbux1d7gdH/rmWiJm6s openssh-7.5p1/regress/unittests/sshkey/testdata/dsa_1.fp.bb010064400017500001750000000001021306364033700222050ustar00djmdjmxetag-todiz-mifah-torec-mynyv-cyvit-gopon-pygag-rupic-cenav-bexax openssh-7.5p1/regress/unittests/sshkey/testdata/dsa_1.param.g010064400017500001750000000004031306364033700225470ustar00djmdjm00eee5f505556d24a8cb996ae9c3adbe97fc525c0e6bafb30706e5a3882615dd51c17d725a403c910ed1ae109283c1dcea62069ca460291962ff72e06d27d9d286c525e86446d116b4de0f87c7d551e4bbe2241b23015078a9581c894d4d1a06b406dd8b79c7755f81064110735577ae3a98aa18cea33ff236c8332cd0f6e87add openssh-7.5p1/regress/unittests/sshkey/testdata/dsa_1.param.priv010064400017500001750000000000511306364033700233000ustar00djmdjm5821b43929f5ec66e04fb967b9149cf795d68483 openssh-7.5p1/regress/unittests/sshkey/testdata/dsa_1.param.pub010064400017500001750000000004031306364033700231070ustar00djmdjm00e757a727e6a1b10168ea9902ebe08f53f4ba18c6d8fdf551fbabbf6d8558f054dc0f6aae4c5b397c04d0bc2f8c2bebb1057f96b621273fed8b2b38d1579a86e956644e520073171887fde4b88b4a0697323928ee3a28b7e2caf3896d2f29b067840c9d88e765249c95fd54bb240c714b5bdf8f88d2ef58727ca1a7699216c42d openssh-7.5p1/regress/unittests/sshkey/testdata/dsa_1.pub010064400017500001750000000011351306364033700220130ustar00djmdjmssh-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.5p1/regress/unittests/sshkey/testdata/dsa_1_pw010064400017500001750000000014031306364033700217320ustar00djmdjm-----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.5p1/regress/unittests/sshkey/testdata/dsa_2010064400017500001750000000012401306364033700212240ustar00djmdjm-----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.5p1/regress/unittests/sshkey/testdata/dsa_2.fp010064400017500001750000000000631306364033700216320ustar00djmdjmSHA256:ecwhWcXgpdBxZ2e+OjpRRY7dqXHHCD62BGtoVQQBwCk openssh-7.5p1/regress/unittests/sshkey/testdata/dsa_2.fp.bb010064400017500001750000000001021306364033700222060ustar00djmdjmxeser-megad-pocan-rozit-belup-tapoh-fapif-kyvit-vonav-cehab-naxax openssh-7.5p1/regress/unittests/sshkey/testdata/dsa_2.pub010064400017500001750000000011351306364033700220140ustar00djmdjmssh-dss AAAAB3NzaC1kc3MAAACBAJvI9c10d4uyOmhs9UIyR9qAGS3XlmyW2p/88Y0/XLVy7PuuxNdl6RDBSRJM2blyipd75k7DY7i2OhskN3rQjX9U+BoHQ1iVBH0efzszbzhYPh/pVj5q6ceY/XfhrzJsbkbg2pU0XeKG/EBHalUhOpvuQTjqva5hk1w2Ucjy+hELAAAAFQDHD28KhTbEGx+aScmVt9MI+ClWdwAAAIEAgr3wFV4pBV/yoMWrH2i8y42BVLGl343Ri1rlkTLU4jbOK7lGGO54gzYrsarYyenfyhvUAzncFTGqVwElocQNrquPrK+4yBb2gIl0iYEzywgXF8Ftc1ukmIxoPBrpbJPzg6SkMTq64B6lMydY5RaRRWQCLKiQcNQZeQYbKhBuVtcAAACBAIsf7TaZ804sUWwRV0wI8DYx+hxD5QdrfYPYMtL2fHn3lICimGt0FTtUZ25jKg0E0DMBPdET6ZEHB3ZZkR8hFoUzZhdnyJMu3UjVtgaV88Ue3PrXxchk0W2jHPaAgQU3JIWzo8HFIFqvC/HEL+EyW3rBTY2uXM3XGI+YcWSA4ZrZ DSA test key #2 openssh-7.5p1/regress/unittests/sshkey/testdata/dsa_n010064400017500001750000000012401306364033700213200ustar00djmdjm-----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.5p1/regress/unittests/sshkey/testdata/dsa_n_pw010064400017500001750000000026111306364033700220310ustar00djmdjm-----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.5p1/regress/unittests/sshkey/testdata/ecdsa_1010064400017500001750000000003431306364033700215360ustar00djmdjm-----BEGIN EC PRIVATE KEY----- MHcCAQEEIPPNyUAnjvFr+eT/7t/IyjuQQd/aLFiTY92LB9gIjyrMoAoGCCqGSM49 AwEHoUQDQgAEDFlblkOrW9ydKVhtM+9AY3c9saBE7SG3lFx38nBavkADDaI9jh3/ kvG/Jt9vpm22qwoklTCGDfzCkXkIKaWlBw== -----END EC PRIVATE KEY----- openssh-7.5p1/regress/unittests/sshkey/testdata/ecdsa_1-cert.fp010064400017500001750000000000631306364033700230740ustar00djmdjmSHA256:8ty77fOpABat1y88aNdclQTfU+lVvWe7jYZGw8VYtfg openssh-7.5p1/regress/unittests/sshkey/testdata/ecdsa_1-cert.pub010064400017500001750000000012201306364033700232510ustar00djmdjmecdsa-sha2-nistp256-cert-v01@openssh.com AAAAKGVjZHNhLXNoYTItbmlzdHAyNTYtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgOtFRnMigkGliaYfPmX5IidVWfV3tRH6lqRXv0l8bvKoAAAAIbmlzdHAyNTYAAABBBAxZW5ZDq1vcnSlYbTPvQGN3PbGgRO0ht5Rcd/JwWr5AAw2iPY4d/5Lxvybfb6ZttqsKJJUwhg38wpF5CCmlpQcAAAAAAAAABwAAAAIAAAAGanVsaXVzAAAAEgAAAAVob3N0MQAAAAVob3N0MgAAAAA2jAHwAAAAAE0eYHAAAAAAAAAAAAAAAAAAAABoAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBAxZW5ZDq1vcnSlYbTPvQGN3PbGgRO0ht5Rcd/JwWr5AAw2iPY4d/5Lxvybfb6ZttqsKJJUwhg38wpF5CCmlpQcAAABkAAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAABJAAAAIHbxGwTnue7KxhHXGFvRcxBnekhQ3Qx84vV/Vs4oVCrpAAAAIQC7vk2+d14aS7td7kVXLQn392oALjEBzMZoDvT1vT/zOA== ECDSA test key #1 openssh-7.5p1/regress/unittests/sshkey/testdata/ecdsa_1.fp010064400017500001750000000000631306364033700221410ustar00djmdjmSHA256:8ty77fOpABat1y88aNdclQTfU+lVvWe7jYZGw8VYtfg openssh-7.5p1/regress/unittests/sshkey/testdata/ecdsa_1.fp.bb010064400017500001750000000001021306364033700225150ustar00djmdjmxibah-vocun-sogyn-byhen-rivem-hegyh-luneh-dozyr-vatyf-dufid-myxyx openssh-7.5p1/regress/unittests/sshkey/testdata/ecdsa_1.param.curve010064400017500001750000000000131306364033700237520ustar00djmdjmprime256v1 openssh-7.5p1/regress/unittests/sshkey/testdata/ecdsa_2010064400017500001750000000005551306364033700215440ustar00djmdjm-----BEGIN EC PRIVATE KEY----- MIHcAgEBBEIBqBtN7e6Essd3dlsgISViPCXXC0atlNkGtoMgSQdBTKVUfeJOi4lc RZaXJdXnqWUqI/KEsH8h8QN4YcB8ugmAcc+gBwYFK4EEACOhgYkDgYYABAHZ2VNy oDedBwqsdzY+kkNptc9DrtRCVmO6cULLj+691MhItqVqTMJbTFlI4MnAg9PoGTF/ 0KmLJfy8vSffXGKqqwGKcFNtd1XCo+7Qu9tXbxron9g6Dmu7y8jaLkixcwZwnwLs 6GmA9qZGuiAfOGV0Gf9/u98sr+vikOa4Ow5JFDTw5g== -----END EC PRIVATE KEY----- openssh-7.5p1/regress/unittests/sshkey/testdata/ecdsa_1.param.priv010064400017500001750000000001031306364033700236060ustar00djmdjm00f3cdc940278ef16bf9e4ffeedfc8ca3b9041dfda2c589363dd8b07d8088f2acc openssh-7.5p1/regress/unittests/sshkey/testdata/ecdsa_1.param.pub010064400017500001750000000002031306364033700234150ustar00djmdjm040c595b9643ab5bdc9d29586d33ef4063773db1a044ed21b7945c77f2705abe40030da23d8e1dff92f1bf26df6fa66db6ab0a249530860dfcc291790829a5a507 openssh-7.5p1/regress/unittests/sshkey/testdata/ecdsa_1.pub010064400017500001750000000002631306364033700223240ustar00djmdjmecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBAxZW5ZDq1vcnSlYbTPvQGN3PbGgRO0ht5Rcd/JwWr5AAw2iPY4d/5Lxvybfb6ZttqsKJJUwhg38wpF5CCmlpQc= ECDSA test key #1 openssh-7.5p1/regress/unittests/sshkey/testdata/ecdsa_1_pw010064400017500001750000000004721306364033700222470ustar00djmdjm-----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.5p1/regress/unittests/sshkey/testdata/ecdsa_2.fp010064400017500001750000000000631306364033700221420ustar00djmdjmSHA256:ed8YniRHA6qCrErCRnzrWxPHxYuA62a+CAFYUVxJgaI openssh-7.5p1/regress/unittests/sshkey/testdata/ecdsa_2.fp.bb010064400017500001750000000001021306364033700225160ustar00djmdjmxufag-danul-putub-mokin-pugaz-covid-dofag-nihuz-sysab-genar-zaxyx openssh-7.5p1/regress/unittests/sshkey/testdata/ecdsa_2.param.curve010064400017500001750000000000121306364033700237520ustar00djmdjmsecp521r1 openssh-7.5p1/regress/unittests/sshkey/testdata/ecdsa_2.param.priv010064400017500001750000000002051306364033700236120ustar00djmdjm01a81b4dedee84b2c777765b202125623c25d70b46ad94d906b683204907414ca5547de24e8b895c45969725d5e7a9652a23f284b07f21f1037861c07cba098071cf openssh-7.5p1/regress/unittests/sshkey/testdata/ecdsa_2.param.pub010064400017500001750000000004131306364033700234210ustar00djmdjm0401d9d95372a0379d070aac77363e924369b5cf43aed4425663ba7142cb8feebdd4c848b6a56a4cc25b4c5948e0c9c083d3e819317fd0a98b25fcbcbd27df5c62aaab018a70536d7755c2a3eed0bbdb576f1ae89fd83a0e6bbbcbc8da2e48b17306709f02ece86980f6a646ba201f38657419ff7fbbdf2cafebe290e6b83b0e491434f0e6 openssh-7.5p1/regress/unittests/sshkey/testdata/ecdsa_2.pub010064400017500001750000000004171306364033700223260ustar00djmdjmecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAHZ2VNyoDedBwqsdzY+kkNptc9DrtRCVmO6cULLj+691MhItqVqTMJbTFlI4MnAg9PoGTF/0KmLJfy8vSffXGKqqwGKcFNtd1XCo+7Qu9tXbxron9g6Dmu7y8jaLkixcwZwnwLs6GmA9qZGuiAfOGV0Gf9/u98sr+vikOa4Ow5JFDTw5g== ECDSA test key #2 openssh-7.5p1/regress/unittests/sshkey/testdata/ecdsa_n010064400017500001750000000003431306364033700216330ustar00djmdjm-----BEGIN EC PRIVATE KEY----- MHcCAQEEIPPNyUAnjvFr+eT/7t/IyjuQQd/aLFiTY92LB9gIjyrMoAoGCCqGSM49 AwEHoUQDQgAEDFlblkOrW9ydKVhtM+9AY3c9saBE7SG3lFx38nBavkADDaI9jh3/ kvG/Jt9vpm22qwoklTCGDfzCkXkIKaWlBw== -----END EC PRIVATE KEY----- openssh-7.5p1/regress/unittests/sshkey/testdata/ecdsa_n_pw010064400017500001750000000010311306364033700223340ustar00djmdjm-----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.5p1/regress/unittests/sshkey/testdata/ed25519_1010064400017500001750000000006331306364033700214570ustar00djmdjm-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW QyNTUxOQAAACBThupGO0X+FLQhbz8CoKPwc7V3JNsQuGtlsgN+F7SMGQAAAJjnj4Ao54+A KAAAAAtzc2gtZWQyNTUxOQAAACBThupGO0X+FLQhbz8CoKPwc7V3JNsQuGtlsgN+F7SMGQ AAAED3KgoDbjR54V7bdNpfKlQY5m20UK1QaHytkCR+6rZEDFOG6kY7Rf4UtCFvPwKgo/Bz tXck2xC4a2WyA34XtIwZAAAAE0VEMjU1MTkgdGVzdCBrZXkgIzEBAg== -----END OPENSSH PRIVATE KEY----- openssh-7.5p1/regress/unittests/sshkey/testdata/ed25519_1-cert.fp010064400017500001750000000000631306364033700230130ustar00djmdjmSHA256:L3k/oJubblSY0lB9Ulsl7emDMnRPKm/8udf2ccwk560 openssh-7.5p1/regress/unittests/sshkey/testdata/ed25519_1-cert.pub010064400017500001750000000007461306364033700232040ustar00djmdjmssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIIxzuxl4z3uwAIslne8Huft+1n1IhHAlNbWZkQyyECCGAAAAIFOG6kY7Rf4UtCFvPwKgo/BztXck2xC4a2WyA34XtIwZAAAAAAAAAAgAAAACAAAABmp1bGl1cwAAABIAAAAFaG9zdDEAAAAFaG9zdDIAAAAANowB8AAAAABNHmBwAAAAAAAAAAAAAAAAAAAAMwAAAAtzc2gtZWQyNTUxOQAAACBThupGO0X+FLQhbz8CoKPwc7V3JNsQuGtlsgN+F7SMGQAAAFMAAAALc3NoLWVkMjU1MTkAAABABGTn+Bmz86Ajk+iqKCSdP5NClsYzn4alJd0V5bizhP0Kumc/HbqQfSt684J1WdSzih+EjvnTgBhK9jTBKb90AQ== ED25519 test key #1 openssh-7.5p1/regress/unittests/sshkey/testdata/ed25519_1.fp010064400017500001750000000000631306364033700220600ustar00djmdjmSHA256:L3k/oJubblSY0lB9Ulsl7emDMnRPKm/8udf2ccwk560 openssh-7.5p1/regress/unittests/sshkey/testdata/ed25519_1.fp.bb010064400017500001750000000001021306364033700224340ustar00djmdjmxubop-rekyd-bakal-nubuf-pahaf-gicuh-logeb-gocif-petod-galip-fuxux openssh-7.5p1/regress/unittests/sshkey/testdata/ed25519_1.pub010064400017500001750000000001451306364033700222420ustar00djmdjmssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFOG6kY7Rf4UtCFvPwKgo/BztXck2xC4a2WyA34XtIwZ ED25519 test key #1 openssh-7.5p1/regress/unittests/sshkey/testdata/ed25519_1_pw010064400017500001750000000007201306364033700221620ustar00djmdjm-----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.5p1/regress/unittests/sshkey/testdata/ed25519_2010064400017500001750000000006331306364033700214600ustar00djmdjm-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW QyNTUxOQAAACDPVKyLnm3eZE0lm0IfM3Uy9AsdGSBtozcoCt21blYBCwAAAJix1mBGsdZg RgAAAAtzc2gtZWQyNTUxOQAAACDPVKyLnm3eZE0lm0IfM3Uy9AsdGSBtozcoCt21blYBCw AAAECZEQHXs18o3DKjhUYaTyt+bUbhqfMeqmsKjYyFvzGVgs9UrIuebd5kTSWbQh8zdTL0 Cx0ZIG2jNygK3bVuVgELAAAAE0VEMjU1MTkgdGVzdCBrZXkgIzEBAg== -----END OPENSSH PRIVATE KEY----- openssh-7.5p1/regress/unittests/sshkey/testdata/ed25519_2.fp010064400017500001750000000000631306364033700220610ustar00djmdjmSHA256:vMbaARqVciRgXyZPNHDo+P5p5WK5yWG1Oo6VC35Bomw openssh-7.5p1/regress/unittests/sshkey/testdata/pw010064400017500001750000000000171306364033700206630ustar00djmdjmmekmitasdigoat openssh-7.5p1/regress/unittests/sshkey/testdata/ed25519_2.fp.bb010064400017500001750000000001021306364033700224350ustar00djmdjmxuces-bapyb-vikob-zesyv-budod-nupip-kebon-tacyc-fofed-lezic-soxax openssh-7.5p1/regress/unittests/sshkey/testdata/ed25519_2.pub010064400017500001750000000001451306364033700222430ustar00djmdjmssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM9UrIuebd5kTSWbQh8zdTL0Cx0ZIG2jNygK3bVuVgEL ED25519 test key #1 openssh-7.5p1/regress/unittests/sshkey/testdata/rsa1_1010064400017500001750000000010251306364033700213230ustar00djmdjmSSH 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.5p1/regress/unittests/sshkey/testdata/rsa1_2010064400017500001750000000017251306364033700213330ustar00djmdjmSSH 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.5p1/regress/unittests/sshkey/testdata/rsa1_2.fp010064400017500001750000000000631306364033700217310ustar00djmdjmSHA256:JaOeRCnLl/TLe7vn1+aQ4ONyKZCUhK5x3k4VHilmbpE openssh-7.5p1/regress/unittests/sshkey/testdata/rsa1_2.fp.bb010064400017500001750000000001021306364033700223050ustar00djmdjmxipag-zohut-zepuk-pisyv-kamog-pupus-netud-tudis-melup-cynov-gaxox openssh-7.5p1/regress/unittests/sshkey/testdata/rsa1_2.param.n010064400017500001750000000010031306364033700226530ustar00djmdjm00cab091b57a154740c1bb7020f46a21a19dc40f647db2aab1babd30cabe241f0437391e68376ba35e48c624b8eaf6b59424d4c1a848c9fd1ef5cdc7c1b7f5e5df23b7ad513b79021286d38c52fdfae35656659e8649b2bf8bedf7c99664e45534007bd1c5dc3de1dafdf2d34ad087155951aa0f3d500b36d0d804bbccdef15ab31ca3dd40bdf5196065a97f397ef576caffb606be8232f6e0614aea0e979b9584296673fabb1dbd9f3212495c428842a2ab1f1768dd424fb6fdceeeab9126cacdfc834f0a0d09ba73ad8360d183ba85bb1565555cc6a536eb8d06df1a1e841107c021ae28a2d8b3465f9d8b58ef4045aea1c4ad7f8bf639574d6b142af67b4eb3 openssh-7.5p1/regress/unittests/sshkey/testdata/rsa1_2.pub010064400017500001750000000012061306364033700221120ustar00djmdjm2048 65537 25587207108642486834576012232250034427766229965612147538722032399009467293691448851087324679403117563681753304072089087252850866332601294130674473984011813227791089686736237645788471744456489819306046398653719249100878753563464696688916667605969658659855996383142110932332560049231682024775766802333675397528993897914717996946881193454997890776063024953924432026083898531677702536941151535135950834711001926404724453460085864892836473957600610133803037286539329764689125111700732309717375455919436557475211197800228646235077584780367991159670572954337165006813357814232200750568307753718414790655085790471723847208627 RSA1 test key #2 openssh-7.5p1/regress/unittests/sshkey/testdata/rsa_1010064400017500001750000000015671306364033700212550ustar00djmdjm-----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.5p1/regress/unittests/sshkey/testdata/rsa_1-cert.fp010064400017500001750000000000631306364033700226020ustar00djmdjmSHA256:l6itGumSMcRBBAFteCgmjQBIXqLK/jFGUH3viHX1RmE openssh-7.5p1/regress/unittests/sshkey/testdata/rsa_1-cert.pub010064400017500001750000000011421306364033700227620ustar00djmdjmssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAg98LhS2EHxLOWCLopZPwHdg/RJXusnkOqQXSc9R7aITkAAAADAQABAAAAgQDLV5lUTt7FrADseB/CGhEZzpoojjEW5y8+ePvLppmK3MmMI18ud6vxzpK3bwZLYkVSyfJYI0HmIuGhdu7yMrW6wb84gbq8C31Xoe9EORcIUuGSvDKdNSM1SjlhDquRblDFB8kToqXyx1lqrXecXylxIUOL0jE+u0rU1967pDJx+wAAAAAAAAAFAAAAAgAAAAZqdWxpdXMAAAASAAAABWhvc3QxAAAABWhvc3QyAAAAADaMAfAAAAAATR5gcAAAAAAAAAAAAAAAAAAAADMAAAALc3NoLWVkMjU1MTkAAAAgU4bqRjtF/hS0IW8/AqCj8HO1dyTbELhrZbIDfhe0jBkAAABTAAAAC3NzaC1lZDI1NTE5AAAAQI3QGlUCzC07KorupxpDkkGy6tniaZ8EvBflzvv+itXWNchGvfUeHmVT6aX0sRqehdz/lR+GmXRoZBhofwh0qAM= RSA test key #1 openssh-7.5p1/regress/unittests/sshkey/testdata/rsa_1.fp010064400017500001750000000000631306364033700216470ustar00djmdjmSHA256:l6itGumSMcRBBAFteCgmjQBIXqLK/jFGUH3viHX1RmE openssh-7.5p1/regress/unittests/sshkey/testdata/rsa_1.fp.bb010064400017500001750000000001021306364033700222230ustar00djmdjmxosis-fodod-votot-dibum-ryvac-rediz-naruf-votun-kevis-halis-gexux openssh-7.5p1/regress/unittests/sshkey/testdata/rsa_1.param.n010064400017500001750000000004031306364033700225740ustar00djmdjm00cb5799544edec5ac00ec781fc21a1119ce9a288e3116e72f3e78fbcba6998adcc98c235f2e77abf1ce92b76f064b624552c9f2582341e622e1a176eef232b5bac1bf3881babc0b7d57a1ef4439170852e192bc329d3523354a39610eab916e50c507c913a2a5f2c7596aad779c5f297121438bd2313ebb4ad4d7debba43271fb openssh-7.5p1/regress/unittests/sshkey/testdata/rsa_1.param.p010064400017500001750000000002031306364033700225740ustar00djmdjm00f56077ef05be4574906f52175ed8897e8da1626bc9b055534d6a20f6102c57c7a0b31b3e7864b101f4d3d57c35192bc949e14243a9e956361de23c5dd179f583 openssh-7.5p1/regress/unittests/sshkey/testdata/rsa_1.param.q010064400017500001750000000002031306364033700225750ustar00djmdjm00d42541cc014be26370a657953f3adfcbaf713f781639adba33133f184eb3c7d8c2ec7810dca3da58a746fc5b87b34f396934436832e619c67c22f32ebbb36029 openssh-7.5p1/regress/unittests/sshkey/testdata/rsa_1.pub010064400017500001750000000003451306364033700220330ustar00djmdjmssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDLV5lUTt7FrADseB/CGhEZzpoojjEW5y8+ePvLppmK3MmMI18ud6vxzpK3bwZLYkVSyfJYI0HmIuGhdu7yMrW6wb84gbq8C31Xoe9EORcIUuGSvDKdNSM1SjlhDquRblDFB8kToqXyx1lqrXecXylxIUOL0jE+u0rU1967pDJx+w== RSA test key #1 openssh-7.5p1/regress/unittests/sshkey/testdata/rsa_1_pw010064400017500001750000000017321306364033700217550ustar00djmdjm-----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.5p1/regress/unittests/sshkey/testdata/rsa_2010064400017500001750000000032171306364033700212500ustar00djmdjm-----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.5p1/regress/unittests/sshkey/testdata/rsa_2.fp010064400017500001750000000000631306364033700216500ustar00djmdjmSHA256:NoQh0XBUuYUSWqnzOzOBnfpgJTRWLMj7BlWAb8IbjeE openssh-7.5p1/regress/unittests/sshkey/testdata/rsa_2.fp.bb010064400017500001750000000001021306364033700222240ustar00djmdjmxogit-gupof-mydon-hocep-zuval-feson-rarif-cefar-tobar-ryvap-kuxex openssh-7.5p1/regress/unittests/sshkey/testdata/rsa_2.param.n010064400017500001750000000010031306364033700225720ustar00djmdjm00f4d1145e9efc4809262f8f9e023e260733ce8e4f9c7023d5ce44d1fa66497724f09090011d4378727e1ada44e687b12bf8df025c2b22ab120e57519f1f67f068288194e117790262fdc323c6bf645563b81610ba97552a6ef3d476b5025198c54c0f7f021f4c2a093ba8662ae528c4de9fac9f818b85129baa6abd2e388780c9a406ebff6b54a58adfab5c7cced85f1f1f98648de1e2bf2615830e3968dbc609ed9145f6e9a1e5b6991b6022fef2f7049ec2de9a9a11035d2a3f17a9a4a80ef15629f3ae8e4d7adb445cba3dd6d03d1dbe9feb1fcc73f1890cd5d32a1a56086789eb17969c079f0d939158063b63d61bb80c61109562f502f9356a05380d02eb openssh-7.5p1/regress/unittests/sshkey/testdata/rsa_2.param.p010064400017500001750000000004031306364033700225770ustar00djmdjm00fb82dee3474e88898acebcf23b8a970737490ea07abe5f7c0837c9a36111ca4792f3ad759945fc27d7f78c5accca2ffd8a85c24be949274ab17f8f797b9aaa76f584f28d617e6de3953d46307fa31ec12108ffdab3f105fb3df54156f4728fe07b1598bbb5c5e260d4f73d8b29532bfc6b9f07d8899f87ec819571c8b38e7a87 openssh-7.5p1/regress/unittests/sshkey/testdata/rsa_2.param.q010064400017500001750000000004031306364033700226000ustar00djmdjm00f92f9f57e501dc41cc91ff3b4ad7a2283612d66c0d130f639d4c18376a54e5b5e1939f4d5966bb43929e448a426dadc1fae84cf0d56f64d8df04d1badcfc1fdc8e156d5cd4dcf860ec936fc166261136156010f6df10a70525867d7989fef6752fd8db6faf3fe018bbbc1fa862fb4155445e1a398468d78b4e77884bdf5c197d openssh-7.5p1/regress/unittests/sshkey/testdata/rsa_2.pub010064400017500001750000000006151306364033700220340ustar00djmdjmssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD00RRenvxICSYvj54CPiYHM86OT5xwI9XORNH6Zkl3JPCQkAEdQ3hyfhraROaHsSv43wJcKyKrEg5XUZ8fZ/BoKIGU4Rd5AmL9wyPGv2RVY7gWELqXVSpu89R2tQJRmMVMD38CH0wqCTuoZirlKMTen6yfgYuFEpuqar0uOIeAyaQG6/9rVKWK36tcfM7YXx8fmGSN4eK/JhWDDjlo28YJ7ZFF9umh5baZG2Ai/vL3BJ7C3pqaEQNdKj8XqaSoDvFWKfOujk1620Rcuj3W0D0dvp/rH8xz8YkM1dMqGlYIZ4nrF5acB58Nk5FYBjtj1hu4DGEQlWL1Avk1agU4DQLr RSA test key #2 openssh-7.5p1/regress/unittests/sshkey/testdata/rsa_n010064400017500001750000000015671306364033700213520ustar00djmdjm-----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.5p1/regress/unittests/sshkey/testdata/rsa_n_pw010064400017500001750000000020651306364033700220520ustar00djmdjm-----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.5p1/regress/unittests/sshkey/tests.c010064400017500001750000000007151306364033700200140ustar00djmdjm/* $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.5p1/regress/unittests/test_helper004075500017500001750000000000001306364033700174375ustar00djmdjmopenssh-7.5p1/regress/unittests/test_helper/Makefile010064400017500001750000000003661306364033700211600ustar00djmdjm# $OpenBSD: Makefile,v 1.3 2016/07/04 18:01:44 guenther Exp $ LIB= test_helper SRCS= test_helper.c fuzz.c NOPROFILE= yes NOPIC= yes # Hack to allow building with SUBDIR in ../../Makefile regress: all install: @echo -n .include openssh-7.5p1/regress/unittests/test_helper/fuzz.c010064400017500001750000000241761306364033700206670ustar00djmdjm/* $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.5p1/regress/unittests/test_helper/test_helper.c010064400017500001750000000310611306364033700221760ustar00djmdjm/* $OpenBSD: test_helper.c,v 1.7 2017/03/14 01:10:07 dtucker 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(const char *file, int line, const char *a1, const char *a2, long aa1, long aa2, enum test_predicate pred) { TEST_CHECK(aa1, aa2, pred); test_header(file, line, a1, a2, "LONG", pred); fprintf(stderr, "%12s = %ld / 0x%lx\n", a1, aa1, aa1); fprintf(stderr, "%12s = %ld / 0x%lx\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.5p1/regress/unittests/test_helper/test_helper.h010064400017500001750000000323371306364033700222120ustar00djmdjm/* $OpenBSD: test_helper.h,v 1.7 2017/03/14 01:10:07 dtucker 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(const char *file, int line, const char *a1, const char *a2, long aa1, long 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_EQ(a1, a2) \ assert_long(__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_NE(a1, a2) \ assert_long(__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_LT(a1, a2) \ assert_long(__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_LE(a1, a2) \ assert_long(__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_GT(a1, a2) \ assert_long(__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_GE(a1, a2) \ assert_long(__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.5p1/regress/unittests/utf8004075500017500001750000000000001306364033700160075ustar00djmdjmopenssh-7.5p1/regress/unittests/utf8/Makefile010064400017500001750000000003151306364033700175220ustar00djmdjm# $OpenBSD: Makefile,v 1.4 2016/11/01 13:43:27 tb Exp $ PROG=test_utf8 SRCS=tests.c REGRESS_TARGETS=run-regress-${PROG} run-regress-${PROG}: ${PROG} env ${TEST_ENV} ./${PROG} .include openssh-7.5p1/regress/unittests/utf8/tests.c010064400017500001750000000056471306364033700174050ustar00djmdjm/* $OpenBSD: tests.c,v 1.4 2017/02/19 00:11:29 djm Exp $ */ /* * Regress test for the utf8.h *mprintf() API * * Written by Ingo Schwarze in 2016 * and placed in the public domain. */ #include "includes.h" #include #include #include "../test_helper/test_helper.h" #include "utf8.h" static void badarg(void) { char buf[16]; int len, width; width = 1; TEST_START("utf8_badarg"); len = snmprintf(buf, sizeof(buf), &width, "\377"); ASSERT_INT_EQ(len, -1); ASSERT_STRING_EQ(buf, ""); ASSERT_INT_EQ(width, 0); TEST_DONE(); } static void one(int utf8, const char *name, const char *mbs, int width, int wantwidth, int wantlen, const char *wants) { char buf[16]; int *wp; int len; if (wantlen == -2) wantlen = strlen(wants); (void)strlcpy(buf, utf8 ? "utf8_" : "c_", sizeof(buf)); (void)strlcat(buf, name, sizeof(buf)); TEST_START(buf); wp = wantwidth == -2 ? NULL : &width; len = snmprintf(buf, sizeof(buf), wp, "%s", mbs); ASSERT_INT_EQ(len, wantlen); ASSERT_STRING_EQ(buf, wants); ASSERT_INT_EQ(width, wantwidth); TEST_DONE(); } void tests(void) { char *loc; TEST_START("utf8_setlocale"); loc = setlocale(LC_CTYPE, "en_US.UTF-8"); ASSERT_PTR_NE(loc, NULL); TEST_DONE(); badarg(); one(1, "empty", "", 2, 0, 0, ""); one(1, "ascii", "x", -2, -2, -2, "x"); one(1, "newline", "a\nb", -2, -2, -2, "a\nb"); one(1, "cr", "a\rb", -2, -2, -2, "a\rb"); one(1, "tab", "a\tb", -2, -2, -2, "a\tb"); one(1, "esc", "\033x", -2, -2, -2, "\\033x"); one(1, "inv_badbyte", "\377x", -2, -2, -2, "\\377x"); one(1, "inv_nocont", "\341x", -2, -2, -2, "\\341x"); one(1, "inv_nolead", "a\200b", -2, -2, -2, "a\\200b"); one(1, "sz_ascii", "1234567890123456", -2, -2, 16, "123456789012345"); one(1, "sz_esc", "123456789012\033", -2, -2, 16, "123456789012"); one(1, "width_ascii", "123", 2, 2, -1, "12"); one(1, "width_double", "a\343\201\201", 2, 1, -1, "a"); one(1, "double_fit", "a\343\201\201", 3, 3, 4, "a\343\201\201"); one(1, "double_spc", "a\343\201\201", 4, 3, 4, "a\343\201\201"); TEST_START("C_setlocale"); loc = setlocale(LC_CTYPE, "C"); ASSERT_PTR_NE(loc, NULL); TEST_DONE(); badarg(); one(0, "empty", "", 2, 0, 0, ""); one(0, "ascii", "x", -2, -2, -2, "x"); one(0, "newline", "a\nb", -2, -2, -2, "a\nb"); one(0, "cr", "a\rb", -2, -2, -2, "a\rb"); one(0, "tab", "a\tb", -2, -2, -2, "a\tb"); one(0, "esc", "\033x", -2, -2, -2, "\\033x"); one(0, "inv_badbyte", "\377x", -2, -2, -2, "\\377x"); one(0, "inv_nocont", "\341x", -2, -2, -2, "\\341x"); one(0, "inv_nolead", "a\200b", -2, -2, -2, "a\\200b"); one(0, "sz_ascii", "1234567890123456", -2, -2, 16, "123456789012345"); one(0, "sz_esc", "123456789012\033", -2, -2, 16, "123456789012"); one(0, "width_ascii", "123", 2, 2, -1, "12"); one(0, "width_double", "a\343\201\201", 2, 1, -1, "a"); one(0, "double_fit", "a\343\201\201", 7, 5, -1, "a\\343"); one(0, "double_spc", "a\343\201\201", 13, 13, 13, "a\\343\\201\\201"); } openssh-7.5p1/regress/valgrind-unit.sh010075500017500001750000000007611306364033700162610ustar00djmdjm#!/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.5p1/regress/yes-head.sh010064400017500001750000000007031306364033700151660ustar00djmdjm# $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.5p1/rijndael.c010064400017500001750000001471121306364033700134230ustar00djmdjm/* $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.5p1/rijndael.h010064400017500001750000000041051306364033700134220ustar00djmdjm/* $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.5p1/rsa.c010064400017500001750000000120051306364033700124100ustar00djmdjm/* $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.5p1/rsa.h010064400017500001750000000015401306364033700124170ustar00djmdjm/* $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.5p1/sandbox-capsicum.c010064400017500001750000000065041306364033700150720ustar00djmdjm/* * 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.5p1/sandbox-darwin.c010064400017500001750000000047661306364033700145620ustar00djmdjm/* * 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 "monitor.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.5p1/sandbox-null.c010064400017500001750000000031721306364033700142360ustar00djmdjm/* $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.5p1/sandbox-pledge.c010064400017500001750000000035231306364033700145240ustar00djmdjm/* $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.5p1/sandbox-rlimit.c010064400017500001750000000046671306364033700145760ustar00djmdjm/* $OpenBSD: sandbox-rlimit.c,v 1.4 2016/09/12 01:22:38 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_RLIMIT #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.5p1/sandbox-seccomp-filter.c010064400017500001750000000227651306364033700162110ustar00djmdjm/* * 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 */ #if __BYTE_ORDER == __LITTLE_ENDIAN # define ARG_LO_OFFSET 0 # define ARG_HI_OFFSET sizeof(uint32_t) #elif __BYTE_ORDER == __BIG_ENDIAN # define ARG_LO_OFFSET sizeof(uint32_t) # define ARG_HI_OFFSET 0 #else #error "Unknown endianness" #endif /* Simple helpers to avoid manual errors (but larger BPF programs). */ #define SC_DENY(_nr, _errno) \ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, (_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), 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), 0, 6), \ /* load and test first syscall argument, low word */ \ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ offsetof(struct seccomp_data, args[(_arg_nr)]) + ARG_LO_OFFSET), \ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, \ ((_arg_val) & 0xFFFFFFFF), 0, 3), \ /* load and test first syscall argument, high word */ \ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, \ offsetof(struct seccomp_data, args[(_arg_nr)]) + ARG_HI_OFFSET), \ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, \ (((uint32_t)((uint64_t)(_arg_val) >> 32)) & 0xFFFFFFFF), 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_lstat SC_DENY(__NR_lstat, EACCES), #endif #ifdef __NR_lstat64 SC_DENY(__NR_lstat64, EACCES), #endif #ifdef __NR_fstat SC_DENY(__NR_fstat, EACCES), #endif #ifdef __NR_fstat64 SC_DENY(__NR_fstat64, EACCES), #endif #ifdef __NR_open SC_DENY(__NR_open, EACCES), #endif #ifdef __NR_openat SC_DENY(__NR_openat, EACCES), #endif #ifdef __NR_newfstatat SC_DENY(__NR_newfstatat, EACCES), #endif #ifdef __NR_stat SC_DENY(__NR_stat, EACCES), #endif #ifdef __NR_stat64 SC_DENY(__NR_stat64, EACCES), #endif /* Syscalls to permit */ #ifdef __NR_brk SC_ALLOW(__NR_brk), #endif #ifdef __NR_clock_gettime SC_ALLOW(__NR_clock_gettime), #endif #ifdef __NR_close SC_ALLOW(__NR_close), #endif #ifdef __NR_exit SC_ALLOW(__NR_exit), #endif #ifdef __NR_exit_group SC_ALLOW(__NR_exit_group), #endif #ifdef __NR_getpgid SC_ALLOW(__NR_getpgid), #endif #ifdef __NR_getpid SC_ALLOW(__NR_getpid), #endif #ifdef __NR_getrandom SC_ALLOW(__NR_getrandom), #endif #ifdef __NR_gettimeofday SC_ALLOW(__NR_gettimeofday), #endif #ifdef __NR_madvise SC_ALLOW(__NR_madvise), #endif #ifdef __NR_mmap SC_ALLOW(__NR_mmap), #endif #ifdef __NR_mmap2 SC_ALLOW(__NR_mmap2), #endif #ifdef __NR_mremap SC_ALLOW(__NR_mremap), #endif #ifdef __NR_munmap SC_ALLOW(__NR_munmap), #endif #ifdef __NR__newselect SC_ALLOW(__NR__newselect), #endif #ifdef __NR_poll SC_ALLOW(__NR_poll), #endif #ifdef __NR_pselect6 SC_ALLOW(__NR_pselect6), #endif #ifdef __NR_read SC_ALLOW(__NR_read), #endif #ifdef __NR_rt_sigprocmask SC_ALLOW(__NR_rt_sigprocmask), #endif #ifdef __NR_select SC_ALLOW(__NR_select), #endif #ifdef __NR_shutdown SC_ALLOW(__NR_shutdown), #endif #ifdef __NR_sigprocmask SC_ALLOW(__NR_sigprocmask), #endif #ifdef __NR_time SC_ALLOW(__NR_time), #endif #ifdef __NR_write SC_ALLOW(__NR_write), #endif #ifdef __NR_socketcall SC_ALLOW_ARG(__NR_socketcall, 0, SYS_SHUTDOWN), #endif #if defined(__NR_ioctl) && defined(__s390__) /* Allow ioctls for ICA crypto card on s390 */ SC_ALLOW_ARG(__NR_ioctl, 1, Z90STAT_STATUS_MASK), SC_ALLOW_ARG(__NR_ioctl, 1, ICARSAMODEXPO), SC_ALLOW_ARG(__NR_ioctl, 1, ICARSACRT), #endif #if defined(__x86_64__) && defined(__ILP32__) && defined(__X32_SYSCALL_BIT) /* * On Linux x32, the clock_gettime VDSO falls back to the * x86-64 syscall under some circumstances, e.g. * https://bugs.debian.org/849923 */ SC_ALLOW(__NR_clock_gettime & ~__X32_SYSCALL_BIT); #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.5p1/sandbox-solaris.c010064400017500001750000000053571306364033700147470ustar00djmdjm/* * 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.5p1/sandbox-systrace.c010064400017500001750000000143501306364033700151210ustar00djmdjm/* $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.5p1/sc25519.c010064400017500001750000000162441306364033700126470ustar00djmdjm/* $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.5p1/sc25519.h010064400017500001750000000055151306364033700126530ustar00djmdjm/* $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.5p1/scp.1010064400017500001750000000121111306364033700123240ustar00djmdjm.\" .\" 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.71 2016/07/16 06:57:55 jmc Exp $ .\" .Dd $Mdocdate: July 16 2016 $ .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 IdentitiesOnly .It IdentityAgent .It IdentityFile .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 ProxyJump .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.5p1/scp.c010064400017500001750000000774421306364033700124300ustar00djmdjm/* $OpenBSD: scp.c,v 1.187 2016/09/12 01:22:38 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 #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 #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" #include "utf8.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++) fmprintf(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) fmprintf(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) fmprintf(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(); msetlocale(); /* Copy argv, because we modify it */ newargv = xcalloc(MAXIMUM(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) fmprintf(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 (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(); if (showprogress) stop_progress_meter(); } } 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) fmprintf(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], visbuf[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) fmprintf(stderr, "Sink: %s", buf); if (buf[0] == '\01' || buf[0] == '\02') { if (iamremote == 0) { (void) snmprintf(visbuf, sizeof(visbuf), NULL, "%s", buf + 1); (void) atomicio(vwrite, STDERR_FILENO, visbuf, strlen(visbuf)); } 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 (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 (showprogress) stop_progress_meter(); 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], visbuf[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) { cp[-1] = '\0'; (void) snmprintf(visbuf, sizeof(visbuf), NULL, "%s\n", rbuf); (void) atomicio(vwrite, STDERR_FILENO, visbuf, strlen(visbuf)); } ++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); vfmprintf(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: fmprintf(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.5p1/servconf.c010064400017500001750000002145201306364033700134560ustar00djmdjm /* $OpenBSD: servconf.c,v 1.306 2017/03/14 07:19:07 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->login_grace_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->hostbased_authentication = -1; options->hostbased_uses_name_from_packet_only = -1; options->hostbased_key_types = NULL; options->hostkeyalgorithms = NULL; 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->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->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; options->disable_forwarding = -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->num_host_key_files == 0) { /* fill default hostkeys for protocols */ 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->login_grace_time == -1) options->login_grace_time = 120; 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->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->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 = 1; 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->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; if (options->disable_forwarding == -1) options->disable_forwarding = 0; 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 /* Similar handling for AuthenticationMethods=any */ if (options->num_auth_methods == 1 && strcmp(options->auth_methods[0], "any") == 0) { free(options->auth_methods[0]); options->auth_methods[0] = NULL; options->num_auth_methods = 0; } #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, sLoginGraceTime, 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, sAllowTcpForwarding, sCompression, sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, sIgnoreUserKnownHosts, sCiphers, sMacs, 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, sDisableForwarding, sDeprecated, sIgnore, 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", sDeprecated, SSHCFG_GLOBAL }, { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL }, { "keyregenerationinterval", sDeprecated, SSHCFG_GLOBAL }, { "permitrootlogin", sPermitRootLogin, SSHCFG_ALL }, { "syslogfacility", sLogFacility, SSHCFG_GLOBAL }, { "loglevel", sLogLevel, SSHCFG_GLOBAL }, { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL }, { "rhostsrsaauthentication", sDeprecated, SSHCFG_ALL }, { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL }, { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_ALL }, { "hostbasedacceptedkeytypes", sHostbasedAcceptedKeyTypes, SSHCFG_ALL }, { "hostkeyalgorithms", sHostKeyAlgorithms, SSHCFG_GLOBAL }, { "rsaauthentication", sDeprecated, 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", sDeprecated, 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", sIgnore, 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_ALL }, { "clientalivecountmax", sClientAliveCountMax, SSHCFG_ALL }, { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_ALL }, { "authorizedkeysfile2", sDeprecated, SSHCFG_ALL }, { "useprivilegeseparation", sDeprecated, 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 }, { "disableforwarding", sDisableForwarding, SSHCFG_ALL }, { 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) { struct ssh *ssh = active_state; /* XXX */ static struct connection_info ci; if (!populate) return &ci; ci.host = auth_get_canonical_hostname(ssh, use_dns); ci.address = ssh_remote_ipaddr(ssh); ci.laddress = ssh_local_ipaddr(ssh); ci.lport = ssh_local_port(ssh); 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. 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[] = { { "yes", COMP_DELAYED }, { "delayed", COMP_DELAYED }, { "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; /* Strip trailing whitespace. Allow \f (form feed) at EOL only */ if ((len = strlen(line)) == 0) return 0; for (len--; len > 0; len--) { if (strchr(WHITESPACE "\f", line[len]) == NULL) break; line[len] = '\0'; } 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 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 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; 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 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 (*arg != '-' && !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 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; 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 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 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 sDisableForwarding: intptr = &options->disable_forwarding; goto parse_flag; case sAllowUsers: while ((arg = strdelim(&cp)) && *arg != '\0') { if (options->num_allow_users >= MAX_ALLOW_USERS) fatal("%s line %d: too many allow users.", filename, linenum); if (match_user(NULL, NULL, NULL, arg) == -1) fatal("%s line %d: invalid AllowUsers pattern: " "\"%.100s\"", filename, linenum, arg); 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 (match_user(NULL, NULL, NULL, arg) == -1) fatal("%s line %d: invalid DenyUsers pattern: " "\"%.100s\"", filename, linenum, arg); 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 (*arg != '-' && !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 (*arg != '-' && !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 (*arg != '-' && !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 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) { value = 0; /* seen "any" pseudo-method */ value2 = 0; /* sucessfully parsed any method */ 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 (strcmp(arg, "any") == 0) { if (options->num_auth_methods > 0) { fatal("%s line %d: \"any\" " "must appear alone in " "AuthenticationMethods", filename, linenum); } value = 1; } else if (value) { fatal("%s line %d: \"any\" must appear " "alone in AuthenticationMethods", filename, linenum); } else if (auth2_methods_valid(arg, 0) != 0) { fatal("%s line %d: invalid " "authentication method list.", filename, linenum); } value2 = 1; if (!*activep) continue; options->auth_methods[ options->num_auth_methods++] = xstrdup(arg); } if (value2 == 0) { fatal("%s line %d: no AuthenticationMethods " "specified", filename, linenum); } } 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: case sIgnore: case sUnsupported: do_log2(opcode == sIgnore ? SYSLOG_LEVEL_DEBUG2 : SYSLOG_LEVEL_INFO, "%s line %d: %s option %s", filename, linenum, opcode == sUnsupported ? "Unsupported" : "Deprecated", 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(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(disable_forwarding); M_CP_INTOPT(permit_tun); M_CP_INTOPT(fwd_opts.gateway_ports); M_CP_INTOPT(fwd_opts.streamlocal_bind_unlink); 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(client_alive_count_max); M_CP_INTOPT(client_alive_interval); M_CP_INTOPT(ip_qos_interactive); M_CP_INTOPT(ip_qos_bulk); M_CP_INTOPT(rekey_limit); M_CP_INTOPT(rekey_interval); /* * The bind_mask is a mode_t that may be unsigned, so we can't use * M_CP_INTOPT - it does a signed comparison that causes compiler * warnings. */ if (src->fwd_opts.streamlocal_bind_mask != (mode_t)-1) { dst->fwd_opts.streamlocal_bind_mask = src->fwd_opts.streamlocal_bind_mask; } /* 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)); if ((obuf = cbuf = sshbuf_dup_string(conf)) == NULL) fatal("%s: sshbuf_dup_string failed", __func__); 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 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); 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) { 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 && code != sAuthenticationMethods) return; printf("%s", lookup_opcode_name(code)); for (i = 0; i < count; i++) printf(" %s", vals[i]); if (code == sAuthenticationMethods && count == 0) printf(" any"); 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(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(sLoginGraceTime, o->login_grace_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(sHostbasedAuthentication, o->hostbased_authentication); dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly, o->hostbased_uses_name_from_packet_only); 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(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(sDisableForwarding, o->disable_forwarding); dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding); dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink); 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.5p1/servconf.h010064400017500001750000000230441306364033700134620ustar00djmdjm/* $OpenBSD: servconf.h,v 1.123 2016/11/30 03:00:05 djm 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 login_grace_time; /* Disconnect if no auth in this time * (sec). */ 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. */ struct ForwardOptions fwd_opts; /* forwarding options */ SyslogFacility log_facility; /* Facility for system logging. */ LogLevel log_level; /* Level for system logging. */ 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 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 compression; /* If true, compression is allowed */ int allow_tcp_forwarding; /* One of FORWARD_* */ int allow_streamlocal_forwarding; /* One of FORWARD_* */ int allow_agent_forwarding; int disable_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.5p1/serverloop.c010064400017500001750000000604171306364033700140350ustar00djmdjm/* $OpenBSD: serverloop.c,v 1.191 2017/02/01 02:59:09 dtucker 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 #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 "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 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; } 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(int connection_in, int connection_out, fd_set **readsetp, fd_set **writesetp, int *maxfdp, u_int *nallocp, u_int64_t max_time_ms) { struct timeval tv, *tvp; int ret; time_t minwait_secs = 0; int client_alive_scheduled = 0; /* Allocate and update select() masks for channel descriptors. */ channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, &minwait_secs, 0); /* XXX need proper deadline system for rekey/client alive */ if (minwait_secs != 0) max_time_ms = MINIMUM(max_time_ms, (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 (options.client_alive_interval) { uint64_t keepalive_ms = (uint64_t)options.client_alive_interval * 1000; client_alive_scheduled = 1; if (max_time_ms == 0 || max_time_ms > keepalive_ms) max_time_ms = keepalive_ms; } #if 0 /* wrong: bad condition XXX */ if (channel_not_very_much_buffered_data()) #endif FD_SET(connection_in, *readsetp); 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_ms == 0 || client_alive_scheduled) max_time_ms = 100; if (max_time_ms == 0) tvp = NULL; else { tv.tv_sec = max_time_ms / 1000; tv.tv_usec = 1000 * (max_time_ms % 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(); notify_done(*readsetp); } /* * Processes input from the client and the program. Input data is stored * in buffers and processed later. */ static int process_input(fd_set *readset, int connection_in) { struct ssh *ssh = active_state; /* XXX */ 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 port %d", ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); return -1; } else if (len < 0) { if (errno != EINTR && errno != EAGAIN && errno != EWOULDBLOCK) { verbose("Read error from remote host " "%.100s port %d: %.100s", ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), strerror(errno)); cleanup_exit(255); } } else { /* Buffer any received data. */ packet_process_incoming(buf, len); } } return 0; } /* * Sends data from internal buffers to client program stdin. */ static void process_output(fd_set *writeset, int connection_out) { /* Send any buffered packet data to the client. */ if (FD_ISSET(connection_out, writeset)) packet_write_poll(); } static void process_buffered_input_packets(void) { dispatch_run(DISPATCH_NONBLOCK, NULL, active_state); } 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, connection_in, connection_out; 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 = MAXIMUM(connection_in, connection_out); max_fd = MAXIMUM(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 && !ssh_packet_is_rekeying(active_state)) rekey_timeout_ms = packet_get_rekey_timeout() * 1000; else rekey_timeout_ms = 0; wait_until_can_do_something(connection_in, connection_out, &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); if (process_input(readset, connection_in) < 0) break; process_output(writeset, connection_out); } 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 Channel * server_request_direct_tcpip(int *reason, const char **errmsg) { 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 && !options.disable_forwarding) { c = channel_connect_to_port(target, target_port, "direct-tcpip", "direct-tcpip", reason, errmsg); } else { logit("refused local port forward: " "originator %s port %d, target %s port %d", originator, originator_port, target, target_port); if (reason != NULL) *reason = SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED; } free(originator); free(target); return c; } static Channel * server_request_direct_streamlocal(void) { Channel *c = NULL; char *target, *originator; u_short originator_port; struct passwd *pw = the_authctxt->pw; if (pw == NULL || !the_authctxt->valid) fatal("server_input_global_request: no/invalid user"); 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 && !options.disable_forwarding && (pw->pw_uid == 0 || use_privsep)) { 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; const char *errmsg = NULL; int rchan, reason = SSH2_OPEN_CONNECT_FAILED; 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(&reason, &errmsg); } 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(reason); if (!(datafellows & SSH_BUG_OPENFAILURE)) { packet_put_cstring(errmsg ? errmsg : "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; struct passwd *pw = the_authctxt->pw; if (pw == NULL || !the_authctxt->valid) fatal("server_input_global_request: no/invalid user"); 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 Forward fwd; 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 || options.disable_forwarding || (!want_reply && fwd.listen_port == 0) || (fwd.listen_port != 0 && !bind_permitted(fwd.listen_port, pw->pw_uid))) { 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 || options.disable_forwarding || (pw->pw_uid != 0 && !use_privsep)) { success = 0; packet_send_debug("Server has disabled " "streamlocal 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(void) { debug("server_init_dispatch"); 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); } openssh-7.5p1/serverloop.h010064400017500001750000000017201306364033700140320ustar00djmdjm/* $OpenBSD: serverloop.h,v 1.7 2016/08/13 17:47:41 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". */ /* * 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_loop2(Authctxt *); #endif openssh-7.5p1/sftp.1010064400017500001750000000347751306364033700125370ustar00djmdjm.\" $OpenBSD: sftp.1,v 1.105 2016/07/16 06:57:55 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: July 16 2016 $ .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 IdentitiesOnly .It IdentityAgent .It IdentityFile .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 ProxyJump .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.5p1/session.c010064400017500001750000001731371306364033700133240ustar00djmdjm/* $OpenBSD: session.c,v 1.286 2016/11/30 03:00:05 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 "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_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.disable_forwarding || (options.allow_tcp_forwarding & FORWARD_LOCAL) == 0) channel_disable_adm_local_opens(); else channel_permit_all_opens(); auth_debug_send(); do_authenticated2(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; } #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]); session_set_fds(s, pin[1], pout[0], perr[0], s->is_subsystem, 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. */ session_set_fds(s, inout[1], inout[1], err[1], s->is_subsystem, 0); #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) */ #ifdef _UNICOS cray_init_job(s->pw); /* set up cray jid and tmpdir */ #endif /* _UNICOS */ #ifndef HAVE_OSF_SIA do_login(s, command); #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); session_set_fds(s, ptyfd, fdout, -1, 1, 1); return 0; } #ifdef LOGIN_NEEDS_UTMPX static void do_pre_login(Session *s) { struct ssh *ssh = active_state; /* XXX */ 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, session_get_remote_name_or_ip(ssh, 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) { struct ssh *ssh = active_state; /* XXX */ 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, ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), 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) { struct ssh *ssh = active_state; /* XXX */ 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, session_get_remote_name_or_ip(ssh, 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) { struct ssh *ssh = active_state; /* XXX */ 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 /* 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. */ 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", ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), ssh_local_port(ssh)); child_set_env(&env, &envsize, "SSH_CLIENT", buf); laddr = get_local_ipaddr(packet_get_connection_in()); snprintf(buf, sizeof buf, "%.50s %d %.50s %d", ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), laddr, ssh_local_port(ssh)); 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) { 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 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; 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); } #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. */ #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 && !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 /* * 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 * ssh_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); 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); /* 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); s->col = packet_get_int(); s->row = 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); 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) { /* * 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) { struct ssh *ssh = active_state; /* XXX */ u_int i; verbose("Close session: user %s from %.200s port %d id %d", s->pw->pw_name, ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), 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 (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 (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); } /* Return a name for the remote host that fits inside utmp_size */ const char * session_get_remote_name_or_ip(struct ssh *ssh, u_int utmp_size, int use_dns) { const char *remote = ""; if (utmp_size > 0) remote = auth_get_canonical_hostname(ssh, use_dns); if (utmp_size == 0 || strlen(remote) > utmp_size) remote = ssh_remote_ipaddr(ssh); return remote; } openssh-7.5p1/session.h010064400017500001750000000051231306364033700133160ustar00djmdjm/* $OpenBSD: session.h,v 1.33 2016/08/13 17:47:41 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 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; 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); const char *session_get_remote_name_or_ip(struct ssh *, u_int, int); #endif openssh-7.5p1/sftp-client.c010064400017500001750000001422421306364033700140620ustar00djmdjm/* $OpenBSD: sftp-client.c,v 1.126 2017/01/03 05:46:51 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 #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 "utf8.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 /* Directory separator characters */ #ifdef HAVE_CYGWIN # define SFTP_DIRECTORY_CHARS "/\\" #else /* HAVE_CYGWIN */ # define SFTP_DIRECTORY_CHARS "/" #endif /* HAVE_CYGWIN */ 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 = MINIMUM(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, *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 > SSHBUF_SIZE_MAX) fatal("%s: nonsensical number of entries", __func__); 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) mprintf("%s\n", longname); /* * Directory entries should never contain '/' * These can be used to attack recursive ops * (e.g. send '../../../../etc/passwd') */ if (strpbrk(filename, SFTP_DIRECTORY_CHARS) != 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 = MAXIMUM(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) mprintf("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) mprintf("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.5p1/sftp-client.h010064400017500001750000000104471306364033700140700ustar00djmdjm/* $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.5p1/sftp-common.c010064400017500001750000000154341306364033700140760ustar00djmdjm/* $OpenBSD: sftp-common.c,v 1.29 2016/09/12 01:22:38 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 #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 "misc.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 = MAXIMUM(strlen(user), 8); glen = MAXIMUM(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.5p1/sftp-common.h010064400017500001750000000040301306364033700140710ustar00djmdjm/* $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.5p1/sftp-glob.c010064400017500001750000000066121306364033700135270ustar00djmdjm/* $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.5p1/sftp-server-main.c010064400017500001750000000027651306364033700150410ustar00djmdjm/* $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.5p1/sftp-server.8010064400017500001750000000117551306364033700140430ustar00djmdjm.\" $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.5p1/sftp-server.c010064400017500001750000001244031306364033700141110ustar00djmdjm/* $OpenBSD: sftp-server.c,v 1.110 2016/09/12 01:22:38 deraadt 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 #include #ifdef HAVE_SYS_TIME_H # include #endif #ifdef HAVE_SYS_MOUNT_H #include #endif #ifdef HAVE_SYS_STATVFS_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[MINIMUM(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); /* * On platforms where we can, 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. */ platform_disable_tracing(1); /* strict */ /* 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.5p1/sftp.c010064400017500001750000001626121306364033700126110ustar00djmdjm/* $OpenBSD: sftp.c,v 1.178 2017/02/15 01:46:47 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 #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 #include #ifdef HAVE_UTIL_H # include #endif #include "xmalloc.h" #include "log.h" #include "pathnames.h" #include "misc.h" #include "utf8.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 suspchild(int signo) { if (sshpid > 1) { kill(sshpid, signo); while (waitpid(sshpid, NULL, WUNTRACED) == -1 && errno == EINTR) continue; } kill(getpid(), SIGSTOP); } /* 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(const char *path, const 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, const 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(const 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, const 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(const char *pathname) { size_t l = strlen(pathname); return l > 0 && pathname[l - 1] == '/'; } static int process_get(struct sftp_conn *conn, const char *src, const char *dst, const 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) mprintf("Resuming %s to %s\n", g.gl_pathv[i], abs_dst); else if (!quiet && !resume) mprintf("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, const char *src, const char *dst, const 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) mprintf("Resuming upload of %s to %s\n", g.gl_pathv[i], abs_dst); else if (!quiet && !resume) mprintf("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, const char *path, const 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 = MAXIMUM(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 = MAXIMUM(columns, 1); colspace = width / columns; colspace = MINIMUM(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)); mprintf("%s\n", lname); free(lname); } else mprintf("%s\n", d[n]->longname); } else { mprintf("%-*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, const char *path, const 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 = MAXIMUM(m, strlen(g.gl_pathv[i])); columns = width / (m + 2); columns = MAXIMUM(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)); mprintf("%s\n", lname); free(lname); } else { mprintf("%-*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, const char *path, int hflag, int iflag) { struct sftp_statvfs st; char s_used[FMT_SCALED_STRSIZE], s_avail[FMT_SCALED_STRSIZE]; char s_root[FMT_SCALED_STRSIZE], s_total[FMT_SCALED_STRSIZE]; char s_icapacity[16], s_dcapacity[16]; if (do_statvfs(conn, path, &st, 1) == -1) return -1; if (st.f_files == 0) strlcpy(s_icapacity, "ERR", sizeof(s_icapacity)); else { snprintf(s_icapacity, sizeof(s_icapacity), "%3llu%%", (unsigned long long)(100 * (st.f_files - st.f_ffree) / st.f_files)); } if (st.f_blocks == 0) strlcpy(s_dcapacity, "ERR", sizeof(s_dcapacity)); else { snprintf(s_dcapacity, sizeof(s_dcapacity), "%3llu%%", (unsigned long long)(100 * (st.f_blocks - st.f_bfree) / st.f_blocks)); } if (iflag) { printf(" Inodes Used Avail " "(root) %%Capacity\n"); printf("%11llu %11llu %11llu %11llu %s\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, s_icapacity); } 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 %s\n", s_total, s_used, s_avail, s_root, s_dcapacity); } else { printf(" Size Used Avail " "(root) %%Capacity\n"); printf("%12llu %12llu %12llu %12llu %s\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), s_dcapacity); } 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) mprintf("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) mprintf("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) mprintf("Changing owner on %s\n", g.gl_pathv[i]); aa->uid = n_arg; } else { if (!quiet) mprintf("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: mprintf("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; } mprintf("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 = MAXIMUM(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 = MAXIMUM(columns, 1); colspace = width / columns; colspace = MINIMUM(colspace, width); printf("\n"); m = 1; for (y = 0; list[y]; y++) { llen = strlen(list[y]); tmp = llen > len ? list[y] + len : ""; mprintf("%-*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) mprintf("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 */ mprintf("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); signal(SIGTSTP, suspchild); signal(SIGTTIN, suspchild); signal(SIGTTOU, suspchild); 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(); msetlocale(); __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.5p1/sftp.h010064400017500001750000000065221306364033700126130ustar00djmdjm/* $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.5p1/smult_curve25519_ref.c010064400017500001750000000153241306364033700154440ustar00djmdjm/* $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.5p1/ssh-add.1010064400017500001750000000151351306364033700130730ustar00djmdjm.\" $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.5p1/ssh-add.c010064400017500001750000000373641306364033700131650ustar00djmdjm/* $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.5p1/ssh-agent.1010064400017500001750000000161321306364033700134370ustar00djmdjm.\" $OpenBSD: ssh-agent.1,v 1.64 2016/11/30 06:54:26 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 30 2016 $ .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 P Ar pkcs11_whitelist .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 P Ar pkcs11_whitelist Specify a pattern-list of acceptable paths for PKCS#11 shared libraries that may be added using the .Fl s option to .Xr ssh-add 1 . The default is to allow loading PKCS#11 libraries from .Dq /usr/lib/*,/usr/local/lib/* . PKCS#11 libraries that do not match the whitelist will be refused. See PATTERNS in .Xr ssh_config 5 for a description of pattern-list syntax. .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. .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 .An -nosplit OpenSSH is a derivative of the original and free ssh 1.2.12 release by .An Tatu Ylonen . .An Aaron Campbell , Bob Beck , Markus Friedl , Niels Provos , Theo de Raadt and .An Dug Song removed many bugs, re-added newer features and created OpenSSH. .An Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. openssh-7.5p1/ssh-agent.c010064400017500001750000001107351306364033700135250ustar00djmdjm/* $OpenBSD: ssh-agent.c,v 1.218 2017/03/15 03:52:30 deraadt 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 #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" #include "match.h" #ifdef ENABLE_PKCS11 #include "ssh-pkcs11.h" #endif #ifndef DEFAULT_PKCS11_WHITELIST # define DEFAULT_PKCS11_WHITELIST "/usr/lib*/*,/usr/local/lib*/*" #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]; /* PKCS#11 path whitelist */ static char *pkcs11_whitelist; /* locking */ #define LOCK_SIZE 32 #define LOCK_SALT_SIZE 16 #define LOCK_ROUNDS 1 int locked = 0; u_char lock_pwhash[LOCK_SIZE]; u_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 : MINIMUM(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; u_char 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_pwhash, LOCK_SIZE) == 0) { debug("agent unlocked"); locked = 0; fail_count = 0; explicit_bzero(lock_pwhash, sizeof(lock_pwhash)); 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_pwhash, sizeof(lock_pwhash), 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, canonical_provider[PATH_MAX]; 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 (realpath(provider, canonical_provider) == NULL) { verbose("failed PKCS#11 add of \"%.100s\": realpath: %s", provider, strerror(errno)); goto send; } if (match_pattern_list(canonical_provider, pkcs11_whitelist, 0) != 1) { verbose("refusing PKCS#11 add of \"%.100s\": " "provider not whitelisted", canonical_provider); goto send; } debug("%s: add %.100s", __func__, canonical_provider); if (lifetime && !death) death = monotime() + lifetime; count = pkcs11_add_provider(canonical_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(canonical_provider); id->comment = xstrdup(canonical_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, canonical_provider[PATH_MAX]; 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); if (realpath(provider, canonical_provider) == NULL) { verbose("failed PKCS#11 add of \"%.100s\": realpath: %s", provider, strerror(errno)); goto send; } debug("%s: remove %.100s", __func__, canonical_provider); 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(canonical_provider, id->provider)) { TAILQ_REMOVE(&tab->idlist, id, next); free_identity(id); tab->nentries--; } } } if (pkcs11_del_provider(canonical_provider) == 0) success = 1; else error("process_remove_smartcard_key:" " pkcs11_del_provider failed"); send: 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 = MAXIMUM(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 : MINIMUM(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" " [-P pkcs11_whitelist] [-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()); platform_disable_tracing(0); /* strict=no */ #ifdef WITH_OPENSSL OpenSSL_add_all_algorithms(); #endif __progname = ssh_get_progname(av[0]); seed_rng(); while ((ch = getopt(ac, av, "cDdksE:a:P: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 'P': if (pkcs11_whitelist != NULL) fatal("-P option already specified"); pkcs11_whitelist = xstrdup(optarg); 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 (pkcs11_whitelist == NULL) pkcs11_whitelist = xstrdup(DEFAULT_PKCS11_WHITELIST); 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 rpath 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.5p1/ssh-dss.c010064400017500001750000000134531306364033700132170ustar00djmdjm/* $OpenBSD: ssh-dss.c,v 1.35 2016/04/21 06:08:02 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" #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 || signature == NULL || signaturelen == 0) 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.5p1/ssh-ecdsa.c010064400017500001750000000122761306364033700135070ustar00djmdjm/* $OpenBSD: ssh-ecdsa.c,v 1.13 2016/04/21 06:08:02 djm 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 || signature == NULL || signaturelen == 0) 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.5p1/ssh-ed25519.c010064400017500001750000000103311306364033700134140ustar00djmdjm/* $OpenBSD: ssh-ed25519.c,v 1.7 2016/04/21 06:08:02 djm 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 || signature == NULL || signaturelen == 0) 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.5p1/ssh-gss.h010064400017500001750000000110671306364033700132260ustar00djmdjm/* $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.5p1/ssh-keygen.1010064400017500001750000000640761306364033700136350ustar00djmdjm.\" $OpenBSD: ssh-keygen.1,v 1.133 2016/06/16 06:10:45 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: June 16 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 and keys stored in the newer OpenSSH format, 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 and keys stored in the newer OpenSSH format. 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 , a visual 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.5p1/ssh-keygen.c010064400017500001750000002214401306364033700137050ustar00djmdjm/* $OpenBSD: ssh-keygen.c,v 1.299 2017/03/10 04:26:06 djm 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 #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" #include "utf8.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__); mprintf("%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; u_long 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:%lu: 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); int was_hashed = l->hosts && l->hosts[0] == HASH_DELIM; 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 (was_hashed || has_wild || l->marker != MRK_NONE) { fprintf(ctx->out, "%s\n", l->line); if (has_wild && !find_host) { logit("%s:%lu: 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') { lowercase(cp); 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:%lu: 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 %lu\n", ctx->host, l->linenum); } return 0; } else if (find_host) { ctx->found_key = 1; if (!quiet) { printf("# Host %s found: line %lu %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); mprintf("%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:%lu: 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) mprintf("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); } if (comment) printf("Key now has comment '%s'\n", comment); else printf("Key now has no comment\n"); 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); if (key_type_name != NULL && sshkey_type_from_name(key_type_name) != ca->type) { fatal("CA key type %s doesn't match specified %s", sshkey_ssh_name(ca), key_type_name); } 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 ((r = sshkey_certify(public, ca, key_type_name)) != 0) fatal("Couldn't certify key %s: %s", tmp, ssh_err(r)); 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; u_long 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); } #ifdef WITH_SSH1 # define RSA1_USAGE " | rsa1" #else # define RSA1_USAGE "" #endif static void usage(void) { fprintf(stderr, "usage: ssh-keygen [-q] [-b bits] [-t dsa | ecdsa | ed25519 | rsa%s]\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", RSA1_USAGE); #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(); msetlocale(); /* 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 'G': do_gen_candidates = 1; if (strlcpy(out_file, optarg, sizeof(out_file)) >= sizeof(out_file)) fatal("Output filename too long"); break; case 'J': lines_to_process = strtoul(optarg, NULL, 10); break; case 'j': start_lineno = strtoul(optarg, NULL, 10); break; case 'K': if (strlen(optarg) >= PATH_MAX) fatal("Checkpoint filename too long"); checkpoint = xstrdup(optarg); 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 'S': /* XXX - also compare length against bits */ if (BN_hex2bn(&start, optarg) == 0) fatal("Invalid start point."); 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 'W': generator_wanted = (u_int32_t)strtonum(optarg, 1, UINT_MAX, &errstr); if (errstr != NULL) fatal("Desired generator invalid: %s (%s)", optarg, errstr); 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.5p1/ssh-keyscan.1010064400017500001750000000104351306364033700137760ustar00djmdjm.\" $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.5p1/ssh-keyscan.c010064400017500001750000000462321306364033700140640ustar00djmdjm/* $OpenBSD: ssh-keyscan.c,v 1.109 2017/03/10 04:26:06 djm 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_GRP14_SHA256] = kexdh_client; c->c_ssh->kex->kex[KEX_DH_GRP16_SHA512] = kexdh_client; c->c_ssh->kex->kex[KEX_DH_GRP18_SHA512] = 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(const char *host, struct sshkey *key) { char *hostport; const char *known_host, *hashed; hostport = put_host_port(host, ssh_port); lowercase(hostport); if (hash_hosts && (hashed = host_hash(host, NULL, 0)) == NULL) fatal("host_hash failed"); known_host = hash_hosts ? hashed : hostport; if (!get_cert) fprintf(stdout, "%s ", known_host); 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) { #ifdef WITH_SSH1 case KEY_RSA1: get_keytypes |= KT_RSA1; break; #endif 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: default: 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.5p1/ssh-keysign.8010064400017500001750000000057131306364033700140240ustar00djmdjm.\" $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.5p1/ssh-keysign.c010064400017500001750000000206021306364033700140710ustar00djmdjm/* $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.5p1/ssh-pkcs11-client.c010064400017500001750000000123451306364033700150030ustar00djmdjm/* $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.5p1/ssh-pkcs11-helper.8010064400017500001750000000025241306364033700147270ustar00djmdjm.\" $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.5p1/ssh-pkcs11-helper.c010064400017500001750000000177671306364033700150210ustar00djmdjm/* $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.5p1/ssh-pkcs11.c010064400017500001750000000454711306364033700135350ustar00djmdjm/* $OpenBSD: ssh-pkcs11.c,v 1.23 2016/10/28 03:33:52 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) { debug("%s: provider already registered: %s", __func__, 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 for provider %s failed: %lu", provider_id, rv); goto fail; } p->function_list = f; if ((rv = f->C_Initialize(NULL)) != CKR_OK) { error("C_Initialize for provider %s failed: %lu", provider_id, rv); goto fail; } need_finalize = 1; if ((rv = f->C_GetInfo(&p->info)) != CKR_OK) { error("C_GetInfo for provider %s failed: %lu", provider_id, rv); goto fail; } rmspace(p->info.manufacturerID, sizeof(p->info.manufacturerID)); rmspace(p->info.libraryDescription, sizeof(p->info.libraryDescription)); debug("provider %s: manufacturerID <%s> cryptokiVersion %d.%d" " libraryDescription <%s> libraryVersion %d.%d", provider_id, 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) { debug("%s: provider %s returned no slots", __func__, provider_id); 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 for provider %s failed: %lu", provider_id, 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 for provider %s slot %lu " "failed: %lu", provider_id, (unsigned long)i, rv); continue; } if ((token->flags & CKF_TOKEN_INITIALIZED) == 0) { debug2("%s: ignoring uninitialised token in " "provider %s slot %lu", __func__, provider_id, (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("provider %s slot %lu: label <%s> manufacturerID <%s> " "model <%s> serial <%s> flags 0x%lx", provider_id, (unsigned long)i, 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); } debug("%s: provider %s returned no keys", __func__, provider_id); /* 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 for provider %s failed: %lu", provider_id, 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.5p1/ssh-pkcs11.h010064400017500001750000000020761306364033700135340ustar00djmdjm/* $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.5p1/ssh-rsa.c010064400017500001750000000224571306364033700132170ustar00djmdjm/* $OpenBSD: ssh-rsa.c,v 1.60 2016/09/12 23:39:34 djm 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 || strcmp(ident, "ssh-rsa-cert-v01@openssh.com") == 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) 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 || sig == NULL || siglen == 0) 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.5p1/ssh-sandbox.h010064400017500001750000000021301306364033700140570ustar00djmdjm/* $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.5p1/ssh.1010064400017500001750000001275701306364033700123540ustar00djmdjm.\" .\" 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.376 2016/07/16 06:57:55 jmc Exp $ .Dd $Mdocdate: July 16 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 J Oo Ar user Ns @ Oc Ns Ar host Ns Op : Ns Ar port .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 J Xo .Sm off .Op Ar user No @ .Ar host .Op : Ar port .Sm on .Xc Connect to the target host by first making a .Nm connection to the jump .Ar host and then establishing a TCP forwarding to the ultimate destination from there. Multiple jump hops may be specified separated by comma characters. This is a shortcut to specify a .Cm ProxyJump configuration directive. .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 IdentitiesOnly .It IdentityAgent .It IdentityFile .It Include .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 ProxyJump .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 , though these can be overridden in the configuration file or using .Fl o command line options. .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.5p1/ssh.c010064400017500001750000001756621306364033700124430ustar00djmdjm/* $OpenBSD: ssh.c,v 1.451 2017/03/10 04:07:20 djm 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 #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" #include "utf8.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; /* * 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]\n" " [-J [user@]host[:port]] [-L address] [-l login_name] [-m mac_spec]\n" " [-O ctl_cmd] [-o option] [-p port] [-Q query_option] [-R address]\n" " [-S ctl_path] [-W host:port] [-w local_tun[:remote_tun]]\n" " [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); /* ~/ 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(int direct, 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 or jump host unless the user specifically requests so. */ if (!direct && 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, direct, 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. */ direct = option_clear_or_none(options.proxy_command) && options.jump_host == NULL; if (!direct && 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(direct, &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) { struct ssh *ssh = NULL; int i, r, opt, exit_status, use_syslog, direct, 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); msetlocale(); /* * 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:J: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 (options.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 if (strcmp(optarg, "proxy") == 0) muxclient_command = SSHMUX_COMMAND_PROXY; 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 = sshkey_alg_list(0, 0, 0, '\n'); else if (strcmp(optarg, "key-cert") == 0) cp = sshkey_alg_list(1, 0, 0, '\n'); else if (strcmp(optarg, "key-plain") == 0) cp = sshkey_alg_list(0, 1, 0, '\n'); 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 'J': if (options.jump_host != NULL) fatal("Only a single -J option permitted"); if (options.proxy_command != NULL) fatal("Cannot specify -J with ProxyCommand"); if (parse_jump(optarg, &options, 1) == -1) fatal("Invalid -J argument"); options.proxy_command = xstrdup("none"); 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) { debug_flag++; 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 (options.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)) { options.stdio_forward_host = fwd.listen_host; options.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; 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 */ direct = option_clear_or_none(options.proxy_command) && options.jump_host == NULL; if (addrs == NULL && options.num_permitted_cnames != 0 && (direct || 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(direct, &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 ProxyJump option specified, then construct a ProxyCommand now. */ if (options.jump_host != NULL) { char port_s[8]; /* Consistency check */ if (options.proxy_command != NULL) fatal("inconsistent options: ProxyCommand+ProxyJump"); /* Never use FD passing for ProxyJump */ options.proxy_use_fdpass = 0; snprintf(port_s, sizeof(port_s), "%d", options.jump_port); xasprintf(&options.proxy_command, "ssh%s%s%s%s%s%s%s%s%s%.*s -W '[%%h]:%%p' %s", /* Optional "-l user" argument if jump_user set */ options.jump_user == NULL ? "" : " -l ", options.jump_user == NULL ? "" : options.jump_user, /* Optional "-p port" argument if jump_port set */ options.jump_port <= 0 ? "" : " -p ", options.jump_port <= 0 ? "" : port_s, /* Optional additional jump hosts ",..." */ options.jump_extra == NULL ? "" : " -J ", options.jump_extra == NULL ? "" : options.jump_extra, /* Optional "-F" argumment if -F specified */ config == NULL ? "" : " -F ", config == NULL ? "" : config, /* Optional "-v" arguments if -v set */ debug_flag ? " -" : "", debug_flag, "vvv", /* Mandatory hostname */ options.jump_host); debug("Setting implicit ProxyCommand from ProxyJump: %s", options.proxy_command); } 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 && muxclient_command != SSHMUX_COMMAND_PROXY)) 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) { int sock; if ((sock = muxclient(options.control_path)) >= 0) { packet_set_connection(sock, sock); ssh = active_state; /* XXX */ enable_compat20(); /* XXX */ packet_set_mux(); goto skip_connect; } } /* * 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); ssh = active_state; /* XXX */ 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(); /* optionally set the SSH_AUTHSOCKET_ENV_NAME varibale */ if (options.identity_agent && strcmp(options.identity_agent, SSH_AUTHSOCKET_ENV_NAME) != 0) { if (strcmp(options.identity_agent, "none") == 0) { unsetenv(SSH_AUTHSOCKET_ENV_NAME); } else { p = tilde_expand_filename(options.identity_agent, original_real_uid); cp = percent_expand(p, "d", pw->pw_dir, "u", pw->pw_name, "l", thishost, "h", host, "r", options.user, (char *)NULL); setenv(SSH_AUTHSOCKET_ENV_NAME, cp, 1); free(cp); free(p); } } /* 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, ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); } 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; } skip_connect: 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, keep_stderr; 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 { keep_stderr = log_is_on_stderr() && debug_flag; if (dup2(devnull, STDIN_FILENO) == -1 || dup2(devnull, STDOUT_FILENO) == -1 || (!keep_stderr && dup2(devnull, STDERR_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 (options.stdio_forward_host == NULL) return; if (!compat20) fatal("stdio forwarding require Protocol 2"); debug3("%s: %s:%d", __func__, options.stdio_forward_host, options.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(options.stdio_forward_host, options.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 */ if (!packet_get_mux()) 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; } /* NB. leave filename pointing to private key */ identity_files[n_ids] = xstrdup(filename); identity_keys[n_ids] = public; 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.5p1/ssh.h010064400017500001750000000056231306364033700124350ustar00djmdjm/* $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.5p1/ssh1.h010064400017500001750000000101011306364033700125010ustar00djmdjm/* $OpenBSD: ssh1.h,v 1.7 2016/05/04 14:22:33 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". */ /* * 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_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.5p1/ssh2.h010064400017500001750000000132461306364033700125170ustar00djmdjm/* $OpenBSD: ssh2.h,v 1.18 2016/05/04 14:22:33 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 */ /* special marker for no message */ #define SSH_MSG_NONE 0 /* 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.5p1/ssh_api.c010064400017500001750000000335271306364033700132650ustar00djmdjm/* $OpenBSD: ssh_api.c,v 1.7 2016/05/04 14:22:33 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 "ssh_api.h" #include "compat.h" #include "log.h" #include "authfile.h" #include "sshkey.h" #include "misc.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_GRP14_SHA256] = kexdh_server; ssh->kex->kex[KEX_DH_GRP16_SHA512] = kexdh_server; ssh->kex->kex[KEX_DH_GRP18_SHA512] = 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_GRP14_SHA256] = kexdh_client; ssh->kex->kex[KEX_DH_GRP16_SHA512] = kexdh_client; ssh->kex->kex[KEX_DH_GRP18_SHA512] = 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.5p1/ssh_api.h010064400017500001750000000105241306364033700132620ustar00djmdjm/* $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.5p1/ssh_config010064400017500001750000000031521306364033700135270ustar00djmdjm# $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.5p1/ssh_config.5010064400017500001750000001444631306364033700137050ustar00djmdjm.\" .\" 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.242 2017/02/27 14:30:33 jmc Exp $ .Dd $Mdocdate: February 27 2017 $ .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 .Cm 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 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. 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. .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 keyword 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. Arguments to .Cm exec accept the tokens described in the .Sx TOKENS section. .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 .Cm 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 .Cm ask , .Xr ssh 1 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 .Cm 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 .Cm no , no keys are added to the agent. The argument must be .Cm yes , .Cm confirm , .Cm ask , or .Cm no (the default). .It Cm AddressFamily Specifies which address family to use when connecting. Valid arguments are .Cm any (the default), .Cm inet (use IPv4 only), or .Cm inet6 (use IPv6 only). .It Cm BatchMode If set to .Cm 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 .Cm yes or .Cm no (the default). .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 .Cm 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, .Cm yes , will attempt to look up the unqualified hostname using the system resolver's search rules. A value of .Cm 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, .Cm no , is not to perform any name rewriting and let the system resolver handle all hostname lookups. If set to .Cm 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 .Cm 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, 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, .Qq *.a.example.com:*.b.example.com,*.c.example.com will allow hostnames matching .Qq *.a.example.com to be canonicalized to names in the .Qq *.b.example.com or .Qq *.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 Arguments to .Cm CertificateFile may use the tilde syntax to refer to a user's home directory or the tokens described in the .Sx TOKENS section. .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 .Cm yes (the default) or .Cm no . .It Cm CheckHostIP If set to .Cm yes (the default), .Xr ssh 1 will additionally check the host IP address in the .Pa known_hosts file. This allows it 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 .Cm no , the check will not be executed. .It Cm Cipher Specifies the cipher to use for encrypting the session in protocol version 1. Currently, .Cm blowfish , .Cm 3des (the default), and .Cm des are supported, though .Cm des is only supported in the .Xr ssh 1 client for interoperability with legacy protocol 1 implementations; its use is strongly discouraged due to cryptographic weaknesses. .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. If the specified value begins with a .Sq - character, then the specified ciphers (including wildcards) will be removed from the default set instead of replacing them. .Pp The supported ciphers are: .Bd -literal -offset indent 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 .Ed .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 .Ed .Pp The list of available ciphers may also be obtained using .Qq ssh -Q 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 .Cm yes or .Cm no (the default). .It Cm Compression Specifies whether to use compression. The argument must be .Cm yes or .Cm no (the default). .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 .Cm 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 .Cm 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 .Cm ask will cause .Xr ssh 1 to listen for control connections, but require confirmation using .Xr ssh-askpass 1 . If the .Cm ControlPath cannot be opened, .Xr ssh 1 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: .Cm auto and .Cm autoask . The latter requires confirmation like the .Cm 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 .Cm none to disable connection sharing. Arguments to .Cm ControlPath may use the tilde syntax to refer to a user's home directory or the tokens described in the .Sx TOKENS section. 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 .Cm 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 .Cm yes or 0, then the master connection will remain in the background indefinitely (until killed or closed via a mechanism such as the .Qq ssh -O exit ) . 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 .Cm 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 .Cm 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 .Cm yes or .Cm no (the default). 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 .Cm 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 .Cm yes or .Cm no (the default). .It Cm FingerprintHash Specifies the hash algorithm used when displaying key fingerprints. Valid options are: .Cm md5 and .Cm sha256 (the default). .It Cm ForwardAgent Specifies whether the connection to the authentication agent (if any) will be forwarded to the remote machine. The argument must be .Cm yes or .Cm no (the default). .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 .Cm yes or .Cm no (the default). .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 .Sx 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 .Cm yes , remote X11 clients will have full access to the original X11 display. .Pp If this option is set to .Cm no (the default), 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 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 .Cm yes or .Cm no (the default). .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 .Cm no . .It Cm GSSAPIDelegateCredentials Forward (delegate) credentials to the server. The default is .Cm 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 .Cm 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 .Cm yes or .Cm no (the default). .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. If the specified value begins with a .Sq - character, then the specified key types (including wildcards) will be removed from 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. If the specified value begins with a .Sq - character, then the specified key types (including wildcards) will be removed from 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 .Qq ssh -Q 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. Arguments to .Cm HostName accept the tokens described in the .Sx TOKENS section. Numeric IP addresses are also permitted (both on the command line and in .Cm HostName specifications). The default is the name given on the command line. .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 .Cm yes or .Cm no (the default). This option is intended for situations where ssh-agent offers many different identities. .It Cm IdentityAgent Specifies the .Ux Ns -domain socket used to communicate with the authentication agent. .Pp This option overrides the .Ev SSH_AUTH_SOCK environment variable and can be used to select a specific agent. Setting the socket name to .Cm none disables the use of an authentication agent. If the string .Qq SSH_AUTH_SOCK is specified, the location of the socket will be read from the .Ev SSH_AUTH_SOCK environment variable. .Pp Arguments to .Cm IdentityAgent may use the tilde syntax to refer to a user's home directory or the tokens described in the .Sx TOKENS section. .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 Arguments to .Cm IdentityFile may use the tilde syntax to refer to a user's home directory or the tokens described in the .Sx TOKENS section. .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 Include Include the specified configuration file(s). Multiple pathnames may be specified and each pathname may contain .Xr glob 3 wildcards and, for user configurations, shell-like .Sq ~ references to user home directories. Files without absolute paths are assumed to be in .Pa ~/.ssh if included in a user configuration file or .Pa /etc/ssh if included from the system configuration file. .Cm Include directive may appear inside a .Cm Match or .Cm Host block to perform conditional inclusion. .It Cm IPQoS Specifies the IPv4 type-of-service or DSCP class for connections. Accepted values are .Cm af11 , .Cm af12 , .Cm af13 , .Cm af21 , .Cm af22 , .Cm af23 , .Cm af31 , .Cm af32 , .Cm af33 , .Cm af41 , .Cm af42 , .Cm af43 , .Cm cs0 , .Cm cs1 , .Cm cs2 , .Cm cs3 , .Cm cs4 , .Cm cs5 , .Cm cs6 , .Cm cs7 , .Cm ef , .Cm lowdelay , .Cm throughput , .Cm 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 .Cm lowdelay for interactive sessions and .Cm throughput for non-interactive sessions. .It Cm KbdInteractiveAuthentication Specifies whether to use keyboard-interactive authentication. The argument to this keyword must be .Cm yes (the default) or .Cm no . .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: .Cm bsdauth , .Cm pam , and .Cm 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. If the specified value begins with a .Sq - character, then the specified methods (including wildcards) will be removed from the default set instead of replacing them. The default is: .Bd -literal -offset indent curve25519-sha256,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 .Qq ssh -Q 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. Arguments to .Cm LocalCommand accept the tokens described in the .Sx TOKENS section. .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 .Cm 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. If the specified value begins with a .Sq - character, then the specified algorithms (including wildcards) will be removed from the default set instead of replacing them. .Pp The algorithms that contain .Qq -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 .Qq ssh -Q 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 .Cm yes or .Cm no (the default). .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 .Cm yes (the default) or .Cm no . .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 .Cm yes or .Cm no (the default). .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 1 and 2. Multiple versions must be comma-separated. When this option is set to .Cm 2,1 .Nm ssh will try version 2 and fall back to version 1 if version 2 is not available. The default is version 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 Arguments to .Cm ProxyCommand accept the tokens described in the .Sx TOKENS section. 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 .Cm 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 ProxyJump Specifies one or more jump proxies as .Xo .Sm off .Op Ar user No @ .Ar host .Op : Ns Ar port .Sm on .Xc . Multiple proxies may be separated by comma characters and will be visited sequentially. Setting this option will cause .Xr ssh 1 to connect to the target host by first making a .Xr ssh 1 connection to the specified .Cm ProxyJump host and then establishing a TCP forwarding to the ultimate target from there. .Pp Note that this option will compete with the .Cm ProxyCommand option - whichever is specified first will prevent later instances of the other from taking effect. .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 .Cm 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. If the specified value begins with a .Sq - character, then the specified key types (including wildcards) will be removed from 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 list of available key types may also be obtained using .Qq ssh -Q key . .It Cm PubkeyAuthentication Specifies whether to try public key authentication. The argument to this keyword must be .Cm yes (the default) or .Cm no . .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 of .Xr sshd_config 5 . The default value for .Cm RekeyLimit is .Cm 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 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: .Cm no (never request a TTY), .Cm yes (always request a TTY when standard input is a TTY), .Cm force (always request a TTY) or .Cm 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 .Cm yes or .Cm no (the default). 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 .Cm yes (the default) or .Cm no . RSA authentication will only be attempted if the identity file exists, or an authentication agent is running. 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 .Cm yes or .Cm no (the default). .It Cm StrictHostKeyChecking If this flag is set to .Cm 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 .Cm no , ssh will automatically add new host keys to the user known hosts files. If this flag is set to .Cm ask (the default), 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. .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 .Cm 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 .Cm no . .It Cm Tunnel Request .Xr tun 4 device forwarding between the client and the server. The argument must be .Cm yes , .Cm point-to-point (layer 3), .Cm ethernet (layer 2), or .Cm no (the default). Specifying .Cm yes requests the default tunnel mode, which is .Cm point-to-point . .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 .Cm any , which uses the next available tunnel device. If .Ar remote_tun is not specified, it defaults to .Cm any . The default is .Cm 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 .Cm yes , .Cm no (the default) or .Cm 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 .Cm 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 .Qq 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 .Cm yes or .Cm no (the default). If set to .Cm yes , .Xr ssh 1 must be setuid root. Note that this option must be set to .Cm 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 .Cm 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 .Cm ask . If this option is set to .Cm 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 default is .Cm no . .Pp See also .Sx VERIFYING HOST KEYS in .Xr ssh 1 . .It Cm VisualHostKey If this flag is set to .Cm 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 .Cm no (the default), no fingerprint strings are printed at login and only the fingerprint string will be printed for unknown host keys. .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 .Qq .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 .Qq dialup pool, the following entry (in authorized_keys) could be used: .Pp .Dl from=\&"!*.dialup.example.com,*.example.com\&" .Sh TOKENS Arguments to some keywords can make use of tokens, which are expanded at runtime: .Pp .Bl -tag -width XXXX -offset indent -compact .It %% A literal .Sq % . .It \&%C Shorthand for %l%h%p%r. .It %d Local user's home directory. .It %h The remote hostname. .It %i The local user ID. .It %L The local hostname. .It %l The local hostname, including the domain name. .It %n The original remote hostname, as given on the command line. .It %p The remote port. .It %r The remote username. .It %u The local username. .El .Pp .Cm Match exec accepts the tokens %%, %h, %L, %l, %n, %p, %r, and %u. .Pp .Cm CertificateFile accepts the tokens %%, %d, %h, %l, %r, and %u. .Pp .Cm ControlPath accepts the tokens %%, %C, %h, %i, %L, %l, %n, %p, %r, and %u. .Pp .Cm HostName accepts the tokens %% and %h. .Pp .Cm IdentityAgent and .Cm IdentityFile accept the tokens %%, %d, %h, %l, %r, and %u. .Pp .Cm LocalCommand accepts the tokens %%, %C, %d, %h, %l, %n, %p, %r, and %u. .Pp .Cm ProxyCommand accepts the tokens %%, %h, %p, and %r. .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 .An -nosplit OpenSSH is a derivative of the original and free ssh 1.2.12 release by .An Tatu Ylonen . .An Aaron Campbell , Bob Beck , Markus Friedl , .An Niels Provos , Theo de Raadt and .An Dug Song removed many bugs, re-added newer features and created OpenSSH. .An Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. openssh-7.5p1/sshbuf-getput-basic.c010064400017500001750000000223641306364033700155130ustar00djmdjm/* $OpenBSD: sshbuf-getput-basic.c,v 1.6 2016/06/16 11:00:17 dtucker 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 #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.5p1/sshbuf-getput-crypto.c010064400017500001750000000132131306364033700157430ustar00djmdjm/* $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.5p1/sshbuf-misc.c010064400017500001750000000070371306364033700140570ustar00djmdjm/* $OpenBSD: sshbuf-misc.c,v 1.6 2016/05/02 08:49:03 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; } char * sshbuf_dup_string(struct sshbuf *buf) { const u_char *p = NULL, *s = sshbuf_ptr(buf); size_t l = sshbuf_len(buf); char *r; if (s == NULL || l > SIZE_MAX) return NULL; /* accept a nul only as the last character in the buffer */ if (l > 0 && (p = memchr(s, '\0', l)) != NULL) { if (p != s + l - 1) return NULL; l--; /* the nul is put back below */ } if ((r = malloc(l + 1)) == NULL) return NULL; if (l > 0) memcpy(r, s, l); r[l] = '\0'; return r; } openssh-7.5p1/sshbuf.c010064400017500001750000000224161306364033700131240ustar00djmdjm/* $OpenBSD: sshbuf.c,v 1.8 2016/11/25 23:22:04 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 #include "ssherr.h" #include "sshbuf.h" #include "misc.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_allocate(struct sshbuf *buf, size_t len) { size_t rlen, need; u_char *dp; int r; SSHBUF_DBG(("allocate 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("allocate"); if (len + buf->size <= buf->alloc) return 0; /* already have it. */ /* * 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")); return SSH_ERR_ALLOC_FAIL; } buf->alloc = rlen; buf->cd = buf->d = dp; if ((r = sshbuf_check_reserve(buf, len)) < 0) { /* shouldn't fail */ return r; } SSHBUF_TELL("done"); return 0; } int sshbuf_reserve(struct sshbuf *buf, size_t len, u_char **dpp) { u_char *dp; int r; if (dpp != NULL) *dpp = NULL; SSHBUF_DBG(("reserve buf = %p len = %zu", buf, len)); if ((r = sshbuf_allocate(buf, len)) != 0) return r; dp = buf->d + buf->size; buf->size += len; 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.5p1/sshbuf.h010064400017500001750000000275271306364033700131410ustar00djmdjm/* $OpenBSD: sshbuf.h,v 1.8 2016/11/25 23:22:04 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 _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); /* * Preallocates len additional bytes in buf. * Useful for cases where the caller knows how many bytes will ultimately be * required to avoid realloc in the buffer code. * Returns 0 on success, or a negative SSH_ERR_* error code on failure. */ int sshbuf_allocate(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); /* * Duplicate the contents of a buffer to a string (caller to free). * Returns NULL on buffer error, or if the buffer contains a premature * nul character. */ char *sshbuf_dup_string(struct sshbuf *buf); /* 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.5p1/sshconnect.c010064400017500001750000001244551306364033700140070ustar00djmdjm/* $OpenBSD: sshconnect.c,v 1.273 2017/03/10 03:22:40 dtucker 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 #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"); close(auth_sock); 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); close(auth_sock); } openssh-7.5p1/sshconnect.h010064400017500001750000000053271306364033700140100ustar00djmdjm/* $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.5p1/sshconnect1.c010064400017500001750000000544041306364033700140640ustar00djmdjm/* $OpenBSD: sshconnect1.c,v 1.80 2017/03/10 03:53:11 dtucker 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; 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. */ if ((server_key = key_new(KEY_RSA1)) == NULL) fatal("%s: key_new(KEY_RSA1) failed", __func__); 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. */ if ((host_key = key_new(KEY_RSA1)) == NULL) fatal("%s: key_new(KEY_RSA1) failed", __func__); 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. */ arc4random_buf(session_key, sizeof(session_key)); /* * 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.5p1/sshconnect2.c010064400017500001750000001476631306364033700140770ustar00djmdjm/* $OpenBSD: sshconnect2.c,v 1.255 2017/03/11 23:40:26 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" #include "utf8.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); myproposal[PROPOSAL_COMP_ALGS_CTOS] = myproposal[PROPOSAL_COMP_ALGS_STOC] = options.compression ? "zlib@openssh.com,zlib,none" : "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(options.rekey_limit, 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_GRP14_SHA256] = kexdh_client; kex->kex[KEX_DH_GRP16_SHA512] = kexdh_client; kex->kex[KEX_DH_GRP18_SHA512] = 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 void pubkey_reset(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); if (!authctxt.success) fatal("Authentication failed."); 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, *lang; u_int len; debug3("%s", __func__); msg = packet_get_string(&len); lang = packet_get_string(NULL); if (len > 0 && options.log_level >= SYSLOG_LEVEL_INFO) fmprintf(stderr, "%s", msg); free(msg); 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) { verbose("Authenticated with partial success."); /* reset state */ pubkey_reset(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; debug2("input_userauth_passwd_changereq"); if (authctxt == NULL) fatal("input_userauth_passwd_changereq: " "no authentication context"); host = options.host_key_alias ? options.host_key_alias : authctxt->host; 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 * key_sign_encode(const struct sshkey *key) { struct ssh *ssh = active_state; if (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(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; /* the agent supports this key */ if (id->key != NULL && id->agent_fd != -1) return ssh_agent_sign(id->agent_fd, id->key, sigp, lenp, data, datalen, key_sign_encode(id->key), compat); /* * we have already loaded the private key or * the private key is stored in external hardware */ if (id->key != NULL && (id->isprivate || (id->key->flags & SSHKEY_FLAG_EXT))) return (sshkey_sign(id->key, sigp, lenp, data, datalen, key_sign_encode(id->key), 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, key_sign_encode(prv), compat); sshkey_free(prv); return (ret); } static int id_filename_matches(Identity *id, Identity *private_id) { const char *suffixes[] = { ".pub", "-cert.pub", NULL }; size_t len = strlen(id->filename), plen = strlen(private_id->filename); size_t i, slen; if (strcmp(id->filename, private_id->filename) == 0) return 1; for (i = 0; suffixes[i]; i++) { slen = strlen(suffixes[i]); if (len > slen && plen == len - slen && strcmp(id->filename + (len - slen), suffixes[i]) == 0 && memcmp(id->filename, private_id->filename, plen) == 0) return 1; } return 0; } 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, key_sign_encode(id->key)); } 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, fall back to trying the certificate * key itself in case it has a private half already loaded. */ 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; } } /* * Exact key matches are preferred, but also allow * filename matches for non-PKCS#11/agent keys that * didn't load public keys. This supports the case * of keeping just a private key file and public * certificate on disk. */ if (!matched && !id->isprivate && id->agent_fd == -1 && (id->key->flags & SSHKEY_FLAG_EXT) == 0) { TAILQ_FOREACH(private_id, &authctxt->keys, next) { if (private_id->key == NULL && id_filename_matches(id, private_id)) { 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 { debug("%s: no separate private key for certificate " "\"%s\"", __func__, id->filename); } } /* 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(key_sign_encode(id->key)); 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); } /* 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; } /* 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); } } /* 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 void pubkey_reset(Authctxt *authctxt) { Identity *id; TAILQ_FOREACH(id, &authctxt->keys, next) id->tried = 0; } 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; id->isprivate = 0; } } 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)); } } if ((list = sshbuf_dup_string(&b)) == NULL) fatal("%s: sshbuf_dup_string failed", __func__); buffer_free(&b); return list; } openssh-7.5p1/sshd.8010064400017500001750000000725411306364033700125240ustar00djmdjm.\" .\" 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.288 2017/01/30 23:27:39 dtucker Exp $ .Dd $Mdocdate: January 30 2017 $ .Dt SSHD 8 .Os .Sh NAME .Nm sshd .Nd OpenSSH SSH daemon .Sh SYNOPSIS .Nm sshd .Bk -words .Op Fl 46DdeiqTt .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 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 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_dsa_key , .Pa /etc/ssh/ssh_host_ecdsa_key , .Pa /etc/ssh/ssh_host_ed25519_key and .Pa /etc/ssh/ssh_host_rsa_key . It is possible to have multiple host key files for the different host key algorithms. .It Fl i Specifies that .Nm is being run from .Xr inetd 8 . .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 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 protocol 2 only. Each host has a host-specific key, used to identify the host. Whenever a client connects, the daemon responds with its public host key. The client compares the host key against its own database to verify that it has not changed. 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). Public keys consist of the following space-separated fields: options, keytype, base64-encoded key, comment. The options field is optional. 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 ; the comment field is not used for anything (but may be convenient for the user to identify the key). .Pp Note that lines in this file can be 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 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 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. .Pp 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, e.g. using the .Cm restrict key option. .Pp 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 a .Xr sshd_config 5 .Cm ForceCommand directive. .Pp If a command is specified and a forced-command is embedded in a certificate used for authentication, then the certificate will be accepted only if the two commands are identical. .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. .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 to 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, keytype, base64-encoded key, 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 The keytype and base64-encoded key are taken directly from the host key; they can be obtained, for example, from .Pa /etc/ssh/ssh_host_rsa_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, for example, .Pa /etc/ssh/ssh_host_rsa_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_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_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.5p1/sshd.c010064400017500001750000001647001306364033700125760ustar00djmdjm/* $OpenBSD: sshd.c,v 1.485 2017/03/15 03:52:30 deraadt 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 "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.h" #ifdef GSSAPI #include "ssh-gss.h" #endif #include "monitor_wrap.h" #include "ssh-sandbox.h" #include "version.h" #include "ssherr.h" /* 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 **host_keys; /* all private host keys */ Key **host_pubkeys; /* all public host keys */ Key **host_certificates; /* all public host certificates */ int have_ssh2_key; } sensitive_data; /* 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); 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."); if (options.pid_file != NULL) unlink(options.pid_file); 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 port %d", ssh_remote_ipaddr(active_state), ssh_remote_port(active_state)); } static void sshd_exchange_identification(struct ssh *ssh, int sock_in, int sock_out) { u_int i; int remote_major, remote_minor; char *s; char buf[256]; /* Must not be larger than remote_version. */ char remote_version[256]; /* Must be at least as big as buf. */ xasprintf(&server_version_string, "SSH-%d.%d-%.100s%s%s\r\n", PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2, SSH_VERSION, *options.version_addendum == '\0' ? "" : " ", options.version_addendum); /* 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 port %d", ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); 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 port %d", ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); 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, ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); 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); ssh->compat = compat_datafellows(remote_version); if ((ssh->compat & SSH_BUG_PROBE) != 0) { logit("probed from %s port %d with %s. Don't panic.", ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), client_version_string); cleanup_exit(255); } if ((ssh->compat & SSH_BUG_SCANNER) != 0) { logit("scanned from %s port %d with %s. Don't panic.", ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), client_version_string); cleanup_exit(255); } if ((ssh->compat & SSH_BUG_RSASIGMD5) != 0) { logit("Client version \"%.100s\" uses unsafe RSA signature " "scheme; disabling use of RSA keys", remote_version); } if ((ssh->compat & SSH_BUG_DERIVEKEY) != 0) { fatal("Client version \"%.100s\" uses unsafe key agreement; " "refusing connection", remote_version); } chop(server_version_string); debug("Local version string %.200s", server_version_string); if (remote_major == 2 || (remote_major == 1 && remote_minor == 99)) { enable_compat20(); } else { 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 port %d: " "%.200s vs. %.200s", ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), 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; 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; } } } /* Demote private to public keys for network child */ void demote_sensitive_data(void) { Key *tmp; int i; 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; } /* Certs do not need demotion */ } } static void reseed_prngs(void) { u_int32_t rnd[256]; #ifdef WITH_OPENSSL RAND_poll(); #endif arc4random_stir(); /* noop on recent arc4random() implementations */ arc4random_buf(rnd, sizeof(rnd)); /* let arc4random notice PID change */ #ifdef WITH_OPENSSL RAND_seed(rnd, sizeof(rnd)); /* give libcrypto a chance to notice the PID change */ if ((RAND_bytes((u_char *)rnd, 1)) != 1) fatal("%s: RAND_bytes failed", __func__); #endif explicit_bzero(rnd, sizeof(rnd)); } static void privsep_preauth_child(void) { 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 reseed_prngs(); /* 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); /* 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) { #ifdef DISABLE_FD_PASSING if (1) { #else if (authctxt->pw->pw_uid == 0) { #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(); reseed_prngs(); /* 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) 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; } } if ((ret = sshbuf_dup_string(&b)) == NULL) fatal("%s: sshbuf_dup_string failed", __func__); 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 || 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] [-C connection_spec] [-c host_cert_file]\n" " [-E log_file] [-f config_file] [-g login_grace_time]\n" " [-h host_key_file] [-o option] [-p port] [-u len]\n" ); exit(1); } static void send_rexec_state(int fd, struct sshbuf *conf) { struct sshbuf *m; int r; debug3("%s: entering fd = %d config len %zu", __func__, fd, sshbuf_len(conf)); /* * Protocol from reexec master to child: * string configuration * string rngseed (only if OpenSSL is not self-seeded) */ if ((m = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); if ((r = sshbuf_put_stringb(m, conf)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); #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__); sshbuf_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); free(cp); #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; } if (fcntl(listen_sock, F_SETFD, FD_CLOEXEC) == -1) { verbose("socket: CLOEXEC: %s", strerror(errno)); 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 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 (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) { char *laddr = get_local_ipaddr(*newsock); char *raddr = get_peer_ipaddr(*newsock); verbose("drop connection #%d from [%s]:%d " "on [%s]:%d past MaxStartups", startups, raddr, get_peer_port(*newsock), laddr, get_local_port(*newsock)); free(laddr); free(raddr); 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]); } 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; } } /* * If IP options are supported, make sure there are none (log and * return an error 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. */ static void check_ip_options(struct ssh *ssh) { #ifdef IP_OPTIONS int sock_in = ssh_packet_get_connection_in(ssh); struct sockaddr_storage from; u_char opts[200]; socklen_t i, option_size = sizeof(opts), fromlen = sizeof(from); char text[sizeof(opts) * 3 + 1]; memset(&from, 0, sizeof(from)); if (getpeername(sock_in, (struct sockaddr *)&from, &fromlen) < 0) return; if (from.ss_family != AF_INET) return; /* XXX IPv6 options? */ if (getsockopt(sock_in, IPPROTO_IP, IP_OPTIONS, opts, &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", opts[i]); fatal("Connection from %.100s port %d with IP opts: %.800s", ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), text); } return; #endif /* IP_OPTIONS */ } /* * Main program for the daemon. */ int main(int ac, char **av) { struct ssh *ssh = NULL; extern char *optarg; extern int optind; int r, opt, i, j, on = 1, already_daemon; 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': /* protocol 1, ignored */ 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': /* protocol 1, ignored */ 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.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) { 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 && pubkey->type == KEY_RSA1) || (key != NULL && key->type == KEY_RSA1)) { verbose("Ignoring RSA1 key %s", options.host_key_files[i]); key_free(key); key_free(pubkey); continue; } 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 && 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_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, sshkey_ssh_name(pubkey), fp); free(fp); } if (!sensitive_data.have_ssh2_key) { 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)); } 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, not started from inetd and not already * daemonized (eg re-exec via SIGHUP), disconnect from the controlling * terminal, and fork. The original process exits. */ already_daemon = daemonized(); if (!(debug_flag || inetd_flag || no_daemon_flag || already_daemon)) { if (daemon(0, 0) < 0) fatal("daemon() failed: %.200s", strerror(errno)); disconnect_controlling_tty(); } /* 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(); 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(); ssh = active_state; /* XXX */ check_ip_options(ssh); /* 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 = ssh_remote_port(ssh)) < 0) { debug("ssh_remote_port failed"); cleanup_exit(255); } /* * The rest of the code depends on the fact that * ssh_remote_ipaddr() caches the remote ip, even if * the socket goes away. */ remote_ip = ssh_remote_ipaddr(ssh); #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, ssh_local_port(ssh)); 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(ssh, sock_in, sock_out); 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 (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 */ do_ssh2_kex(); do_authentication2(authctxt); /* * 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 */ } packet_set_timeout(options.client_alive_interval, options.client_alive_count_max); /* Try to send all our hostkeys to the client */ 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); } 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"; } if (options.rekey_limit || options.rekey_interval) packet_set_rekey_limits(options.rekey_limit, 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_GRP14_SHA256] = kexdh_server; kex->kex[KEX_DH_GRP16_SHA512] = kexdh_server; kex->kex[KEX_DH_GRP18_SHA512] = 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.5p1/sshd_config010064400017500001750000000061431306364033700136760ustar00djmdjm# $OpenBSD: sshd_config,v 1.101 2017/03/14 07:19:07 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 :: #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 # Ciphers and keying #RekeyLimit default none # Logging #SyslogFacility AUTH #LogLevel INFO # Authentication: #LoginGraceTime 2m #PermitRootLogin prohibit-password #StrictModes yes #MaxAuthTries 6 #MaxSessions 10 #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 #HostbasedAuthentication no # Change to yes if you don't trust ~/.ssh/known_hosts for # 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 #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.5p1/sshd_config.5010064400017500001750000001341711306364033700140440ustar00djmdjm.\" .\" 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.243 2017/03/14 07:19:07 djm Exp $ .Dd $Mdocdate: March 14 2017 $ .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 .Cm any (the default), .Cm inet (use IPv4 only), or .Cm inet6 (use IPv6 only). .It Cm AllowAgentForwarding Specifies whether .Xr ssh-agent 1 forwarding is permitted. The default is .Cm 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 AllowStreamLocalForwarding Specifies whether StreamLocal (Unix-domain socket) forwarding is permitted. The available options are .Cm yes (the default) or .Cm all to allow StreamLocal forwarding, .Cm no to prevent all StreamLocal forwarding, .Cm local to allow local (from the perspective of .Xr ssh 1 ) forwarding only or .Cm remote to allow remote forwarding only. 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 AllowTcpForwarding Specifies whether TCP forwarding is permitted. The available options are .Cm yes (the default) or .Cm all to allow TCP forwarding, .Cm no to prevent all TCP forwarding, .Cm local to allow local (from the perspective of .Xr ssh 1 ) forwarding only or .Cm remote to allow remote forwarding only. 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 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. HOST criteria may additionally contain addresses to match in CIDR address/masklen format. 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, or by the single string .Cm any to indicate the default behaviour of accepting any single authentication method. If the default is overridden, then successful authentication requires completion of every method in at least one of these lists. .Pp For example, .Qq 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 .Cm bsdauth , .Cm pam , or .Cm skey , depending on the server configuration. For example, .Qq keyboard-interactive:bsdauth would restrict keyboard interactive authentication to the .Cm bsdauth device. .Pp If the 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, .Qq publickey,publickey requires successful authentication using two different public keys. .Pp Note that each authentication method listed should also be explicitly enabled in the configuration. .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. Arguments to .Cm AuthorizedKeysCommand accept the tokens described in the .Sx TOKENS section. If no arguments are specified then the username of the target user is used. .Pp The program should produce on standard output zero or more lines of authorized_keys output (see .Sx AUTHORIZED_KEYS in .Xr sshd 8 ) . If a key supplied by .Cm AuthorizedKeysCommand does not successfully authenticate and authorize the user then public key authentication continues using the usual .Cm AuthorizedKeysFile files. By default, no .Cm AuthorizedKeysCommand is run. .It Cm AuthorizedKeysCommandUser Specifies the user under whose account the .Cm 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 used for user authentication. The format is described in the .Sx AUTHORIZED_KEYS FILE FORMAT section of .Xr sshd 8 . Arguments to .Cm AuthorizedKeysFile accept the tokens described in the .Sx TOKENS section. 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 .Cm none to skip checking for user keys in files. The default is .Qq .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. Arguments to .Cm AuthorizedPrincipalsCommand accept the tokens described in the .Sx TOKENS section. If no arguments are specified then the username of the target user is used. .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 .Cm AuthorizedPrincipalsCommand is run. .It Cm AuthorizedPrincipalsCommandUser Specifies the user under whose account the .Cm 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 .Sx AUTHORIZED_KEYS FILE FORMAT in .Xr sshd 8 ) . Empty lines and comments starting with .Ql # are ignored. .Pp Arguments to .Cm AuthorizedPrincipalsFile accept the tokens described in the .Sx TOKENS section. After expansion, .Cm AuthorizedPrincipalsFile is taken to be an absolute path or one relative to the user's home directory. The default is .Cm 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. .Pp 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 .Cm 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 .Cm 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. Arguments to .Cm ChrootDirectory accept the tokens described in the .Sx TOKENS section. .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 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 .Cm 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. If the specified value begins with a .Sq - character, then the specified ciphers (including wildcards) will be removed from 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 .Qq ssh -Q cipher . .It Cm ClientAliveCountMax Sets the number of client alive messages 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 . 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 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 enabled after the user has authenticated successfully. The argument must be .Cm yes , .Cm delayed (a legacy synonym for .Cm yes ) or .Cm no . The default is .Cm yes . .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. HOST criteria may additionally contain addresses to match in CIDR address/masklen format. 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 DisableForwarding Disables all forwarding features, including X11, .Xr ssh-agent 1 , TCP and StreamLocal. This option overrides all other forwarding-related options and may simplify restricted configurations. .It Cm FingerprintHash Specifies the hash algorithm used when logging key fingerprints. Valid options are: .Cm md5 and .Cm sha256 . The default is .Cm 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 .Cm 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 .Cm 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 .Cm no to force remote port forwardings to be available to the local host only, .Cm yes to force remote port forwardings to bind to the wildcard address, or .Cm clientspecified to allow the client to select the address to which the forwarding is bound. The default is .Cm no . .It Cm GSSAPIAuthentication Specifies whether user authentication based on GSSAPI is allowed. The default is .Cm no . .It Cm GSSAPICleanupCredentials Specifies whether to automatically destroy the user's credentials cache on logout. The default is .Cm yes . .It Cm GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. If set to .Cm yes then the client must authenticate against the host service on the current hostname. If set to .Cm 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 .Cm 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. If the specified value begins with a .Sq - character, then the specified key types (including wildcards) will be removed from 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 list of available key types may also be obtained using .Qq ssh -Q key . .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 .Cm 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 .Cm 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 .Cm 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 defaults are .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 . .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. 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 the string .Qq 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 .Qq ssh -Q key . .It Cm IgnoreRhosts Specifies that .Pa .rhosts and .Pa .shosts files will not be used in .Cm HostbasedAuthentication . .Pp .Pa /etc/hosts.equiv and .Pa /etc/shosts.equiv are still used. The default is .Cm yes . .It Cm IgnoreUserKnownHosts Specifies whether .Xr sshd 8 should ignore the user's .Pa ~/.ssh/known_hosts during .Cm HostbasedAuthentication . The default is .Cm no . .It Cm IPQoS Specifies the IPv4 type-of-service or DSCP class for the connection. Accepted values are .Cm af11 , .Cm af12 , .Cm af13 , .Cm af21 , .Cm af22 , .Cm af23 , .Cm af31 , .Cm af32 , .Cm af33 , .Cm af41 , .Cm af42 , .Cm af43 , .Cm cs0 , .Cm cs1 , .Cm cs2 , .Cm cs3 , .Cm cs4 , .Cm cs5 , .Cm cs6 , .Cm cs7 , .Cm ef , .Cm lowdelay , .Cm throughput , .Cm 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 .Cm lowdelay for interactive sessions and .Cm throughput for non-interactive sessions. .It Cm KbdInteractiveAuthentication Specifies whether to allow keyboard-interactive authentication. The argument to this keyword must be .Cm yes or .Cm no . The default is to use whatever value .Cm ChallengeResponseAuthentication is set to (by default .Cm 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 .Cm 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 .Cm 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 .Cm yes . .It Cm KerberosTicketCleanup Specifies whether to automatically destroy the user's ticket cache file on logout. The default is .Cm 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. If the specified value begins with a .Sq - character, then the specified methods (including wildcards) will be removed from the default set instead of replacing them. The supported algorithms are: .Pp .Bl -item -compact -offset indent .It curve25519-sha256 .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,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 .Qq ssh -Q kex . .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. If the specified value begins with a .Sq - character, then the specified algorithms (including wildcards) will be removed from the default set instead of replacing them. .Pp The algorithms that contain .Qq -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 .Qq ssh -Q 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 .Sx 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, such as 192.0.2.0/24 or 2001:db8::/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, 192.0.2.0/33 and 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 ClientAliveCountMax , .Cm ClientAliveInterval , .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 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 start:rate:full (e.g. "10:30:60"). .Xr sshd 8 will refuse connection attempts with a probability of rate/100 (30%) if there are currently start (10) unauthenticated connections. The probability increases linearly and all connection attempts are refused if the number of unauthenticated connections reaches full (60). .It Cm PasswordAuthentication Specifies whether password authentication is allowed. The default is .Cm 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 .Cm 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 .Cm any can be used to remove all restrictions and permit any forwarding requests. An argument of .Cm none can be used to prohibit all forwarding requests. The wildcard .Sq * can be used for host or port to allow all hosts or ports, respectively. 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 .Cm yes , .Cm prohibit-password , .Cm without-password , .Cm forced-commands-only , or .Cm no . The default is .Cm prohibit-password . .Pp If this option is set to .Cm prohibit-password or .Cm without-password , password and keyboard-interactive authentication are disabled for root. .Pp If this option is set to .Cm 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 .Cm no , root is not allowed to log in. .It Cm PermitTTY Specifies whether .Xr pty 4 allocation is permitted. The default is .Cm yes . .It Cm PermitTunnel Specifies whether .Xr tun 4 device forwarding is allowed. The argument must be .Cm yes , .Cm point-to-point (layer 3), .Cm ethernet (layer 2), or .Cm no . Specifying .Cm yes permits both .Cm point-to-point and .Cm ethernet . The default is .Cm no . .Pp Independent of this setting, the permissions of the selected .Xr tun 4 device must allow access to the user. .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 .Cm 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 .Cm yes . .It Cm PidFile Specifies the file that contains the process ID of the SSH daemon, or .Cm 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 .Cm 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 .Cm yes . .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. If the specified value begins with a .Sq - character, then the specified key types (including wildcards) will be removed from 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 list of available key types may also be obtained using .Qq ssh -Q key . .It Cm PubkeyAuthentication Specifies whether public key authentication is allowed. The default is .Cm 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 .Cm 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 .Cm 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 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 .Cm yes or .Cm no . The default is .Cm 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 .Cm 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 .Cm sftp-server implements the SFTP file transfer subsystem. .Pp Alternately the name .Cm internal-sftp implements an in-process 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 .Qq ghost users and consuming server resources. .Pp The default is .Cm 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 .Cm no . .It Cm TrustedUserCAKeys Specifies a file containing public keys of certificate authorities that are trusted to sign user certificates for authentication, or .Cm 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 .Cm no (the default) then only addresses and not host names may be used in .Pa ~/.ssh/authorized_keys .Cm from and .Nm .Cm Match .Cm Host directives. .It Cm UsePAM Enables the Pluggable Authentication Module interface. If set to .Cm 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 .Cm no . .It Cm VersionAddendum Optionally specifies additional text to append to the SSH protocol banner sent by the server upon connection. The default is .Cm 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 .Cm yes or .Cm no . The default is .Cm 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 ) , 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 .Cm no setting. .Pp Note that disabling X11 forwarding does not prevent users from forwarding X11 traffic, as users can always install their own forwarders. .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 .Cm 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 .Cm no to specify that the forwarding server should be bound to the wildcard address. The argument must be .Cm yes or .Cm no . The default is .Cm yes . .It Cm XAuthLocation Specifies the full pathname of the .Xr xauth 1 program, or .Cm 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 TOKENS Arguments to some keywords can make use of tokens, which are expanded at runtime: .Pp .Bl -tag -width XXXX -offset indent -compact .It %% A literal .Sq % . .It %F The fingerprint of the CA key. .It %f The fingerprint of the key or certificate. .It %h The home directory of the user. .It %i The key ID in the certificate. .It %K The base64-encoded CA key. .It %k The base64-encoded key or certificate for authentication. .It %s The serial number of the certificate. .It \&%T The type of the CA key. .It %t The key or certificate type. .It %u The username. .El .Pp .Cm AuthorizedKeysCommand accepts the tokens %%, %f, %h, %k, %t, and %u. .Pp .Cm AuthorizedKeysFile accepts the tokens %%, %h, and %u. .Pp .Cm AuthorizedPrincipalsCommand accepts the tokens %%, %F, %f, %h, %i, %K, %k, %s, %T, %t, and %u. .Pp .Cm AuthorizedPrincipalsFile accepts the tokens %%, %h, and %u. .Pp .Cm ChrootDirectory accepts the tokens %%, %h, and %u. .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 sftp-server 8 , .Xr sshd 8 .Sh AUTHORS .An -nosplit OpenSSH is a derivative of the original and free ssh 1.2.12 release by .An Tatu Ylonen . .An Aaron Campbell , Bob Beck , Markus Friedl , Niels Provos , .An Theo de Raadt and .An Dug Song removed many bugs, re-added newer features and created OpenSSH. .An Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. .An Niels Provos and .An Markus Friedl contributed support for privilege separation. openssh-7.5p1/ssherr.c010064400017500001750000000115311306364033700131340ustar00djmdjm/* $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.5p1/ssherr.h010064400017500001750000000062621306364033700131460ustar00djmdjm/* $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.5p1/sshkey.c010064400017500001750000003033451306364033700131430ustar00djmdjm/* $OpenBSD: sshkey.c,v 1.45 2017/03/10 04:07:20 djm 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 #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 # ifdef WITH_SSH1 { NULL, "RSA1", KEY_RSA1, 0, 0, 0 }, # endif { "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 * sshkey_alg_list(int certs_only, int plain_only, int include_sigonly, char sep) { char *tmp, *ret = NULL; size_t nlen, rlen = 0; const struct keytype *kt; for (kt = keytypes; kt->type != -1; kt++) { if (kt->name == NULL) continue; if (!include_sigonly && kt->sigonly) continue; if ((certs_only && !kt->cert) || (plain_only && kt->cert)) continue; if (ret != NULL) ret[rlen++] = sep; 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; } 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); if (nlen < 0 || elen < 0 || nlen >= INT_MAX - elen) { r = SSH_ERR_INVALID_FORMAT; goto out; } blob_len = nlen + elen; if ((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 = MAXIMUM(x, 0); y = MAXIMUM(y, 0); x = MINIMUM(x, FLDSIZE_X - 1); y = MINIMUM(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[MINIMUM(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 */ if (ret == NULL) return SSH_ERR_INVALID_ARGUMENT; 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 if (keyp != NULL) *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; if (keyp != NULL) { *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, const char *alg) { 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), alg, 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; /* * NB. This assumes OpenSSL has already verified that the public * point lies on the curve. This is done by EC_POINT_oct2point() * implicitly calling EC_POINT_is_on_curve(). If this code is ever * reachable with public points not unmarshalled using * EC_POINT_oct2point then the caller will need to explicitly check. */ 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 = NULL; const struct sshcipher *cipher; const char *kdfname = KDFNAME; struct sshbuf *encoded = NULL, *encrypted = NULL, *kdf = NULL; 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_free(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 = NULL; struct sshkey *k = NULL; u_char *key = NULL, *salt = NULL, *dp, pad, last; u_int blocksize, rounds, nkeys, encrypted_len, check1, check2; 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_free(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 = NULL; 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; r = sshbuf_putb(blob, encrypted); out: cipher_free(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; 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 = NULL; const struct sshcipher *cipher; struct sshkey *prv = 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; 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) 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; if (keyp != NULL) { *keyp = prv; prv = NULL; } if (commentp != NULL) { *commentp = comment; comment = NULL; } out: cipher_free(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; if (keyp != NULL) *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) { unsigned long pem_err = ERR_peek_last_error(); int pem_reason = ERR_GET_REASON(pem_err); /* * Translate OpenSSL error codes to determine whether * passphrase is required/incorrect. */ switch (ERR_GET_LIB(pem_err)) { case ERR_LIB_PEM: switch (pem_reason) { case PEM_R_BAD_PASSWORD_READ: case PEM_R_PROBLEMS_GETTING_PASSWORD: case PEM_R_BAD_DECRYPT: r = SSH_ERR_KEY_WRONG_PASSPHRASE; goto out; default: r = SSH_ERR_INVALID_FORMAT; goto out; } case ERR_LIB_EVP: switch (pem_reason) { case EVP_R_BAD_DECRYPT: r = SSH_ERR_KEY_WRONG_PASSPHRASE; goto out; case EVP_R_BN_DECODE_ERROR: case EVP_R_DECODE_ERROR: #ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR case EVP_R_PRIVATE_KEY_DECODE_ERROR: #endif r = SSH_ERR_INVALID_FORMAT; goto out; default: r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } case ERR_LIB_ASN1: r = SSH_ERR_INVALID_FORMAT; goto out; } r = SSH_ERR_LIBCRYPTO_ERROR; 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; if (keyp != NULL) { *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) { int r = SSH_ERR_INTERNAL_ERROR; if (keyp != NULL) *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: r = sshkey_parse_private2(blob, type, passphrase, keyp, commentp); /* Do not fallback to PEM parser if only passphrase is wrong. */ if (r == 0 || r == SSH_ERR_KEY_WRONG_PASSPHRASE) return r; #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.5p1/sshkey.h010064400017500001750000000202131306364033700131360ustar00djmdjm/* $OpenBSD: sshkey.h,v 1.15 2017/03/10 04:07:20 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 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 *, const char *); 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 *sshkey_alg_list(int, int, int, char); 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.5p1/sshlogin.c010064400017500001750000000121631306364033700134560ustar00djmdjm/* $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.5p1/sshlogin.h010064400017500001750000000016471306364033700134700ustar00djmdjm/* $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.5p1/sshpty.c010064400017500001750000000142251306364033700131630ustar00djmdjm/* $OpenBSD: sshpty.c,v 1.31 2016/11/29 03:54:50 dtucker 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)); } } } /* Disconnect from the controlling tty. */ void disconnect_controlling_tty(void) { #ifdef TIOCNOTTY int fd; if ((fd = open(_PATH_TTY, O_RDWR | O_NOCTTY)) >= 0) { (void) ioctl(fd, TIOCNOTTY, NULL); close(fd); } #endif /* TIOCNOTTY */ } openssh-7.5p1/sshpty.h010064400017500001750000000020351306364033700131640ustar00djmdjm/* $OpenBSD: sshpty.h,v 1.13 2016/11/29 03:54:50 dtucker 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 *); void disconnect_controlling_tty(void); openssh-7.5p1/sshtty.c010064400017500001750000000057131306364033700131710ustar00djmdjm/* $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.5p1/survey.sh.in010064400017500001750000000032711306364033700137620ustar00djmdjm#!/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 "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.5p1/ttymodes.h010064400017500001750000000124501306364033700135040ustar00djmdjm/* $OpenBSD: ttymodes.h,v 1.15 2016/05/03 09:03:49 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". */ /* * 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 */ #ifdef IUTF8 TTYMODE(IUTF8, c_iflag, 42) #endif /* IUTF8 */ 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.5p1/uidswap.c010064400017500001750000000175511306364033700133120ustar00djmdjm/* $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.5p1/uidswap.h010064400017500001750000000013141306364033700133050ustar00djmdjm/* $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.5p1/umac.c010064400017500001750000001327431306364033700125640ustar00djmdjm/* $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.5p1/umac.h010064400017500001750000000111241306364033700125560ustar00djmdjm/* $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.5p1/utf8.c010064400017500001750000000175041306364033700125220ustar00djmdjm/* $OpenBSD: utf8.c,v 1.5 2017/02/19 00:10:57 djm Exp $ */ /* * Copyright (c) 2016 Ingo Schwarze * * 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 for multibyte-character handling, * in particular to sanitize untrusted strings for terminal output. */ #include "includes.h" #include #ifdef HAVE_LANGINFO_H # include #endif #include #include #include #include #include #include #if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS) # include #endif #ifdef HAVE_WCHAR_H # include #endif #include "utf8.h" static int dangerous_locale(void); static int grow_dst(char **, size_t *, size_t, char **, size_t); static int vasnmprintf(char **, size_t, int *, const char *, va_list); /* * For US-ASCII and UTF-8 encodings, we can safely recover from * encoding errors and from non-printable characters. For any * other encodings, err to the side of caution and abort parsing: * For state-dependent encodings, recovery is impossible. * For arbitrary encodings, replacement of non-printable * characters would be non-trivial and too fragile. */ static int dangerous_locale(void) { char *loc; loc = nl_langinfo(CODESET); return strcmp(loc, "US-ASCII") != 0 && strcmp(loc, "UTF-8") != 0 && strcmp(loc, "ANSI_X3.4-1968") != 0 && strcmp(loc, "646") != 0; } static int grow_dst(char **dst, size_t *sz, size_t maxsz, char **dp, size_t need) { char *tp; size_t tsz; if (*dp + need < *dst + *sz) return 0; tsz = *sz + 128; if (tsz > maxsz) tsz = maxsz; if ((tp = realloc(*dst, tsz)) == NULL) return -1; *dp = tp + (*dp - *dst); *dst = tp; *sz = tsz; return 0; } /* * The following two functions limit the number of bytes written, * including the terminating '\0', to sz. Unless wp is NULL, * they limit the number of display columns occupied to *wp. * Whichever is reached first terminates the output string. * To stay close to the standard interfaces, they return the number of * non-NUL bytes that would have been written if both were unlimited. * If wp is NULL, newline, carriage return, and tab are allowed; * otherwise, the actual number of columns occupied by what was * written is returned in *wp. */ static int vasnmprintf(char **str, size_t maxsz, int *wp, const char *fmt, va_list ap) { char *src; /* Source string returned from vasprintf. */ char *sp; /* Pointer into src. */ char *dst; /* Destination string to be returned. */ char *dp; /* Pointer into dst. */ char *tp; /* Temporary pointer for dst. */ size_t sz; /* Number of bytes allocated for dst. */ wchar_t wc; /* Wide character at sp. */ int len; /* Number of bytes in the character at sp. */ int ret; /* Number of bytes needed to format src. */ int width; /* Display width of the character wc. */ int total_width, max_width, print; src = NULL; if ((ret = vasprintf(&src, fmt, ap)) <= 0) goto fail; sz = strlen(src) + 1; if ((dst = malloc(sz)) == NULL) { free(src); ret = -1; goto fail; } if (maxsz > INT_MAX) maxsz = INT_MAX; sp = src; dp = dst; ret = 0; print = 1; total_width = 0; max_width = wp == NULL ? INT_MAX : *wp; while (*sp != '\0') { if ((len = mbtowc(&wc, sp, MB_CUR_MAX)) == -1) { (void)mbtowc(NULL, NULL, MB_CUR_MAX); if (dangerous_locale()) { ret = -1; break; } len = 1; width = -1; } else if (wp == NULL && (wc == L'\n' || wc == L'\r' || wc == L'\t')) { /* * Don't use width uninitialized; the actual * value doesn't matter because total_width * is only returned for wp != NULL. */ width = 0; } else if ((width = wcwidth(wc)) == -1 && dangerous_locale()) { ret = -1; break; } /* Valid, printable character. */ if (width >= 0) { if (print && (dp - dst >= (int)maxsz - len || total_width > max_width - width)) print = 0; if (print) { if (grow_dst(&dst, &sz, maxsz, &dp, len) == -1) { ret = -1; break; } total_width += width; memcpy(dp, sp, len); dp += len; } sp += len; if (ret >= 0) ret += len; continue; } /* Escaping required. */ while (len > 0) { if (print && (dp - dst >= (int)maxsz - 4 || total_width > max_width - 4)) print = 0; if (print) { if (grow_dst(&dst, &sz, maxsz, &dp, 4) == -1) { ret = -1; break; } tp = vis(dp, *sp, VIS_OCTAL | VIS_ALL, 0); width = tp - dp; total_width += width; dp = tp; } else width = 4; len--; sp++; if (ret >= 0) ret += width; } if (len > 0) break; } free(src); *dp = '\0'; *str = dst; if (wp != NULL) *wp = total_width; /* * If the string was truncated by the width limit but * would have fit into the size limit, the only sane way * to report the problem is using the return value, such * that the usual idiom "if (ret < 0 || ret >= sz) error" * works as expected. */ if (ret < (int)maxsz && !print) ret = -1; return ret; fail: if (wp != NULL) *wp = 0; if (ret == 0) { *str = src; return 0; } else { *str = NULL; return -1; } } int snmprintf(char *str, size_t sz, int *wp, const char *fmt, ...) { va_list ap; char *cp; int ret; va_start(ap, fmt); ret = vasnmprintf(&cp, sz, wp, fmt, ap); va_end(ap); if (cp != NULL) { (void)strlcpy(str, cp, sz); free(cp); } else *str = '\0'; return ret; } /* * To stay close to the standard interfaces, the following functions * return the number of non-NUL bytes written. */ int vfmprintf(FILE *stream, const char *fmt, va_list ap) { char *str; int ret; if ((ret = vasnmprintf(&str, INT_MAX, NULL, fmt, ap)) < 0) return -1; if (fputs(str, stream) == EOF) ret = -1; free(str); return ret; } int fmprintf(FILE *stream, const char *fmt, ...) { va_list ap; int ret; va_start(ap, fmt); ret = vfmprintf(stream, fmt, ap); va_end(ap); return ret; } int mprintf(const char *fmt, ...) { va_list ap; int ret; va_start(ap, fmt); ret = vfmprintf(stdout, fmt, ap); va_end(ap); return ret; } /* * Set up libc for multibyte output in the user's chosen locale. * * XXX: we are known to have problems with Turkish (i/I confusion) so we * deliberately fall back to the C locale for now. Longer term we should * always prefer to select C.[encoding] if possible, but there's no * standardisation in locales between systems, so we'll need to survey * what's out there first. */ void msetlocale(void) { const char *vars[] = { "LC_ALL", "LC_CTYPE", "LANG", NULL }; char *cp; int i; /* * We can't yet cope with dotless/dotted I in Turkish locales, * so fall back to the C locale for these. */ for (i = 0; vars[i] != NULL; i++) { if ((cp = getenv(vars[i])) == NULL) continue; if (strncasecmp(cp, "TR", 2) != 0) break; /* * If we're in a UTF-8 locale then prefer to use * the C.UTF-8 locale (or equivalent) if it exists. */ if ((strcasestr(cp, "UTF-8") != NULL || strcasestr(cp, "UTF8") != NULL) && (setlocale(LC_CTYPE, "C.UTF-8") != NULL || setlocale(LC_CTYPE, "POSIX.UTF-8") != NULL)) return; setlocale(LC_CTYPE, "C"); return; } /* We can handle this locale */ setlocale(LC_CTYPE, ""); } openssh-7.5p1/utf8.h010064400017500001750000000022541306364033700125230ustar00djmdjm/* $OpenBSD: utf8.h,v 1.1 2016/05/25 23:48:45 schwarze Exp $ */ /* * Copyright (c) 2016 Ingo Schwarze * * 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 mprintf(const char *, ...) __attribute__((format(printf, 1, 2))); int fmprintf(FILE *, const char *, ...) __attribute__((format(printf, 2, 3))); int vfmprintf(FILE *, const char *, va_list); int snmprintf(char *, size_t, int *, const char *, ...) __attribute__((format(printf, 4, 5))); void msetlocale(void); openssh-7.5p1/uuencode.c010064400017500001750000000057061306364033700134440ustar00djmdjm/* $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.5p1/uuencode.h010064400017500001750000000027751306364033700134540ustar00djmdjm/* $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.5p1/verify.c010064400017500001750000000012341306364033700131310ustar00djmdjm/* $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.5p1/version.h010064400017500001750000000002521306364033700133160ustar00djmdjm/* $OpenBSD: version.h,v 1.79 2017/03/20 01:18:59 djm Exp $ */ #define SSH_VERSION "OpenSSH_7.5" #define SSH_PORTABLE "p1" #define SSH_RELEASE SSH_VERSION SSH_PORTABLE openssh-7.5p1/xmalloc.c010064400017500001750000000042161306364033700132670ustar00djmdjm/* $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.5p1/xmalloc.h010064400017500001750000000020361306364033700132720ustar00djmdjm/* $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.5p1/ChangeLog010064400017500001750000010573651306372316600132560ustar00djmdjmcommit d38f05dbdd291212bc95ea80648b72b7177e9f4e Author: Darren Tucker Date: Mon Mar 20 13:38:27 2017 +1100 Add llabs() implementation. commit 72536316a219b7394996a74691a5d4ec197480f7 Author: Damien Miller Date: Mon Mar 20 12:23:04 2017 +1100 crank version numbers commit 3be52bc36bdfd24ded7e0f46999e7db520fb4e3f Author: djm@openbsd.org Date: Mon Mar 20 01:18:59 2017 +0000 upstream commit openssh-7.5 Upstream-ID: b8b9a4a949427c393cd868215e1724ceb3467ee5 commit db84e52fe9cfad57f22e7e23c5fbf00092385129 Author: Damien Miller Date: Mon Mar 20 12:07:20 2017 +1100 I'm a doofus. Unbreak obvious syntax error. commit 89f04852db27643717c9c3a2b0dde97ae50099ee Author: Damien Miller Date: Mon Mar 20 11:53:34 2017 +1100 on Cygwin, check paths from server for backslashes Pointed out by Jann Horn of Google Project Zero commit 7ef1f9bafc2cc8d97ff2fbd4f280002b6e8ea5d9 Author: Damien Miller Date: Mon Mar 20 11:48:34 2017 +1100 Yet another synonym for ASCII: "646" Used by NetBSD; this unbreaks mprintf() and friends there for the C locale (caught by dtucker@ and his menagerie of test systems). commit 9165abfea3f68a0c684a6ed2e575e59bc31a3a6b Author: Damien Miller Date: Mon Mar 20 09:58:34 2017 +1100 create test mux socket in /tmp Creating the socket in $OBJ could blow past the (quite limited) path limit for Unix domain sockets. As a bandaid for bz#2660, reported by Colin Watson; ok dtucker@ commit 2adbe1e63bc313d03e8e84e652cc623af8ebb163 Author: markus@openbsd.org Date: Wed Mar 15 07:07:39 2017 +0000 upstream commit disallow KEXINIT before NEWKEYS; ok djm; report by vegard.nossum at oracle.com Upstream-ID: 3668852d1f145050e62f1da08917de34cb0c5234 commit 2fbf91684d76d38b9cf06550b69c9e41bca5a71c Author: Darren Tucker Date: Thu Mar 16 14:05:46 2017 +1100 Include includes.h for compat bits. commit b55f634e96b9c5b0cd991e23a9ca181bec4bdbad Author: Darren Tucker Date: Thu Mar 16 13:45:17 2017 +1100 Wrap stdint.h in #ifdef HAVE_STDINT_H commit 55a1117d7342a0bf8b793250cf314bab6b482b99 Author: Damien Miller Date: Thu Mar 16 11:22:42 2017 +1100 Adapt Cygwin config script to privsep knob removal Patch from Corinna Vinschen. commit 1a321bfdb91defe3c4d9cca5651724ae167e5436 Author: deraadt@openbsd.org Date: Wed Mar 15 03:52:30 2017 +0000 upstream commit accidents happen to the best of us; ok djm Upstream-ID: b7a9dbd71011ffde95e06f6945fe7197dedd1604 commit 25f837646be8c2017c914d34be71ca435dfc0e07 Author: djm@openbsd.org Date: Wed Mar 15 02:25:09 2017 +0000 upstream commit fix regression in 7.4: deletion of PKCS#11-hosted keys would fail unless they were specified by full physical pathname. Report and fix from Jakub Jelen via bz#2682; ok dtucker@ Upstream-ID: 5b5bc20ca11cacb5d5eb29c3f93fd18425552268 commit a8c5eeacf032a7d3408957e45dd7603cc1baf55f Author: djm@openbsd.org Date: Wed Mar 15 02:19:09 2017 +0000 upstream commit Fix segfault when sshd attempts to load RSA1 keys (can only happen when protocol v.1 support is enabled for the client). Reported by Jakub Jelen in bz#2686; ok dtucker Upstream-ID: 8fdaec2ba4b5f65db1d094f6714ce64b25d871d7 commit 66705948c0639a7061a0d0753266da7685badfec Author: djm@openbsd.org Date: Tue Mar 14 07:19:07 2017 +0000 upstream commit Mark the sshd_config UsePrivilegeSeparation option as deprecated, effectively making privsep mandatory in sandboxing mode. ok markus@ deraadt@ (note: this doesn't remove the !privsep code paths, though that will happen eventually). Upstream-ID: b4c52666256c4dd865f8ce9431af5d6ce2d74a0a commit f86586b03fe6cd8f595289bde200a94bc2c191af Author: Damien Miller Date: Tue Mar 14 18:26:29 2017 +1100 Make seccomp-bpf sandbox work on Linux/X32 Allow clock_gettime syscall with X32 bit masked off. Apparently this is required for at least some kernel versions. bz#2142 Patch mostly by Colin Watson. ok dtucker@ commit 2429cf78dd2a9741ce27ba25ac41c535274a0af6 Author: Damien Miller Date: Tue Mar 14 18:01:52 2017 +1100 require OpenSSL >=1.0.1 commit e3ea335abeab731c68f2b2141bee85a4b0bf680f Author: Damien Miller Date: Tue Mar 14 17:48:43 2017 +1100 Remove macro trickery; no binary change This stops the SC_ALLOW(), SC_ALLOW_ARG() and SC_DENY() macros prepending __NR_ to the syscall number parameter and just makes them explicit in the macro invocations. No binary change in stripped object file before/after. commit 5f1596e11d55539678c41f68aed358628d33d86f Author: Damien Miller Date: Tue Mar 14 13:15:18 2017 +1100 support ioctls for ICA crypto card on Linux/s390 Based on patch from Eduardo Barretto; ok dtucker@ commit b1b22dd0df2668b322dda174e501dccba2cf5c44 Author: Darren Tucker Date: Tue Mar 14 14:19:36 2017 +1100 Plumb conversion test into makefile. commit f57783f1ddfb4cdfbd612c6beb5ec01cb5b9a6b9 Author: dtucker@openbsd.org Date: Tue Mar 14 01:20:29 2017 +0000 upstream commit Add unit test for convtime(). Upstream-Regress-ID: 8717bc0ca4c21120f6dd3a1d3b7a363f707c31e1 commit 8884b7247d094cd11ff9e39c325ba928c5bdbc6c Author: dtucker@openbsd.org Date: Tue Mar 14 01:10:07 2017 +0000 upstream commit Add ASSERT_LONG_* helpers. Upstream-Regress-ID: fe15beaea8f5063c7f21b0660c722648e3d76431 commit c6774d21185220c0ba11e8fd204bf0ad1a432071 Author: dtucker@openbsd.org Date: Tue Mar 14 00:55:37 2017 +0000 upstream commit Fix convtime() overflow test on boundary condition, spotted by & ok djm. Upstream-ID: 51f14c507ea87a3022e63f574100613ab2ba5708 commit f5746b40cfe6d767c8e128fe50c43274b31cd594 Author: dtucker@openbsd.org Date: Tue Mar 14 00:25:03 2017 +0000 upstream commit Check for integer overflow when parsing times in convtime(). Reported by nicolas.iooss at m4x.org, ok djm@ Upstream-ID: 35e6a4e98f6fa24df50bfb8ba1307cf70e966f13 commit f5907982f42a8d88a430b8a46752cbb7859ba979 Author: Darren Tucker Date: Tue Mar 14 13:38:15 2017 +1100 Add a "unit" target to run only unit tests. commit 9e96b41682aed793fadbea5ccd472f862179fb02 Author: Damien Miller Date: Tue Mar 14 12:24:47 2017 +1100 Fix weakness in seccomp-bpf sandbox arg inspection Syscall arguments are passed via an array of 64-bit values in struct seccomp_data, but we were only inspecting the bottom 32 bits and not even those correctly for BE systems. Fortunately, the only case argument inspection was used was in the socketcall filtering so using this for sandbox escape seems impossible. ok dtucker commit 8ff3fc3f2f7c13e8968717bc2b895ee32c441275 Author: djm@openbsd.org Date: Sat Mar 11 23:44:16 2017 +0000 upstream commit regress tests for loading certificates without public keys; bz#2617 based on patch from Adam Eijdenberg; ok markus@ dtucker@ Upstream-Regress-ID: 0145d19328ed995b73fe2d9da33596b17429d0d0 commit 1e24552716194db8f2f620587b876158a9ef56ad Author: djm@openbsd.org Date: Sat Mar 11 23:40:26 2017 +0000 upstream commit allow ssh to use certificates accompanied by a private key file but no corresponding plain *.pub public key. bz#2617 based on patch from Adam Eijdenberg; ok dtucker@ markus@ Upstream-ID: 295668dca2c39505281577217583ddd2bd4b00b9 commit 0fb1a617a07b8df5de188dd5a0c8bf293d4bfc0e Author: markus@openbsd.org Date: Sat Mar 11 13:07:35 2017 +0000 upstream commit Don't count the initial block twice when computing how many bytes to discard for the work around for the attacks against CBC-mode. ok djm@; report from Jean Paul, Kenny, Martin and Torben @ RHUL Upstream-ID: f445f509a4e0a7ba3b9c0dae7311cb42458dc1e2 commit ef653dd5bd5777132d9f9ee356225f9ee3379504 Author: dtucker@openbsd.org Date: Fri Mar 10 07:18:32 2017 +0000 upstream commit krl.c Upstream-ID: fc5e695d5d107d730182e2da7b23f00b489e0ee1 commit d94c1dfef2ea30ca67b1204ada7c3b537c54f4d0 Author: Damien Miller Date: Sun Mar 12 10:48:14 2017 +1100 sync fmt_scaled.c with OpenBSD revision 1.13 date: 2017/03/11 23:37:23; author: djm; state: Exp; lines: +14 -1; commitid: jnFKyHkB3CEiEZ2R; fix signed integer overflow in scan_scaled. Found by Nicolas Iooss using AFL against ssh_config. ok deraadt@ millert@ ---------------------------- revision 1.12 date: 2013/11/29 19:00:51; author: deraadt; state: Exp; lines: +6 -5; fairly simple unsigned char casts for ctype ok krw ---------------------------- revision 1.11 date: 2012/11/12 14:07:20; author: halex; state: Exp; lines: +4 -2; make scan_scaled set errno to EINVAL rather than ERANGE if it encounters an invalid multiplier, like the man page says it should "looks sensible" deraadt@, ok ian@ ---------------------------- revision 1.10 date: 2009/06/20 15:00:04; author: martynas; state: Exp; lines: +4 -4; use llabs instead of the home-grown version; and some comment changes ok ian@, millert@ ---------------------------- commit 894221a63fa061e52e414ca58d47edc5fe645968 Author: djm@openbsd.org Date: Fri Mar 10 05:01:13 2017 +0000 upstream commit When updating hostkeys, accept RSA keys if HostkeyAlgorithms contains any RSA keytype. Previously, ssh could ignore RSA keys when any of the ssh-rsa-sha2-* methods was enabled in HostkeyAlgorithms nit ssh-rsa (SHA1 signatures) was not. bz#2650 reported by Luis Ressel; ok dtucker@ Upstream-ID: c5e8cfee15c42f4a05d126158a0766ea06da79d2 commit dd3e2298663f4cc1a06bc69582d00dcfee27d73c Author: djm@openbsd.org Date: Fri Mar 10 04:24:55 2017 +0000 upstream commit make hostname matching really insensitive to case; bz#2685, reported by Petr Cerny; ok dtucker@ Upstream-ID: e467622ff154269e36ba8b6c9e3d105e1c4a9253 commit 77a9be9446697fe8b5499fe651f4a82a71a4b51f Author: djm@openbsd.org Date: Fri Mar 10 03:52:48 2017 +0000 upstream commit reword a comment to make it fit 80 columns Upstream-ID: 4ef509a66b96c7314bbcc87027c2af71fa9d0ba4 commit 61b8ef6a66efaec07e023342cb94a10bdc2254dc Author: djm@openbsd.org Date: Fri Mar 10 04:27:32 2017 +0000 upstream commit better match sshd config parser behaviour: fatal() if line is overlong, increase line buffer to match sshd's; bz#2651 reported by Don Fong; ok dtucker@ Upstream-ID: b175ae7e0ba403833f1ee566edf10f67443ccd18 commit db2597207e69912f2592cd86a1de8e948a9d7ffb Author: djm@openbsd.org Date: Fri Mar 10 04:26:06 2017 +0000 upstream commit ensure hostname is lower-case before hashing it; bz#2591 reported by Griff Miller II; ok dtucker@ Upstream-ID: c3b8b93804f376bd00d859b8bcd9fc0d86b4db17 commit df9936936c695f85c1038bd706d62edf752aca4b Author: djm@openbsd.org Date: Fri Mar 10 04:24:55 2017 +0000 upstream commit make hostname matching really insensitive to case; bz#2685, reported by Petr Cerny; ok dtucker@ Upstream-ID: e632b7a9bf0d0558d5ff56dab98b7cca6c3db549 commit 67eed24bfa7645d88fa0b883745fccb22a0e527e Author: dtucker@openbsd.org Date: Fri Mar 10 04:11:00 2017 +0000 upstream commit Remove old null check from config dumper. Patch from jjelen at redhat.com vi bz#2687, ok djm@ Upstream-ID: 824ab71467b78c4bab0dd1b3a38e8bc5f63dd528 commit 183ba55aaaecca0206184b854ad6155df237adbe Author: djm@openbsd.org Date: Fri Mar 10 04:07:20 2017 +0000 upstream commit fix regression in 7.4 server-sig-algs, where we were accidentally excluding SHA2 RSA signature methods. bz#2680, patch from Nuno Goncalves; ok dtucker@ Upstream-ID: 81ac8bfb30960447740b9b8f6a214dcf322f12e8 commit 66be4fe8c4435af5bbc82998501a142a831f1181 Author: dtucker@openbsd.org Date: Fri Mar 10 03:53:11 2017 +0000 upstream commit Check for NULL return value from key_new. Patch from jjelen at redhat.com via bz#2687, ok djm@ Upstream-ID: 059e33cd43cba88dc8caf0b1936fd4dd88fd5b8e commit ec2892b5c7fea199914cb3a6afb3af38f84990bf Author: djm@openbsd.org Date: Fri Mar 10 03:52:48 2017 +0000 upstream commit reword a comment to make it fit 80 columns Upstream-ID: b4b48b4487c0821d16e812c40c9b09f03b28e349 commit 7fadbb6da3f4122de689165651eb39985e1cba85 Author: dtucker@openbsd.org Date: Fri Mar 10 03:48:57 2017 +0000 upstream commit Check for NULL argument to sshkey_read. Patch from jjelen at redhat.com via bz#2687, ok djm@ Upstream-ID: c2d00c2ea50c4861d271d0a586f925cc64a87e0e commit 5a06b9e019e2b0b0f65a223422935b66f3749de3 Author: dtucker@openbsd.org Date: Fri Mar 10 03:45:40 2017 +0000 upstream commit Plug some mem leaks mostly on error paths. From jjelen at redhat.com via bz#2687, ok djm@ Upstream-ID: 3fb030149598957a51b7c8beb32bf92cf30c96f2 commit f6edbe9febff8121f26835996b1229b5064d31b7 Author: dtucker@openbsd.org Date: Fri Mar 10 03:24:48 2017 +0000 upstream commit Plug mem leak on GLOB_NOMATCH case. From jjelen at redhat.com via bz#2687, ok djm@ Upstream-ID: 8016a7ae97719d3aa55fb723fc2ad3200058340d commit 566b3a46e89a2fda2db46f04f2639e92da64a120 Author: dtucker@openbsd.org Date: Fri Mar 10 03:22:40 2017 +0000 upstream commit Plug descriptor leaks of auth_sock. From jjelen at redhat.com via bz#2687, ok djm@ Upstream-ID: 248acb99a5ed2fdca37d1aa33c0fcee7be286d88 commit 8a2834454c73dfc1eb96453c0e97690595f3f4c2 Author: djm@openbsd.org Date: Fri Mar 10 03:18:24 2017 +0000 upstream commit correctly hash hosts with a port number. Reported by Josh Powers in bz#2692; ok dtucker@ Upstream-ID: 468e357ff143e00acc05bdd2803a696b3d4b6442 commit 9747b9c742de409633d4753bf1a752cbd211e2d3 Author: djm@openbsd.org Date: Fri Mar 10 03:15:58 2017 +0000 upstream commit don't truncate off \r\n from long stderr lines; bz#2688, reported by Brian Dyson; ok dtucker@ Upstream-ID: cdfdc4ba90639af807397ce996153c88af046ca4 commit 4a4b75adac862029a1064577eb5af299b1580cdd Author: dtucker@openbsd.org Date: Fri Mar 10 02:59:51 2017 +0000 upstream commit Validate digest arg in ssh_digest_final; from jjelen at redhat.com via bz#2687, ok djm@ Upstream-ID: dbe5494dfddfe523fab341a3dab5a79e7338f878 commit bee0167be2340d8de4bdc1ab1064ec957c85a447 Author: Darren Tucker Date: Fri Mar 10 13:40:18 2017 +1100 Check for NULL from malloc. Part of bz#2687, from jjelen at redhat.com. commit da39b09d43b137a5a3d071b51589e3efb3701238 Author: Darren Tucker Date: Fri Mar 10 13:22:32 2017 +1100 If OSX is using launchd, remove screen no. Check for socket with and without screen number. From Apple and Jakob Schlyter via bz#2341, with contributions from Ron Frederick, ok djm@ commit 8fb15311a011517eb2394bb95a467c209b8b336c Author: djm@openbsd.org Date: Wed Mar 8 12:07:47 2017 +0000 upstream commit quote [host]:port in generated ProxyJump commandline; the [ / ] characters can confuse some shells (e.g. zsh). Reported by Lauri Tirkkonen via bugs@ Upstream-ID: 65cdd161460e1351c3d778e974c1c2a4fa4bc182 commit 18501151cf272a15b5f2c5e777f2e0933633c513 Author: dtucker@openbsd.org Date: Mon Mar 6 02:03:20 2017 +0000 upstream commit Check l->hosts before dereferencing; fixes potential null pointer deref. ok djm@ Upstream-ID: 81c0327c6ec361da794b5c680601195cc23d1301 commit d072370793f1a20f01ad827ba8fcd3b8f2c46165 Author: dtucker@openbsd.org Date: Mon Mar 6 00:44:51 2017 +0000 upstream commit linenum is unsigned long so use %lu in log formats. ok deraadt@ Upstream-ID: 9dc582d9bb887ebe0164e030d619fc20b1a4ea08 commit 12d3767ba4c84c32150cbe6ff6494498780f12c9 Author: djm@openbsd.org Date: Fri Mar 3 06:13:11 2017 +0000 upstream commit fix ssh-keygen -H accidentally corrupting known_hosts that contained already-hashed entries. HKF_MATCH_HOST_HASHED is only set by hostkeys_foreach() when hostname matching is in use, so we need to look for the hash marker explicitly. Upstream-ID: da82ad653b93e8a753580d3cf5cd448bc2520528 commit d7abb771bd5a941b26144ba400a34563a1afa589 Author: djm@openbsd.org Date: Tue Feb 28 06:10:08 2017 +0000 upstream commit small memleak: free fd_set on connection timeout (though we are heading to exit anyway). From Tom Rix in bz#2683 Upstream-ID: 10e3dadbb8199845b66581473711642d9e6741c4 commit 78142e3ab3887e53a968d6e199bcb18daaf2436e Author: jmc@openbsd.org Date: Mon Feb 27 14:30:33 2017 +0000 upstream commit errant dot; from klemens nanni Upstream-ID: 83d93366a5acf47047298c5d3ebc5e7426f37921 commit 8071a6924c12bb51406a9a64a4b2892675112c87 Author: djm@openbsd.org Date: Fri Feb 24 03:16:34 2017 +0000 upstream commit might as well set the listener socket CLOEXEC Upstream-ID: 9c538433d6a0ca79f5f21decc5620e46fb68ab57 commit d5499190559ebe374bcdfa8805408646ceffad64 Author: djm@openbsd.org Date: Sun Feb 19 00:11:29 2017 +0000 upstream commit add test cases for C locale; ok schwarze@ Upstream-Regress-ID: 783d75de35fbc923d46e2a5e6cee30f8f381ba87 commit 011c8ffbb0275281a0cf330054cf21be10c43e37 Author: djm@openbsd.org Date: Sun Feb 19 00:10:57 2017 +0000 upstream commit Add a common nl_langinfo(CODESET) alias for US-ASCII "ANSI_X3.4-1968" that is used by Linux. Fixes mprintf output truncation for non-UTF-8 locales on Linux spotted by dtucker@; ok deraadt@ schwarze@ Upstream-ID: c6808956ebffd64066f9075d839f74ff0dd60719 commit 0c4430a19b73058a569573492f55e4c9eeaae67b Author: dtucker@openbsd.org Date: Tue Feb 7 23:03:11 2017 +0000 upstream commit Remove deprecated SSH1 options RSAAuthentication and RhostsRSAAuthentication from regression test sshd_config. Upstream-Regress-ID: 8066b753d9dce7cf02ff87af5c727ff680d99491 commit 3baa4cdd197c95d972ec3d07f1c0d08f2d7d9199 Author: dtucker@openbsd.org Date: Fri Feb 17 02:32:05 2017 +0000 upstream commit Do not show rsa1 key type in usage when compiled without SSH1 support. Upstream-ID: 068b5c41357a02f319957746fa4e84ea73960f57 commit ecc35893715f969e98fee118481f404772de4132 Author: dtucker@openbsd.org Date: Fri Feb 17 02:31:14 2017 +0000 upstream commit ifdef out "rsa1" from the list of supported keytypes when compiled without SSH1 support. Found by kdunlop at guralp.com, ok djm@ Upstream-ID: cea93a26433d235bb1d64b1d990f19a9c160a70f commit 10577c6d96a55b877a960b2d0b75edef1b9945af Author: djm@openbsd.org Date: Fri Feb 17 02:04:15 2017 +0000 upstream commit For ProxyJump/-J, surround host name with brackets to allow literal IPv6 addresses. From Dick Visser; ok dtucker@ Upstream-ID: 3a5d3b0171250daf6a5235e91bce09c1d5746bf1 commit b2afdaf1b52231aa23d2153f4a8c5a60a694dda4 Author: jsg@openbsd.org Date: Wed Feb 15 23:38:31 2017 +0000 upstream commit Fix memory leaks in match_filter_list() error paths. ok dtucker@ markus@ Upstream-ID: c7f96ac0877f6dc9188bbc908100a8d246cc7f0e commit 6d5a41b38b55258213ecfaae9df7a758caa752a1 Author: djm@openbsd.org Date: Wed Feb 15 01:46:47 2017 +0000 upstream commit fix division by zero crash in "df" output when server returns zero total filesystem blocks/inodes. Spotted by Guido Vranken; ok dtucker@ Upstream-ID: 6fb6c2ae6b289aa07b6232dbc0be54682ef5419f commit bd5d7d239525d595ecea92765334af33a45d9d63 Author: Darren Tucker Date: Sun Feb 12 15:45:15 2017 +1100 ifdef out EVP_R_PRIVATE_KEY_DECODE_ERROR EVP_R_PRIVATE_KEY_DECODE_ERROR was added in OpenSSL 1.0.0 so ifdef out for the benefit of OpenSSL versions prior to that. commit 155d540d00ff55f063421ec182ec8ff2b7ab6cbe Author: djm@openbsd.org Date: Fri Feb 10 04:34:50 2017 +0000 upstream commit bring back r1.34 that was backed out for problems loading public keys: translate OpenSSL error codes to something more meaninful; bz#2522 reported by Jakub Jelen, ok dtucker@ with additional fix from Jakub Jelen to solve the backout. bz#2525 bz#2523 re-ok dtucker@ Upstream-ID: a9d5bc0306f4473d9b4f4484f880e95f3c1cc031 commit a287c5ad1e0bf9811c7b9221979b969255076019 Author: djm@openbsd.org Date: Fri Feb 10 03:36:40 2017 +0000 upstream commit Sanitise escape sequences in key comments sent to printf but preserve valid UTF-8 when the locale supports it; bz#2520 ok dtucker@ Upstream-ID: e8eed28712ba7b22d49be534237eed019875bd1e commit e40269be388972848aafcca7060111c70aab5b87 Author: millert@openbsd.org Date: Wed Feb 8 20:32:43 2017 +0000 upstream commit Avoid printf %s NULL. From semarie@, OK djm@ Upstream-ID: 06beef7344da0208efa9275d504d60d2a5b9266c commit 5b90709ab8704dafdb31e5651073b259d98352bc Author: djm@openbsd.org Date: Mon Feb 6 09:22:51 2017 +0000 upstream commit Restore \r\n newline sequence for server ident string. The CR got lost in the flensing of SSHv1. Pointed out by Stef Bon Upstream-ID: 5333fd43ce5396bf5999496096fac5536e678fac commit 97c31c46ee2e6b46dfffdfc4f90bbbf188064cbc Author: djm@openbsd.org Date: Fri Feb 3 23:01:42 2017 +0000 upstream commit unit test for match_filter_list() function; still want a better name for this... Upstream-Regress-ID: 840ad6118552c35111f0a897af9c8d93ab8de92a commit f1a193464a7b77646f0d0cedc929068e4a413ab4 Author: djm@openbsd.org Date: Fri Feb 3 23:05:57 2017 +0000 upstream commit use ssh_packet_set_log_preamble() to include connection username in packet log messages, e.g. Connection closed by invalid user foo 10.1.1.1 port 44056 [preauth] ok markus@ bz#113 Upstream-ID: 3591b88bdb5416d6066fb3d49d8fff2375bf1a15 commit 07edd7e9537ab32aa52abb5fb2a915c350fcf441 Author: djm@openbsd.org Date: Fri Feb 3 23:03:33 2017 +0000 upstream commit add ssh_packet_set_log_preamble() to allow inclusion of a preamble string in disconnect messages; ok markus@ Upstream-ID: 34cb41182cd76d414c214ccb01c01707849afead commit 68bc8cfa7642d3ccbf2cd64281c16b8b9205be59 Author: djm@openbsd.org Date: Fri Feb 3 23:01:19 2017 +0000 upstream commit support =- for removing methods from algorithms lists, e.g. Ciphers=-*cbc; suggested by Cristian Ionescu-Idbohrn in bz#2671 "I like it" markus@ Upstream-ID: c78c38f9f81a963b33d0eade559f6048add24a6d commit c924b2ef941028a1f31e6e94f54dfeeeef462a4e Author: djm@openbsd.org Date: Fri Feb 3 05:05:56 2017 +0000 upstream commit allow form-feed characters at EOL; bz#2431 ok dtucker@ Upstream-ID: 1f453afaba6da2ae69d6afdf1ae79a917552f1a2 commit 523db8540b720c4d21ab0ff6f928476c70c38aab Author: Damien Miller Date: Fri Feb 3 16:01:22 2017 +1100 prefer to use ldns-config to find libldns Should fix bz#2603 - "Build with ldns and without kerberos support fails if ldns compiled with kerberos support" by including correct cflags/libs ok dtucker@ commit c998bf0afa1a01257a53793eba57941182e9e0b7 Author: dtucker@openbsd.org Date: Fri Feb 3 02:56:00 2017 +0000 upstream commit Make ssh_packet_set_rekey_limits take u32 for the number of seconds until rekeying (negative values are rejected at config parse time). This allows the removal of some casts and a signed vs unsigned comparison warning. rekey_time is cast to int64 for the comparison which is a no-op on OpenBSD, but should also do the right thing in -portable on anything still using 32bit time_t (until the system time actually wraps, anyway). some early guidance deraadt@, ok djm@ Upstream-ID: c9f18613afb994a07e7622eb326f49de3d123b6c commit 3ec5fa4ba97d4c4853620daea26a33b9f1fe3422 Author: jsg@openbsd.org Date: Thu Feb 2 10:54:25 2017 +0000 upstream commit In vasnmprintf() return an error if malloc fails and don't set a function argument to the address of free'd memory. ok djm@ Upstream-ID: 1efffffff2f51d53c9141f245b90ac23d33b9779 commit 858252fb1d451ebb0969cf9749116c8f0ee42753 Author: dtucker@openbsd.org Date: Wed Feb 1 02:59:09 2017 +0000 upstream commit Return true reason for port forwarding failures where feasible rather than always "administratively prohibited". bz#2674, ok djm@ Upstream-ID: d901d9887951774e604ca970e1827afaaef9e419 commit 6ba9f893838489add6ec4213c7a997b425e4a9e0 Author: dtucker@openbsd.org Date: Mon Jan 30 23:27:39 2017 +0000 upstream commit Small correction to the known_hosts section on when it is updated. Patch from lkppo at free.fr some time ago, pointed out by smallm at sdf.org Upstream-ID: 1834d7af179dea1a12ad2137f84566664af225d5 commit c61d5ec3c11e7ff9779b6127421d9f166cf10915 Author: Darren Tucker Date: Fri Feb 3 14:10:34 2017 +1100 Remove _XOPEN_SOURCE from wide char detection. Having _XOPEN_SOURCE unconditionally causes problems on some platforms and configurations, notably Solaris 64-bit binaries. It was there for the benefit of Linux put the required bits in the *-*linux* section. Patch from yvoinov at gmail.com. commit f25ee13b3e81fd80efeb871dc150fe49d7fc8afd Author: djm@openbsd.org Date: Mon Jan 30 05:22:14 2017 +0000 upstream commit fully unbreak: some $SSH invocations did not have -F specified and could pick up the ~/.ssh/config of the user running the tests Upstream-Regress-ID: f362d1892c0d3e66212d5d3fc02d915c58ef6b89 commit 6956e21fb26652887475fe77ea40d2efcf25908b Author: djm@openbsd.org Date: Mon Jan 30 04:54:07 2017 +0000 upstream commit partially unbreak: was not specifying hostname on some $SSH invocations Upstream-Regress-ID: bc8a5e98e57bad0a92ef4f34ed91c1d18294e2cc commit 52763dd3fe0a4678dafdf7aeb32286e514130afc Author: djm@openbsd.org Date: Mon Jan 30 01:03:00 2017 +0000 upstream commit revise keys/principals command hang fix (bz#2655) to consume entire output, avoiding sending SIGPIPE to subprocesses early; ok dtucker@ Upstream-ID: 7cb04b31a61f8c78c4e48ceededcd2fd5c4ee1bc commit 381a2615a154a82c4c53b787f4a564ef894fe9ac Author: djm@openbsd.org Date: Mon Jan 30 00:38:50 2017 +0000 upstream commit small cleanup post SSHv1 removal: remove SSHv1-isms in commented examples reorder token table to group deprecated and compile-time conditional tokens better fix config dumping code for some compile-time conditional options that weren't being correctly skipped (SSHv1 and PKCS#11) Upstream-ID: f2e96b3cb3158d857c5a91ad2e15925df3060105 commit 4833d01591b7eb049489d9558b65f5553387ed43 Author: djm@openbsd.org Date: Mon Jan 30 00:34:01 2017 +0000 upstream commit some explicit NULL tests when dumping configured forwardings; from Karsten Weiss Upstream-ID: 40957b8dea69672b0e50df6b4a91a94e3e37f72d commit 326e2fae9f2e3e067b5651365eba86b35ee5a6b2 Author: djm@openbsd.org Date: Mon Jan 30 00:32:28 2017 +0000 upstream commit misplaced braces in test; from Karsten Weiss Upstream-ID: f7b794074d3aae8e35b69a91d211c599c94afaae commit 3e032a95e46bfaea9f9e857678ac8fa5f63997fb Author: djm@openbsd.org Date: Mon Jan 30 00:32:03 2017 +0000 upstream commit don't dereference authctxt before testing != NULL, it causes compilers to make assumptions; from Karsten Weiss Upstream-ID: 794243aad1e976ebc717885b7a97a25e00c031b2 commit 01cfaa2b1cfb84f3cdd32d1bf82b120a8d30e057 Author: djm@openbsd.org Date: Fri Jan 6 02:51:16 2017 +0000 upstream commit use correct ssh-add program; bz#2654, from Colin Watson Upstream-Regress-ID: 7042a36e1bdaec6562f6e57e9d047efe9c7a6030 commit e5c7ec67cdc42ae2584085e0fc5cc5ee91133cf5 Author: dtucker@openbsd.org Date: Fri Jan 6 02:26:10 2017 +0000 upstream commit Account for timeouts in the integrity tests as failures. If the first test in a series for a given MAC happens to modify the low bytes of a packet length, then ssh will time out and this will be interpreted as a test failure. Patch from cjwatson at debian.org via bz#2658. Upstream-Regress-ID: e7467613b0badedaa300bc6fc7495ec2f44e2fb9 commit dbaf599b61bd6e0f8469363a8c8e7f633b334018 Author: dtucker@openbsd.org Date: Fri Jan 6 02:09:25 2017 +0000 upstream commit Make forwarding test less racy by using unix domain sockets instead of TCP ports where possible. Patch from cjwatson at debian.org via bz#2659. Upstream-Regress-ID: 4756375aac5916ef9d25452a1c1d5fa9e90299a9 commit 9390b0031ebd6eb5488d3bc4d4333c528dffc0a6 Author: dtucker@openbsd.org Date: Sun Jan 29 21:35:23 2017 +0000 upstream commit Fix typo in ~C error message for bad port forward cancellation. bz#2672, from Brad Marshall via Colin Watson and Ubuntu's bugtracker. Upstream-ID: 0d4a7e5ead6cc59c9a44b4c1e5435ab3aada09af commit 4ba15462ca38883b8a61a1eccc093c79462d5414 Author: guenther@openbsd.org Date: Sat Jan 21 11:32:04 2017 +0000 upstream commit The POSIX APIs that that sockaddrs all ignore the s*_len field in the incoming socket, so userspace doesn't need to set it unless it has its own reasons for tracking the size along with the sockaddr. ok phessler@ deraadt@ florian@ Upstream-ID: ca6e49e2f22f2b9e81d6d924b90ecd7e422e7437 commit a1187bd3ef3e4940af849ca953a1b849dae78445 Author: jmc@openbsd.org Date: Fri Jan 6 16:28:12 2017 +0000 upstream commit keep the tokens list sorted; Upstream-ID: b96239dae4fb3aa94146bb381afabcc7740a1638 commit b64077f9767634715402014f509e58decf1e140d Author: djm@openbsd.org Date: Fri Jan 6 09:27:52 2017 +0000 upstream commit fix previous Upstream-ID: c107d6a69bc22325d79fbf78a2a62e04bcac6895 commit 5e820e9ea2e949aeb93071fe31c80b0c42f2b2de Author: djm@openbsd.org Date: Fri Jan 6 03:53:58 2017 +0000 upstream commit show a useful error message when included config files can't be opened; bz#2653, ok dtucker@ Upstream-ID: f598b73b5dfe497344cec9efc9386b4e5a3cb95b commit 13bd2e2d622d01dc85d22b94520a5b243d006049 Author: djm@openbsd.org Date: Fri Jan 6 03:45:41 2017 +0000 upstream commit sshd_config is documented to set GSSAPIStrictAcceptorCheck=yes by default, so actually make it do this. bz#2637 ok dtucker Upstream-ID: 99ef8ac51f17f0f7aec166cb2e34228d4d72a665 commit f89b928534c9e77f608806a217d39a2960cc7fd0 Author: djm@openbsd.org Date: Fri Jan 6 03:41:58 2017 +0000 upstream commit Avoid confusing error message when attempting to use ssh-keyscan built without SSH protocol v.1 to scan for v.1 keys; bz#2583 Upstream-ID: 5d214abd3a21337d67c6dcc5aa6f313298d0d165 commit 0999533014784579aa6f01c2d3a06e3e8804b680 Author: dtucker@openbsd.org Date: Fri Jan 6 02:34:54 2017 +0000 upstream commit Re-add '%k' token for AuthorizedKeysCommand which was lost during the re-org in rev 1.235. bz#2656, from jboning at gmail.com. Upstream-ID: 2884e203c02764d7b3fe7472710d9c24bdc73e38 commit 51045869fa084cdd016fdd721ea760417c0a3bf3 Author: djm@openbsd.org Date: Wed Jan 4 05:37:40 2017 +0000 upstream commit unbreak Unix domain socket forwarding for root; ok markus@ Upstream-ID: 6649c76eb7a3fa15409373295ca71badf56920a2 commit 58fca12ba967ea5c768653535604e1522d177e44 Author: Darren Tucker Date: Mon Jan 16 09:08:32 2017 +1100 Remove LOGIN_PROGRAM. UseLogin is gone, remove leftover. bz#2665, from cjwatson at debian.org commit b108ce92aae0ca0376dce9513d953be60e449ae1 Author: djm@openbsd.org Date: Wed Jan 4 02:21:43 2017 +0000 upstream commit relax PKCS#11 whitelist a bit to allow libexec as well as lib directories. Upstream-ID: cf5617958e2e2d39f8285fd3bc63b557da484702 commit c7995f296b9222df2846f56ecf61e5ae13d7a53d Author: djm@openbsd.org Date: Tue Jan 3 05:46:51 2017 +0000 upstream commit check number of entries in SSH2_FXP_NAME response; avoids unreachable overflow later. Reported by Jann Horn Upstream-ID: b6b2b434a6d6035b1644ca44f24cd8104057420f commit ddd3d34e5c7979ca6f4a3a98a7d219a4ed3d98c2 Author: djm@openbsd.org Date: Fri Dec 30 22:08:02 2016 +0000 upstream commit fix deadlock when keys/principals command produces a lot of output and a key is matched early; bz#2655, patch from jboning AT gmail.com Upstream-ID: e19456429bf99087ea994432c16d00a642060afe commit 30eee7d1b2fec33c14870cc11910610be5d2aa6f Author: Darren Tucker Date: Tue Dec 20 12:16:11 2016 +1100 Re-add missing "Prerequisites" header and fix typo Patch from HARUYAMA Seigo . commit c8c60f3663165edd6a52632c6ddbfabfce1ca865 Author: djm@openbsd.org Date: Mon Dec 19 22:35:23 2016 +0000 upstream commit use standard /bin/sh equality test; from Mike Frysinger Upstream-Regress-ID: 7b6f0b63525f399844c8ac211003acb8e4b0bec2 commit 4a354fc231174901f2629437c2a6e924a2dd6772 Author: Damien Miller Date: Mon Dec 19 15:59:26 2016 +1100 crank version numbers for release commit 5f8d0bb8413d4d909cc7aa3c616fb0538224c3c9 Author: djm@openbsd.org Date: Mon Dec 19 04:55:51 2016 +0000 upstream commit openssh-7.4 Upstream-ID: 1ee404adba6bbe10ae9277cbae3a94abe2867b79 commit 3a8213ea0ed843523e34e55ab9c852332bab4c7b Author: djm@openbsd.org Date: Mon Dec 19 04:55:18 2016 +0000 upstream commit remove testcase that depends on exact output and behaviour of snprintf(..., "%s", NULL) Upstream-Regress-ID: cab4288531766bd9593cb556613b91a2eeefb56f commit eae735a82d759054f6ec7b4e887fb7a5692c66d7 Author: dtucker@openbsd.org Date: Mon Dec 19 03:32:57 2016 +0000 upstream commit Use LOGNAME to get current user and fall back to whoami if not set. Mainly to benefit -portable since some platforms don't have whoami. Upstream-Regress-ID: e3a16b7836a3ae24dc8f8a4e43fdf8127a60bdfa commit 0d2f88428487518eea60602bd593989013831dcf Author: dtucker@openbsd.org Date: Fri Dec 16 03:51:19 2016 +0000 upstream commit Add regression test for AllowUsers and DenyUsers. Patch from Zev Weiss Upstream-Regress-ID: 8f1aac24d52728398871dac14ad26ea38b533fb9 commit 3bc8180a008929f6fe98af4a56fb37d04444b417 Author: Darren Tucker Date: Fri Dec 16 15:02:24 2016 +1100 Add missing monitor.h include. Fixes warning pointed out by Zev Weiss commit 410681f9015d76cc7b137dd90dac897f673244a0 Author: djm@openbsd.org Date: Fri Dec 16 02:48:55 2016 +0000 upstream commit revert to rev1.2; the new bits in this test depend on changes to ssh that aren't yet committed Upstream-Regress-ID: 828ffc2c7afcf65d50ff2cf3dfc47a073ad39123 commit 2f2ffa4fbe4b671bbffa0611f15ba44cff64d58e Author: dtucker@openbsd.org Date: Fri Dec 16 01:06:27 2016 +0000 upstream commit Move the "stop sshd" code into its own helper function. Patch from Zev Weiss , ok djm@ Upstream-Regress-ID: a113dea77df5bd97fb4633ea31f3d72dbe356329 commit e15e7152331e3976b35475fd4e9c72897ad0f074 Author: djm@openbsd.org Date: Fri Dec 16 01:01:07 2016 +0000 upstream commit regression test for certificates along with private key with no public half. bz#2617, mostly from Adam Eijdenberg Upstream-Regress-ID: 2e74dc2c726f4dc839609b3ce045466b69f01115 commit 9a70ec085faf6e55db311cd1a329f1a35ad2a500 Author: dtucker@openbsd.org Date: Thu Dec 15 23:50:37 2016 +0000 upstream commit Use $SUDO to read pidfile in case root's umask is restricted. From portable. Upstream-Regress-ID: f6b1c7ffbc5a0dfb7d430adb2883344899174a98 commit fe06b68f824f8f55670442fb31f2c03526dd326c Author: dtucker@openbsd.org Date: Thu Dec 15 21:29:05 2016 +0000 upstream commit Add missing braces in DenyUsers code. Patch from zev at bewilderbeest.net, ok deraadt@ Upstream-ID: d747ace338dcf943b077925f90f85f789714b54e commit dcc7d74242a574fd5c4afbb4224795b1644321e7 Author: dtucker@openbsd.org Date: Thu Dec 15 21:20:41 2016 +0000 upstream commit Fix text in error message. Patch from zev at bewilderbeest.net. Upstream-ID: deb0486e175e7282f98f9a15035d76c55c84f7f6 commit b737e4d7433577403a31cff6614f6a1b0b5e22f4 Author: djm@openbsd.org Date: Wed Dec 14 00:36:34 2016 +0000 upstream commit disable Unix-domain socket forwarding when privsep is disabled Upstream-ID: ab61516ae0faadad407857808517efa900a0d6d0 commit 08a1e7014d65c5b59416a0e138c1f73f417496eb Author: djm@openbsd.org Date: Fri Dec 9 03:04:29 2016 +0000 upstream commit log connections dropped in excess of MaxStartups at verbose LogLevel; bz#2613 based on diff from Tomas Kuthan; ok dtucker@ Upstream-ID: 703ae690dbf9b56620a6018f8a3b2389ce76d92b commit 10e290ec00964b2bf70faab15a10a5574bb80527 Author: Darren Tucker Date: Tue Dec 13 13:51:32 2016 +1100 Get default of TEST_SSH_UTF8 from environment. commit b9b8ba3f9ed92c6220b58d70d1e6d8aa3eea1104 Author: Darren Tucker Date: Tue Dec 13 12:56:40 2016 +1100 Remove commented-out includes. These commented-out includes have "Still needed?" comments. Since they've been commented out for ~13 years I assert that they're not. commit 25275f1c9d5f01a0877d39444e8f90521a598ea0 Author: Darren Tucker Date: Tue Dec 13 12:54:23 2016 +1100 Add prototype for strcasestr in compat library. commit afec07732aa2985142f3e0b9a01eb6391f523dec Author: Darren Tucker Date: Tue Dec 13 10:23:03 2016 +1100 Add strcasestr to compat library. Fixes build on (at least) Solaris 10. commit dda78a03af32e7994f132d923c2046e98b7c56c8 Author: Damien Miller Date: Mon Dec 12 13:57:10 2016 +1100 Force Turkish locales back to C/POSIX; bz#2643 Turkish locales are unique in their handling of the letters 'i' and 'I' (yes, they are different letters) and OpenSSH isn't remotely prepared to deal with that. For now, the best we can do is to force OpenSSH to use the C/POSIX locale and try to preserve the UTF-8 encoding if possible. ok dtucker@ commit c35995048f41239fc8895aadc3374c5f75180554 Author: Darren Tucker Date: Fri Dec 9 12:52:02 2016 +1100 exit is in stdlib.h not unistd.h (that's _exit). commit d399a8b914aace62418c0cfa20341aa37a192f98 Author: Darren Tucker Date: Fri Dec 9 12:33:25 2016 +1100 Include for exit in utf8 locale test. commit 47b8c99ab3221188ad3926108dd9d36da3b528ec Author: Darren Tucker Date: Thu Dec 8 15:48:34 2016 +1100 Check for utf8 local support before testing it. Check for utf8 local support and if not found, do not attempt to run the utf8 tests. Suggested by djm@ commit 4089fc1885b3a2822204effbb02b74e3da58240d Author: Darren Tucker Date: Thu Dec 8 12:57:24 2016 +1100 Use AC_PATH_TOOL for krb5-config. This will use the host-prefixed version when cross compiling; patch from david.michael at coreos.com. commit b4867e0712c89b93be905220c82f0a15e6865d1e Author: djm@openbsd.org Date: Tue Dec 6 07:48:01 2016 +0000 upstream commit make IdentityFile successfully load and use certificates that have no corresponding bare public key. E.g. just a private id_rsa and certificate id_rsa-cert.pub (and no id_rsa.pub). bz#2617 ok dtucker@ Upstream-ID: c1e9699b8c0e3b63cc4189e6972e3522b6292604 commit c9792783a98881eb7ed295680013ca97a958f8ac Author: Damien Miller Date: Fri Nov 25 14:04:21 2016 +1100 Add a gnome-ssh-askpass3 target for GTK+3 version Based on patch from Colin Watson via bz#2640 commit 7be85ae02b9de0993ce0a1d1e978e11329f6e763 Author: Damien Miller Date: Fri Nov 25 14:03:53 2016 +1100 Make gnome-ssh-askpass2.c GTK+3-friendly Patch from Colin Watson via bz#2640 commit b9844a45c7f0162fd1b5465683879793d4cc4aaa Author: djm@openbsd.org Date: Sun Dec 4 23:54:02 2016 +0000 upstream commit Fix public key authentication when multiple authentication is in use. Instead of deleting and re-preparing the entire keys list, just reset the 'used' flags; the keys list is already in a good order (with already- tried keys at the back) Analysis and patch from Vincent Brillault on bz#2642; ok dtucker@ Upstream-ID: 7123f12dc2f3bcaae715853035a97923d7300176 commit f2398eb774075c687b13af5bc22009eb08889abe Author: dtucker@openbsd.org Date: Sun Dec 4 22:27:25 2016 +0000 upstream commit Unlink PidFile on SIGHUP and always recreate it when the new sshd starts. Regression tests (and possibly other things) depend on the pidfile being recreated after SIGHUP, and unlinking it means it won't contain a stale pid if sshd fails to restart. ok djm@ markus@ Upstream-ID: 132dd6dda0c77dd49d2f15b2573b5794f6160870 commit 85aa2efeba51a96bf6834f9accf2935d96150296 Author: djm@openbsd.org Date: Wed Nov 30 03:01:33 2016 +0000 upstream commit test new behaviour of cert force-command restriction vs. authorized_key/ principals Upstream-Regress-ID: 399efa7469d40c404c0b0a295064ce75d495387c commit 5d333131cd8519d022389cfd3236280818dae1bc Author: jmc@openbsd.org Date: Wed Nov 30 06:54:26 2016 +0000 upstream commit tweak previous; while here fix up FILES and AUTHORS; Upstream-ID: 93f6e54086145a75df8d8ec7d8689bdadbbac8fa commit 786d5994da79151180cb14a6cf157ebbba61c0cc Author: djm@openbsd.org Date: Wed Nov 30 03:07:37 2016 +0000 upstream commit add a whitelist of paths from which ssh-agent will load (via ssh-pkcs11-helper) a PKCS#11 module; ok markus@ Upstream-ID: fe79769469d9cd6d26fe0dc15751b83ef2a06e8f commit 7844f357cdd90530eec81340847783f1f1da010b Author: djm@openbsd.org Date: Wed Nov 30 03:00:05 2016 +0000 upstream commit Add a sshd_config DisableForwaring option that disables X11, agent, TCP, tunnel and Unix domain socket forwarding, as well as anything else we might implement in the future. This, like the 'restrict' authorized_keys flag, is intended to be a simple and future-proof way of restricting an account. Suggested as a complement to 'restrict' by Jann Horn; ok markus@ Upstream-ID: 203803f66e533a474086b38a59ceb4cf2410fcf7 commit fd6dcef2030d23c43f986d26979f84619c10589d Author: djm@openbsd.org Date: Wed Nov 30 02:57:40 2016 +0000 upstream commit When a forced-command appears in both a certificate and an authorized keys/principals command= restriction, refuse to accept the certificate unless they are identical. The previous (documented) behaviour of having the certificate forced- command override the other could be a bit confused and more error-prone. Pointed out by Jann Horn of Project Zero; ok dtucker@ Upstream-ID: 79d811b6eb6bbe1221bf146dde6928f92d2cd05f commit 7fc4766ac78abae81ee75b22b7550720bfa28a33 Author: dtucker@openbsd.org Date: Wed Nov 30 00:28:31 2016 +0000 upstream commit On startup, check to see if sshd is already daemonized and if so, skip the call to daemon() and do not rewrite the PidFile. This means that when sshd re-execs itself on SIGHUP the process ID will no longer change. Should address bz#2641. ok djm@ markus@. Upstream-ID: 5ea0355580056fb3b25c1fd6364307d9638a37b9 commit c9f880c195c65f1dddcbc4ce9d6bfea7747debcc Author: Damien Miller Date: Wed Nov 30 13:51:49 2016 +1100 factor out common PRNG reseed before privdrop Add a call to RAND_poll() to ensure than more than pid+time gets stirred into child processes states. Prompted by analysis from Jann Horn at Project Zero. ok dtucker@ commit 79e4829ec81dead1b30999e1626eca589319a47f Author: dtucker@openbsd.org Date: Fri Nov 25 03:02:01 2016 +0000 upstream commit Allow PuTTY interop tests to run unattended. bz#2639, patch from cjwatson at debian.org. Upstream-Regress-ID: 4345253558ac23b2082aebabccd48377433b6fe0 commit 504c3a9a1bf090f6b27260fc3e8ea7d984d163dc Author: dtucker@openbsd.org Date: Fri Nov 25 02:56:49 2016 +0000 upstream commit Reverse args to sshd-log-wrapper. Matches change in portable, where it allows sshd do be optionally run under Valgrind. Upstream-Regress-ID: b438d1c6726dc5caa2a45153e6103a0393faa906 commit bd13017736ec2f8f9ca498fe109fb0035f322733 Author: dtucker@openbsd.org Date: Fri Nov 25 02:49:18 2016 +0000 upstream commit Fix typo in trace message; from portable. Upstream-Regress-ID: 4c4a2ba0d37faf5fd230a91b4c7edb5699fbd73a commit 7da751d8b007c7f3e814fd5737c2351440d78b4c Author: tb@openbsd.org Date: Tue Nov 1 13:43:27 2016 +0000 upstream commit Clean up MALLOC_OPTIONS. For the unittests, move MALLOC_OPTIONS and TEST_ENV to unittets/Makefile.inc. ok otto Upstream-Regress-ID: 890d497e0a38eeddfebb11cc429098d76cf29f12 commit 36f58e68221bced35e06d1cca8d97c48807a8b71 Author: tb@openbsd.org Date: Mon Oct 31 23:45:08 2016 +0000 upstream commit Remove the obsolete A and P flags from MALLOC_OPTIONS. ok dtucker Upstream-Regress-ID: 6cc25024c8174a87e5734a0dc830194be216dd59 commit b0899ee26a6630883c0f2350098b6a35e647f512 Author: dtucker@openbsd.org Date: Tue Nov 29 03:54:50 2016 +0000 upstream commit Factor out code to disconnect from controlling terminal into its own function. ok djm@ Upstream-ID: 39fd9e8ebd7222615a837312face5cc7ae962885 commit 54d022026aae4f53fa74cc636e4a032d9689b64d Author: djm@openbsd.org Date: Fri Nov 25 23:24:45 2016 +0000 upstream commit use sshbuf_allocate() to pre-allocate the buffer used for loading keys. This avoids implicit realloc inside the buffer code, which might theoretically leave fragments of the key on the heap. This doesn't appear to happen in practice for normal sized keys, but was observed for novelty oversize ones. Pointed out by Jann Horn of Project Zero; ok markus@ Upstream-ID: d620e1d46a29fdea56aeadeda120879eddc60ab1 commit a9c746088787549bb5b1ae3add7d06a1b6d93d5e Author: djm@openbsd.org Date: Fri Nov 25 23:22:04 2016 +0000 upstream commit split allocation out of sshbuf_reserve() into a separate sshbuf_allocate() function; ok markus@ Upstream-ID: 11b8a2795afeeb1418d508a2c8095b3355577ec2 commit f0ddedee460486fa0e32fefb2950548009e5026e Author: markus@openbsd.org Date: Wed Nov 23 23:14:15 2016 +0000 upstream commit allow ClientAlive{Interval,CountMax} in Match; ok dtucker, djm Upstream-ID: 8beb4c1eadd588f1080b58932281983864979f55 commit 1a6f9d2e2493d445cd9ee496e6e3c2a2f283f66a Author: djm@openbsd.org Date: Tue Nov 8 22:04:34 2016 +0000 upstream commit unbreak DenyUsers; reported by henning@ Upstream-ID: 1c67d4148f5e953c35acdb62e7c08ae8e33f7cb2 commit 010359b32659f455fddd2bd85fd7cc4d7a3b994a Author: djm@openbsd.org Date: Sun Nov 6 05:46:37 2016 +0000 upstream commit Validate address ranges for AllowUser/DenyUsers at configuration load time and refuse to accept bad ones. It was previously possible to specify invalid CIDR address ranges (e.g. djm@127.1.2.3/55) and these would always match. Thanks to Laurence Parry for a detailed bug report. ok markus (for a previous diff version) Upstream-ID: 9dfcdd9672b06e65233ea4434c38226680d40bfb commit efb494e81d1317209256b38b49f4280897c61e69 Author: djm@openbsd.org Date: Fri Oct 28 03:33:52 2016 +0000 upstream commit Improve pkcs11_add_provider() logging: demote some excessively verbose error()s to debug()s, include PKCS#11 provider name and slot in log messages where possible. bz#2610, based on patch from Jakub Jelen Upstream-ID: 3223ef693cfcbff9079edfc7e89f55bf63e1973d commit 5ee3fb5affd7646f141749483205ade5fc54adaf Author: Darren Tucker Date: Tue Nov 1 08:12:33 2016 +1100 Use ptrace(PT_DENY_ATTACH, ..) on OS X. commit 315d2a4e674d0b7115574645cb51f968420ebb34 Author: Damien Miller Date: Fri Oct 28 14:34:07 2016 +1100 Unbreak AES-CTR ciphers on old (~0.9.8) OpenSSL ok dtucker@ commit a9ff3950b8e80ff971b4d44bbce96df27aed28af Author: Darren Tucker Date: Fri Oct 28 14:26:58 2016 +1100 Move OPENSSL_NO_RIPEMD160 to compat. Move OPENSSL_NO_RIPEMD160 to compat and add ifdefs to mac.c around the ripemd160 MACs. commit bce58885160e5db2adda3054c3b81fe770f7285a Author: Darren Tucker Date: Fri Oct 28 13:52:31 2016 +1100 Check if RIPEMD160 is disabled in OpenSSL. commit d924640d4c355d1b5eca1f4cc60146a9975dbbff Author: Darren Tucker Date: Fri Oct 28 13:38:19 2016 +1100 Skip ssh1 specfic ciphers. cipher-3des1.c and cipher-bf1.c are specific to sshv1 so don't even try to compile them when Protocol 1 is not enabled. commit 79d078e7a49caef746516d9710ec369ba45feab6 Author: jsg@openbsd.org Date: Tue Oct 25 04:08:13 2016 +0000 upstream commit Fix logic in add_local_forward() that inverted a test when code was refactored out into bind_permitted(). This broke ssh port forwarding for non-priv ports as a non root user. ok dtucker@ 'looks good' deraadt@ Upstream-ID: ddb8156ca03cc99997de284ce7777536ff9570c9 commit a903e315dee483e555c8a3a02c2946937f9b4e5d Author: dtucker@openbsd.org Date: Mon Oct 24 01:09:17 2016 +0000 upstream commit Remove dead breaks, found via opencoverage.net. ok deraadt@ Upstream-ID: ad9cc655829d67fad219762810770787ba913069 commit b4e96b4c9bea4182846e4942ba2048e6d708ee54 Author: Darren Tucker Date: Wed Oct 26 08:43:25 2016 +1100 Use !=NULL instead of >0 for getdefaultproj. getdefaultproj() returns a pointer so test it for NULL inequality instead of >0. Fixes compiler warning and is more correct. Patch from David Binderman. commit 1c4ef0b808d3d38232aeeb1cebb7e9a43def42c5 Author: dtucker@openbsd.org Date: Sun Oct 23 22:04:05 2016 +0000 upstream commit Factor out "can bind to low ports" check into its own function. This will make it easier for Portable to support platforms with permissions models other than uid==0 (eg bz#2625). ok djm@, "doesn't offend me too much" deraadt@. Upstream-ID: 86213df4183e92b8f189a6d2dac858c994bfface commit 0b9ee623d57e5de7e83e66fd61a7ba9a5be98894 Author: dtucker@openbsd.org Date: Wed Oct 19 23:21:56 2016 +0000 upstream commit When tearing down ControlMaster connecctions, don't pollute stderr when LogLevel=quiet. Patch from Tim Kuijsten via tech@. Upstream-ID: d9b3a68b2a7c2f2fc7f74678e29a4618d55ceced commit 09e6a7d8354224933febc08ddcbc2010f542284e Author: Darren Tucker Date: Mon Oct 24 09:06:18 2016 +1100 Wrap stdint.h include in ifdef. commit 08d9e9516e587b25127545c029e5464b2e7f2919 Author: Darren Tucker Date: Fri Oct 21 09:46:46 2016 +1100 Fix formatting. commit 461f50e7ab8751d3a55e9158c44c13031db7ba1d Author: Darren Tucker Date: Fri Oct 21 06:55:58 2016 +1100 Update links to https. www.openssh.com now supports https and ftp.openbsd.org no longer supports ftp. Make all links to these https. commit dd4e7212a6141f37742de97795e79db51e4427ad Author: Darren Tucker Date: Fri Oct 21 06:48:46 2016 +1100 Update host key generation examples. Remove ssh1 host key generation, add ssh-keygen -A commit 6d49ae82634c67e9a4d4af882bee20b40bb8c639 Author: Darren Tucker Date: Fri Oct 21 05:22:55 2016 +1100 Update links. Make links to openssh.com HTTPS now that it's supported, point release notes link to the HTML release notes page, and update a couple of other links and bits of text. commit fe0d1ca6ace06376625084b004ee533f2c2ea9d6 Author: Darren Tucker Date: Thu Oct 20 03:42:09 2016 +1100 Remote channels .orig and .rej files. These files were incorrectly added during an OpenBSD sync. commit 246aa842a4ad368d8ce030495e657ef3a0e1f95c Author: dtucker@openbsd.org Date: Tue Oct 18 17:32:54 2016 +0000 upstream commit Remove channel_input_port_forward_request(); the only caller was the recently-removed SSH1 server code so it's now dead code. ok markus@ Upstream-ID: 05453983230a1f439562535fec2818f63f297af9 commit 2c6697c443d2c9c908260eed73eb9143223e3ec9 Author: millert@openbsd.org Date: Tue Oct 18 12:41:22 2016 +0000 upstream commit Install a signal handler for tty-generated signals and wait for the ssh child to suspend before suspending sftp. This lets ssh restore the terminal mode as needed when it is suspended at the password prompt. OK dtucker@ Upstream-ID: a31c1f42aa3e2985dcc91e46e6a17bd22e372d69 commit fd2a8f1033fa2316fff719fd5176968277560158 Author: jmc@openbsd.org Date: Sat Oct 15 19:56:25 2016 +0000 upstream commit various formatting fixes, specifically removing Dq; Upstream-ID: 81e85df2b8e474f5f93d66e61d9a4419ce87347c commit 8f866d8a57b9a2dc5dd04504e27f593b551618e3 Author: Darren Tucker Date: Wed Oct 19 03:26:09 2016 +1100 Import readpassphrase.c rev 1.26. Author: miller@openbsd.org: Avoid generate SIGTTOU when restoring the terminal mode. If we get SIGTTOU it means the process is not in the foreground process group which, in most cases, means that the shell has taken control of the tty. Requiring the user the fg the process in this case doesn't make sense and can result in both SIGTSTP and SIGTTOU being sent which can lead to the process being suspended again immediately after being brought into the foreground. commit f901440cc844062c9bab0183d133f7ccc58ac3a5 Author: Darren Tucker Date: Wed Oct 19 03:23:16 2016 +1100 Import readpassphrase.c rev 1.25. Wrap so internal calls go direct and readpassphrase is weak. (DEF_WEAK is a no-op in portable.) commit 032147b69527e5448a511049b2d43dbcae582624 Author: Darren Tucker Date: Sat Oct 15 05:51:12 2016 +1100 Move DEF_WEAK into defines.h. As well pull in more recent changes from OpenBSD these will start to arrive so put it where the definition is shared. commit e0259a82ddd950cfb109ddee86fcebbc09c6bd04 Author: Darren Tucker Date: Sat Oct 15 04:34:46 2016 +1100 Remove do_pam_set_tty which is dead code. The callers of do_pam_set_tty were removed in 2008, so this is now dead code. bz#2604, pointed out by jjelen at redhat.com. commit ca04de83f210959ad2ed870a30ba1732c3ae00e3 Author: Damien Miller Date: Thu Oct 13 18:53:43 2016 +1100 unbreak principals-command test Undo inconsistetly updated variable name. commit 1723ec92eb485ce06b4cbf49712d21975d873909 Author: djm@openbsd.org Date: Tue Oct 11 21:49:54 2016 +0000 upstream commit fix the KEX fuzzer - the previous method of obtaining the packet contents was broken. This now uses the new per-packet input hook, so it sees exact post-decrypt packets and doesn't have to pass packet integrity checks. ok markus@ Upstream-Regress-ID: 402fb6ffabd97de590e8e57b25788949dce8d2fd commit 09f997893f109799cddbfce6d7e67f787045cbb2 Author: natano@openbsd.org Date: Thu Oct 6 09:31:38 2016 +0000 upstream commit Move USER out of the way to unbreak the BUILDUSER mechanism. ok tb Upstream-Regress-ID: 74ab9687417dd071d62316eaadd20ddad1d5af3c commit 3049a012c482a7016f674db168f23fd524edce27 Author: bluhm@openbsd.org Date: Fri Sep 30 11:55:20 2016 +0000 upstream commit In ssh tests set REGRESS_FAIL_EARLY with ?= so that the environment can change it. OK djm@ Upstream-Regress-ID: 77bcb50e47b68c7209c7f0a5a020d73761e5143b commit 39af7b444db28c1cb01b7ea468a4f574a44f375b Author: djm@openbsd.org Date: Tue Oct 11 21:47:45 2016 +0000 upstream commit Add a per-packet input hook that is called with the decrypted packet contents. This will be used for fuzzing; ok markus@ Upstream-ID: a3221cee6b1725dd4ae1dd2c13841b4784cb75dc commit ec165c392ca54317dbe3064a8c200de6531e89ad Author: markus@openbsd.org Date: Mon Oct 10 19:28:48 2016 +0000 upstream commit Unregister the KEXINIT handler after message has been received. Otherwise an unauthenticated peer can repeat the KEXINIT and cause allocation of up to 128MB -- until the connection is closed. Reported by shilei-c at 360.cn Upstream-ID: 43649ae12a27ef94290db16d1a98294588b75c05 commit 29d40319392e6e19deeca9d45468aa1119846e50 Author: Darren Tucker Date: Thu Oct 13 04:07:20 2016 +1100 Import rev 1.24 from OpenBSD. revision 1.24 date: 2013/11/24 23:51:29; author: deraadt; state: Exp; lines: +4 -4; most obvious unsigned char casts for ctype ok jca krw ingo commit 12069e56221de207ed666c2449dedb431a2a7ca2 Author: Darren Tucker Date: Thu Oct 13 04:04:44 2016 +1100 Import rev 1.23 from OpenBSD. Fixes bz#2619. revision 1.23 date: 2010/05/14 13:30:34; author: millert; state: Exp; lines: +41 -39; Defer installing signal handlers until echo is disabled so that we get suspended normally when not the foreground process. Fix potential infinite loop when restoring terminal settings if process is in the background when restore occurs. OK miod@ commit 7508d83eff89af069760b4cc587305588a64e415 Author: Darren Tucker Date: Thu Oct 13 03:53:51 2016 +1100 If we don't have TCSASOFT, define it to zero. This makes it a no-op when we use it below, which allows us to re-sync those lines with the upstream and make future updates easier. commit aae4dbd4c058d3b1fe1eb5c4e6ddf35827271377 Author: jmc@openbsd.org Date: Fri Oct 7 14:41:52 2016 +0000 upstream commit tidy up the formatting in this file. more specifically, replace .Dq, which looks appalling, with .Cm, where appropriate; Upstream-ID: ff8e90aa0343d9bb56f40a535e148607973cc738 commit a571dbcc7b7b25371174569b13df5159bc4c6c7a Author: djm@openbsd.org Date: Tue Oct 4 21:34:40 2016 +0000 upstream commit add a comment about implicitly-expected checks to sshkey_ec_validate_public() Upstream-ID: 74a7f71c28f7c13a50f89fc78e7863b9cd61713f commit 2f78a2a698f4222f8e05cad57ac6e0c3d1faff00 Author: djm@openbsd.org Date: Fri Sep 30 20:24:46 2016 +0000 upstream commit fix some -Wpointer-sign warnings in the new mux proxy; ok markus@ Upstream-ID: b1ba7b3769fbc6b7f526792a215b0197f5e55dfd commit ca71c36645fc26fcd739a8cfdc702cec85607761 Author: bluhm@openbsd.org Date: Wed Sep 28 20:09:52 2016 +0000 upstream commit Add a makefile rule to create the ssh library when regress needs it. This allows to run the ssh regression tests without doing a "make build" before. Discussed with dtucker@ and djm@; OK djm@ Upstream-Regress-ID: ce489bd53afcd471225a125b4b94565d4717c025 commit ce44c970f913d2a047903dba8670554ac42fc479 Author: bluhm@openbsd.org Date: Mon Sep 26 21:34:38 2016 +0000 upstream commit Allow to run ssh regression tests as root. If the user is already root, the test should not expect that SUDO is set. If ssh needs another user, use sudo or doas to switch from root if necessary. OK dtucker@ Upstream-Regress-ID: b464e55185ac4303529e3e6927db41683aaeace2 commit 8d0578478586e283e751ca51e7b0690631da139a Author: markus@openbsd.org Date: Fri Sep 30 09:19:13 2016 +0000 upstream commit ssh proxy mux mode (-O proxy; idea from Simon Tatham): - mux client speaks the ssh-packet protocol directly over unix-domain socket. - mux server acts as a proxy, translates channel IDs and relays to the server. - no filedescriptor passing necessary. - combined with unix-domain forwarding it's even possible to run mux client and server on different machines. feedback & ok djm@ Upstream-ID: 666a2fb79f58e5c50e246265fb2b9251e505c25b commit b7689155f3f5c4999846c07a852b1c7a43b09cec Author: djm@openbsd.org Date: Wed Sep 28 21:44:52 2016 +0000 upstream commit put back some pre-auth zlib bits that I shouldn't have removed - they are still used by the client. Spotted by naddy@ Upstream-ID: 80919468056031037d56a1f5b261c164a6f90dc2 commit 4577adead6a7d600c8e764619d99477a08192c8f Author: djm@openbsd.org Date: Wed Sep 28 20:32:42 2016 +0000 upstream commit restore pre-auth compression support in the client -- the previous commit was intended to remove it from the server only. remove a few server-side pre-auth compression bits that escaped adjust wording of Compression directive in sshd_config(5) pointed out by naddy@ ok markus@ Upstream-ID: d23696ed72a228dacd4839dd9f2dec424ba2016b commit 80d1c963b4dc84ffd11d09617b39c4bffda08956 Author: jmc@openbsd.org Date: Wed Sep 28 17:59:22 2016 +0000 upstream commit use a separate TOKENS section, as we've done for sshd_config(5); help/ok djm Upstream-ID: 640e32b5e4838e4363738cdec955084b3579481d commit 1cfd5c06efb121e58e8b6671548fda77ef4b4455 Author: Damien Miller Date: Thu Sep 29 03:19:23 2016 +1000 Remove portability support for mmap We no longer need to wrap/replace mmap for portability now that pre-auth compression has been removed from OpenSSH. commit 0082fba4efdd492f765ed4c53f0d0fbd3bdbdf7f Author: djm@openbsd.org Date: Wed Sep 28 16:33:06 2016 +0000 upstream commit Remove support for pre-authentication compression. Doing compression early in the protocol probably seemed reasonable in the 1990s, but today it's clearly a bad idea in terms of both cryptography (cf. multiple compression oracle attacks in TLS) and attack surface. Moreover, to support it across privilege-separation zlib needed the assistance of a complex shared-memory manager that made the required attack surface considerably larger. Prompted by Guido Vranken pointing out a compiler-elided security check in the shared memory manager found by Stack (http://css.csail.mit.edu/stack/); ok deraadt@ markus@ NB. pre-auth authentication has been disabled by default in sshd for >10 years. Upstream-ID: 32af9771788d45a0779693b41d06ec199d849caf commit 27c3a9c2aede2184856b5de1e6eca414bb751c38 Author: djm@openbsd.org Date: Mon Sep 26 21:16:11 2016 +0000 upstream commit Avoid a theoretical signed integer overflow should BN_num_bytes() ever violate its manpage and return a negative value. Improve order of tests to avoid confusing increasingly pedantic compilers. Reported by Guido Vranken from stack (css.csail.mit.edu/stack) unstable optimisation analyser output. ok deraadt@ Upstream-ID: f8508c830c86d8f36c113985e52bf8eedae23505 commit 8663e51c80c6aa3d750c6d3bcff6ee05091922be Author: Damien Miller Date: Wed Sep 28 07:40:33 2016 +1000 fix mdoc2man.awk formatting for top-level lists Reported by Glenn Golden Diagnosis and fix from Ingo Schwarze commit b97739dc21570209ed9d4e7beee0c669ed23b097 Author: djm@openbsd.org Date: Thu Sep 22 21:15:41 2016 +0000 upstream commit missing bit from previous commit Upstream-ID: 438d5ed6338b28b46e822eb13eee448aca31df37 commit de6a175a99d22444e10d19ad3fffef39bc3ee3bb Author: jmc@openbsd.org Date: Thu Sep 22 19:19:01 2016 +0000 upstream commit organise the token stuff into a separate section; ok markus for an earlier version of the diff ok/tweaks djm Upstream-ID: 81a6daa506a4a5af985fce7cf9e59699156527c8 commit 16277fc45ffc95e4ffc3d45971ff8320b974de2b Author: djm@openbsd.org Date: Thu Sep 22 17:55:13 2016 +0000 upstream commit mention curve25519-sha256 KEX Upstream-ID: 33ae1f433ce4795ffa6203761fbdf86e0d7ffbaf commit 0493766d5676c7ca358824ea8d3c90f6047953df Author: djm@openbsd.org Date: Thu Sep 22 17:52:53 2016 +0000 upstream commit support plain curve25519-sha256 KEX algorithm now that it is approaching standardisation (same algorithm is currently supported as curve25519-sha256@libssh.org) Upstream-ID: 5e2b6db2e72667048cf426da43c0ee3fc777baa2 commit f31c654b30a6f02ce0b8ea8ab81791b675489628 Author: dtucker@openbsd.org Date: Thu Sep 22 02:29:57 2016 +0000 upstream commit If ssh receives a PACKET_DISCONNECT during userauth it will cause ssh_dispatch_run(DISPATCH_BLOCK, ...) to return without the session being authenticated. Check for this and exit if necessary. ok djm@ Upstream-ID: b3afe126c0839d2eae6cddd41ff2ba317eda0903 commit 1622649b7a829fc8dc313042a43a974f0f3e8a99 Author: djm@openbsd.org Date: Wed Sep 21 19:53:12 2016 +0000 upstream commit correctly return errors from kex_send_ext_info(). Fix from Sami Farin via https://github.com/openssh/openssh-portable/pull/50 Upstream-ID: c85999af28aaecbf92cfa2283381df81e839b42c commit f83a0cfe16c7a73627b46a9a94e40087d60f32fb Author: djm@openbsd.org Date: Wed Sep 21 17:44:20 2016 +0000 upstream commit cast uint64_t for printf Upstream-ID: 76d23e89419ccbd2320f92792a6d878211666ac1 commit 5f63ab474f58834feca4f35c498be03b7dd38a16 Author: djm@openbsd.org Date: Wed Sep 21 17:03:54 2016 +0000 upstream commit disable tests for affirmative negated match after backout of match change Upstream-Regress-ID: acebb8e5042f03d66d86a50405c46c4de0badcfd commit a5ad3a9db5a48f350f257a67b62fafd719ecb7e0 Author: djm@openbsd.org Date: Wed Sep 21 16:55:42 2016 +0000 upstream commit Revert two recent changes to negated address matching. The new behaviour offers unintuitive surprises. We'll find a better way to deal with single negated matches. match.c 1.31: > fix matching for pattern lists that contain a single negated match, > e.g. "Host !example" > > report and patch from Robin Becker. bz#1918 ok dtucker@ addrmatch.c 1.11: > fix negated address matching where the address list consists of a > single negated match, e.g. "Match addr !192.20.0.1" > > Report and patch from Jakub Jelen. bz#2397 ok dtucker@ Upstream-ID: ec96c770f0f5b9a54e5e72fda25387545e9c80c6 commit 119b7a2ca0ef2bf3f81897ae10301b8ca8cba844 Author: djm@openbsd.org Date: Wed Sep 21 01:35:12 2016 +0000 upstream commit test all the AuthorizedPrincipalsCommand % expansions Upstream-Regress-ID: 0a79a84dfaa59f958e46b474c3db780b454d30e3 commit bfa9d969ab6235d4938ce069d4db7e5825c56a19 Author: djm@openbsd.org Date: Wed Sep 21 01:34:45 2016 +0000 upstream commit add a way for principals command to get see key ID and serial too Upstream-ID: 0d30978bdcf7e8eaeee4eea1b030eb2eb1823fcb commit 920585b826af1c639e4ed78b2eba01fd2337b127 Author: djm@openbsd.org Date: Fri Sep 16 06:09:31 2016 +0000 upstream commit add a note on kexfuzz' limitations Upstream-Regress-ID: 03804d4a0dbc5163e1a285a4c8cc0a76a4e864ec commit 0445ff184080b196e12321998b4ce80b0f33f8d1 Author: djm@openbsd.org Date: Fri Sep 16 01:01:41 2016 +0000 upstream commit fix for newer modp DH groups (diffie-hellman-group14-sha256 etc) Upstream-Regress-ID: fe942c669959462b507516ae1634fde0725f1c68 commit 28652bca29046f62c7045e933e6b931de1d16737 Author: markus@openbsd.org Date: Mon Sep 19 19:02:19 2016 +0000 upstream commit move inbound NEWKEYS handling to kex layer; otherwise early NEWKEYS causes NULL deref; found by Robert Swiecki/honggfuzz; fixed with & ok djm@ Upstream-ID: 9a68b882892e9f51dc7bfa9f5a423858af358b2f commit 492710894acfcc2f173d14d1d45bd2e688df605d Author: natano@openbsd.org Date: Mon Sep 19 07:52:42 2016 +0000 upstream commit Replace two more arc4random() loops with arc4random_buf(). tweaks and ok dtucker ok deraadt Upstream-ID: 738d3229130ccc7eac975c190276ca6fcf0208e4 commit 1036356324fecc13099ac6e986b549f6219327d7 Author: tedu@openbsd.org Date: Sat Sep 17 18:00:27 2016 +0000 upstream commit replace two arc4random loops with arc4random_buf ok deraadt natano Upstream-ID: e18ede972d1737df54b49f011fa4f3917a403f48 commit 00df97ff68a49a756d4b977cd02283690f5dfa34 Author: djm@openbsd.org Date: Wed Sep 14 20:11:26 2016 +0000 upstream commit take fingerprint of correct key for AuthorizedPrincipalsCommand Upstream-ID: 553581a549cd6a3e73ce9f57559a325cc2cb1f38 commit e7907c1cb938b96dd33d27c2fea72c4e08c6b2f6 Author: djm@openbsd.org Date: Wed Sep 14 05:42:25 2016 +0000 upstream commit add %-escapes to AuthorizedPrincipalsCommand to match those supported for AuthorizedKeysCommand (key, key type, fingerprint, etc) and a few more to provide access to the certificate's CA key; 'looks ok' dtucker@ Upstream-ID: 6b00fd446dbebe67f4e4e146d2e492d650ae04eb commit 2b939c272a81c4d0c47badeedbcb2ba7c128ccda Author: dtucker@openbsd.org Date: Wed Sep 14 00:45:31 2016 +0000 upstream commit Improve test coverage of ssh-keygen -T a bit. Upstream-Regress-ID: 8851668c721bcc2b400600cfc5a87644cc024e72 commit 44d82fc83be6c5ccd70881c2dac1a73e5050398b Author: dtucker@openbsd.org Date: Mon Sep 12 02:25:46 2016 +0000 upstream commit Add testcase for ssh-keygen -j, -J and -K options for moduli screening. Does not currently test generation as that is extremely slow. Upstream-Regress-ID: 9de6ce801377ed3ce0a63a1413f1cd5fd3c2d062 commit 44e5f756d286bc3a1a5272ea484ee276ba3ac5c2 Author: djm@openbsd.org Date: Tue Aug 23 08:17:04 2016 +0000 upstream commit add tests for addr_match_list() Upstream-Regress-ID: fae2d1fef84687ece584738a924c7bf969616c8e commit 445e218878035b59c704c18406e8aeaff4c8aa25 Author: djm@openbsd.org Date: Mon Sep 12 23:39:34 2016 +0000 upstream commit handle certs in rsa_hash_alg_from_ident(), saving an unnecessary special case elsewhere. Upstream-ID: 901cb081c59d6d2698b57901c427f3f6dc7397d4 commit 130f5df4fa37cace8c079dccb690e5cafbf00751 Author: djm@openbsd.org Date: Mon Sep 12 23:31:27 2016 +0000 upstream commit list all supported signature algorithms in the server-sig-algs Reported by mb AT smartftp.com in bz#2547 and (independantly) Ron Frederick; ok markus@ Upstream-ID: ddf702d721f54646b11ef2cee6d916666cb685cd commit 8f750ccfc07acb8aa98be5a5dd935033a6468cfd Author: Darren Tucker Date: Mon Sep 12 14:43:58 2016 +1000 Remove no-op brackets to resync with upstream. commit 7050896e7395866278c19c2ff080c26152619d1d Author: Darren Tucker Date: Mon Sep 12 13:57:28 2016 +1000 Resync ssh-keygen -W error message with upstream. commit 43cceff82cc20413cce58ba3375e19684e62cec4 Author: Darren Tucker Date: Mon Sep 12 13:55:37 2016 +1000 Move ssh-keygen -W handling code to match upstream commit af48d541360b1d7737b35740a4b1ca34e1652cd9 Author: Darren Tucker Date: Mon Sep 12 13:52:17 2016 +1000 Move ssh-keygen -T handling code to match upstream. commit d8c3cfbb018825c6c86547165ddaf11924901c49 Author: Darren Tucker Date: Mon Sep 12 13:30:50 2016 +1000 Move -M handling code to match upstream. commit 7b63cf6dbbfa841c003de57d1061acbf2ff22364 Author: dtucker@openbsd.org Date: Mon Sep 12 03:29:16 2016 +0000 upstream commit Spaces->tabs. Upstream-ID: f4829dfc3f36318273f6082b379ac562eead70b7 commit 11e5e644536821ceb3bb4dd8487fbf0588522887 Author: dtucker@openbsd.org Date: Mon Sep 12 03:25:20 2016 +0000 upstream commit Style whitespace fix. Also happens to remove a no-op diff with portable. Upstream-ID: 45d90f9a62ad56340913a433a9453eb30ceb8bf3 commit 9136ec134c97a8aff2917760c03134f52945ff3c Author: deraadt@openbsd.org Date: Mon Sep 12 01:22:38 2016 +0000 upstream commit Add MAXIMUM(), MINIMUM(), and ROUNDUP() to misc.h, then use those definitions rather than pulling and unknown namespace pollution. ok djm markus dtucker Upstream-ID: 712cafa816c9f012a61628b66b9fbd5687223fb8 commit f219fc8f03caca7ac82a38ed74bbd6432a1195e7 Author: jmc@openbsd.org Date: Wed Sep 7 18:39:24 2016 +0000 upstream commit sort; from matthew martin Upstream-ID: 73cec7f7ecc82d37a4adffad7745e4684de67ce7 commit 06ce56b05def9460aecc7cdb40e861a346214793 Author: markus@openbsd.org Date: Tue Sep 6 09:22:56 2016 +0000 upstream commit ssh_set_newkeys: print correct block counters on rekeying; ok djm@ Upstream-ID: 32bb7a9cb9919ff5bab28d50ecef3a2b2045dd1e commit e5e8d9114ac6837a038f4952994ca95a97fafe8d Author: markus@openbsd.org Date: Tue Sep 6 09:14:05 2016 +0000 upstream commit update ext_info_c every time we receive a kexinit msg; fixes sending of ext_info if privsep is disabled; report Aris Adamantiadis & Mancha; ok djm@ Upstream-ID: 2ceaa1076e19dbd3542254b4fb8e42d608f28856 commit da95318dbedbaa1335323dba370975c2f251afd8 Author: djm@openbsd.org Date: Mon Sep 5 14:02:42 2016 +0000 upstream commit remove 3des-cbc from the client's default proposal; 64-bit block ciphers are not safe in 2016 and we don't want to wait until attacks like sweet32 are extended to SSH. As 3des-cbc was the only mandatory cipher in the SSH RFCs, this may cause problems connecting to older devices using the defaults, but it's highly likely that such devices already need explicit configuration for KEX and hostkeys anyway. ok deraadt, markus, dtucker Upstream-ID: a505dfe65c6733af0f751b64cbc4bb7e0761bc2f commit b33ad6d997d36edfea65e243cd12ccd01f413549 Author: djm@openbsd.org Date: Mon Sep 5 13:57:31 2016 +0000 upstream commit enforce expected request flow for GSSAPI calls; thanks to Jakub Jelen for testing; ok markus@ Upstream-ID: d4bc0e70e1be403735d3d9d7e176309b1fd626b9 commit 0bb2980260fb24e5e0b51adac471395781b66261 Author: Darren Tucker Date: Mon Sep 12 11:07:00 2016 +1000 Restore ssh-keygen's -J and -j option handling. These were incorrectly removed in the 1d9a2e28 sync commit. commit 775f8a23f2353f5869003c57a213d14b28e0736e Author: Damien Miller Date: Wed Aug 31 10:48:07 2016 +1000 tighten PAM monitor calls only allow kbd-interactive ones when that authentication method is enabled. Prompted by Solar Designer commit 7fd0ea8a1db4bcfb3d8cd9df149e5d571ebea1f4 Author: djm@openbsd.org Date: Tue Aug 30 07:50:21 2016 +0000 upstream commit restrict monitor auth calls to be allowed only when their respective authentication methods are enabled in the configuration. prompted by Solar Designer; ok markus dtucker Upstream-ID: 6eb3f89332b3546d41d6dbf5a8e6ff920142b553 commit b38b95f5bcc52278feb839afda2987933f68ff96 Author: Damien Miller Date: Mon Aug 29 11:47:07 2016 +1000 Tighten monitor state-machine flow for PAM calls (attack surface reduction) commit dc664d1bd0fc91b24406a3e9575b81c285b8342b Author: djm@openbsd.org Date: Sun Aug 28 22:28:12 2016 +0000 upstream commit fix uninitialised optlen in getsockopt() call; harmless on Unix/BSD but potentially crashy on Cygwin. Reported by James Slepicka ok deraadt@ Upstream-ID: 1987ccee508ba5b18f016c85100d7ac3f70ff965 commit 5bcc1e2769f7d6927d41daf0719a9446ceab8dd7 Author: guenther@openbsd.org Date: Sat Aug 27 04:05:12 2016 +0000 upstream commit Pull in for struct timeval ok deraadt@ Upstream-ID: ae34525485a173bccd61ac8eefeb91c57e3b7df6 commit fa4a4c96b19127dc2fd4e92f20d99c0c7f34b538 Author: guenther@openbsd.org Date: Sat Aug 27 04:04:56 2016 +0000 upstream commit Pull in for NULL ok deraadt@ Upstream-ID: 7baa6a0f1e049bb3682522b4b95a26c866bfc043 commit ae363d74ccc1451185c0c8bd4631e28c67c7fd36 Author: djm@openbsd.org Date: Thu Aug 25 23:57:54 2016 +0000 upstream commit add a sIgnore opcode that silently ignores options and use it to suppress noisy deprecation warnings for the Protocol directive. req henning, ok markus Upstream-ID: 9fe040aca3d6ff393f6f7e60045cdd821dc4cbe0 commit a94c60306643ae904add6e8ed219e4be3494255c Author: djm@openbsd.org Date: Thu Aug 25 23:56:51 2016 +0000 upstream commit remove superfluous NOTREACHED comment Upstream-ID: a7485c1f1be618e8c9e38fd9be46c13b2d03b90c commit fc041c47144ce28cf71353124a8a5d183cd6a251 Author: otto@openbsd.org Date: Tue Aug 23 16:21:45 2016 +0000 upstream commit fix previous, a condition was modified incorrectly; ok markus@ deraadt@ Upstream-ID: c443e339768e7ed396dff3bb55f693e7d3641453 commit 23555eb13a9b0550371a16dcf8beaab7a5806a64 Author: djm@openbsd.org Date: Tue Aug 23 08:17:42 2016 +0000 upstream commit downgrade an error() to a debug2() to match similar cases in addr_match_list() Upstream-ID: 07c3d53e357214153d9d08f234411e0d1a3d6f5c commit a39627134f6d90e7009eeb14e9582ecbc7a99192 Author: djm@openbsd.org Date: Tue Aug 23 06:36:23 2016 +0000 upstream commit remove Protocol directive from client/server configs that causes spammy deprecation warnings hardcode SSH_PROTOCOLS=2, since that's all we support on the server now (the client still may support both, so it could get confused) Upstream-Regress-ID: c16662c631af51633f9fd06aca552a70535de181 commit 6ee4f1c01ee31e65245881d49d4bccf014956066 Author: Damien Miller Date: Tue Aug 23 16:33:48 2016 +1000 hook match and utf8 unittests up to Makefile commit 114efe2bc0dd2842d997940a833f115e6fc04854 Author: djm@openbsd.org Date: Fri Aug 19 06:44:13 2016 +0000 upstream commit add tests for matching functions Upstream-Regress-ID: 0869d4f5c5d627c583c6a929d69c17d5dd65882c commit 857568d2ac81c14bcfd625b27536c1e28c992b3c Author: Damien Miller Date: Tue Aug 23 14:32:37 2016 +1000 removing UseLogin bits from configure.ac commit cc182d01cef8ca35a1d25ea9bf4e2ff72e588208 Author: djm@openbsd.org Date: Tue Aug 23 03:24:10 2016 +0000 upstream commit fix negated address matching where the address list consists of a single negated match, e.g. "Match addr !192.20.0.1" Report and patch from Jakub Jelen. bz#2397 ok dtucker@ Upstream-ID: 01dcac3f3e6ca47518cf293e31c73597a4bb40d8 commit 4067ec8a4c64ccf16250c35ff577b4422767da64 Author: djm@openbsd.org Date: Tue Aug 23 03:22:49 2016 +0000 upstream commit fix matching for pattern lists that contain a single negated match, e.g. "Host !example" report and patch from Robin Becker. bz#1918 ok dtucker@ Upstream-ID: 05a0cb323ea4bc20e98db099b42c067bfb9ea1ea commit 83b581862a1dbb06fc859959f829dde2654aef3c Author: djm@openbsd.org Date: Fri Aug 19 03:18:06 2016 +0000 upstream commit remove UseLogin option and support for having /bin/login manage login sessions; ok deraadt markus dtucker Upstream-ID: bea7213fbf158efab7e602d9d844fba4837d2712 commit ffe6549c2f7a999cc5264b873a60322e91862581 Author: naddy@openbsd.org Date: Mon Aug 15 12:32:04 2016 +0000 upstream commit Catch up with the SSH1 code removal and delete all mention of protocol 1 particularities, key files and formats, command line options, and configuration keywords from the server documentation and examples. ok jmc@ Upstream-ID: 850328854675b4b6a0d4a90f0b4a9dd9ca4e905f commit c38ea634893a1975dbbec798fb968c9488013f4a Author: naddy@openbsd.org Date: Mon Aug 15 12:27:56 2016 +0000 upstream commit Remove more SSH1 server code: * Drop sshd's -k option. * Retire configuration keywords that only apply to protocol 1, as well as the "protocol" keyword. * Remove some related vestiges of protocol 1 support. ok markus@ Upstream-ID: 9402f82886de917779db12f8ee3f03d4decc244d commit 33ba55d9e358c07f069e579bfab80eccaaad52cb Author: Darren Tucker Date: Wed Aug 17 16:26:04 2016 +1000 Only check for prctl once. commit 976ba8a8fd66a969bf658280c1e5adf694cc2fc6 Author: Darren Tucker Date: Wed Aug 17 15:33:10 2016 +1000 Fix typo. commit 9abf84c25ff4448891edcde60533a6e7b2870de1 Author: Darren Tucker Date: Wed Aug 17 14:25:43 2016 +1000 Correct LDFLAGS for clang example. --with-ldflags isn't used until after the -ftrapv test, so mention LDFLAGS instead for now. commit 1e8013a17ff11e3c6bd0012fb1fc8d5f1330eb21 Author: Darren Tucker Date: Wed Aug 17 14:08:42 2016 +1000 Remove obsolete CVS $Id from source files. Since -portable switched to git the CVS $Id tags are no longer being updated and are becoming increasingly misleading. Remove them. commit adab758242121181700e48b4f6c60d6b660411fe Author: Darren Tucker Date: Wed Aug 17 13:40:58 2016 +1000 Remove now-obsolete CVS $Id tags from text files. Since -portable switched to git, the CVS $Id tags are no longer being updated and are becoming increasingly misleading. Remove them. commit 560c0068541315002ec4c1c00a560bbd30f2d671 Author: Darren Tucker Date: Wed Aug 17 13:38:30 2016 +1000 Add a section for compiler specifics. Add a section for compiler specifics and document the runtime requirements for clang's integer sanitization. commit a8fc0f42e1eda2fa3393d1ea5e61322d5e07a9cd Author: Darren Tucker Date: Wed Aug 17 13:35:43 2016 +1000 Test multiplying two long long ints. When using clang with -ftrapv or -sanitize=integer the tests would pass but linking would fail with "undefined reference to __mulodi4". Explicitly test for this before enabling -trapv. commit a1cc637e7e11778eb727559634a6ef1c19c619f6 Author: Damien Miller Date: Tue Aug 16 14:47:34 2016 +1000 add a --with-login-program configure argument Saves messing around with LOGIN_PROGRAM env var, which come packaging environments make hard to do during configure phase. commit 8bd81e1596ab1bab355146cb65e82fb96ade3b23 Author: Damien Miller Date: Tue Aug 16 13:30:56 2016 +1000 add --with-pam-service to specify PAM service name Saves messing around with CFLAGS to do it. commit 74433a19bb6f4cef607680fa4d1d7d81ca3826aa Author: Damien Miller Date: Tue Aug 16 13:28:23 2016 +1000 fix false positives when compiled with msan Our explicit_bzero successfully confused clang -fsanitize-memory in to thinking that memset is never called to initialise memory. Ensure that it is called in a way that the compiler recognises. commit 6cb6dcffe1a2204ba9006de20f73255c268fcb6b Author: markus@openbsd.org Date: Sat Aug 13 17:47:40 2016 +0000 upstream commit remove ssh1 server code; ok djm@ Upstream-ID: c24c0c32c49b91740d5a94ae914fb1898ea5f534 commit 42d47adc5ad1187f22c726cbc52e71d6b1767ca2 Author: jca@openbsd.org Date: Fri Aug 12 19:19:04 2016 +0000 upstream commit Use 2001:db8::/32, the official IPv6 subnet for configuration examples. This makes the IPv6 example consistent with IPv4, and removes a dubious mention of a 6bone subnet. ok sthen@ millert@ Upstream-ID: b027f3d0e0073419a132fd1bf002e8089b233634 commit b61f53c0c3b43c28e013d3b3696d64d1c0204821 Author: dtucker@openbsd.org Date: Thu Aug 11 01:42:11 2016 +0000 upstream commit Update moduli file. Upstream-ID: 6da9a37f74aef9f9cc639004345ad893cad582d8 commit f217d9bd42d306f69f56335231036b44502d8191 Author: Darren Tucker Date: Thu Aug 11 11:42:48 2016 +1000 Import updated moduli. commit 67dca60fbb4923b7a11c1645b90a5ca57c03d8be Author: dtucker@openbsd.org Date: Mon Aug 8 22:40:57 2016 +0000 upstream commit Improve error message for overlong ControlPath. ok markus@ djm@ Upstream-ID: aed374e2e88dd3eb41390003e5303d0089861eb5 commit 4706c1d8c15cd5565b59512853c2da9bd4ca26c9 Author: djm@openbsd.org Date: Wed Aug 3 05:41:57 2016 +0000 upstream commit small refactor of cipher.c: make ciphercontext opaque to callers feedback and ok markus@ Upstream-ID: 094849f8be68c3bdad2c0f3dee551ecf7be87f6f commit e600348a7afd6325cc5cd783cb424065cbc20434 Author: dtucker@openbsd.org Date: Wed Aug 3 04:23:55 2016 +0000 upstream commit Fix bug introduced in rev 1.467 which causes "buffer_get_bignum_ret: incomplete message" errors when built with WITH_SSH1 and run such that no Protocol 1 ephemeral host key is generated (eg "Protocol 2", no SSH1 host key supplied). Reported by rainer.laatsch at t-online.de, ok deraadt@ Upstream-ID: aa6b132da5c325523aed7989cc5a320497c919dc commit d7e7348e72f9b203189e3fffb75605afecba4fda Author: djm@openbsd.org Date: Wed Jul 27 23:18:12 2016 +0000 upstream commit better bounds check on iovcnt (we only ever use fixed, positive values) Upstream-ID: 9baa6eb5cd6e30c9dc7398e5fe853721a3a5bdee commit 5faa52d295f764562ed6dd75c4a4ce9134ae71e3 Author: Darren Tucker Date: Tue Aug 2 15:22:40 2016 +1000 Use tabs consistently inside "case $host". commit 20e5e8ba9c5d868d897896190542213a60fffbd2 Author: Darren Tucker Date: Tue Aug 2 12:16:34 2016 +1000 Explicitly test for broken strnvis. NetBSD added an strnvis and unfortunately made it incompatible with the existing one in OpenBSD and Linux's libbsd (the former having existed for over ten years). Despite this incompatibility being reported during development (see http://gnats.netbsd.org/44977) they still shipped it. Even more unfortunately FreeBSD and later MacOS picked up this incompatible implementation. Try to detect this mess, and assume the only safe option if we're cross compiling. OpenBSD 2.9 (2001): strnvis(char *dst, const char *src, size_t dlen, int flag); NetBSD 6.0 (2012): strnvis(char *dst, size_t dlen, const char *src, int flag); ok djm@ commit b0b48beab1b74100b61ecbadb9140c9ab4c2ea8c Author: Damien Miller Date: Tue Aug 2 11:06:23 2016 +1000 update recommended autoconf version commit 23902e31dfd18c6d7bb41ccd73de3b5358a377da Author: Damien Miller Date: Tue Aug 2 10:48:04 2016 +1000 update config.guess and config.sub to current upstream commit 562f3512b3911ba0c77a7f68214881d1f241f46e commit dd1031b78b83083615b68d7163c44f4408635be2 Author: Darren Tucker Date: Tue Aug 2 10:01:52 2016 +1000 Replace spaces with tabs. Mechanically replace spaces with tabs in compat files not synced with OpenBSD. commit c20dccb5614c5714f4155dda01bcdebf97cfae7e Author: Darren Tucker Date: Tue Aug 2 09:44:25 2016 +1000 Strip trailing whitespace. Mechanically strip trailing whitespace on files not synced with OpenBSD (or in the case of bsd-snprint.c, rsync). commit 30f9bd1c0963c23bfba8468dfd26aa17609ba42f Author: Darren Tucker Date: Tue Aug 2 09:06:27 2016 +1000 Repair $OpenBSD markers. commit 9715d4ad4b53877ec23dc8681dd7a405de9419a6 Author: Darren Tucker Date: Tue Aug 2 09:02:42 2016 +1000 Repair $OpenBSD marker. commit cf3e0be7f5828a5e5f6c296a607d20be2f07d60c Author: Tim Rice Date: Mon Aug 1 14:31:52 2016 -0700 modified: configure.ac opensshd.init.in Skip generating missing RSA1 key on startup unless ssh1 support is enabled. Spotted by Jean-Pierre Radley commit 99522ba7ec6963a05c04a156bf20e3ba3605987c Author: Damien Miller Date: Thu Jul 28 08:54:27 2016 +1000 define _OPENBSD_SOURCE for reallocarray on NetBSD Report by and debugged with Hisashi T Fujinaka, dtucker nailed the problem (lack of prototype causing return type confusion). commit 3e1e076550c27c6bbdddf36d8f42bd79fbaaa187 Author: Damien Miller Date: Wed Jul 27 08:25:42 2016 +1000 KNF commit d99ee9c4e5e217e7d05eeec84e9ce641f4675331 Author: Damien Miller Date: Wed Jul 27 08:25:23 2016 +1000 Linux auditing also needs packet.h commit 393bd381a45884b589baa9aed4394f1d250255ca Author: Damien Miller Date: Wed Jul 27 08:18:05 2016 +1000 fix auditing on Linux get_remote_ipaddr() was replaced with ssh_remote_ipaddr() commit 80e766fb089de4f3c92b1600eb99e9495e37c992 Author: Damien Miller Date: Sun Jul 24 21:50:13 2016 +1000 crank version numbers commit b1a478792d458f2e938a302e64bab2b520edc1b3 Author: djm@openbsd.org Date: Sun Jul 24 11:45:36 2016 +0000 upstream commit openssh-7.3 Upstream-ID: af106a7eb665f642648cf1993e162c899f358718 commit 353766e0881f069aeca30275ab706cd60a1a8fdd Author: Darren Tucker Date: Sat Jul 23 16:14:42 2016 +1000 Move Cygwin IPPORT_RESERVED overrride to defines.h Patch from vinschen at redhat.com. commit 368dd977ae07afb93f4ecea23615128c95ab2b32 Author: djm@openbsd.org Date: Sat Jul 23 02:54:08 2016 +0000 upstream commit fix pledge violation with ssh -f; reported by Valentin Kozamernik ok dtucker@ Upstream-ID: a61db7988db88d9dac3c4dd70e18876a8edf84aa commit f00211e3c6d24d6ea2b64b4b1209f671f6c1d42e Author: djm@openbsd.org Date: Fri Jul 22 07:00:46 2016 +0000 upstream commit improve wording; suggested by jmc@ Upstream-ID: 55cb0a24c8e0618b3ceec80998dc82c85db2d2f8 commit 83cbca693c3b0719270e6a0f2efe3f9ee93a65b8 Author: dtucker@openbsd.org Date: Fri Jul 22 05:46:11 2016 +0000 upstream commit Lower loglevel for "Authenticated with partial success" message similar to other similar level. bz#2599, patch from cgallek at gmail.com, ok markus@ Upstream-ID: 3faab814e947dc7b2e292edede23e94c608cb4dd commit 10358abd087ab228b7ce2048efc4f3854a9ab9a6 Author: Damien Miller Date: Fri Jul 22 14:06:36 2016 +1000 retry waitpid on EINTR failure patch from Jakub Jelen on bz#2581; ok dtucker@ commit da88a70a89c800e74ea8e5661ffa127a3cc79a92 Author: djm@openbsd.org Date: Fri Jul 22 03:47:36 2016 +0000 upstream commit constify a few functions' arguments; patch from Jakub Jelen bz#2581 Upstream-ID: f2043f51454ea37830ff6ad60c8b32b4220f448d commit c36d91bd4ebf767f310f7cea88d61d1c15f53ddf Author: djm@openbsd.org Date: Fri Jul 22 03:39:13 2016 +0000 upstream commit move debug("%p", key) to before key is free'd; probable undefined behaviour on strict compilers; reported by Jakub Jelen bz#2581 Upstream-ID: 767f323e1f5819508a0e35e388ec241bac2f953a commit 286f5a77c3bfec1e8892ca268087ac885ac871bf Author: djm@openbsd.org Date: Fri Jul 22 03:35:11 2016 +0000 upstream commit reverse the order in which -J/JumpHost proxies are visited to be more intuitive and document reported by and manpage bits naddy@ Upstream-ID: 3a68fd6a841fd6cf8cedf6552a9607ba99df179a commit fcd135c9df440bcd2d5870405ad3311743d78d97 Author: dtucker@openbsd.org Date: Thu Jul 21 01:39:35 2016 +0000 upstream commit Skip passwords longer than 1k in length so clients can't easily DoS sshd by sending very long passwords, causing it to spend CPU hashing them. feedback djm@, ok markus@. Brought to our attention by tomas.kuthan at oracle.com, shilei-c at 360.cn and coredump at autistici.org Upstream-ID: d0af7d4a2190b63ba1d38eec502bc4be0be9e333 commit 324583e8fb3935690be58790425793df619c6d4d Author: naddy@openbsd.org Date: Wed Jul 20 10:45:27 2016 +0000 upstream commit Do not clobber the global jump_host variables when parsing an inactive configuration. ok djm@ Upstream-ID: 5362210944d91417d5976346d41ac0b244350d31 commit 32d921c323b989d28405e78d0a8923d12913d737 Author: jmc@openbsd.org Date: Tue Jul 19 12:59:16 2016 +0000 upstream commit tweak previous; Upstream-ID: f3c1a5b3f05dff366f60c028728a2b43f15ff534 commit d7eabc86fa049a12ba2c3fb198bd1d51b37f7025 Author: dtucker@openbsd.org Date: Tue Jul 19 11:38:53 2016 +0000 upstream commit Allow wildcard for PermitOpen hosts as well as ports. bz#2582, patch from openssh at mzpqnxow.com and jjelen at redhat.com. ok markus@ Upstream-ID: af0294e9b9394c4e16e991424ca0a47a7cc605f2 commit b98a2a8348e907b3d71caafd80f0be8fdd075943 Author: markus@openbsd.org Date: Mon Jul 18 11:35:33 2016 +0000 upstream commit Reduce timing attack against obsolete CBC modes by always computing the MAC over a fixed size of data. Reported by Jean Paul Degabriele, Kenny Paterson, Torben Hansen and Martin Albrecht. ok djm@ Upstream-ID: f20a13279b00ba0afbacbcc1f04e62e9d41c2912 commit dbf788b4d9d9490a5fff08a7b09888272bb10fcc Author: Darren Tucker Date: Thu Jul 21 14:17:31 2016 +1000 Search users for one with a valid salt. If the root account is locked (eg password "!!" or "*LK*") keep looking until we find a user with a valid salt to use for crypting passwords of invalid users. ok djm@ commit e8b58f48fbb1b524fb4f0d4865fa0005d6a4b782 Author: Darren Tucker Date: Mon Jul 18 17:22:49 2016 +1000 Explicitly specify source files for regress tools. Since adding $(REGRESSLIBS), $? is wrong because it includes only the changed source files. $< seems like it'd be right however it doesn't seem to work on some non-GNU makes, so do what works everywhere. commit eac1bbd06872c273f16ac0f9976b0aef026b701b Author: Darren Tucker Date: Mon Jul 18 17:12:22 2016 +1000 Conditionally include err.h. commit 0a454147568746c503f669e1ba861f76a2e7a585 Author: Darren Tucker Date: Mon Jul 18 16:26:26 2016 +1000 Remove local implementation of err, errx. We now have a shared implementation in libopenbsd-compat. commit eb999a4590846ba4d56ddc90bd07c23abfbab7b1 Author: djm@openbsd.org Date: Mon Jul 18 06:08:01 2016 +0000 upstream commit Add some unsigned overflow checks for extra_pad. None of these are reachable with the amount of padding that we use internally. bz#2566, pointed out by Torben Hansen. ok markus@ Upstream-ID: 4d4be8450ab2fc1b852d5884339f8e8c31c3fd76 commit c71ba790c304545464bb494de974cdf0f4b5cf1e Author: Darren Tucker Date: Mon Jul 18 15:43:25 2016 +1000 Add dependency on libs for unit tests. Makes "./configure && make tests" work again. ok djm@ commit 8199d0311aea3e6fd0284c9025e7a83f4ece79e8 Author: Darren Tucker Date: Mon Jul 18 13:47:39 2016 +1000 Correct location for kexfuzz in clean target. commit 01558b7b07af43da774d3a11a5c51fa9c310849d Author: Darren Tucker Date: Mon Jul 18 09:33:25 2016 +1000 Handle PAM_MAXTRIES from modules. bz#2249: handle the case where PAM returns PAM_MAXTRIES by ceasing to offer password and keyboard-interative authentication methods. Should prevent "sshd ignoring max retries" warnings in the log. ok djm@ It probably won't trigger with keyboard-interactive in the default configuration because the retry counter is stored in module-private storage which goes away with the sshd PAM process (see bz#688). On the other hand, those cases probably won't log a warning either. commit 65c6c6b567ab5ab12945a5ad8e0ab3a8c26119cc Author: djm@openbsd.org Date: Sun Jul 17 04:20:16 2016 +0000 upstream commit support UTF-8 characters in ssh(1) banners using schwarze@'s safe fmprintf printer; bz#2058 feedback schwarze@ ok dtucker@ Upstream-ID: a72ce4e3644c957643c9524eea2959e41b91eea7 commit e4eb7d910976fbfc7ce3e90c95c11b07b483d0d7 Author: jmc@openbsd.org Date: Sat Jul 16 06:57:55 2016 +0000 upstream commit - add proxyjump to the options list - formatting fixes - update usage() ok djm Upstream-ID: 43d318e14ce677a2eec8f21ef5ba2f9f68a59457 commit af1f084857621f14bd9391aba8033d35886c2455 Author: dtucker@openbsd.org Date: Fri Jul 15 05:01:58 2016 +0000 upstream commit Reduce the syslog level of some relatively common protocol events from LOG_CRIT by replacing fatal() calls with logdie(). Part of bz#2585, ok djm@ Upstream-ID: 9005805227c94edf6ac02a160f0e199638d288e5 commit bd5f2b78b69cf38d6049a0de445a79c8595e4a1f Author: Damien Miller Date: Fri Jul 15 19:14:48 2016 +1000 missing openssl/dh.h commit 4a984fd342effe5f0aad874a0d538c4322d973c0 Author: Damien Miller Date: Fri Jul 15 18:47:07 2016 +1000 cast to avoid type warning in error message commit 5abfb15ced985c340359ae7fb65a625ed3692b3e Author: Darren Tucker Date: Fri Jul 15 14:48:30 2016 +1000 Move VA_COPY macro into compat header. Some AIX compilers unconditionally undefine va_copy but don't set it back to an internal function, causing link errors. In some compat code we already use VA_COPY instead so move the two existing instances into the shared header and use for sshbuf-getput-basic.c too. Should fix building with at lease some versions of AIX's compiler. bz#2589, ok djm@ commit 832b7443b7a8e181c95898bc5d73497b7190decd Author: Damien Miller Date: Fri Jul 15 14:45:34 2016 +1000 disable ciphers not supported by OpenSSL bz#2466 ok dtucker@ commit 5fbe93fc6fbb2fe211e035703dec759d095e3dd8 Author: Damien Miller Date: Fri Jul 15 13:54:31 2016 +1000 add a --disable-pkcs11 knob commit 679ce88ec2a8e2fe6515261c489e8c1449bb9da9 Author: Damien Miller Date: Fri Jul 15 13:44:38 2016 +1000 fix newline escaping for unsupported_algorithms The hmac-ripemd160 was incorrect and could lead to broken Makefiles on systems that lacked support for it, but I made all the others consistent too. commit ed877ef653847d056bb433975d731b7a1132a979 Author: djm@openbsd.org Date: Fri Jul 15 00:24:30 2016 +0000 upstream commit Add a ProxyJump ssh_config(5) option and corresponding -J ssh(1) command-line flag to allow simplified indirection through a SSH bastion or "jump host". These options construct a proxy command that connects to the specified jump host(s) (more than one may be specified) and uses port-forwarding to establish a connection to the next destination. This codifies the safest way of indirecting connections through SSH servers and makes it easy to use. ok markus@ Upstream-ID: fa899cb8b26d889da8f142eb9774c1ea36b04397 commit 5c02dd126206a26785379e80f2d3848e4470b711 Author: Darren Tucker Date: Fri Jul 15 12:56:39 2016 +1000 Map umac_ctx struct name too. Prevents size mismatch linker warnings on Solaris 11. commit 283b97ff33ea2c641161950849931bd578de6946 Author: Darren Tucker Date: Fri Jul 15 13:49:44 2016 +1000 Mitigate timing of disallowed users PAM logins. When sshd decides to not allow a login (eg PermitRootLogin=no) and it's using PAM, it sends a fake password to PAM so that the timing for the failure is not noticeably different whether or not the password is correct. This behaviour can be detected by sending a very long password string which is slower to hash than the fake password. Mitigate by constructing an invalid password that is the same length as the one from the client and thus takes the same time to hash. Diff from djm@ commit 9286875a73b2de7736b5e50692739d314cd8d9dc Author: Darren Tucker Date: Fri Jul 15 13:32:45 2016 +1000 Determine appropriate salt for invalid users. When sshd is processing a non-PAM login for a non-existent user it uses the string from the fakepw structure as the salt for crypt(3)ing the password supplied by the client. That string has a Blowfish prefix, so on systems that don't understand that crypt will fail fast due to an invalid salt, and even on those that do it may have significantly different timing from the hash methods used for real accounts (eg sha512). This allows user enumeration by, eg, sending large password strings. This was noted by EddieEzra.Harari at verint.com (CVE-2016-6210). To mitigate, use the same hash algorithm that root uses for hashing passwords for users that do not exist on the system. ok djm@ commit a162dd5e58ca5b224d7500abe35e1ef32b5de071 Author: Darren Tucker Date: Thu Jul 14 21:19:59 2016 +1000 OpenSSL 1.1.x not currently supported. commit 7df91b01fc558a33941c5c5f31abbcdc53a729fb Author: Darren Tucker Date: Thu Jul 14 12:25:24 2016 +1000 Check for VIS_ALL. If we don't have it, set BROKEN_STRNVIS to activate the compat replacement. commit ee67716f61f1042d5e67f91c23707cca5dcdd7d0 Author: dtucker@openbsd.org Date: Thu Jul 14 01:24:21 2016 +0000 upstream commit Correct equal in test. Upstream-Regress-ID: 4e32f7a5c57a619c4e8766cb193be2a1327ec37a commit 372807c2065c8572fdc6478b25cc5ac363743073 Author: tb@openbsd.org Date: Mon Jul 11 21:38:13 2016 +0000 upstream commit Add missing "recvfd" pledge promise: Raf Czlonka reported ssh coredumps when Control* keywords were set in ssh_config. This patch also fixes similar problems with scp and sftp. ok deraadt, looks good to millert Upstream-ID: ca2099eade1ef3e87a79614fefa26a0297ad8a3b commit e0453f3df64bf485c61c7eb6bd12893eee9fe2cd Author: tedu@openbsd.org Date: Mon Jul 11 03:19:44 2016 +0000 upstream commit obsolete note about fascistloggin is obsolete. ok djm dtucker Upstream-ID: dae60df23b2bb0e89f42661ddd96a7b0d1b7215a commit a2333584170a565adf4f209586772ef8053b10b8 Author: Darren Tucker Date: Thu Jul 14 10:59:09 2016 +1000 Add compat code for missing wcwidth. If we don't have wcwidth force fallback implementations of nl_langinfo and mbtowc. Based on advice from Ingo Schwarze. commit 8aaec7050614494014c47510b7e94daf6e644c62 Author: Damien Miller Date: Thu Jul 14 09:48:48 2016 +1000 fix missing include for systems with err.h commit 6310ef27a2567cda66d6cf0c1ad290ee1167f243 Author: Darren Tucker Date: Wed Jul 13 14:42:35 2016 +1000 Move err.h replacements into compat lib. Move implementations of err.h replacement functions into their own file in the libopenbsd-compat so we can use them in kexfuzz.c too. ok djm@ commit f3f2cc8386868f51440c45210098f65f9787449a Author: Darren Tucker Date: Mon Jul 11 17:23:38 2016 +1000 Check for wchar.h and langinfo.h Wrap includes in the appropriate #ifdefs. commit b9c50614eba9d90939b2b119b6e1b7e03b462278 Author: Damien Miller Date: Fri Jul 8 13:59:13 2016 +1000 whitelist more architectures for seccomp-bpf bz#2590 - testing and patch from Jakub Jelen commit 18813a32b6fd964037e0f5e1893cb4468ac6a758 Author: guenther@openbsd.org Date: Mon Jul 4 18:01:44 2016 +0000 upstream commit DEBUGLIBS has been broken since the gcc4 switch, so delete it. CFLAGS contains -g by default anyway problem noted by Edgar Pettijohn (edgar (at) pettijohn-web.com) ok millert@ kettenis@ deraadt@ Upstream-Regress-ID: 4a0bb72f95c63f2ae9daa8a040ac23914bddb542 commit 6d31193d0baa3da339c196ac49625b7ba1c2ecc7 Author: djm@openbsd.org Date: Fri Jul 8 03:44:42 2016 +0000 upstream commit Improve crypto ordering for Encrypt-then-MAC (EtM) mode MAC algorithms. Previously we were computing the MAC, decrypting the packet and then checking the MAC. This gave rise to the possibility of creating a side-channel oracle in the decryption step, though no such oracle has been identified. This adds a mac_check() function that computes and checks the MAC in one pass, and uses it to advance MAC checking for EtM algorithms to before payload decryption. Reported by Jean Paul Degabriele, Kenny Paterson, Torben Hansen and Martin Albrecht. feedback and ok markus@ Upstream-ID: 1999bb67cab47dda5b10b80d8155fe83d4a1867b commit 71f5598f06941f645a451948c4a5125c83828e1c Author: guenther@openbsd.org Date: Mon Jul 4 18:01:44 2016 +0000 upstream commit DEBUGLIBS has been broken since the gcc4 switch, so delete it. CFLAGS contains -g by default anyway problem noted by Edgar Pettijohn (edgar (at) pettijohn-web.com) ok millert@ kettenis@ deraadt@ Upstream-ID: 96c5054e3e1f170c6276902d5bc65bb3b87a2603 commit e683fc6f1c8c7295648dbda679df8307786ec1ce Author: dtucker@openbsd.org Date: Thu Jun 30 05:17:05 2016 +0000 upstream commit Explicitly check for 100% completion to avoid potential floating point rounding error, which could cause progressmeter to report 99% on completion. While there invert the test so the 100% case is clearer. with & ok djm@ Upstream-ID: a166870c5878e422f3c71ff802e2ccd7032f715d commit 772e6cec0ed740fc7db618dc30b4134f5a358b43 Author: jmc@openbsd.org Date: Wed Jun 29 17:14:28 2016 +0000 upstream commit sort the -o list; Upstream-ID: 1a97465ede8790b4d47cb618269978e07f41f8ac commit 46ecd19e554ccca15a7309cd1b6b44bc8e6b84af Author: djm@openbsd.org Date: Thu Jun 23 05:17:51 2016 +0000 upstream commit fix AuthenticationMethods during configuration re-parse; reported by Juan Francisco Cantero Hurtado Upstream-ID: 8ffa1dac25c7577eca8238e825317ab20848f9b4 commit 3147e7595d0f2f842a666c844ac53e6c7a253d7e Author: djm@openbsd.org Date: Sun Jun 19 07:48:02 2016 +0000 upstream commit revert 1.34; causes problems loading public keys reported by semarie@ Upstream-ID: b393794f8935c8b15d98a407fe7721c62d2ed179 commit ad23a75509f4320d43f628c50f0817e3ad12bfa7 Author: jmc@openbsd.org Date: Fri Jun 17 06:33:30 2016 +0000 upstream commit grammar fix; Upstream-ID: 5d5b21c80f1e81db367333ce0bb3e5874fb3e463 commit 5e28b1a2a3757548b40018cc2493540a17c82e27 Author: djm@openbsd.org Date: Fri Jun 17 05:06:23 2016 +0000 upstream commit translate OpenSSL error codes to something more meaninful; bz#2522 reported by Jakub Jelen, ok dtucker@ Upstream-ID: 4cb0795a366381724314e6515d57790c5930ffe5 commit b64faeb5eda7eff8210c754d00464f9fe9d23de5 Author: djm@openbsd.org Date: Fri Jun 17 05:03:40 2016 +0000 upstream commit ban AuthenticationMethods="" and accept AuthenticationMethods=any for the default behaviour of not requiring multiple authentication bz#2398 from Jakub Jelen; ok dtucker@ Upstream-ID: fabd7f44d59e4518d241d0d01e226435cc23cf27 commit 9816fc5daee5ca924dd5c4781825afbaab728877 Author: dtucker@openbsd.org Date: Thu Jun 16 11:00:17 2016 +0000 upstream commit Include stdarg.h for va_copy as per man page. Upstream-ID: 105d6b2f1af2fbd9d91c893c436ab121434470bd commit b6cf84b51bc0f5889db48bf29a0c771954ade283 Author: jmc@openbsd.org Date: Thu Jun 16 06:10:45 2016 +0000 upstream commit keys stored in openssh format can have comments too; diff from yonas yanfa, tweaked a bit; ok djm Upstream-ID: 03d48536da6e51510d73ade6fcd44ace731ceb27 commit aa37768f17d01974b6bfa481e5e83841b6c76f86 Author: Darren Tucker Date: Mon Jun 20 15:55:34 2016 +1000 get_remote_name_or_ip inside LOGIN_NEEDS_UTMPX Apply the same get_remote_name_or_ip -> session_get_remote_name_or_ip change as commit 95767262 to the code inside #ifdef LOGIN_NEEDS_UTMPX. Fixes build on AIX. commit 009891afc8df37bc2101e15d1e0b6433cfb90549 Author: Darren Tucker Date: Fri Jun 17 14:34:09 2016 +1000 Remove duplicate code from PAM. ok djm@ commit e690fe85750e93fca1fb7c7c8587d4130a4f7aba Author: dtucker@openbsd.org Date: Wed Jun 15 00:40:40 2016 +0000 upstream commit Remove "POSSIBLE BREAK-IN ATTEMPT!" from log message about forward and reverse DNS not matching. We haven't supported IP-based auth methods for a very long time so it's now misleading. part of bz#2585, ok markus@ Upstream-ID: 5565ef0ee0599b27f0bd1d3bb1f8a323d8274e29 commit 57b4ee04cad0d3e0fec1194753b0c4d31e39a1cd Author: Darren Tucker Date: Wed Jun 15 11:22:38 2016 +1000 Move platform_disable_tracing into its own file. Prevents link errors resolving the extern "options" when platform.o gets linked into ssh-agent when building --with-pam. commit 78dc8e3724e30ee3e1983ce013e80277dc6ca070 Author: Darren Tucker Date: Tue Jun 14 13:55:12 2016 +1000 Track skipped upstream commit IDs. There are a small number of "upstream" commits that do not correspond to a file in -portable. This file tracks those so that we can reconcile OpenBSD and Portable to ensure that no commits are accidentally missed. If you add something to .skipped-commit-ids please also add an upstream ID line in the following format when you commit it. Upstream-ID: 321065a95a7ccebdd5fd08482a1e19afbf524e35 Upstream-ID: d4f699a421504df35254cf1c6f1a7c304fb907ca Upstream-ID: aafe246655b53b52bc32c8a24002bc262f4230f7 Upstream-ID: 8fa9cd1dee3c3339ae329cf20fb591db6d605120 Upstream-ID: f31327a48dd4103333cc53315ec53fe65ed8a17a Upstream-ID: edbfde98c40007b7752a4ac106095e060c25c1ef Upstream-ID: 052fd565e3ff2d8cec3bc957d1788f50c827f8e2 Upstream-ID: 7cf73737f357492776223da1c09179fa6ba74660 Upstream-ID: 180d84674be1344e45a63990d60349988187c1ae Upstream-ID: f6ae971186ba68d066cd102e57d5b0b2c211a5ee commit 9f919d1a3219d476d6a662d18df058e1c4f36a6f Author: Darren Tucker Date: Tue Jun 14 13:51:01 2016 +1000 Remove now-defunct .cvsignore files. ok djm commit 68777faf271efb2713960605c748f6c8a4b26d55 Author: dtucker@openbsd.org Date: Wed Jun 8 02:13:01 2016 +0000 upstream commit Back out rev 1.28 "Check min and max sizes sent by the client" change. It caused "key_verify failed for server_host_key" in clients that send a DH-GEX min value less that DH_GRP_MIN, eg old OpenSSH and PuTTY. ok djm@ Upstream-ID: 452979d3ca5c1e9dff063287ea0a5314dd091f65 commit a86ec4d0737ac5879223e7cd9d68c448df46e169 Author: Darren Tucker Date: Tue Jun 14 10:48:27 2016 +1000 Use Solaris setpflags(__PROC_PROTECT, ...). Where possible, use Solaris setpflags to disable process tracing on ssh-agent and sftp-server. bz#2584, based on a patch from huieying.lee at oracle.com, ok djm. commit 0f916d39b039fdc0b5baf9b5ab0754c0f11ec573 Author: Darren Tucker Date: Tue Jun 14 10:43:53 2016 +1000 Shorten prctl code a tiny bit. commit 0fb7f5985351fbbcd2613d8485482c538e5123be Author: Darren Tucker Date: Thu Jun 9 16:23:07 2016 +1000 Move prctl PR_SET_DUMPABLE into platform.c. This should make it easier to add additional platform support such as Solaris (bz#2584). commit e6508898c3cd838324ecfe1abd0eb8cf802e7106 Author: dtucker@openbsd.org Date: Fri Jun 3 04:10:41 2016 +0000 upstream commit Add a test for ssh(1)'s config file parsing. Upstream-Regress-ID: 558b7f4dc45cc3761cc3d3e889b9f3c5bc91e601 commit ab0a536066dfa32def0bd7272c096ebb5eb25b11 Author: dtucker@openbsd.org Date: Fri Jun 3 03:47:59 2016 +0000 upstream commit Add 'sshd' to the test ID as I'm about to add a similar set for ssh. Upstream-Regress-ID: aea7a9c3bac638530165c801ce836875b228ae7a commit a5577c1ed3ecdfe4b7b1107c526cae886fc91afb Author: schwarze@openbsd.org Date: Mon May 30 12:14:08 2016 +0000 upstream commit stricter malloc.conf(5) options for utf8 tests Upstream-Regress-ID: 111efe20a0fb692fa1a987f6e823310f9b25abf6 commit 75f0844b4f29d62ec3a5e166d2ee94b02df819fc Author: schwarze@openbsd.org Date: Mon May 30 12:05:56 2016 +0000 upstream commit Fix two rare edge cases: 1. If vasprintf() returns < 0, do not access a NULL pointer in snmprintf(), and do not free() the pointer returned from vasprintf() because on some systems other than OpenBSD, it might be a bogus pointer. 2. If vasprintf() returns == 0, return 0 and "" rather than -1 and NULL. Besides, free(dst) is pointless after failure (not a bug). One half OK martijn@, the other half OK deraadt@; committing quickly before people get hurt. Upstream-Regress-ID: b164f20923812c9bac69856dbc1385eb1522cba4 commit 016881eb33a7948028848c90f4c7ac42e3af0e87 Author: schwarze@openbsd.org Date: Thu May 26 19:14:25 2016 +0000 upstream commit test the new utf8 module Upstream-Regress-ID: c923d05a20e84e4ef152cbec947fdc4ce6eabbe3 commit d4219028bdef448e089376f3afe81ef6079da264 Author: dtucker@openbsd.org Date: Tue May 3 15:30:46 2016 +0000 upstream commit Set umask to prevent "Bad owner or permissions" errors. Upstream-Regress-ID: 8fdf2fc4eb595ccd80c443f474d639f851145417 commit 07d5608bb237e9b3fe86a2aeaa429392230faebf Author: djm@openbsd.org Date: Tue May 3 14:41:04 2016 +0000 upstream commit support doas Upstream-Regress-ID: 8d5572b27ea810394eeda432d8b4e9e1064a7c38 commit 01cabf10adc7676cba5f40536a34d3b246edb73f Author: djm@openbsd.org Date: Tue May 3 13:48:33 2016 +0000 upstream commit unit tests for sshbuf_dup_string() Upstream-Regress-ID: 7521ff150dc7f20511d1c2c48fd3318e5850a96d commit 6915f1698e3d1dd4e22eac20f435e1dfc1d46372 Author: jmc@openbsd.org Date: Fri Jun 3 06:44:12 2016 +0000 upstream commit tweak previous; Upstream-ID: 92979f1a0b63e041a0e5b08c9ed0ba9b683a3698 commit 0cb2f4c2494b115d0f346ed2d8b603ab3ba643f4 Author: dtucker@openbsd.org Date: Fri Jun 3 04:09:38 2016 +0000 upstream commit Allow ExitOnForwardFailure and ClearAllForwardings to be overridden when using ssh -W (but still default to yes in that case). bz#2577, ok djm@. Upstream-ID: 4b20c419e93ca11a861c81c284090cfabc8c54d4 commit 8543ff3f5020fe659839b15f05b8c522bde6cee5 Author: dtucker@openbsd.org Date: Fri Jun 3 03:14:41 2016 +0000 upstream commit Move the host and port used by ssh -W into the Options struct. This will make future changes a bit easier. ok djm@ Upstream-ID: 151bce5ecab2fbedf0d836250a27968d30389382 commit 6b87311d3acdc460f926b2c40f4c4f3fd345f368 Author: dtucker@openbsd.org Date: Wed Jun 1 04:19:49 2016 +0000 upstream commit Check min and max sizes sent by the client against what we support before passing them to the monitor. ok djm@ Upstream-ID: 750627e8117084215412bff00a25b1586ab17ece commit 564cd2a8926ccb1dca43a535073540935b5e0373 Author: dtucker@openbsd.org Date: Tue May 31 23:46:14 2016 +0000 upstream commit Ensure that the client's proposed DH-GEX max value is at least as big as the minimum the server will accept. ok djm@ Upstream-ID: b4b84fa04aab2de7e79a6fee4a6e1c189c0fe775 commit df820722e40309c9b3f360ea4ed47a584ed74333 Author: Darren Tucker Date: Mon Jun 6 11:36:13 2016 +1000 Add compat bits to utf8.c. commit 05c6574652571becfe9d924226c967a3f4b3f879 Author: Darren Tucker Date: Mon Jun 6 11:33:43 2016 +1000 Fix utf->utf8 typo. commit 6c1717190b4d5ddd729cd9e24e8ed71ed4f087ce Author: schwarze@openbsd.org Date: Mon May 30 18:34:41 2016 +0000 upstream commit Backout rev. 1.43 for now. The function update_progress_meter() calls refresh_progress_meter() which calls snmprintf() which calls malloc(); but update_progress_meter() acts as the SIGALRM signal handler. "malloc(): error: recursive call" reported by sobrado@. Upstream-ID: aaae57989431e5239c101f8310f74ccc83aeb93e commit cd9e1eabeb4137182200035ab6fa4522f8d24044 Author: schwarze@openbsd.org Date: Mon May 30 12:57:21 2016 +0000 upstream commit Even when only writing an unescaped character, the dst buffer may need to grow, or it would be overrun; issue found by tb@ with malloc.conf(5) 'C'. While here, reserve an additional byte for the terminating NUL up front such that we don't have to realloc() later just for that. OK tb@ Upstream-ID: 30ebcc0c097c4571b16f0a78b44969f170db0cff commit ac284a355f8065eaef2a16f446f3c44cdd17371d Author: schwarze@openbsd.org Date: Mon May 30 12:05:56 2016 +0000 upstream commit Fix two rare edge cases: 1. If vasprintf() returns < 0, do not access a NULL pointer in snmprintf(), and do not free() the pointer returned from vasprintf() because on some systems other than OpenBSD, it might be a bogus pointer. 2. If vasprintf() returns == 0, return 0 and "" rather than -1 and NULL. Besides, free(dst) is pointless after failure (not a bug). One half OK martijn@, the other half OK deraadt@; committing quickly before people get hurt. Upstream-ID: b7bcd2e82fc168a8eff94e41f5db336ed986fed0 commit 0e059cdf5fd86297546c63fa8607c24059118832 Author: schwarze@openbsd.org Date: Wed May 25 23:48:45 2016 +0000 upstream commit To prevent screwing up terminal settings when printing to the terminal, for ASCII and UTF-8, escape bytes not forming characters and bytes forming non-printable characters with vis(3) VIS_OCTAL. For other character sets, abort printing of the current string in these cases. In particular, * let scp(1) respect the local user's LC_CTYPE locale(1); * sanitize data received from the remote host; * sanitize filenames, usernames, and similar data even locally; * take character display widths into account for the progressmeter. This is believed to be sufficient to keep the local terminal safe on OpenBSD, but bad things can still happen on other systems with state-dependent locales because many places in the code print unencoded ASCII characters into the output stream. Using feedback from djm@ and martijn@, various aspects discussed with many others. deraadt@ says it should go in now, i probably already hesitated too long Upstream-ID: e66afbc94ee396ddcaffd433b9a3b80f387647e0 commit 8c02e3639acefe1e447e293dbe23a0917abd3734 Author: dtucker@openbsd.org Date: Tue May 24 04:43:45 2016 +0000 upstream commit KNF compression proposal and simplify the client side a little. ok djm@ Upstream-ID: aa814b694efe9e5af8a26e4c80a05526ae6d6605 commit 7ec4946fb686813eb5f8c57397e465f5485159f4 Author: dtucker@openbsd.org Date: Tue May 24 02:31:57 2016 +0000 upstream commit Back out 'plug memleak'. Upstream-ID: 4faacdde136c24a961e24538de373660f869dbc0 commit 82f24c3ddc52053aeb7beb3332fa94c92014b0c5 Author: djm@openbsd.org Date: Mon May 23 23:30:50 2016 +0000 upstream commit prefer agent-hosted keys to keys from PKCS#11; ok markus Upstream-ID: 7417f7653d58d6306d9f8c08d0263d050e2fd8f4 commit a0cb7778fbc9b43458f7072eb68dd858766384d1 Author: dtucker@openbsd.org Date: Mon May 23 00:17:27 2016 +0000 upstream commit Plug mem leak in filter_proposal. ok djm@ Upstream-ID: bf968da7cfcea2a41902832e7d548356a4e2af34 commit ae9c0d4d5c581b3040d1f16b5c5f4b1cd1616743 Author: Darren Tucker Date: Fri Jun 3 16:03:44 2016 +1000 Update vis.h and vis.c from OpenBSD. This will be needed for the upcoming utf8 changes. commit e1d93705f8f48f519433d6ca9fc3d0abe92a1b77 Author: Tim Rice Date: Tue May 31 11:13:22 2016 -0700 modified: configure.ac whitspace clean up. No code changes. commit 604a037d84e41e31f0aec9075df0b8740c130200 Author: Damien Miller Date: Tue May 31 16:45:28 2016 +1000 whitespace at EOL commit 18424200160ff5c923113e0a37ebe21ab7bcd17c Author: Darren Tucker Date: Mon May 30 19:35:28 2016 +1000 Add missing ssh-host-config --name option Patch from vinschen@redhat.com. commit 39c0cecaa188a37a2e134795caa68e03f3ced592 Author: Darren Tucker Date: Fri May 20 10:01:58 2016 +1000 Fix comment about sshpam_const and AIX. From mschwager via github. commit f64062b1f74ad5ee20a8a49aab2732efd0f7ce30 Author: Damien Miller Date: Fri May 20 09:56:53 2016 +1000 Deny lstat syscalls in seccomp sandbox Avoids sandbox violations for some krb/gssapi libraries. commit 531c135409b8d8810795b1f3692a4ebfd5c9cae0 Author: djm@openbsd.org Date: Thu May 19 07:45:32 2016 +0000 upstream commit fix type of ed25519 values Upstream-ID: b32d0cb372bbe918ca2de56906901eae225a59b0 commit 75e21688f523799c9e0cc6601d76a9c5ca79f787 Author: markus@openbsd.org Date: Wed May 4 14:32:26 2016 +0000 upstream commit add IdentityAgent; noticed & ok jmc@ Upstream-ID: 4ba9034b00a4cf1beae627f0728da897802df88a commit 1a75d14daf4b60db903e6103cf50e74e0cd0a76b Author: markus@openbsd.org Date: Wed May 4 14:29:58 2016 +0000 upstream commit allow setting IdentityAgent to SSH_AUTH_SOCK; ok djm@ Upstream-ID: 20c508480d8db3eef18942c0fc39b1fcf25652ac commit 0516454151ae722fc8256c3c56115c6baf24c5b0 Author: markus@openbsd.org Date: Wed May 4 14:22:33 2016 +0000 upstream commit move SSH_MSG_NONE, so we don't have to include ssh1.h; ok deraadt@ Upstream-ID: c2f97502efc761a41b18c17ddf460e138ca7994e commit 332ff3d770631e7513fea38cf0d3689f673f0e3f Author: Damien Miller Date: Tue May 10 09:51:06 2016 +1000 initialise salen in binresvport_sa avoids failures with UsePrivilegedPort=yes patch from Juan Gallego commit c5c1d5d2f04ce00d2ddd6647e61b32f28be39804 Author: markus@openbsd.org Date: Wed May 4 14:04:40 2016 +0000 upstream commit missing const in prototypes (ssh1) Upstream-ID: 789c6ad4928b5fa557369b88c3a6a34926082c05 commit 9faae50e2e82ba42eb0cb2726bf6830fe7948f28 Author: dtucker@openbsd.org Date: Wed May 4 14:00:09 2016 +0000 upstream commit Fix inverted logic for updating StreamLocalBindMask which would cause the server to set an invalid mask. ok djm@ Upstream-ID: 8a4404c8307a5ef9e07ee2169fc6d8106b527587 commit b02ad1ce9105bfa7394ac7590c0729dd52e26a81 Author: markus@openbsd.org Date: Wed May 4 12:21:53 2016 +0000 upstream commit IdentityAgent for specifying specific agent sockets; ok djm@ Upstream-ID: 3e6a15eb89ea0fd406f108826b7dc7dec4fbfac1 commit 910e59bba09ac309d78ce61e356da35292212935 Author: djm@openbsd.org Date: Wed May 4 12:16:39 2016 +0000 upstream commit fix junk characters after quotes Upstream-ID: cc4d0cd32cb6b55a2ef98975d2f7ae857d0dc578 commit 9283884e647b8be50ccd2997537af0065672107d Author: jmc@openbsd.org Date: Tue May 3 18:38:12 2016 +0000 upstream commit correct article; Upstream-ID: 1fbd5b7ab16d2d9834ec79c3cedd4738fa42a168 commit cfefbcea1057c2623e76c579174a4107a0b6e6cd Author: djm@openbsd.org Date: Tue May 3 15:57:39 2016 +0000 upstream commit fix overriding of StreamLocalBindMask and StreamLocalBindUnlink in Match blocks; found the hard way Rogan Dawes Upstream-ID: 940bc69ec0249ab428d24ccd0722ce35cb932ee2 commit 771c2f51ffc0c9a2877b7892fada0c77bd1f6549 Author: djm@openbsd.org Date: Tue May 3 15:25:06 2016 +0000 upstream commit don't forget to include StreamLocalBindUnlink in the config dump output Upstream-ID: 14a6d970b3b45c8e94272e3c661e9a0b2a0ee7cb commit cdcd941994dc430f50d0a4e6a712d32b66e6199e Author: djm@openbsd.org Date: Tue May 3 14:54:08 2016 +0000 upstream commit make nethack^wrandomart fingerprint flag more readily searchable pointed out by Matt Johnston Upstream-ID: cb40d0235dc153c478c1aad3bc60b195422a54fb commit 05855bf2ce7d5cd0a6db18bc0b4214ed5ef7516d Author: djm@openbsd.org Date: Tue May 3 13:10:24 2016 +0000 upstream commit clarify ordering of subkeys; pointed out by ietf-ssh AT stbuehler.de Upstream-ID: 05ebe9f949449a555ebce8e0aad7c8c9acaf8463 commit cca3b4395807bfb7aaeb83d2838f5c062ce30566 Author: dtucker@openbsd.org Date: Tue May 3 12:15:49 2016 +0000 upstream commit Use a subshell for constructing key types to work around different sed behaviours for -portable. Upstream-Regress-ID: 0f6eb673162df229eda9a134a0f10da16151552d commit fa58208c6502dcce3e0daac0ca991ee657daf1f5 Author: djm@openbsd.org Date: Tue May 3 10:27:59 2016 +0000 upstream commit correct some typos and remove a long-stale XXX note. add specification for ed25519 certificates mention no host certificate options/extensions are currently defined pointed out by Simon Tatham Upstream-ID: 7b535ab7dba3340b7d8210ede6791fdaefdf839a commit b466f956c32cbaff4200bfcd5db6739fe4bc7d04 Author: djm@openbsd.org Date: Tue May 3 10:24:27 2016 +0000 upstream commit add ed25519 keys that are supported but missing from this documents; from Peter Moody Upstream-ID: 8caac2d8e8cfd2fca6dc304877346e0a064b014b commit 7f3d76319a69dab2efe3a520a8fef5b97e923636 Author: dtucker@openbsd.org Date: Tue May 3 09:03:49 2016 +0000 upstream commit Implement IUTF8 as per draft-sgtatham-secsh-iutf8-00. Patch from Simon Tatham, ok markus@ Upstream-ID: 58268ebdf37d9d467f78216c681705a5e10c58e8 commit 31bc01c05d9f51bee3ebe33dc57c4fafb059fb62 Author: djm@openbsd.org Date: Mon May 2 14:10:58 2016 +0000 upstream commit unbreak config parsing on reexec from previous commit Upstream-ID: bc69932638a291770955bd05ca55a32660a613ab commit 67f1459efd2e85bf03d032539283fa8107218936 Author: djm@openbsd.org Date: Mon May 2 09:52:00 2016 +0000 upstream commit unit and regress tests for SHA256/512; ok markus Upstream-Regress-ID: a0cd1a92dc824067076a5fcef83c18df9b0bf2c6 commit 0e8eeec8e75f6d0eaf33317376f773160018a9c7 Author: djm@openbsd.org Date: Mon May 2 10:26:04 2016 +0000 upstream commit add support for additional fixed DH groups from draft-ietf-curdle-ssh-kex-sha2-03 diffie-hellman-group14-sha256 (2K group) diffie-hellman-group16-sha512 (4K group) diffie-hellman-group18-sha512 (8K group) based on patch from Mark D. Baushke and Darren Tucker ok markus@ Upstream-ID: ac00406ada4f0dfec41585ca0839f039545bc46f commit 57464e3934ba53ad8590ee3ccd840f693407fc1e Author: djm@openbsd.org Date: Mon May 2 09:36:42 2016 +0000 upstream commit support SHA256 and SHA512 RSA signatures in certificates; ok markus@ Upstream-ID: b45be2f2ce8cacd794dc5730edaabc90e5eb434a commit 1a31d02b2411c4718de58ce796dbb7b5e14db93e Author: djm@openbsd.org Date: Mon May 2 08:49:03 2016 +0000 upstream commit fix signed/unsigned errors reported by clang-3.7; add sshbuf_dup_string() to replace a common idiom of strdup(sshbuf_ptr()) with better safety checking; feedback and ok markus@ Upstream-ID: 71f926d9bb3f1efed51319a6daf37e93d57c8820 commit d2d6bf864e52af8491a60dd507f85b74361f5da3 Author: djm@openbsd.org Date: Fri Apr 29 08:07:53 2016 +0000 upstream commit close ControlPersist background process stderr when not in debug mode or when logging to a file or syslog. bz#1988 ok dtucker Upstream-ID: 4fb726f0fdcb155ad419913cea10dc4afd409d24 commit 9ee692fa1146e887e008a2b9a3d3ea81770c9fc8 Author: djm@openbsd.org Date: Thu Apr 28 14:30:21 2016 +0000 upstream commit fix comment Upstream-ID: 313a385bd7b69a82f8e28ecbaf5789c774457b15 commit ee1e0a16ff2ba41a4d203c7670b54644b6c57fa6 Author: jmc@openbsd.org Date: Wed Apr 27 13:53:48 2016 +0000 upstream commit cidr permitted for {allow,deny}users; from lars nooden ok djm Upstream-ID: 13e7327fe85f6c63f3f7f069e0fdc8c351515d11 commit b6e0140a5aa883c27b98415bd8aa9f65fc04ee22 Author: djm@openbsd.org Date: Thu Apr 21 06:08:02 2016 +0000 upstream commit make argument == NULL tests more consistent Upstream-ID: dc4816678704aa5cbda3a702e0fa2033ff04581d commit 6aaabc2b610e44bae473457ad9556ffb43d90ee3 Author: jmc@openbsd.org Date: Sun Apr 17 14:34:46 2016 +0000 upstream commit tweak previous; Upstream-ID: 46c1bab91c164078edbccd5f7d06b9058edd814f commit 0f839e5969efa3bda615991be8a9d9311554c573 Author: djm@openbsd.org Date: Fri Apr 15 02:57:10 2016 +0000 upstream commit missing bit of Include regress Upstream-Regress-ID: 1063595f7f40f8489a1b7a27230b9e8acccea34f commit 12e4ac46aed681da55c2bba3cd11dfcab23591be Author: djm@openbsd.org Date: Fri Apr 15 02:55:53 2016 +0000 upstream commit remove redundant CLEANFILES section Upstream-Regress-ID: 29ef1b267fa56daa60a1463396635e7d53afb587 commit b1d05aa653ae560c44baf8e8a9756e33f98ea75c Author: djm@openbsd.org Date: Fri Apr 15 00:48:01 2016 +0000 upstream commit sync CLEANFILES with portable, sort Upstream-Regress-ID: cb782f4f1ab3e079efbc335c6b64942f790766ed commit 35f22dad263cce5c61d933ae439998cb965b8748 Author: djm@openbsd.org Date: Fri Apr 15 00:31:10 2016 +0000 upstream commit regression test for ssh_config Include directive Upstream-Regress-ID: 46a38c8101f635461c506d1aac2d96af80f97f1e commit 6b8a1a87005818d4700ce8b42faef746e82c1f51 Author: djm@openbsd.org Date: Thu Apr 14 23:57:17 2016 +0000 upstream commit unbreak test for recent ssh de-duplicated forwarding change Upstream-Regress-ID: 6b2b115d99acd7cff13986e6739ea214cf2a3da3 commit 076787702418985a2cc6808212dc28ce7afc01f0 Author: djm@openbsd.org Date: Thu Apr 14 23:21:42 2016 +0000 upstream commit add test knob and warning for StrictModes Upstream-Regress-ID: 8cd10952ce7898655ee58945904f2a0a3bdf7682 commit dc7990be865450574c7940c9880567f5d2555b37 Author: djm@openbsd.org Date: Fri Apr 15 00:30:19 2016 +0000 upstream commit Include directive for ssh_config(5); feedback & ok markus@ Upstream-ID: ae3b76e2e343322b9f74acde6f1e1c5f027d5fff commit 85bdcd7c92fe7ff133bbc4e10a65c91810f88755 Author: Damien Miller Date: Wed Apr 13 10:39:57 2016 +1000 ignore PAM environment vars when UseLogin=yes If PAM is configured to read user-specified environment variables and UseLogin=yes in sshd_config, then a hostile local user may attack /bin/login via LD_PRELOAD or similar environment variables set via PAM. CVE-2015-8325, found by Shayan Sadigh, via Colin Watson commit dce19bf6e4a2a3d0b13a81224de63fc316461ab9 Author: djm@openbsd.org Date: Sat Apr 9 12:39:30 2016 +0000 upstream commit make private key loading functions consistently handle NULL key pointer arguments; ok markus@ Upstream-ID: 92038726ef4a338169c35dacc9c5a07fcc7fa761 commit 5f41f030e2feb5295657285aa8c6602c7810bc4b Author: Darren Tucker Date: Fri Apr 8 21:14:13 2016 +1000 Remove NO_IPPORT_RESERVED_CONCEPT Replace by defining IPPORT_RESERVED to zero on Cygwin, which should have the same effect without causing problems syncing patches with OpenBSD. Resync the two affected functions with OpenBSD. ok djm, sanity checked by Corinna. commit 34a01b2cf737d946ddb140618e28c3048ab7a229 Author: djm@openbsd.org Date: Fri Apr 8 08:19:17 2016 +0000 upstream commit whitespace at EOL Upstream-ID: 5beffd4e001515da12851b974e2323ae4aa313b6 commit 90ee563fa6b54c59896c6c332c5188f866c5e75f Author: djm@openbsd.org Date: Fri Apr 8 06:35:54 2016 +0000 upstream commit We accidentally send an empty string and a zero uint32 with every direct-streamlocal@openssh.com channel open, in contravention of our own spec. Fixing this is too hard wrt existing versions that expect these fields to be present and fatal() if they aren't, so document them as "reserved" fields in the PROTOCOL spec as though we always intended this and let us never speak of it again. bz#2529, reported by Ron Frederick Upstream-ID: 34cd326a4d236ca6e39084c4ff796bd97ab833e7 commit 0ccbd5eca0f0dd78e71a4b69c66f03a66908d558 Author: djm@openbsd.org Date: Wed Apr 6 06:42:17 2016 +0000 upstream commit don't record duplicate LocalForward and RemoteForward entries; fixes failure with ExitOnForwardFailure+hostname canonicalisation where the same forwards are added on the second pass through the configuration file. bz#2562; ok dtucker@ Upstream-ID: 40a51d68b6300f1cc61deecdb7d4847b8b7b0de1 commit 574def0eb493cd6efeffd4ff2e9257abcffee0c8 Author: krw@openbsd.org Date: Sat Apr 2 14:37:42 2016 +0000 upstream commit Another use for fcntl() and thus of the superfluous 3rd parameter is when sanitising standard fd's before calling daemon(). Use a tweaked version of the ssh(1) function in all three places found using fcntl() this way. ok jca@ beck@ Upstream-ID: f16811ffa19a1c5f4ef383c5f0fecb843c84e218 commit b3413534aa9d71a941005df2760d1eec2c2b0854 Author: Darren Tucker Date: Mon Apr 4 11:09:21 2016 +1000 Tidy up openssl header test. commit 815bcac0b94bb448de5acdd6ba925b8725240b4f Author: Darren Tucker Date: Mon Apr 4 11:07:59 2016 +1000 Fix configure-time warnings for openssl test. commit 95687f5831ae680f7959446d8ae4b52452ee05dd Author: djm@openbsd.org Date: Fri Apr 1 02:34:10 2016 +0000 upstream commit whitespace at EOL Upstream-ID: 40ae2203d07cb14e0a89e1a0d4c6120ee8fd8c3a commit fdfbf4580de09d84a974211715e14f88a5704b8e Author: dtucker@openbsd.org Date: Thu Mar 31 05:24:06 2016 +0000 upstream commit Remove fallback from moduli to "primes" file that was deprecated in 2001 and fix log messages referring to primes file. Based on patch from xnox at ubuntu.com via bz#2559. "kill it" deraadt@ Upstream-ID: 0d4f8c70e2fa7431a83b95f8ca81033147ba8713 commit 0235a5fa67fcac51adb564cba69011a535f86f6b Author: djm@openbsd.org Date: Thu Mar 17 17:19:43 2016 +0000 upstream commit UseDNS affects ssh hostname processing in authorized_keys, not known_hosts; bz#2554 reported by jjelen AT redhat.com Upstream-ID: c1c1bb895dde46095fc6d81d8653703928437591 commit 8c4739338f5e379d05b19d6e544540114965f07e Author: Darren Tucker Date: Tue Mar 15 09:24:43 2016 +1100 Don't call Solaris setproject() with UsePAM=yes. When Solaris Projects are enabled along with PAM setting the project is PAM's responsiblity. bz#2425, based on patch from brent.paulson at gmail.com. commit cff26f373c58457a32cb263e212cfff53fca987b Author: Damien Miller Date: Tue Mar 15 04:30:21 2016 +1100 remove slogin from *.spec commit c38905ba391434834da86abfc988a2b8b9b62477 Author: djm@openbsd.org Date: Mon Mar 14 16:20:54 2016 +0000 upstream commit unbreak authentication using lone certificate keys in ssh-agent: when attempting pubkey auth with a certificate, if no separate private key is found among the keys then try with the certificate key itself. bz#2550 reported by Peter Moody Upstream-ID: f939cd76d68e6a9a3d1711b5a943d6ed1e623966 commit 4b4bfb01cd40b9ddb948e6026ddd287cc303d871 Author: djm@openbsd.org Date: Thu Mar 10 11:47:57 2016 +0000 upstream commit sanitise characters destined for xauth reported by github.com/tintinweb feedback and ok deraadt and markus Upstream-ID: 18ad8d0d74cbd2ea3306a16595a306ee356aa261 commit 732b463d37221722b1206f43aa59563766a6a968 Author: Darren Tucker Date: Mon Mar 14 16:04:23 2016 +1100 Pass supported malloc options to connect-privsep. This allows us to activate only the supported options during the malloc option portion of the connect-privsep test. commit d29c5b9b3e9f27394ca97a364ed4bb4a55a59744 Author: Darren Tucker Date: Mon Mar 14 09:30:58 2016 +1100 Remove leftover roaming.h file. Pointed out by des at des.no. commit 8ff20ec95f4377021ed5e9b2331320f5c5a34cea Author: Darren Tucker Date: Mon Mar 14 09:24:03 2016 +1100 Quote variables that may contain whitespace. The variable $L_TMP_ID_FILE needs to be surrounded by quotes in order to survive paths containing whitespace. bz#2551, from Corinna Vinschen via Philip Hands. commit 627824480c01f0b24541842c7206ab9009644d02 Author: Darren Tucker Date: Fri Mar 11 14:47:41 2016 +1100 Include priv.h for priv_set_t. From alex at cooperi.net. commit e960051f9a264f682c4d2fefbeecffcfc66b0ddf Author: Darren Tucker Date: Wed Mar 9 13:14:18 2016 +1100 Wrap stdint.h inside #ifdef HAVE_STDINT_H. commit 2c48bd344d2c4b5e08dae9aea5ff44fc19a5e363 Author: Darren Tucker Date: Wed Mar 9 12:46:50 2016 +1100 Add compat to monotime_double(). Apply all of the portability changes in monotime() to monotime() double. Fixes build on at least older FreeBSD systems. commit 7b40ef6c2eef40c339f6ea8920cb8a44838e10c9 Author: Damien Miller Date: Tue Mar 8 14:12:58 2016 -0800 make a regress-binaries target Easier to build all the regression/unit test binaries in one pass than going through all of ${REGRESS_BINARIES} commit c425494d6b6181beb54a1b3763ef9e944fd3c214 Author: Damien Miller Date: Tue Mar 8 14:03:54 2016 -0800 unbreak kexfuzz for -Werror without __bounded__ commit 3ed9218c336607846563daea5d5ab4f701f4e042 Author: Damien Miller Date: Tue Mar 8 14:01:29 2016 -0800 unbreak PAM after canohost refactor commit 885fb2a44ff694f01e4f6470f803629e11f62961 Author: Darren Tucker Date: Tue Mar 8 11:58:43 2016 +1100 auth_get_canonical_hostname in portable code. "refactor canohost.c" replaced get_canonical_hostname, this makes the same change to some portable-specific code. commit 95767262caa6692eff1e1565be1f5cb297949a89 Author: djm@openbsd.org Date: Mon Mar 7 19:02:43 2016 +0000 upstream commit refactor canohost.c: move functions that cache results closer to the places that use them (authn and session code). After this, no state is cached in canohost.c feedback and ok markus@ Upstream-ID: 5f2e4df88d4803fc8ec59ec53629105e23ce625e commit af0bb38ffd1f2c4f9f43b0029be2efe922815255 Author: Damien Miller Date: Fri Mar 4 15:11:55 2016 +1100 hook unittests/misc/kexfuzz into build commit 331b8e07ee5bcbdca12c11cc8f51a7e8de09b248 Author: dtucker@openbsd.org Date: Fri Mar 4 02:48:06 2016 +0000 upstream commit Filter debug messages out of log before picking the last two lines. Should prevent problems if any more debug output is added late in the connection. Upstream-Regress-ID: 345d0a9589c381e7d640a4ead06cfaadf4db1363 commit 0892edaa3ce623381d3a7635544cbc69b31cf9cb Author: djm@openbsd.org Date: Fri Mar 4 02:30:36 2016 +0000 upstream commit add KEX fuzzer harness; ok deraadt@ Upstream-Regress-ID: 3df5242d30551b12b828aa9ba4a4cec0846be8d1 commit ae2562c47d41b68dbb00240fd6dd60bed205367a Author: dtucker@openbsd.org Date: Thu Mar 3 00:46:53 2016 +0000 upstream commit Look back 3 lines for possible error messages. Changes to the code mean that "Bad packet length" errors are 3 lines back instead of the previous two, which meant we didn't skip some offsets that we intended to. Upstream-Regress-ID: 24f36912740a634d509a3144ebc8eb7c09b9c684 commit 988e429d903acfb298bfddfd75e7994327adfed0 Author: djm@openbsd.org Date: Fri Mar 4 03:35:44 2016 +0000 upstream commit fix ClientAliveInterval when a time-based RekeyLimit is set; previously keepalive packets were not being sent. bz#2252 report and analysis by Christian Wittenhorst and Garrett Lee feedback and ok dtucker@ Upstream-ID: d48f9deadd35fdacdd5106b41bb07630ddd4aa81 commit 8ef04d7a94bcdb8b0085fdd2a79a844b7d40792d Author: dtucker@openbsd.org Date: Wed Mar 2 22:43:52 2016 +0000 upstream commit Improve accuracy of reported transfer speeds by waiting for the ack from the other end. Pointed out by mmcc@, ok deraadt@ markus@ Upstream-ID: 99f1cf15c9a8f161086b814d414d862795ae153d commit b8d4eafe29684fe4f5bb587f7eab948e6ed62723 Author: dtucker@openbsd.org Date: Wed Mar 2 22:42:40 2016 +0000 upstream commit Improve precision of progressmeter for sftp and scp by storing sub-second timestamps. Pointed out by mmcc@, ok deraadt@ markus@ Upstream-ID: 38fd83a3d83dbf81c8ff7b5d1302382fe54970ab commit 18f64b969c70ed00e74b9d8e50359dbe698ce4c0 Author: jca@openbsd.org Date: Mon Feb 29 20:22:36 2016 +0000 upstream commit Print ssize_t with %zd; ok deraadt@ mmcc@ Upstream-ID: 0590313bbb013ff6692298c98f7e0be349d124bd commit 6e7f68ce38130c794ec1fb8d2a6091fbe982628d Author: djm@openbsd.org Date: Sun Feb 28 22:27:00 2016 +0000 upstream commit rearrange DH public value tests to be a little more clear rearrange DH private value generation to explain rationale more clearly and include an extra sanity check. ok deraadt Upstream-ID: 9ad8a07e1a12684e1b329f9bd88941b249d4b2ad commit 2ed17aa34008bdfc8db674315adc425a0712be11 Author: Darren Tucker Date: Tue Mar 1 15:24:20 2016 +1100 Import updated moduli file from OpenBSD. Note that 1.5k bit groups have been removed. 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 openssh-7.5p1/moduli.0010064400017500001750000000065661306372317000130450ustar00djmdjmMODULI(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 6.0 September 26, 2012 OpenBSD 6.0 openssh-7.5p1/scp.0010064400017500001750000000141301306372317000123230ustar00djmdjmSCP(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 IdentitiesOnly IdentityAgent IdentityFile IPQoS KbdInteractiveAuthentication KbdInteractiveDevices KexAlgorithms LogLevel MACs NoHostAuthenticationForLocalhost NumberOfPasswordPrompts PasswordAuthentication PKCS11Provider Port PreferredAuthentications Protocol ProxyCommand ProxyJump 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 6.0 July 16, 2016 OpenBSD 6.0 openssh-7.5p1/ssh-add.0010064400017500001750000000124531306372317000130670ustar00djmdjmSSH-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 6.0 March 30, 2015 OpenBSD 6.0 openssh-7.5p1/ssh-agent.0010064400017500001750000000131501306372317000134300ustar00djmdjmSSH-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] [-P pkcs11_whitelist] [-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). -P pkcs11_whitelist Specify a pattern-list of acceptable paths for PKCS#11 shared libraries that may be added using the -s option to ssh-add(1). The default is to allow loading PKCS#11 libraries from M-bM-^@M-^\/usr/lib/*,/usr/local/lib/*M-bM-^@M-^]. PKCS#11 libraries that do not match the whitelist will be refused. See PATTERNS in ssh_config(5) for a description of pattern-list syntax. -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 6.0 November 30, 2016 OpenBSD 6.0 openssh-7.5p1/ssh-keygen.0010064400017500001750000000665321306372317000136300ustar00djmdjmSSH-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 and keys stored in the newer OpenSSH format, 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 and keys stored in the newer OpenSSH format. 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, a visual 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 6.0 June 16, 2016 OpenBSD 6.0 openssh-7.5p1/ssh-keyscan.0010064400017500001750000000111121306372317000137630ustar00djmdjmSSH-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 6.0 November 8, 2015 OpenBSD 6.0 openssh-7.5p1/ssh.0010064400017500001750000001372441306372317000123470ustar00djmdjmSSH(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] [-J [user@]host[:port]] [-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. -J [user@]host[:port] Connect to the target host by first making a ssh connection to the jump host and then establishing a TCP forwarding to the ultimate destination from there. Multiple jump hops may be specified separated by comma characters. This is a shortcut to specify a ProxyJump configuration directive. -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 IdentitiesOnly IdentityAgent IdentityFile Include IPQoS KbdInteractiveAuthentication KbdInteractiveDevices KexAlgorithms LocalCommand LocalForward LogLevel MACs Match NoHostAuthenticationForLocalhost NumberOfPasswordPrompts PasswordAuthentication PermitLocalCommand PKCS11Provider Port PreferredAuthentications Protocol ProxyCommand ProxyJump 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, though these can be overridden in the configuration file or using -o command line options. -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 6.0 July 16, 2016 OpenBSD 6.0 openssh-7.5p1/sshd.0010064400017500001750000000770001306372317000125040ustar00djmdjmSSHD(8) System Manager's Manual SSHD(8) NAME sshd M-bM-^@M-^S OpenSSH SSH daemon SYNOPSIS sshd [-46DdeiqTt] [-C connection_spec] [-c host_certificate_file] [-E log_file] [-f config_file] [-g login_grace_time] [-h host_key_file] [-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. -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_dsa_key, /etc/ssh/ssh_host_ecdsa_key, /etc/ssh/ssh_host_ed25519_key and /etc/ssh/ssh_host_rsa_key. It is possible to have multiple host key files for the different host key algorithms. -i Specifies that sshd is being run from inetd(8). -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 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 protocol 2 only. Each host has a host-specific key, used to identify the host. Whenever a client connects, the daemon responds with its public host key. The client compares the host key against its own database to verify that it has not changed. 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). Public keys consist of the following space- separated fields: options, keytype, base64-encoded key, comment. The options field is optional. 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-^]; the comment field is not used for anything (but may be convenient for the user to identify the key). Note that lines in this file can be 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 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 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, e.g. using the restrict key option. 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 a sshd_config(5) ForceCommand directive. If a command is specified and a forced-command is embedded in a certificate used for authentication, then the certificate will be accepted only if the two commands are identical. 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. 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 to an unknown host, its key is added to the per-user file. Each line in these files contains the following fields: markers (optional), hostnames, keytype, base64-encoded key, 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. The keytype and base64-encoded key are taken directly from the host key; they can be obtained, for example, from /etc/ssh/ssh_host_rsa_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, for example, /etc/ssh/ssh_host_rsa_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_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_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 6.0 January 30, 2017 OpenBSD 6.0 openssh-7.5p1/sftp-server.0010064400017500001750000000103461306372317000140230ustar00djmdjmSFTP-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 6.0 December 11, 2014 OpenBSD 6.0 openssh-7.5p1/sftp.0010064400017500001750000000365021306372317000125210ustar00djmdjmSFTP(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 IdentitiesOnly IdentityAgent IdentityFile IPQoS KbdInteractiveAuthentication KbdInteractiveDevices KexAlgorithms LogLevel MACs NoHostAuthenticationForLocalhost NumberOfPasswordPrompts PasswordAuthentication PKCS11Provider Port PreferredAuthentications Protocol ProxyCommand ProxyJump 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 6.0 July 16, 2016 OpenBSD 6.0 openssh-7.5p1/ssh-keysign.0010064400017500001750000000035001306372317000140010ustar00djmdjmSSH-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 6.0 February 17, 2016 OpenBSD 6.0 openssh-7.5p1/ssh-pkcs11-helper.0010064400017500001750000000012021306372317000147040ustar00djmdjmSSH-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 6.0 July 16, 2013 OpenBSD 6.0 openssh-7.5p1/sshd_config.0010064400017500001750000001471031306372317000140330ustar00djmdjmSSHD_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 any (the default), inet (use IPv4 only), or inet6 (use IPv6 only). AllowAgentForwarding Specifies whether ssh-agent(1) forwarding is permitted. The default is 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. 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. AllowStreamLocalForwarding Specifies whether StreamLocal (Unix-domain socket) forwarding is permitted. The available options are yes (the default) or all to allow StreamLocal forwarding, no to prevent all StreamLocal forwarding, local to allow local (from the perspective of ssh(1)) forwarding only or remote to allow remote forwarding only. Note that disabling StreamLocal forwarding does not improve security unless users are also denied shell access, as they can always install their own forwarders. AllowTcpForwarding Specifies whether TCP forwarding is permitted. The available options are yes (the default) or all to allow TCP forwarding, no to prevent all TCP forwarding, local to allow local (from the perspective of ssh(1)) forwarding only or remote to allow remote forwarding only. Note that disabling TCP 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. HOST criteria may additionally contain addresses to match in CIDR address/masklen format. 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, or by the single string any to indicate the default behaviour of accepting any single authentication method. If the default is overridden, then successful authentication requires completion of every method in at least one of these lists. For example, "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. For keyboard interactive authentication it is also possible to restrict authentication to a specific device by appending a colon followed by the device identifier bsdauth, pam, or skey, depending on the server configuration. For example, "keyboard-interactive:bsdauth" would restrict keyboard interactive authentication to the bsdauth device. If the publickey method is listed more than once, sshd(8) verifies that keys that have been used successfully are not reused for subsequent authentications. For example, "publickey,publickey" requires successful authentication using two different public keys. Note that each authentication method listed should also be explicitly enabled in the configuration. 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 accept the tokens described in the TOKENS section. If no arguments are specified then the username of the target user is used. 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 used for user authentication. The format is described in the AUTHORIZED_KEYS FILE FORMAT section of sshd(8). Arguments to AuthorizedKeysFile accept the tokens described in the TOKENS section. 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 none to skip checking for user keys in files. The default is ".ssh/authorized_keys .ssh/authorized_keys2". 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 accept the tokens described in the TOKENS section. If no arguments are specified then the username of the target user is used. 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. Arguments to AuthorizedPrincipalsFile accept the tokens described in the TOKENS section. After expansion, AuthorizedPrincipalsFile is taken to be an absolute path or one relative to the user's home directory. The default is none, 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 none 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 yes. 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. Arguments to ChrootDirectory accept the tokens described in the TOKENS section. 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 SFTP 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 none, 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. If the specified value begins with a M-bM-^@M-^X-M-bM-^@M-^Y character, then the specified ciphers (including wildcards) will be removed from 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 "ssh -Q cipher". ClientAliveCountMax Sets the number of client alive messages 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. 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 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 enabled after the user has authenticated successfully. The argument must be yes, delayed (a legacy synonym for yes) or no. The default is yes. 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. HOST criteria may additionally contain addresses to match in CIDR address/masklen format. 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. DisableForwarding Disables all forwarding features, including X11, ssh-agent(1), TCP and StreamLocal. This option overrides all other forwarding- related options and may simplify restricted configurations. FingerprintHash Specifies the hash algorithm used when logging key fingerprints. Valid options are: md5 and sha256. The default is sha256. 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 internal-sftp will force the use of an in-process SFTP server that requires no support files when used with ChrootDirectory. The default is none. 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 no to force remote port forwardings to be available to the local host only, yes to force remote port forwardings to bind to the wildcard address, or clientspecified to allow the client to select the address to which the forwarding is bound. The default is no. GSSAPIAuthentication Specifies whether user authentication based on GSSAPI is allowed. The default is no. GSSAPICleanupCredentials Specifies whether to automatically destroy the user's credentials cache on logout. The default is yes. GSSAPIStrictAcceptorCheck Determines whether to be strict about the identity of the GSSAPI acceptor a client authenticates against. If set to yes then the client must authenticate against the host service on the current hostname. If set to 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 yes. 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. If the specified value begins with a M-bM-^@M-^X-M-bM-^@M-^Y character, then the specified key types (including wildcards) will be removed from 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 list of available key types may also be obtained using "ssh -Q key". 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 no. 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 yes 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 no. 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 defaults are /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. 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. 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 the string "SSH_AUTH_SOCK" 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 "ssh -Q key". IgnoreRhosts Specifies that .rhosts and .shosts files will not be used in HostbasedAuthentication. /etc/hosts.equiv and /etc/shosts.equiv are still used. The default is yes. IgnoreUserKnownHosts Specifies whether sshd(8) should ignore the user's ~/.ssh/known_hosts during HostbasedAuthentication. The default is no. IPQoS Specifies the IPv4 type-of-service or DSCP class for the connection. Accepted values are af11, af12, af13, af21, af22, af23, af31, af32, af33, af41, af42, af43, cs0, cs1, cs2, cs3, cs4, cs5, cs6, cs7, ef, lowdelay, throughput, 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 lowdelay for interactive sessions and throughput for non-interactive sessions. KbdInteractiveAuthentication Specifies whether to allow keyboard-interactive authentication. The argument to this keyword must be yes or no. The default is to use whatever value ChallengeResponseAuthentication is set to (by default yes). 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 no. 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 no. 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 yes. KerberosTicketCleanup Specifies whether to automatically destroy the user's ticket cache file on logout. The default is yes. 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. If the specified value begins with a M-bM-^@M-^X-M-bM-^@M-^Y character, then the specified methods (including wildcards) will be removed from the default set instead of replacing them. The supported algorithms are: curve25519-sha256 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,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 "ssh -Q kex". 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. If the specified value begins with a M-bM-^@M-^X-M-bM-^@M-^Y character, then the specified algorithms (including wildcards) will be removed from the default set instead of replacing them. The algorithms that contain "-etm" 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 "ssh -Q mac". 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, such as 192.0.2.0/24 or 2001:db8::/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, 192.0.2.0/33 and 192.0.2.0/8, 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, ClientAliveCountMax, ClientAliveInterval, DenyGroups, DenyUsers, ForceCommand, GatewayPorts, GSSAPIAuthentication, HostbasedAcceptedKeyTypes, HostbasedAuthentication, HostbasedUsesNameFromPacketOnly, IPQoS, KbdInteractiveAuthentication, KerberosAuthentication, MaxAuthTries, MaxSessions, PasswordAuthentication, PermitEmptyPasswords, PermitOpen, PermitRootLogin, PermitTTY, PermitTunnel, PermitUserRC, PubkeyAcceptedKeyTypes, PubkeyAuthentication, RekeyLimit, RevokedKeys, 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 start:rate:full (e.g. "10:30:60"). sshd(8) will refuse connection attempts with a probability of rate/100 (30%) if there are currently start (10) unauthenticated connections. The probability increases linearly and all connection attempts are refused if the number of unauthenticated connections reaches full (60). PasswordAuthentication Specifies whether password authentication is allowed. The default is yes. PermitEmptyPasswords When password authentication is allowed, it specifies whether the server allows login to accounts with empty password strings. The default is no. 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 any can be used to remove all restrictions and permit any forwarding requests. An argument of none can be used to prohibit all forwarding requests. The wildcard M-bM-^@M-^X*M-bM-^@M-^Y can be used for host or port to allow all hosts or ports, respectively. By default all port forwarding requests are permitted. PermitRootLogin Specifies whether root can log in using ssh(1). The argument must be yes, prohibit-password, without-password, forced-commands-only, or no. The default is prohibit-password. If this option is set to prohibit-password or without-password, password and keyboard-interactive authentication are disabled for root. If this option is set to forced-commands-only, 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 no, root is not allowed to log in. PermitTTY Specifies whether pty(4) allocation is permitted. The default is yes. PermitTunnel Specifies whether tun(4) device forwarding is allowed. The argument must be yes, point-to-point (layer 3), ethernet (layer 2), or no. Specifying yes permits both point-to-point and ethernet. The default is no. Independent of this setting, the permissions of the selected tun(4) device must allow access to the user. PermitUserEnvironment Specifies whether ~/.ssh/environment and environment= options in ~/.ssh/authorized_keys are processed by sshd(8). The default is no. 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 yes. PidFile Specifies the file that contains the process ID of the SSH daemon, or none 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 yes. 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 yes. 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. If the specified value begins with a M-bM-^@M-^X-M-bM-^@M-^Y character, then the specified key types (including wildcards) will be removed from 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 list of available key types may also be obtained using "ssh -Q key". PubkeyAuthentication Specifies whether public key authentication is allowed. The default is yes. 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 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. RevokedKeys Specifies revoked public keys file, or 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 ssh-keygen(1). For more information on KRLs, see the KEY REVOCATION LISTS section in ssh-keygen(1). 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 yes or no. The default is no. 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 yes. 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 implements the SFTP file transfer subsystem. Alternately the name internal-sftp implements an in-process SFTP 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 "ghost" users and consuming server resources. The default is 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. To disable TCP keepalive messages, the value should be set to no. TrustedUserCAKeys Specifies a file containing public keys of certificate authorities that are trusted to sign user certificates for authentication, or none 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 no (the default) then only addresses and not host names may be used in ~/.ssh/authorized_keys from and sshd_config Match Host directives. UsePAM Enables the Pluggable Authentication Module interface. If set to yes 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 no. VersionAddendum Optionally specifies additional text to append to the SSH protocol banner sent by the server upon connection. The default is none. 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 yes or no. The default is no. 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), 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 no setting. Note that disabling X11 forwarding does not prevent users from forwarding X11 traffic, as users can always install their own forwarders. 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 localhost. 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 no to specify that the forwarding server should be bound to the wildcard address. The argument must be yes or no. The default is yes. XAuthLocation Specifies the full pathname of the xauth(1) program, or none 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) TOKENS Arguments to some keywords can make use of tokens, which are expanded at runtime: %% A literal M-bM-^@M-^X%M-bM-^@M-^Y. %F The fingerprint of the CA key. %f The fingerprint of the key or certificate. %h The home directory of the user. %i The key ID in the certificate. %K The base64-encoded CA key. %k The base64-encoded key or certificate for authentication. %s The serial number of the certificate. %T The type of the CA key. %t The key or certificate type. %u The username. AuthorizedKeysCommand accepts the tokens %%, %f, %h, %k, %t, and %u. AuthorizedKeysFile accepts the tokens %%, %h, and %u. AuthorizedPrincipalsCommand accepts the tokens %%, %F, %f, %h, %i, %K, %k, %s, %T, %t, and %u. AuthorizedPrincipalsFile accepts the tokens %%, %h, and %u. ChrootDirectory accepts the tokens %%, %h, and %u. 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 sftp-server(8), 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 6.0 March 14, 2017 OpenBSD 6.0 openssh-7.5p1/ssh_config.0010064400017500001750000001614041306372317000136670ustar00djmdjmSSH_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 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 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 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. 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. 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 keyword 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. Arguments to exec accept the tokens described in the TOKENS section. 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 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 ssh-add(1). If this option is set to ask, ssh(1) will require confirmation using the SSH_ASKPASS program before adding a key (see ssh-add(1) for details). If this option is set to confirm, 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 no, no keys are added to the agent. The argument must be yes, confirm, ask, or no (the default). AddressFamily Specifies which address family to use when connecting. Valid arguments are any (the default), inet (use IPv4 only), or inet6 (use IPv6 only). BatchMode If set to 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 yes or no (the default). 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 yes. 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, yes, will attempt to look up the unqualified hostname using the system resolver's search rules. A value of no 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, no, is not to perform any name rewriting and let the system resolver handle all hostname lookups. If set to yes 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 always, 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, 1, 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, "*.a.example.com:*.b.example.com,*.c.example.com" will allow hostnames matching "*.a.example.com" to be canonicalized to names in the "*.b.example.com" or "*.c.example.com" 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. Arguments to CertificateFile may use the tilde syntax to refer to a user's home directory or the tokens described in the TOKENS section. 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 yes (the default) or no. CheckHostIP If set to yes (the default), ssh(1) will additionally check the host IP address in the known_hosts file. This allows it 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 no, the check will not be executed. Cipher Specifies the cipher to use for encrypting the session in protocol version 1. Currently, blowfish, 3des (the default), and des are supported, though des is only supported in the ssh(1) client for interoperability with legacy protocol 1 implementations; its use is strongly discouraged due to cryptographic weaknesses. 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. If the specified value begins with a M-bM-^@M-^X-M-bM-^@M-^Y character, then the specified ciphers (including wildcards) will be removed from 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 The list of available ciphers may also be obtained using "ssh -Q cipher". 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 yes or no (the default). Compression Specifies whether to use compression. The argument must be yes or no (the default). 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 yes, 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 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. Setting this to ask will cause ssh(1) to listen for control connections, but require confirmation using ssh-askpass(1). If the ControlPath cannot be opened, ssh(1) 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: auto and autoask. The latter requires confirmation like the ask option. ControlPath Specify the path to the control socket used for connection sharing as described in the ControlMaster section above or the string none to disable connection sharing. Arguments to ControlPath may use the tilde syntax to refer to a user's home directory or the tokens described in the TOKENS section. 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 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 yes or 0, then the master connection will remain in the background indefinitely (until killed or closed via a mechanism such as the "ssh -O exit"). 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 localhost 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 yes 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 yes or no (the default). 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 none 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 yes or no (the default). FingerprintHash Specifies the hash algorithm used when displaying key fingerprints. Valid options are: md5 and sha256 (the default). ForwardAgent Specifies whether the connection to the authentication agent (if any) will be forwarded to the remote machine. The argument must be yes or no (the default). 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 yes or no (the default). 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 yes, remote X11 clients will have full access to the original X11 display. If this option is set to no (the default), 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. 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 yes or no (the default). 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 no. GSSAPIDelegateCredentials Forward (delegate) credentials to the server. The default is no. 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 no. 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 yes or no (the default). 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. If the specified value begins with a M-bM-^@M-^X-M-bM-^@M-^Y character, then the specified key types (including wildcards) will be removed from 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. If the specified value begins with a M-bM-^@M-^X-M-bM-^@M-^Y character, then the specified key types (including wildcards) will be removed from 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 "ssh -Q key". 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. Arguments to HostName accept the tokens described in the TOKENS section. Numeric IP addresses are also permitted (both on the command line and in HostName specifications). The default is the name given on the command line. 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 yes or no (the default). This option is intended for situations where ssh-agent offers many different identities. IdentityAgent Specifies the UNIX-domain socket used to communicate with the authentication agent. This option overrides the SSH_AUTH_SOCK environment variable and can be used to select a specific agent. Setting the socket name to none disables the use of an authentication agent. If the string "SSH_AUTH_SOCK" is specified, the location of the socket will be read from the SSH_AUTH_SOCK environment variable. Arguments to IdentityAgent may use the tilde syntax to refer to a user's home directory or the tokens described in the TOKENS section. 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. Arguments to IdentityFile may use the tilde syntax to refer to a user's home directory or the tokens described in the TOKENS section. 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. Include Include the specified configuration file(s). Multiple pathnames may be specified and each pathname may contain glob(3) wildcards and, for user configurations, shell-like M-bM-^@M-^X~M-bM-^@M-^Y references to user home directories. Files without absolute paths are assumed to be in ~/.ssh if included in a user configuration file or /etc/ssh if included from the system configuration file. Include directive may appear inside a Match or Host block to perform conditional inclusion. IPQoS Specifies the IPv4 type-of-service or DSCP class for connections. Accepted values are af11, af12, af13, af21, af22, af23, af31, af32, af33, af41, af42, af43, cs0, cs1, cs2, cs3, cs4, cs5, cs6, cs7, ef, lowdelay, throughput, 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 lowdelay for interactive sessions and throughput for non-interactive sessions. KbdInteractiveAuthentication Specifies whether to use keyboard-interactive authentication. The argument to this keyword must be yes (the default) or no. 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: bsdauth, pam, and skey. 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. If the specified value begins with a M-bM-^@M-^X-M-bM-^@M-^Y character, then the specified methods (including wildcards) will be removed from the default set instead of replacing them. The default is: curve25519-sha256,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 "ssh -Q kex". 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. Arguments to LocalCommand accept the tokens described in the TOKENS section. 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 localhost 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. If the specified value begins with a M-bM-^@M-^X-M-bM-^@M-^Y character, then the specified algorithms (including wildcards) will be removed from the default set instead of replacing them. The algorithms that contain "-etm" 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 "ssh -Q mac". 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 yes or no (the default). 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 yes (the default) or no. PermitLocalCommand Allow local command execution via the LocalCommand option or using the !command escape sequence in ssh(1). The argument must be yes or no (the default). 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 1 and 2. Multiple versions must be comma-separated. When this option is set to 2,1 ssh will try version 2 and fall back to version 1 if version 2 is not available. The default is version 2. 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. Arguments to ProxyCommand accept the tokens described in the TOKENS section. 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 none 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 ProxyJump Specifies one or more jump proxies as [user@]host[:port]. Multiple proxies may be separated by comma characters and will be visited sequentially. Setting this option will cause ssh(1) to connect to the target host by first making a ssh(1) connection to the specified ProxyJump host and then establishing a TCP forwarding to the ultimate target from there. Note that this option will compete with the ProxyCommand option - whichever is specified first will prevent later instances of the other from taking effect. 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 no. 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. If the specified value begins with a M-bM-^@M-^X-M-bM-^@M-^Y character, then the specified key types (including wildcards) will be removed from 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 list of available key types may also be obtained using "ssh -Q key". PubkeyAuthentication Specifies whether to try public key authentication. The argument to this keyword must be yes (the default) or no. 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 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. 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 0, 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: no (never request a TTY), yes (always request a TTY when standard input is a TTY), force (always request a TTY) or auto (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 yes or no (the default). 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 yes (the default) or no. RSA authentication will only be attempted if the identity file exists, or an authentication agent is running. 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 yes or no (the default). StrictHostKeyChecking If this flag is set to yes, 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 no, ssh will automatically add new host keys to the user known hosts files. If this flag is set to ask (the default), 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. 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 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. To disable TCP keepalive messages, the value should be set to no. Tunnel Request tun(4) device forwarding between the client and the server. The argument must be yes, point-to-point (layer 3), ethernet (layer 2), or no (the default). Specifying yes requests the default tunnel mode, which is point-to-point. 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 any, which uses the next available tunnel device. If remote_tun is not specified, it defaults to any. The default is any:any. 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 yes, no (the default) or 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 UpdateHostKeys is set to ask, 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 "hostkeys@openssh.com" 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 yes or no (the default). If set to yes, ssh(1) must be setuid root. Note that this option must be set to yes 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 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 ask. If this option is set to ask, information on fingerprint match will be displayed, but the user will still need to confirm new host keys according to the StrictHostKeyChecking option. The default is no. See also VERIFYING HOST KEYS in ssh(1). VisualHostKey If this flag is set to 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 no (the default), no fingerprint strings are printed at login and only the fingerprint string will be printed for unknown host keys. 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 ".co.uk" 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 "dialup" pool, the following entry (in authorized_keys) could be used: from="!*.dialup.example.com,*.example.com" TOKENS Arguments to some keywords can make use of tokens, which are expanded at runtime: %% A literal M-bM-^@M-^X%M-bM-^@M-^Y. %C Shorthand for %l%h%p%r. %d Local user's home directory. %h The remote hostname. %i The local user ID. %L The local hostname. %l The local hostname, including the domain name. %n The original remote hostname, as given on the command line. %p The remote port. %r The remote username. %u The local username. Match exec accepts the tokens %%, %h, %L, %l, %n, %p, %r, and %u. CertificateFile accepts the tokens %%, %d, %h, %l, %r, and %u. ControlPath accepts the tokens %%, %C, %h, %i, %L, %l, %n, %p, %r, and %u. HostName accepts the tokens %% and %h. IdentityAgent and IdentityFile accept the tokens %%, %d, %h, %l, %r, and %u. LocalCommand accepts the tokens %%, %C, %d, %h, %l, %n, %p, %r, and %u. ProxyCommand accepts the tokens %%, %h, %p, and %r. 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 6.0 February 27, 2017 OpenBSD 6.0 openssh-7.5p1/configure010075500017500001750000020141371306372320100133700ustar00djmdjm#! /bin/sh # From configure.ac Revision: 1.583 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for OpenSSH Portable. # # Report bugs to . # # # Copyright (C) 1992-1996, 1998-2012 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=: # Pre-4.2 versions of Zsh do 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_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } 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.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= 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 $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do 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_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and $0: openssh-unix-dev@mindrot.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_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 || $as_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" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error 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 if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # 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 as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # 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" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # 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 } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac 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 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then 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 -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' 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='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # 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'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/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= # Identity of this package. PACKAGE_NAME='OpenSSH' PACKAGE_TARNAME='openssh' PACKAGE_VERSION='Portable' PACKAGE_STRING='OpenSSH Portable' PACKAGE_BUGREPORT='openssh-unix-dev@mindrot.org' PACKAGE_URL='' 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='LTLIBOBJS LIBOBJS UNSUPPORTED_ALGORITHMS TEST_MALLOC_OPTIONS TEST_SSH_UTF8 TEST_SSH_IPV6 piddir user_path mansubdir MANTYPE XAUTH_PATH STRIP_OPT xauth_path PRIVSEP_PATH K5LIBS GSSLIBS KRB5CONF SSHDLIBS SSHLIBS SSH_PRIVSEP_USER COMMENT_OUT_ECC TEST_SSH_ECC LIBEDIT PKGCONFIG LDNSCONFIG COMMENT_OUT_RSA1 LD PATH_PASSWD_PROG STARTUP_SCRIPT_SHELL MAKE_PACKAGE_SUPPORTED PATH_USERADD_PROG PATH_GROUPADD_PROG MANFMT TEST_SHELL MANDOC NROFF GROFF SH TEST_MINUS_S_SH ENT SED PERL KILL CAT ac_ct_AR AR INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM RANLIB AWK EGREP GREP CPP host_os host_vendor host_cpu host build_os build_vendor build_cpu build OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_largefile with_openssl with_ssh1 with_stackprotect with_hardening with_rpath with_cflags with_cppflags with_ldflags with_libs with_Werror with_solaris_contracts with_solaris_projects with_solaris_privs with_osfsia with_zlib with_zlib_version_check with_skey with_ldns with_libedit with_audit with_pie enable_pkcs11 with_ssl_dir with_openssl_header_check with_ssl_engine with_prngd_port with_prngd_socket with_pam with_pam_service with_privsep_user with_sandbox with_selinux with_kerberos5 with_privsep_path with_xauth enable_strip with_maildir with_mantype with_md5_passwords with_shadow with_ipaddr_display enable_etc_default_login with_default_path with_superuser_path with_4in6 with_bsd_auth with_pid_dir enable_lastlog enable_utmp enable_utmpx enable_wtmp enable_wtmpx enable_libutil enable_pututline enable_pututxline with_lastlog ' 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 ac_unrecognized_opts= ac_unrecognized_sep= # 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= ;; *) 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_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=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_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$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_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=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 ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_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'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. 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 # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" 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 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 .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # 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 -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | 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 .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" 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-option-checking ignore unrecognized --enable/--with options --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-pkcs11 disable PKCS#11 support code [no] --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-pam-service=name Specify PAM service name --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 (Objective) C/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" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && 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=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_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 $as_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.69 Copyright (C) 2012 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 ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack 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 ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES # --------------------------------------------- # Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR # accordingly. ac_fn_c_check_decl () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack as_decl_name=`echo $2|sed 's/ *(.*//'` as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 $as_echo_n "checking whether $as_decl_name is declared... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { #ifndef $as_decl_name #ifdef __cplusplus (void) $as_decl_use; #else (void) $as_decl_name; #endif #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_decl # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack 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 ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ( $as_echo "## ------------------------------------------- ## ## Report this to openssh-unix-dev@mindrot.org ## ## ------------------------------------------- ##" ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* 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 $2 (); /* 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_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else eval "$3=yes" 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 eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_type # ac_fn_c_compute_int LINENO EXPR VAR INCLUDES # -------------------------------------------- # Tries to find the compile-time value of EXPR in a program that includes # INCLUDES, setting VAR accordingly. Returns whether the value could be # computed ac_fn_c_compute_int () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) >= 0)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_lo=0 ac_mid=0 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=$ac_mid; break else as_fn_arith $ac_mid + 1 && ac_lo=$as_val if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) < 0)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=-1 ac_mid=-1 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) >= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_lo=$ac_mid; break else as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else 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 as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=$ac_mid else as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done case $ac_lo in #(( ?*) eval "$3=\$ac_lo"; ac_retval=0 ;; '') ac_retval=1 ;; esac else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 static long int longval () { return $2; } static unsigned long int ulongval () { return $2; } #include #include int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (($2) < 0) { long int i = longval (); if (i != ($2)) return 1; fprintf (f, "%ld", i); } else { unsigned long int i = ulongval (); if (i != ($2)) return 1; fprintf (f, "%lu", i); } /* Do not output a trailing newline, as this causes \r\n confusion on some platforms. */ return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : echo >>conftest.val; read $3 &5 $as_echo_n "checking for $2.$3... " >&6; } if eval \${$4+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $5 int main () { static $2 ac_aggr; if (ac_aggr.$3) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$4=yes" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $5 int main () { static $2 ac_aggr; if (sizeof ac_aggr.$3) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$4=yes" else eval "$4=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 eval ac_res=\$$4 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_member 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.69. 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=. $as_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=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append 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 as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset 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 $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" 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_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; 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 $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_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'; as_fn_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 $as_echo "/* confdefs.h */" > 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 cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } 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. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_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,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_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 # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_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. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&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 as_fn_executable_p "$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" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM 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. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.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 ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; 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 | *.dSYM | *.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 if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; 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 | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; 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 | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else 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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&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 confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes 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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* 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" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg 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) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : 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_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 as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 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 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&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 && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&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` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&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 confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i 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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$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 confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then 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" as_fn_executable_p "$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 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_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 as_fn_arith $ac_count + 1 && ac_count=$as_val 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 if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then 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" as_fn_executable_p "$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 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_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 as_fn_arith $ac_count + 1 && ac_count=$as_val 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 if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else 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 confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h 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=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 $as_echo_n "checking whether byte ordering is bigendian... " >&6; } if ${ac_cv_c_bigendian+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_bigendian=unknown # See if we're dealing with a universal compiler. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __APPLE_CC__ not a universal capable compiler #endif typedef int dummy; _ACEOF if ac_fn_c_try_compile "$LINENO"; then : # Check for potential -arch flags. It is not universal unless # there are at least two -arch flags with different values. ac_arch= ac_prev= for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do if test -n "$ac_prev"; then case $ac_word in i?86 | x86_64 | ppc | ppc64) if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then ac_arch=$ac_word else ac_cv_c_bigendian=universal break fi ;; esac ac_prev= elif test "x$ac_word" = "x-arch"; then ac_prev=arch fi done fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_c_bigendian = unknown; then # See if sys/param.h defines the BYTE_ORDER macro. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : # It does; now see whether it defined to BIG_ENDIAN or not. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { #if BYTE_ORDER != BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_bigendian=yes else ac_cv_c_bigendian=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 if test $ac_cv_c_bigendian = unknown; then # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { #if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : # It does; now see whether it defined to _BIG_ENDIAN or not. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { #ifndef _BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_bigendian=yes else ac_cv_c_bigendian=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 if test $ac_cv_c_bigendian = unknown; then # Compile a test program. if test "$cross_compiling" = yes; then : # Try to guess by grepping values from an object file. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 }; int use_ascii (int i) { return ascii_mm[i] + ascii_ii[i]; } short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; int use_ebcdic (int i) { return ebcdic_mm[i] + ebcdic_ii[i]; } extern int foo; int main () { return use_ascii (foo) == use_ebcdic (foo); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; 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 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_run "$LINENO"; then : ac_cv_c_bigendian=no else ac_cv_c_bigendian=yes fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 $as_echo "$ac_cv_c_bigendian" >&6; } case $ac_cv_c_bigendian in #( yes) $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h ;; #( no) ;; #( universal) $as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h ;; #( *) as_fn_error $? "unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&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 confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i 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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$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 confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&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. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&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 as_fn_executable_p "$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 rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir 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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$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' { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then 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" as_fn_executable_p "$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 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_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 as_fn_arith $ac_count + 1 && ac_count=$as_val 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 if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_CAT+:} false; then : $as_echo_n "(cached) " >&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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_CAT="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CAT" >&5 $as_echo "$CAT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "kill", so it can be a program name with args. set dummy kill; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_KILL+:} false; then : $as_echo_n "(cached) " >&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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_KILL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $KILL" >&5 $as_echo "$KILL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PERL+:} false; then : $as_echo_n "(cached) " >&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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL" >&5 $as_echo "$PERL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_SED="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SED" >&5 $as_echo "$SED" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "ent", so it can be a program name with args. set dummy ent; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ENT+:} false; then : $as_echo_n "(cached) " >&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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ENT="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ENT" >&5 $as_echo "$ENT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "bash", so it can be a program name with args. set dummy bash; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_TEST_MINUS_S_SH+:} false; then : $as_echo_n "(cached) " >&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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_TEST_MINUS_S_SH="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TEST_MINUS_S_SH" >&5 $as_echo "$TEST_MINUS_S_SH" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "ksh", so it can be a program name with args. set dummy ksh; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_TEST_MINUS_S_SH+:} false; then : $as_echo_n "(cached) " >&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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_TEST_MINUS_S_SH="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TEST_MINUS_S_SH" >&5 $as_echo "$TEST_MINUS_S_SH" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "sh", so it can be a program name with args. set dummy sh; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_TEST_MINUS_S_SH+:} false; then : $as_echo_n "(cached) " >&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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_TEST_MINUS_S_SH="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TEST_MINUS_S_SH" >&5 $as_echo "$TEST_MINUS_S_SH" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "sh", so it can be a program name with args. set dummy sh; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_SH+:} false; then : $as_echo_n "(cached) " >&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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_SH="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SH" >&5 $as_echo "$SH" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "groff", so it can be a program name with args. set dummy groff; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_GROFF+:} false; then : $as_echo_n "(cached) " >&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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_GROFF="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GROFF" >&5 $as_echo "$GROFF" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "nroff", so it can be a program name with args. set dummy nroff; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_NROFF+:} false; then : $as_echo_n "(cached) " >&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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_NROFF="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NROFF" >&5 $as_echo "$NROFF" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "mandoc", so it can be a program name with args. set dummy mandoc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_MANDOC+:} false; then : $as_echo_n "(cached) " >&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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_MANDOC="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANDOC" >&5 $as_echo "$MANDOC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: no manpage formatted found" >&5 $as_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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PATH_GROUPADD_PROG+:} false; then : $as_echo_n "(cached) " >&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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PATH_GROUPADD_PROG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PATH_GROUPADD_PROG" >&5 $as_echo "$PATH_GROUPADD_PROG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "useradd", so it can be a program name with args. set dummy useradd; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PATH_USERADD_PROG+:} false; then : $as_echo_n "(cached) " >&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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PATH_USERADD_PROG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PATH_USERADD_PROG" >&5 $as_echo "$PATH_USERADD_PROG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "pkgmk", so it can be a program name with args. set dummy pkgmk; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_MAKE_PACKAGE_SUPPORTED+:} false; then : $as_echo_n "(cached) " >&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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_MAKE_PACKAGE_SUPPORTED="yes" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAKE_PACKAGE_SUPPORTED" >&5 $as_echo "$MAKE_PACKAGE_SUPPORTED" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5 $as_echo_n "checking for special C compiler options needed for large files... " >&6; } if ${ac_cv_sys_largefile_CC+:} false; then : $as_echo_n "(cached) " >&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 confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : break fi rm -f core conftest.err conftest.$ac_objext CC="$CC -n32" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_largefile_CC=' -n32'; break fi rm -f core conftest.err conftest.$ac_objext break done CC=$ac_save_CC rm -f conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5 $as_echo "$ac_cv_sys_largefile_CC" >&6; } if test "$ac_cv_sys_largefile_CC" != no; then CC=$CC$ac_cv_sys_largefile_CC fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5 $as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; } if ${ac_cv_sys_file_offset_bits+:} false; then : $as_echo_n "(cached) " >&6 else while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_file_offset_bits=no; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_file_offset_bits=64; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_sys_file_offset_bits=unknown break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5 $as_echo "$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 -rf conftest* if test $ac_cv_sys_file_offset_bits = unknown; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5 $as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; } if ${ac_cv_sys_large_files+:} false; then : $as_echo_n "(cached) " >&6 else while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_large_files=no; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_large_files=1; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_sys_large_files=unknown break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5 $as_echo "$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 -rf conftest* fi fi if test -z "$AR" ; then as_fn_error $? "*** 'ar' missing, please install or fix your \$PATH ***" "$LINENO" 5 fi # Extract the first word of "passwd", so it can be a program name with args. set dummy passwd; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PATH_PASSWD_PROG+:} false; then : $as_echo_n "(cached) " >&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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PATH_PASSWD_PROG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PATH_PASSWD_PROG" >&5 $as_echo "$PATH_PASSWD_PROG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 $as_echo_n "checking for inline... " >&6; } if ${ac_cv_c_inline+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_inline=$ac_kw fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test "$ac_cv_c_inline" != no && break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 $as_echo "$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 ac_fn_c_check_decl "$LINENO" "LLONG_MAX" "ac_cv_have_decl_LLONG_MAX" "#include " if test "x$ac_cv_have_decl_LLONG_MAX" = xyes; then : have_llong_max=1 fi ac_fn_c_check_decl "$LINENO" "SYSTR_POLICY_KILL" "ac_cv_have_decl_SYSTR_POLICY_KILL" " #include #include #include " if test "x$ac_cv_have_decl_SYSTR_POLICY_KILL" = xyes; then : have_systr_policy_kill=1 fi ac_fn_c_check_decl "$LINENO" "RLIMIT_NPROC" "ac_cv_have_decl_RLIMIT_NPROC" " #include #include " if test "x$ac_cv_have_decl_RLIMIT_NPROC" = xyes; then : $as_echo "#define HAVE_RLIMIT_NPROC /**/" >>confdefs.h fi ac_fn_c_check_decl "$LINENO" "PR_SET_NO_NEW_PRIVS" "ac_cv_have_decl_PR_SET_NO_NEW_PRIVS" " #include #include " if test "x$ac_cv_have_decl_PR_SET_NO_NEW_PRIVS" = xyes; then : have_linux_no_new_privs=1 fi openssl=yes ssh1=no COMMENT_OUT_RSA1="#no ssh1#" # 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL will be used for cryptography" >&5 $as_echo_n "checking whether OpenSSL will be used for cryptography... " >&6; } if test "x$openssl" = "xyes" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } cat >>confdefs.h <<_ACEOF #define WITH_OPENSSL 1 _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 as_fn_error $? "Cannot enable SSH protocol 1 with OpenSSL disabled" "$LINENO" 5 fi ssh1=yes COMMENT_OUT_RSA1="" elif test "x$withval" = "xno" ; then ssh1=no else as_fn_error $? "unknown --with-ssh1 argument" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether SSH protocol 1 support is enabled" >&5 $as_echo_n "checking whether SSH protocol 1 support is enabled... " >&6; } if test "x$ssh1" = "xyes" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } cat >>confdefs.h <<_ACEOF #define WITH_SSH1 1 _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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. { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports -Werror" >&5 $as_echo_n "checking if $CC supports -Werror... " >&6; } saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main(void) { return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } WERROR="-Werror" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Qunused-arguments" >&5 $as_echo_n "checking if $CC supports compile flag -Qunused-arguments... " >&6; } saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Qunused-arguments" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-Qunused-arguments" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : if `grep -i "unrecognized option" conftest.err >/dev/null` then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$saved_CFLAGS" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } CFLAGS="$saved_CFLAGS $_define_flag" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } { { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wunknown-warning-option" >&5 $as_echo_n "checking if $CC supports compile flag -Wunknown-warning-option... " >&6; } saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wunknown-warning-option" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-Wunknown-warning-option" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : if `grep -i "unrecognized option" conftest.err >/dev/null` then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$saved_CFLAGS" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } CFLAGS="$saved_CFLAGS $_define_flag" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } { { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wall" >&5 $as_echo_n "checking if $CC supports compile flag -Wall... " >&6; } saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wall" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-Wall" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : if `grep -i "unrecognized option" conftest.err >/dev/null` then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$saved_CFLAGS" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } CFLAGS="$saved_CFLAGS $_define_flag" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } { { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wpointer-arith" >&5 $as_echo_n "checking if $CC supports compile flag -Wpointer-arith... " >&6; } saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wpointer-arith" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-Wpointer-arith" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : if `grep -i "unrecognized option" conftest.err >/dev/null` then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$saved_CFLAGS" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } CFLAGS="$saved_CFLAGS $_define_flag" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } { { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wuninitialized" >&5 $as_echo_n "checking if $CC supports compile flag -Wuninitialized... " >&6; } saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wuninitialized" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-Wuninitialized" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : if `grep -i "unrecognized option" conftest.err >/dev/null` then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$saved_CFLAGS" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } CFLAGS="$saved_CFLAGS $_define_flag" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } { { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wsign-compare" >&5 $as_echo_n "checking if $CC supports compile flag -Wsign-compare... " >&6; } saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wsign-compare" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-Wsign-compare" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : if `grep -i "unrecognized option" conftest.err >/dev/null` then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$saved_CFLAGS" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } CFLAGS="$saved_CFLAGS $_define_flag" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } { { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wformat-security" >&5 $as_echo_n "checking if $CC supports compile flag -Wformat-security... " >&6; } saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wformat-security" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-Wformat-security" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : if `grep -i "unrecognized option" conftest.err >/dev/null` then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$saved_CFLAGS" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } CFLAGS="$saved_CFLAGS $_define_flag" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } { { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wsizeof-pointer-memaccess" >&5 $as_echo_n "checking if $CC supports compile flag -Wsizeof-pointer-memaccess... " >&6; } saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wsizeof-pointer-memaccess" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-Wsizeof-pointer-memaccess" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : if `grep -i "unrecognized option" conftest.err >/dev/null` then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$saved_CFLAGS" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } CFLAGS="$saved_CFLAGS $_define_flag" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } { { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wpointer-sign" >&5 $as_echo_n "checking if $CC supports compile flag -Wpointer-sign... " >&6; } saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wpointer-sign" _define_flag="-Wno-pointer-sign" test "x$_define_flag" = "x" && _define_flag="-Wpointer-sign" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : if `grep -i "unrecognized option" conftest.err >/dev/null` then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$saved_CFLAGS" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } CFLAGS="$saved_CFLAGS $_define_flag" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } { { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wunused-result" >&5 $as_echo_n "checking if $CC supports compile flag -Wunused-result... " >&6; } saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wunused-result" _define_flag="-Wno-unused-result" test "x$_define_flag" = "x" && _define_flag="-Wunused-result" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : if `grep -i "unrecognized option" conftest.err >/dev/null` then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$saved_CFLAGS" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } CFLAGS="$saved_CFLAGS $_define_flag" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } { { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -fno-strict-aliasing" >&5 $as_echo_n "checking if $CC supports compile flag -fno-strict-aliasing... " >&6; } saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -fno-strict-aliasing" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-fno-strict-aliasing" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : if `grep -i "unrecognized option" conftest.err >/dev/null` then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$saved_CFLAGS" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } CFLAGS="$saved_CFLAGS $_define_flag" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } { { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -D_FORTIFY_SOURCE=2" >&5 $as_echo_n "checking if $CC supports compile flag -D_FORTIFY_SOURCE=2... " >&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 confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : if `grep -i "unrecognized option" conftest.err >/dev/null` then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$saved_CFLAGS" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } CFLAGS="$saved_CFLAGS $_define_flag" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $LD supports link flag -Wl,-z,relro" >&5 $as_echo_n "checking if $LD supports link flag -Wl,-z,relro... " >&6; } saved_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $WERROR -Wl,-z,relro" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-Wl,-z,relro" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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; long long p = n * o; printf("%d %d %d %f %f %lld %lld %lld\n", i, j, k, l, m, n, o, p); exit(0); } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } LDFLAGS="$saved_LDFLAGS $_define_flag" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } LDFLAGS="$saved_LDFLAGS" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext } { { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $LD supports link flag -Wl,-z,now" >&5 $as_echo_n "checking if $LD supports link flag -Wl,-z,now... " >&6; } saved_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $WERROR -Wl,-z,now" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-Wl,-z,now" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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; long long p = n * o; printf("%d %d %d %f %f %lld %lld %lld\n", i, j, k, l, m, n, o, p); exit(0); } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } LDFLAGS="$saved_LDFLAGS $_define_flag" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } LDFLAGS="$saved_LDFLAGS" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext } { { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $LD supports link flag -Wl,-z,noexecstack" >&5 $as_echo_n "checking if $LD supports link flag -Wl,-z,noexecstack... " >&6; } saved_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $WERROR -Wl,-z,noexecstack" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-Wl,-z,noexecstack" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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; long long p = n * o; printf("%d %d %d %f %f %lld %lld %lld\n", i, j, k, l, m, n, o, p); exit(0); } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } LDFLAGS="$saved_LDFLAGS $_define_flag" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } LDFLAGS="$saved_LDFLAGS" fi rm -f core conftest.err conftest.$ac_objext \ 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. { { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -ftrapv and linking succeeds" >&5 $as_echo_n "checking if $CC supports compile flag -ftrapv and linking succeeds... " >&6; } saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -ftrapv" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-ftrapv" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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; long long int p = n * o; printf("%d %d %d %f %f %lld %lld %lld\n", i, j, k, l, m, n, o, p); exit(0); } _ACEOF if ac_fn_c_try_link "$LINENO"; then : if `grep -i "unrecognized option" conftest.err >/dev/null` then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$saved_CFLAGS" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } CFLAGS="$saved_CFLAGS $_define_flag" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking gcc version" >&5 $as_echo_n "checking gcc version... " >&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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GCC_VER" >&5 $as_echo "$GCC_VER" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -fno-builtin-memset" >&5 $as_echo_n "checking if $CC accepts -fno-builtin-memset... " >&6; } saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -fno-builtin-memset" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { char b[10]; memset(b, 0, sizeof(b)); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext \ 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports $t" >&5 $as_echo_n "checking if $CC supports $t... " >&6; } saved_CFLAGS="$CFLAGS" saved_LDFLAGS="$LDFLAGS" CFLAGS="$CFLAGS $t -Werror" LDFLAGS="$LDFLAGS $t -Werror" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { char x[256]; snprintf(x, sizeof(x), "XXX"); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } CFLAGS="$saved_CFLAGS $t" LDFLAGS="$saved_LDFLAGS $t" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $t works" >&5 $as_echo_n "checking if $t works... " >&6; } if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: cannot test" >&5 $as_echo "$as_me: WARNING: cross compiling: cannot test" >&2;} break else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { char x[256]; snprintf(x, sizeof(x), "XXX"); ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } break else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext \ 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" ac_fn_c_check_decl "$LINENO" "LLONG_MAX" "ac_cv_have_decl_LLONG_MAX" "#include " if test "x$ac_cv_have_decl_LLONG_MAX" = xyes; then : have_llong_max=1 else CFLAGS="$saved_CFLAGS" fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler allows __attribute__ on return types" >&5 $as_echo_n "checking if compiler allows __attribute__ on return types... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include __attribute__((__unused__)) static void foo(void){return;} int main () { exit(0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "#define NO_ATTRIBUTE_ON_RETURN_TYPE 1" >>confdefs.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test "x$no_attrib_nonnull" != "x1" ; then $as_echo "#define HAVE_ATTRIBUTE__NONNULL__ 1" >>confdefs.h 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 \ err.h \ features.h \ fcntl.h \ floatingpoint.h \ getopt.h \ glob.h \ ia.h \ iaf.h \ inttypes.h \ langinfo.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/ptrace.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 \ wchar.h \ do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_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 : ac_fn_c_check_header_compile "$LINENO" "lastlog.h" "ac_cv_header_lastlog_h" " #ifdef HAVE_SYS_TIME_H # include #endif " if test "x$ac_cv_header_lastlog_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LASTLOG_H 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 : ac_fn_c_check_header_compile "$LINENO" "sys/ptms.h" "ac_cv_header_sys_ptms_h" " #ifdef HAVE_SYS_STREAM_H # include #endif " if test "x$ac_cv_header_sys_ptms_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_PTMS_H 1 _ACEOF fi done # login_cap.h requires sys/types.h on NetBSD for ac_header in login_cap.h do : ac_fn_c_check_header_compile "$LINENO" "login_cap.h" "ac_cv_header_login_cap_h" " #include " if test "x$ac_cv_header_login_cap_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LOGIN_CAP_H 1 _ACEOF fi done # older BSDs need sys/param.h before sys/mount.h for ac_header in sys/mount.h do : ac_fn_c_check_header_compile "$LINENO" "sys/mount.h" "ac_cv_header_sys_mount_h" " #include " if test "x$ac_cv_header_sys_mount_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_MOUNT_H 1 _ACEOF fi done # Android requires sys/socket.h to be included before sys/un.h for ac_header in sys/un.h do : ac_fn_c_check_header_compile "$LINENO" "sys/un.h" "ac_cv_header_sys_un_h" " #include #include " if test "x$ac_cv_header_sys_un_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_UN_H 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. { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler allows macro redefinitions" >&5 $as_echo_n "checking if compiler allows macro redefinitions... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define testmacro foo #define testmacro bar int main () { exit(0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to specify blibpath for linker ($LD)" >&5 $as_echo_n "checking how to specify blibpath for linker ($LD)... " >&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 confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : blibflags=$tryflags fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi done if (test -z "$blibflags"); then { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 $as_echo "not found" >&6; } as_fn_error $? "*** must be able to specify blibpath on AIX - check config.log" "$LINENO" 5 else { $as_echo "$as_me:${as_lineno-$LINENO}: result: $blibflags" >&5 $as_echo "$blibflags" >&6; } fi LDFLAGS="$saved_LDFLAGS" ac_fn_c_check_func "$LINENO" "authenticate" "ac_cv_func_authenticate" if test "x$ac_cv_func_authenticate" = xyes; then : $as_echo "#define WITH_AIXAUTHENTICATE 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for authenticate in -ls" >&5 $as_echo_n "checking for authenticate in -ls... " >&6; } if ${ac_cv_lib_s_authenticate+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ls $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_s_authenticate=yes else ac_cv_lib_s_authenticate=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_s_authenticate" >&5 $as_echo "$ac_cv_lib_s_authenticate" >&6; } if test "x$ac_cv_lib_s_authenticate" = xyes; then : $as_echo "#define WITH_AIXAUTHENTICATE 1" >>confdefs.h LIBS="$LIBS -ls" fi fi ac_fn_c_check_decl "$LINENO" "authenticate" "ac_cv_have_decl_authenticate" "#include " if test "x$ac_cv_have_decl_authenticate" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_AUTHENTICATE $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "loginrestrictions" "ac_cv_have_decl_loginrestrictions" "#include " if test "x$ac_cv_have_decl_loginrestrictions" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_LOGINRESTRICTIONS $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "loginsuccess" "ac_cv_have_decl_loginsuccess" "#include " if test "x$ac_cv_have_decl_loginsuccess" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_LOGINSUCCESS $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "passwdexpired" "ac_cv_have_decl_passwdexpired" "#include " if test "x$ac_cv_have_decl_passwdexpired" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_PASSWDEXPIRED $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "setauthdb" "ac_cv_have_decl_setauthdb" "#include " if test "x$ac_cv_have_decl_setauthdb" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_SETAUTHDB $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "loginfailed" "ac_cv_have_decl_loginfailed" "#include " if test "x$ac_cv_have_decl_loginfailed" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_LOGINFAILED $ac_have_decl _ACEOF if test $ac_have_decl = 1; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking if loginfailed takes 4 arguments" >&5 $as_echo_n "checking if loginfailed takes 4 arguments... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { (void)loginfailed("user","host","tty",0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define AIX_LOGINFAILED_4ARG 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi for ac_func in getgrset setauthdb do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done ac_fn_c_check_decl "$LINENO" "F_CLOSEM" "ac_cv_have_decl_F_CLOSEM" " #include #include " if test "x$ac_cv_have_decl_F_CLOSEM" = xyes; then : $as_echo "#define HAVE_FCNTL_CLOSEM 1" >>confdefs.h fi check_for_aix_broken_getaddrinfo=1 $as_echo "#define BROKEN_REALPATH 1" >>confdefs.h $as_echo "#define SETEUID_BREAKS_SETUID 1" >>confdefs.h $as_echo "#define BROKEN_SETREUID 1" >>confdefs.h $as_echo "#define BROKEN_SETREGID 1" >>confdefs.h $as_echo "#define DISABLE_LASTLOG 1" >>confdefs.h $as_echo "#define LOGIN_NEEDS_UTMPX 1" >>confdefs.h $as_echo "#define SPT_TYPE SPT_REUSEARGV" >>confdefs.h $as_echo "#define SSHPAM_CHAUTHTOK_NEEDS_RUID 1" >>confdefs.h $as_echo "#define PTY_ZEROREAD 1" >>confdefs.h $as_echo "#define PLATFORM_SYS_DIR_UID 2" >>confdefs.h ;; *-*-android*) $as_echo "#define DISABLE_UTMP 1" >>confdefs.h $as_echo "#define DISABLE_WTMP 1" >>confdefs.h ;; *-*-cygwin*) check_for_libcrypt_later=1 LIBS="$LIBS /usr/lib/textreadmode.o" $as_echo "#define HAVE_CYGWIN 1" >>confdefs.h $as_echo "#define USE_PIPES 1" >>confdefs.h $as_echo "#define NO_UID_RESTORATION_TEST 1" >>confdefs.h $as_echo "#define DISABLE_SHADOW 1" >>confdefs.h $as_echo "#define NO_X11_UNIX_SOCKETS 1" >>confdefs.h $as_echo "#define DISABLE_FD_PASSING 1" >>confdefs.h $as_echo "#define SSH_IOBUFSZ 65535" >>confdefs.h $as_echo "#define FILESYSTEM_NO_BACKSLASH 1" >>confdefs.h # Cygwin defines optargs, optargs as declspec(dllimport) for historical # reasons which cause compile warnings, so we disable those warnings. { { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -Wno-attributes" >&5 $as_echo_n "checking if $CC supports compile flag -Wno-attributes... " >&6; } saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -Wno-attributes" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-Wno-attributes" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : if `grep -i "unrecognized option" conftest.err >/dev/null` then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$saved_CFLAGS" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } CFLAGS="$saved_CFLAGS $_define_flag" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } ;; *-*-dgux*) $as_echo "#define IP_TOS_IS_BROKEN 1" >>confdefs.h $as_echo "#define SETEUID_BREAKS_SETUID 1" >>confdefs.h $as_echo "#define BROKEN_SETREUID 1" >>confdefs.h $as_echo "#define BROKEN_SETREGID 1" >>confdefs.h ;; *-*-darwin*) use_pie=auto { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we have working getaddrinfo" >&5 $as_echo_n "checking if we have working getaddrinfo... " >&6; } if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: assume it is working" >&5 $as_echo "assume it is working" >&6; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) exit(0); else exit(1); } _ACEOF if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: working" >&5 $as_echo "working" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: buggy" >&5 $as_echo "buggy" >&6; } $as_echo "#define BROKEN_GETADDRINFO 1" >>confdefs.h fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi $as_echo "#define SETEUID_BREAKS_SETUID 1" >>confdefs.h $as_echo "#define BROKEN_SETREUID 1" >>confdefs.h $as_echo "#define BROKEN_SETREGID 1" >>confdefs.h $as_echo "#define BROKEN_GLOB 1" >>confdefs.h cat >>confdefs.h <<_ACEOF #define BIND_8_COMPAT 1 _ACEOF $as_echo "#define SSH_TUN_FREEBSD 1" >>confdefs.h $as_echo "#define SSH_TUN_COMPAT_AF 1" >>confdefs.h $as_echo "#define SSH_TUN_PREPEND_AF 1" >>confdefs.h ac_fn_c_check_decl "$LINENO" "AU_IPv4" "ac_cv_have_decl_AU_IPv4" "$ac_includes_default" if test "x$ac_cv_have_decl_AU_IPv4" = xyes; then : else $as_echo "#define AU_IPv4 0" >>confdefs.h #include $as_echo "#define LASTLOG_WRITE_PUTUTXLINE 1" >>confdefs.h fi $as_echo "#define SPT_TYPE SPT_REUSEARGV" >>confdefs.h for ac_func in sandbox_init do : ac_fn_c_check_func "$LINENO" "sandbox_init" "ac_cv_func_sandbox_init" if test "x$ac_cv_func_sandbox_init" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SANDBOX_INIT 1 _ACEOF fi done for ac_header in sandbox.h do : ac_fn_c_check_header_mongrel "$LINENO" "sandbox.h" "ac_cv_header_sandbox_h" "$ac_includes_default" if test "x$ac_cv_header_sandbox_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SANDBOX_H 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sandbox_apply in -lsandbox" >&5 $as_echo_n "checking for sandbox_apply in -lsandbox... " >&6; } if ${ac_cv_lib_sandbox_sandbox_apply+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsandbox $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_sandbox_sandbox_apply=yes else ac_cv_lib_sandbox_sandbox_apply=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sandbox_sandbox_apply" >&5 $as_echo "$ac_cv_lib_sandbox_sandbox_apply" >&6; } if test "x$ac_cv_lib_sandbox_sandbox_apply" = xyes; then : SSHDLIBS="$SSHDLIBS -lsandbox" fi ;; *-*-dragonfly*) SSHDLIBS="$SSHDLIBS -lcrypt" TEST_MALLOC_OPTIONS="AFGJPRX" ;; *-*-haiku*) LIBS="$LIBS -lbsd " { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lnetwork" >&5 $as_echo_n "checking for socket in -lnetwork... " >&6; } if ${ac_cv_lib_network_socket+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnetwork $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_network_socket=yes else ac_cv_lib_network_socket=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_network_socket" >&5 $as_echo "$ac_cv_lib_network_socket" >&6; } if test "x$ac_cv_lib_network_socket" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBNETWORK 1 _ACEOF LIBS="-lnetwork $LIBS" fi $as_echo "#define HAVE_U_INT64_T 1" >>confdefs.h 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 $as_echo "#define USE_PIPES 1" >>confdefs.h $as_echo "#define LOGIN_NEEDS_UTMPX 1" >>confdefs.h $as_echo "#define LOCKED_PASSWD_STRING \"*\"" >>confdefs.h $as_echo "#define SPT_TYPE SPT_PSTAT" >>confdefs.h $as_echo "#define PLATFORM_SYS_DIR_UID 2" >>confdefs.h maildir="/var/mail" LIBS="$LIBS -lsec" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for t_error in -lxnet" >&5 $as_echo_n "checking for t_error in -lxnet... " >&6; } if ${ac_cv_lib_xnet_t_error+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lxnet $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_xnet_t_error=yes else ac_cv_lib_xnet_t_error=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_xnet_t_error" >&5 $as_echo "$ac_cv_lib_xnet_t_error" >&6; } if test "x$ac_cv_lib_xnet_t_error" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBXNET 1 _ACEOF LIBS="-lxnet $LIBS" else as_fn_error $? "*** -lxnet needed on HP-UX - check config.log ***" "$LINENO" 5 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*) $as_echo "#define PAM_SUN_CODEBASE 1" >>confdefs.h $as_echo "#define DISABLE_UTMP 1" >>confdefs.h $as_echo "#define USE_BTMP 1" >>confdefs.h 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) $as_echo "#define HAVE_SECUREWARE 1" >>confdefs.h disable_ptmx_check=yes LIBS="$LIBS -lsecpw" ;; esac ;; *-*-irix5*) PATH="$PATH:/usr/etc" $as_echo "#define BROKEN_INET_NTOA 1" >>confdefs.h $as_echo "#define SETEUID_BREAKS_SETUID 1" >>confdefs.h $as_echo "#define BROKEN_SETREUID 1" >>confdefs.h $as_echo "#define BROKEN_SETREGID 1" >>confdefs.h $as_echo "#define WITH_ABBREV_NO_TTY 1" >>confdefs.h $as_echo "#define LOCKED_PASSWD_STRING \"*LK*\"" >>confdefs.h ;; *-*-irix6*) PATH="$PATH:/usr/etc" $as_echo "#define WITH_IRIX_ARRAY 1" >>confdefs.h $as_echo "#define WITH_IRIX_PROJECT 1" >>confdefs.h $as_echo "#define WITH_IRIX_AUDIT 1" >>confdefs.h ac_fn_c_check_func "$LINENO" "jlimit_startjob" "ac_cv_func_jlimit_startjob" if test "x$ac_cv_func_jlimit_startjob" = xyes; then : $as_echo "#define WITH_IRIX_JOBS 1" >>confdefs.h fi $as_echo "#define BROKEN_INET_NTOA 1" >>confdefs.h $as_echo "#define SETEUID_BREAKS_SETUID 1" >>confdefs.h $as_echo "#define BROKEN_SETREUID 1" >>confdefs.h $as_echo "#define BROKEN_SETREGID 1" >>confdefs.h $as_echo "#define BROKEN_UPDWTMPX 1" >>confdefs.h $as_echo "#define WITH_ABBREV_NO_TTY 1" >>confdefs.h $as_echo "#define LOCKED_PASSWD_STRING \"*LK*\"" >>confdefs.h ;; *-*-k*bsd*-gnu | *-*-kopensolaris*-gnu) check_for_libcrypt_later=1 $as_echo "#define PAM_TTY_KLUDGE 1" >>confdefs.h $as_echo "#define LOCKED_PASSWD_PREFIX \"!\"" >>confdefs.h $as_echo "#define SPT_TYPE SPT_REUSEARGV" >>confdefs.h $as_echo "#define _PATH_BTMP \"/var/log/btmp\"" >>confdefs.h $as_echo "#define USE_BTMP 1" >>confdefs.h ;; *-*-linux*) no_dev_ptmx=1 use_pie=auto check_for_libcrypt_later=1 check_for_openpty_ctty_bug=1 CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_DEFAULT_SOURCE" $as_echo "#define PAM_TTY_KLUDGE 1" >>confdefs.h $as_echo "#define LOCKED_PASSWD_PREFIX \"!\"" >>confdefs.h $as_echo "#define SPT_TYPE SPT_REUSEARGV" >>confdefs.h $as_echo "#define LINK_OPNOTSUPP_ERRNO EPERM" >>confdefs.h $as_echo "#define _PATH_BTMP \"/var/log/btmp\"" >>confdefs.h $as_echo "#define USE_BTMP 1" >>confdefs.h $as_echo "#define LINUX_OOM_ADJUST 1" >>confdefs.h inet6_default_4in6=yes case `uname -r` in 1.*|2.0.*) $as_echo "#define BROKEN_CMSG_TYPE 1" >>confdefs.h ;; esac # tun(4) forwarding compat code for ac_header in linux/if_tun.h do : ac_fn_c_check_header_mongrel "$LINENO" "linux/if_tun.h" "ac_cv_header_linux_if_tun_h" "$ac_includes_default" if test "x$ac_cv_header_linux_if_tun_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LINUX_IF_TUN_H 1 _ACEOF fi done if test "x$ac_cv_header_linux_if_tun_h" = "xyes" ; then $as_echo "#define SSH_TUN_LINUX 1" >>confdefs.h $as_echo "#define SSH_TUN_COMPAT_AF 1" >>confdefs.h $as_echo "#define SSH_TUN_PREPEND_AF 1" >>confdefs.h fi for ac_header in linux/seccomp.h linux/filter.h linux/audit.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "#include " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for seccomp architecture" >&5 $as_echo_n "checking for seccomp architecture... " >&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 ;; s390x-*) seccomp_audit_arch=AUDIT_ARCH_S390X ;; s390-*) seccomp_audit_arch=AUDIT_ARCH_S390 ;; powerpc64-*) seccomp_audit_arch=AUDIT_ARCH_PPC64 ;; powerpc64le-*) seccomp_audit_arch=AUDIT_ARCH_PPC64LE ;; mips-*) seccomp_audit_arch=AUDIT_ARCH_MIPS ;; mipsel-*) seccomp_audit_arch=AUDIT_ARCH_MIPSEL ;; mips64-*) seccomp_audit_arch=AUDIT_ARCH_MIPS64 ;; mips64el-*) seccomp_audit_arch=AUDIT_ARCH_MIPSEL64 ;; esac if test "x$seccomp_audit_arch" != "x" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"$seccomp_audit_arch\"" >&5 $as_echo "\"$seccomp_audit_arch\"" >&6; } cat >>confdefs.h <<_ACEOF #define SECCOMP_AUDIT_ARCH $seccomp_audit_arch _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: result: architecture not supported" >&5 $as_echo "architecture not supported" >&6; } fi ;; mips-sony-bsd|mips-sony-newsos4) $as_echo "#define NEED_SETPGRP 1" >>confdefs.h SONY=1 ;; *-*-netbsd*) check_for_libcrypt_before=1 if test "x$withval" != "xno" ; then need_dash_r=1 fi CPPFLAGS="$CPPFLAGS -D_OPENBSD_SOURCE" $as_echo "#define SSH_TUN_FREEBSD 1" >>confdefs.h ac_fn_c_check_header_mongrel "$LINENO" "net/if_tap.h" "ac_cv_header_net_if_tap_h" "$ac_includes_default" if test "x$ac_cv_header_net_if_tap_h" = xyes; then : else $as_echo "#define SSH_TUN_NO_L2 1" >>confdefs.h fi $as_echo "#define SSH_TUN_PREPEND_AF 1" >>confdefs.h TEST_MALLOC_OPTIONS="AJRX" $as_echo "#define BROKEN_READ_COMPARISON 1" >>confdefs.h ;; *-*-freebsd*) check_for_libcrypt_later=1 $as_echo "#define LOCKED_PASSWD_PREFIX \"*LOCKED*\"" >>confdefs.h $as_echo "#define SSH_TUN_FREEBSD 1" >>confdefs.h ac_fn_c_check_header_mongrel "$LINENO" "net/if_tap.h" "ac_cv_header_net_if_tap_h" "$ac_includes_default" if test "x$ac_cv_header_net_if_tap_h" = xyes; then : else $as_echo "#define SSH_TUN_NO_L2 1" >>confdefs.h fi $as_echo "#define BROKEN_GLOB 1" >>confdefs.h TEST_MALLOC_OPTIONS="AJRX" # Preauth crypto occasionally uses file descriptors for crypto offload # and will crash if they cannot be opened. $as_echo "#define SANDBOX_SKIP_RLIMIT_NOFILE 1" >>confdefs.h ;; *-*-bsdi*) $as_echo "#define SETEUID_BREAKS_SETUID 1" >>confdefs.h $as_echo "#define BROKEN_SETREUID 1" >>confdefs.h $as_echo "#define BROKEN_SETREGID 1" >>confdefs.h ;; *-next-*) conf_lastlog_location="/usr/adm/lastlog" conf_utmp_location=/etc/utmp conf_wtmp_location=/usr/adm/wtmp maildir=/usr/spool/mail $as_echo "#define HAVE_NEXT 1" >>confdefs.h $as_echo "#define BROKEN_REALPATH 1" >>confdefs.h $as_echo "#define USE_PIPES 1" >>confdefs.h $as_echo "#define BROKEN_SAVED_UIDS 1" >>confdefs.h ;; *-*-openbsd*) use_pie=auto $as_echo "#define HAVE_ATTRIBUTE__SENTINEL__ 1" >>confdefs.h $as_echo "#define HAVE_ATTRIBUTE__BOUNDED__ 1" >>confdefs.h $as_echo "#define SSH_TUN_OPENBSD 1" >>confdefs.h $as_echo "#define SYSLOG_R_SAFE_IN_SIGHAND 1" >>confdefs.h TEST_MALLOC_OPTIONS="AFGJPRX" ;; *-*-solaris*) if test "x$withval" != "xno" ; then need_dash_r=1 fi $as_echo "#define PAM_SUN_CODEBASE 1" >>confdefs.h $as_echo "#define LOGIN_NEEDS_UTMPX 1" >>confdefs.h $as_echo "#define PAM_TTY_KLUDGE 1" >>confdefs.h $as_echo "#define SSHPAM_CHAUTHTOK_NEEDS_RUID 1" >>confdefs.h $as_echo "#define LOCKED_PASSWD_STRING \"*LK*\"" >>confdefs.h # Pushing STREAMS modules will cause sshd to acquire a controlling tty. $as_echo "#define SSHD_ACQUIRES_CTTY 1" >>confdefs.h $as_echo "#define PASSWD_NEEDS_USERNAME 1" >>confdefs.h $as_echo "#define BROKEN_TCGETATTR_ICANON 1" >>confdefs.h external_path_file=/etc/default/login # hardwire lastlog location (can't detect it on some versions) conf_lastlog_location="/var/adm/lastlog" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for obsolete utmp and wtmp in solaris2.x" >&5 $as_echo_n "checking for obsolete utmp and wtmp in solaris2.x... " >&6; } sol2ver=`echo "$host"| sed -e 's/.*[0-9]\.//'` if test "$sol2ver" -ge 8; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define DISABLE_UTMP 1" >>confdefs.h $as_echo "#define DISABLE_WTMP 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi for ac_func in setpflags do : ac_fn_c_check_func "$LINENO" "setpflags" "ac_cv_func_setpflags" if test "x$ac_cv_func_setpflags" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SETPFLAGS 1 _ACEOF fi done for ac_func in setppriv do : ac_fn_c_check_func "$LINENO" "setppriv" "ac_cv_func_setppriv" if test "x$ac_cv_func_setppriv" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SETPPRIV 1 _ACEOF fi done for ac_func in priv_basicset do : ac_fn_c_check_func "$LINENO" "priv_basicset" "ac_cv_func_priv_basicset" if test "x$ac_cv_func_priv_basicset" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_PRIV_BASICSET 1 _ACEOF fi done for ac_header in priv.h do : ac_fn_c_check_header_mongrel "$LINENO" "priv.h" "ac_cv_header_priv_h" "$ac_includes_default" if test "x$ac_cv_header_priv_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_PRIV_H 1 _ACEOF fi done # Check whether --with-solaris-contracts was given. if test "${with_solaris_contracts+set}" = set; then : withval=$with_solaris_contracts; { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ct_tmpl_activate in -lcontract" >&5 $as_echo_n "checking for ct_tmpl_activate in -lcontract... " >&6; } if ${ac_cv_lib_contract_ct_tmpl_activate+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcontract $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_contract_ct_tmpl_activate=yes else ac_cv_lib_contract_ct_tmpl_activate=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_contract_ct_tmpl_activate" >&5 $as_echo "$ac_cv_lib_contract_ct_tmpl_activate" >&6; } if test "x$ac_cv_lib_contract_ct_tmpl_activate" = xyes; then : $as_echo "#define USE_SOLARIS_PROCESS_CONTRACTS 1" >>confdefs.h 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; { $as_echo "$as_me:${as_lineno-$LINENO}: checking for setproject in -lproject" >&5 $as_echo_n "checking for setproject in -lproject... " >&6; } if ${ac_cv_lib_project_setproject+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lproject $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_project_setproject=yes else ac_cv_lib_project_setproject=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_project_setproject" >&5 $as_echo "$ac_cv_lib_project_setproject" >&6; } if test "x$ac_cv_lib_project_setproject" = xyes; then : $as_echo "#define USE_SOLARIS_PROJECTS 1" >>confdefs.h 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; { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Solaris/Illumos privilege support" >&5 $as_echo_n "checking for Solaris/Illumos privilege support... " >&6; } if test "x$ac_cv_func_setppriv" = "xyes" -a \ "x$ac_cv_header_priv_h" = "xyes" ; then SOLARIS_PRIVS=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5 $as_echo "found" >&6; } $as_echo "#define NO_UID_RESTORATION_TEST 1" >>confdefs.h $as_echo "#define USE_SOLARIS_PRIVS 1" >>confdefs.h SPP_MSG="yes" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 $as_echo "not found" >&6; } as_fn_error $? "*** must have support for Solaris privileges to use --with-solaris-privs" "$LINENO" 5 fi fi TEST_SHELL=$SHELL # let configure find us a capable shell ;; *-*-sunos4*) CPPFLAGS="$CPPFLAGS -DSUNOS4" for ac_func in getpwanam do : ac_fn_c_check_func "$LINENO" "getpwanam" "ac_cv_func_getpwanam" if test "x$ac_cv_func_getpwanam" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GETPWANAM 1 _ACEOF fi done $as_echo "#define PAM_SUN_CODEBASE 1" >>confdefs.h conf_utmp_location=/etc/utmp conf_wtmp_location=/var/adm/wtmp conf_lastlog_location=/var/adm/lastlog $as_echo "#define USE_PIPES 1" >>confdefs.h ;; *-ncr-sysv*) LIBS="$LIBS -lc89" $as_echo "#define USE_PIPES 1" >>confdefs.h $as_echo "#define SSHD_ACQUIRES_CTTY 1" >>confdefs.h $as_echo "#define SETEUID_BREAKS_SETUID 1" >>confdefs.h $as_echo "#define BROKEN_SETREUID 1" >>confdefs.h $as_echo "#define BROKEN_SETREGID 1" >>confdefs.h ;; *-sni-sysv*) # /usr/ucblib MUST NOT be searched on ReliantUNIX { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlsym in -ldl" >&5 $as_echo_n "checking for dlsym in -ldl... " >&6; } if ${ac_cv_lib_dl_dlsym+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlsym=yes else ac_cv_lib_dl_dlsym=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlsym" >&5 $as_echo "$ac_cv_lib_dl_dlsym" >&6; } if test "x$ac_cv_lib_dl_dlsym" = xyes; 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for res_query in -lresolv" >&5 $as_echo_n "checking for res_query in -lresolv... " >&6; } if ${ac_cv_lib_resolv_res_query+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lresolv $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_resolv_res_query=yes else ac_cv_lib_resolv_res_query=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_resolv_res_query" >&5 $as_echo "$ac_cv_lib_resolv_res_query" >&6; } if test "x$ac_cv_lib_resolv_res_query" = xyes; then : LIBS="$LIBS -lresolv" fi IPADDR_IN_DISPLAY=yes $as_echo "#define USE_PIPES 1" >>confdefs.h $as_echo "#define IP_TOS_IS_BROKEN 1" >>confdefs.h $as_echo "#define SETEUID_BREAKS_SETUID 1" >>confdefs.h $as_echo "#define BROKEN_SETREUID 1" >>confdefs.h $as_echo "#define BROKEN_SETREGID 1" >>confdefs.h $as_echo "#define SSHD_ACQUIRES_CTTY 1" >>confdefs.h 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*) $as_echo "#define USE_PIPES 1" >>confdefs.h $as_echo "#define SETEUID_BREAKS_SETUID 1" >>confdefs.h $as_echo "#define BROKEN_SETREUID 1" >>confdefs.h $as_echo "#define BROKEN_SETREGID 1" >>confdefs.h $as_echo "#define PASSWD_NEEDS_USERNAME 1" >>confdefs.h $as_echo "#define LOCKED_PASSWD_STRING \"*LK*\"" >>confdefs.h TEST_SHELL=$SHELL # let configure find us a capable shell ;; # UnixWare 7.x, OpenUNIX 8 *-*-sysv5*) CPPFLAGS="$CPPFLAGS -Dvsnprintf=_xvsnprintf -Dsnprintf=_xsnprintf" $as_echo "#define UNIXWARE_LONG_PASSWORDS 1" >>confdefs.h $as_echo "#define USE_PIPES 1" >>confdefs.h $as_echo "#define SETEUID_BREAKS_SETUID 1" >>confdefs.h $as_echo "#define BROKEN_GETADDRINFO 1" >>confdefs.h $as_echo "#define BROKEN_SETREUID 1" >>confdefs.h $as_echo "#define BROKEN_SETREGID 1" >>confdefs.h $as_echo "#define PASSWD_NEEDS_USERNAME 1" >>confdefs.h TEST_SHELL=$SHELL # let configure find us a capable shell case "$host" in *-*-sysv5SCO_SV*) # SCO OpenServer 6.x maildir=/var/spool/mail $as_echo "#define BROKEN_LIBIAF 1" >>confdefs.h $as_echo "#define BROKEN_UPDWTMPX 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getluid in -lprot" >&5 $as_echo_n "checking for getluid in -lprot... " >&6; } if ${ac_cv_lib_prot_getluid+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lprot $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_prot_getluid=yes else ac_cv_lib_prot_getluid=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_prot_getluid" >&5 $as_echo "$ac_cv_lib_prot_getluid" >&6; } if test "x$ac_cv_lib_prot_getluid" = xyes; then : LIBS="$LIBS -lprot" for ac_func in getluid setluid do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done $as_echo "#define HAVE_SECUREWARE 1" >>confdefs.h $as_echo "#define DISABLE_SHADOW 1" >>confdefs.h fi ;; *) $as_echo "#define LOCKED_PASSWD_STRING \"*LK*\"" >>confdefs.h check_for_libcrypt_later=1 ;; esac ;; *-*-sysv*) ;; # SCO UNIX and OEM versions of SCO UNIX *-*-sco3.2v4*) as_fn_error $? "\"This Platform is no longer supported.\"" "$LINENO" 5 ;; # 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 $as_echo "#define USE_PIPES 1" >>confdefs.h $as_echo "#define HAVE_SECUREWARE 1" >>confdefs.h $as_echo "#define DISABLE_SHADOW 1" >>confdefs.h $as_echo "#define DISABLE_FD_PASSING 1" >>confdefs.h $as_echo "#define SETEUID_BREAKS_SETUID 1" >>confdefs.h $as_echo "#define BROKEN_GETADDRINFO 1" >>confdefs.h $as_echo "#define BROKEN_SETREUID 1" >>confdefs.h $as_echo "#define BROKEN_SETREGID 1" >>confdefs.h $as_echo "#define WITH_ABBREV_NO_TTY 1" >>confdefs.h $as_echo "#define BROKEN_UPDWTMPX 1" >>confdefs.h $as_echo "#define PASSWD_NEEDS_USERNAME 1" >>confdefs.h for ac_func in getluid setluid do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_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*) $as_echo "#define NO_SSH_LASTLOG 1" >>confdefs.h $as_echo "#define SETEUID_BREAKS_SETUID 1" >>confdefs.h $as_echo "#define BROKEN_SETREUID 1" >>confdefs.h $as_echo "#define BROKEN_SETREGID 1" >>confdefs.h $as_echo "#define USE_PIPES 1" >>confdefs.h $as_echo "#define DISABLE_FD_PASSING 1" >>confdefs.h LDFLAGS="$LDFLAGS" LIBS="$LIBS -lgen -lrsc -lshare -luex -lacm" MANTYPE=cat ;; *-*-unicosmp*) $as_echo "#define SETEUID_BREAKS_SETUID 1" >>confdefs.h $as_echo "#define BROKEN_SETREUID 1" >>confdefs.h $as_echo "#define BROKEN_SETREGID 1" >>confdefs.h $as_echo "#define WITH_ABBREV_NO_TTY 1" >>confdefs.h $as_echo "#define USE_PIPES 1" >>confdefs.h $as_echo "#define DISABLE_FD_PASSING 1" >>confdefs.h LDFLAGS="$LDFLAGS" LIBS="$LIBS -lgen -lacid -ldb" MANTYPE=cat ;; *-*-unicos*) $as_echo "#define SETEUID_BREAKS_SETUID 1" >>confdefs.h $as_echo "#define BROKEN_SETREUID 1" >>confdefs.h $as_echo "#define BROKEN_SETREGID 1" >>confdefs.h $as_echo "#define USE_PIPES 1" >>confdefs.h $as_echo "#define DISABLE_FD_PASSING 1" >>confdefs.h $as_echo "#define NO_SSH_LASTLOG 1" >>confdefs.h LDFLAGS="$LDFLAGS -Wl,-Dmsglevel=334:fatal" LIBS="$LIBS -lgen -lrsc -lshare -luex -lacm" MANTYPE=cat ;; *-dec-osf*) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Digital Unix SIA" >&5 $as_echo_n "checking for Digital Unix SIA... " >&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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5 $as_echo "disabled" >&6; } no_osfsia=1 fi fi if test -z "$no_osfsia" ; then if test -f /etc/sia/matrix.conf; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define HAVE_OSF_SIA 1" >>confdefs.h $as_echo "#define DISABLE_LOGIN 1" >>confdefs.h $as_echo "#define DISABLE_FD_PASSING 1" >>confdefs.h LIBS="$LIBS -lsecurity -ldb -lm -laud" SIA_MSG="yes" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "#define LOCKED_PASSWD_SUBSTR \"Nologin\"" >>confdefs.h fi fi $as_echo "#define BROKEN_GETADDRINFO 1" >>confdefs.h $as_echo "#define SETEUID_BREAKS_SETUID 1" >>confdefs.h $as_echo "#define BROKEN_SETREUID 1" >>confdefs.h $as_echo "#define BROKEN_SETREGID 1" >>confdefs.h $as_echo "#define BROKEN_READV_COMPARISON 1" >>confdefs.h ;; *-*-nto-qnx*) $as_echo "#define USE_PIPES 1" >>confdefs.h $as_echo "#define NO_X11_UNIX_SOCKETS 1" >>confdefs.h $as_echo "#define DISABLE_LASTLOG 1" >>confdefs.h $as_echo "#define SSHD_ACQUIRES_CTTY 1" >>confdefs.h $as_echo "#define BROKEN_SHADOW_EXPIRE 1" >>confdefs.h enable_etc_default_login=no # has incompatible /etc/default/login case "$host" in *-*-nto-qnx6*) $as_echo "#define DISABLE_FD_PASSING 1" >>confdefs.h ;; esac ;; *-*-ultrix*) $as_echo "#define BROKEN_GETGROUPS 1" >>confdefs.h $as_echo "#define NEED_SETPGRP 1" >>confdefs.h $as_echo "#define HAVE_SYS_SYSLOG_H 1" >>confdefs.h ;; *-*-lynxos) CFLAGS="$CFLAGS -D__NO_INCLUDE_WARN__" $as_echo "#define BROKEN_SETVBUF 1" >>confdefs.h ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking compiler and flags for sanity" >&5 $as_echo_n "checking compiler and flags for sanity... " >&6; } if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: not checking compiler sanity" >&5 $as_echo "$as_me: WARNING: cross compiling: not checking compiler sanity" >&2;} else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { exit(0); ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "*** compiler cannot create working executables, check config.log ***" "$LINENO" 5 fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi # Checks for libraries. ac_fn_c_check_func "$LINENO" "setsockopt" "ac_cv_func_setsockopt" if test "x$ac_cv_func_setsockopt" = xyes; then : else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for setsockopt in -lsocket" >&5 $as_echo_n "checking for setsockopt in -lsocket... " >&6; } if ${ac_cv_lib_socket_setsockopt+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_socket_setsockopt=yes else ac_cv_lib_socket_setsockopt=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_setsockopt" >&5 $as_echo "$ac_cv_lib_socket_setsockopt" >&6; } if test "x$ac_cv_lib_socket_setsockopt" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBSOCKET 1 _ACEOF LIBS="-lsocket $LIBS" fi fi for ac_func in dirname do : ac_fn_c_check_func "$LINENO" "dirname" "ac_cv_func_dirname" if test "x$ac_cv_func_dirname" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DIRNAME 1 _ACEOF for ac_header in libgen.h do : ac_fn_c_check_header_mongrel "$LINENO" "libgen.h" "ac_cv_header_libgen_h" "$ac_includes_default" if test "x$ac_cv_header_libgen_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBGEN_H 1 _ACEOF fi done else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dirname in -lgen" >&5 $as_echo_n "checking for dirname in -lgen... " >&6; } if ${ac_cv_lib_gen_dirname+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgen $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_gen_dirname=yes else ac_cv_lib_gen_dirname=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gen_dirname" >&5 $as_echo "$ac_cv_lib_gen_dirname" >&6; } if test "x$ac_cv_lib_gen_dirname" = xyes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for broken dirname" >&5 $as_echo_n "checking for broken dirname... " >&6; } if ${ac_cv_have_broken_dirname+:} false; then : $as_echo_n "(cached) " >&6 else save_LIBS="$LIBS" LIBS="$LIBS -lgen" if test "$cross_compiling" = yes; then : ac_cv_have_broken_dirname="no" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_run "$LINENO"; then : ac_cv_have_broken_dirname="no" else ac_cv_have_broken_dirname="yes" fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi LIBS="$save_LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_broken_dirname" >&5 $as_echo "$ac_cv_have_broken_dirname" >&6; } if test "x$ac_cv_have_broken_dirname" = "xno" ; then LIBS="$LIBS -lgen" $as_echo "#define HAVE_DIRNAME 1" >>confdefs.h for ac_header in libgen.h do : ac_fn_c_check_header_mongrel "$LINENO" "libgen.h" "ac_cv_header_libgen_h" "$ac_includes_default" if test "x$ac_cv_header_libgen_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBGEN_H 1 _ACEOF fi done fi fi fi done ac_fn_c_check_func "$LINENO" "getspnam" "ac_cv_func_getspnam" if test "x$ac_cv_func_getspnam" = xyes; then : else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getspnam in -lgen" >&5 $as_echo_n "checking for getspnam in -lgen... " >&6; } if ${ac_cv_lib_gen_getspnam+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgen $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_gen_getspnam=yes else ac_cv_lib_gen_getspnam=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gen_getspnam" >&5 $as_echo "$ac_cv_lib_gen_getspnam" >&6; } if test "x$ac_cv_lib_gen_getspnam" = xyes; then : LIBS="$LIBS -lgen" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing basename" >&5 $as_echo_n "checking for library containing basename... " >&6; } if ${ac_cv_search_basename+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_basename=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_basename+:} false; then : break fi done if ${ac_cv_search_basename+:} false; then : else ac_cv_search_basename=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_basename" >&5 $as_echo "$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" $as_echo "#define HAVE_BASENAME 1" >>confdefs.h fi # Check whether --with-zlib was given. if test "${with_zlib+set}" = set; then : withval=$with_zlib; if test "x$withval" = "xno" ; then as_fn_error $? "*** zlib is required ***" "$LINENO" 5 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 ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" if test "x$ac_cv_header_zlib_h" = xyes; then : else as_fn_error $? "*** zlib.h missing - please install first or check config.log ***" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for deflate in -lz" >&5 $as_echo_n "checking for deflate in -lz... " >&6; } if ${ac_cv_lib_z_deflate+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lz $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_z_deflate=yes else ac_cv_lib_z_deflate=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_deflate" >&5 $as_echo "$ac_cv_lib_z_deflate" >&6; } if test "x$ac_cv_lib_z_deflate" = xyes; 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 confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : $as_echo "#define HAVE_LIBZ 1" >>confdefs.h else as_fn_error $? "*** zlib missing - please install first or check config.log ***" "$LINENO" 5 fi rm -f core conftest.err conftest.$ac_objext \ 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for possibly buggy zlib" >&5 $as_echo_n "checking for possibly buggy zlib... " >&6; } if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: not checking zlib version" >&5 $as_echo "$as_me: WARNING: cross compiling: not checking zlib version" >&2;} else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } if test -z "$zlib_check_nonfatal" ; then as_fn_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." "$LINENO" 5 else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: zlib version may have security problems" >&5 $as_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.beam conftest.$ac_ext fi ac_fn_c_check_func "$LINENO" "strcasecmp" "ac_cv_func_strcasecmp" if test "x$ac_cv_func_strcasecmp" = xyes; then : else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for strcasecmp in -lresolv" >&5 $as_echo_n "checking for strcasecmp in -lresolv... " >&6; } if ${ac_cv_lib_resolv_strcasecmp+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lresolv $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_resolv_strcasecmp=yes else ac_cv_lib_resolv_strcasecmp=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_resolv_strcasecmp" >&5 $as_echo "$ac_cv_lib_resolv_strcasecmp" >&6; } if test "x$ac_cv_lib_resolv_strcasecmp" = xyes; then : LIBS="$LIBS -lresolv" fi fi for ac_func in utimes do : ac_fn_c_check_func "$LINENO" "utimes" "ac_cv_func_utimes" if test "x$ac_cv_func_utimes" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UTIMES 1 _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for utimes in -lc89" >&5 $as_echo_n "checking for utimes in -lc89... " >&6; } if ${ac_cv_lib_c89_utimes+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lc89 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_c89_utimes=yes else ac_cv_lib_c89_utimes=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c89_utimes" >&5 $as_echo "$ac_cv_lib_c89_utimes" >&6; } if test "x$ac_cv_lib_c89_utimes" = xyes; then : $as_echo "#define HAVE_UTIMES 1" >>confdefs.h LIBS="$LIBS -lc89" fi fi done for ac_header in bsd/libutil.h libutil.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing fmt_scaled" >&5 $as_echo_n "checking for library containing fmt_scaled... " >&6; } if ${ac_cv_search_fmt_scaled+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_fmt_scaled=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_fmt_scaled+:} false; then : break fi done if ${ac_cv_search_fmt_scaled+:} false; then : else ac_cv_search_fmt_scaled=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_fmt_scaled" >&5 $as_echo "$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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing scan_scaled" >&5 $as_echo_n "checking for library containing scan_scaled... " >&6; } if ${ac_cv_search_scan_scaled+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_scan_scaled=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_scan_scaled+:} false; then : break fi done if ${ac_cv_search_scan_scaled+:} false; then : else ac_cv_search_scan_scaled=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_scan_scaled" >&5 $as_echo "$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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing login" >&5 $as_echo_n "checking for library containing login... " >&6; } if ${ac_cv_search_login+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_login=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_login+:} false; then : break fi done if ${ac_cv_search_login+:} false; then : else ac_cv_search_login=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_login" >&5 $as_echo "$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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing logout" >&5 $as_echo_n "checking for library containing logout... " >&6; } if ${ac_cv_search_logout+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_logout=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_logout+:} false; then : break fi done if ${ac_cv_search_logout+:} false; then : else ac_cv_search_logout=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_logout" >&5 $as_echo "$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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing logwtmp" >&5 $as_echo_n "checking for library containing logwtmp... " >&6; } if ${ac_cv_search_logwtmp+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_logwtmp=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_logwtmp+:} false; then : break fi done if ${ac_cv_search_logwtmp+:} false; then : else ac_cv_search_logwtmp=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_logwtmp" >&5 $as_echo "$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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing openpty" >&5 $as_echo_n "checking for library containing openpty... " >&6; } if ${ac_cv_search_openpty+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_openpty=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_openpty+:} false; then : break fi done if ${ac_cv_search_openpty+:} false; then : else ac_cv_search_openpty=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_openpty" >&5 $as_echo "$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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing updwtmp" >&5 $as_echo_n "checking for library containing updwtmp... " >&6; } if ${ac_cv_search_updwtmp+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_updwtmp=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_updwtmp+:} false; then : break fi done if ${ac_cv_search_updwtmp+:} false; then : else ac_cv_search_updwtmp=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_updwtmp" >&5 $as_echo "$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=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_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. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing inet_ntop" >&5 $as_echo_n "checking for library containing inet_ntop... " >&6; } if ${ac_cv_search_inet_ntop+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_inet_ntop=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_inet_ntop+:} false; then : break fi done if ${ac_cv_search_inet_ntop+:} false; then : else ac_cv_search_inet_ntop=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_inet_ntop" >&5 $as_echo "$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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing gethostbyname" >&5 $as_echo_n "checking for library containing gethostbyname... " >&6; } if ${ac_cv_search_gethostbyname+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_gethostbyname=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_gethostbyname+:} false; then : break fi done if ${ac_cv_search_gethostbyname+:} false; then : else ac_cv_search_gethostbyname=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_gethostbyname" >&5 $as_echo "$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 : ac_fn_c_check_func "$LINENO" "strftime" "ac_cv_func_strftime" if test "x$ac_cv_func_strftime" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRFTIME 1 _ACEOF else # strftime is in -lintl on SCO UNIX. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for strftime in -lintl" >&5 $as_echo_n "checking for strftime in -lintl... " >&6; } if ${ac_cv_lib_intl_strftime+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lintl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_intl_strftime=yes else ac_cv_lib_intl_strftime=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_intl_strftime" >&5 $as_echo "$ac_cv_lib_intl_strftime" >&6; } if test "x$ac_cv_lib_intl_strftime" = xyes; then : $as_echo "#define HAVE_STRFTIME 1" >>confdefs.h LIBS="-lintl $LIBS" fi fi done # Check for ALTDIRFUNC glob() extension { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GLOB_ALTDIRFUNC support" >&5 $as_echo_n "checking for GLOB_ALTDIRFUNC support... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 : $as_echo "#define GLOB_HAS_ALTDIRFUNC 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f conftest* # Check for g.gl_matchc glob() extension { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gl_matchc field in glob_t" >&5 $as_echo_n "checking for gl_matchc field in glob_t... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { glob_t g; g.gl_matchc = 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : $as_echo "#define GLOB_HAS_GL_MATCHC 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Check for g.gl_statv glob() extension { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gl_statv and GLOB_KEEPSTAT extensions for glob" >&5 $as_echo_n "checking for gl_statv and GLOB_KEEPSTAT extensions for glob... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : $as_echo "#define GLOB_HAS_GL_STATV 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_fn_c_check_decl "$LINENO" "GLOB_NOMATCH" "ac_cv_have_decl_GLOB_NOMATCH" "#include " if test "x$ac_cv_have_decl_GLOB_NOMATCH" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_GLOB_NOMATCH $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "VIS_ALL" "ac_cv_have_decl_VIS_ALL" "#include " if test "x$ac_cv_have_decl_VIS_ALL" = xyes; then : else $as_echo "#define BROKEN_STRNVIS 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct dirent allocates space for d_name" >&5 $as_echo_n "checking whether struct dirent allocates space for d_name... " >&6; } if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: assuming BROKEN_ONE_BYTE_DIRENT_D_NAME" >&5 $as_echo "$as_me: WARNING: cross compiling: assuming BROKEN_ONE_BYTE_DIRENT_D_NAME" >&2;} $as_echo "#define BROKEN_ONE_BYTE_DIRENT_D_NAME 1" >>confdefs.h else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { struct dirent d; exit(sizeof(d.d_name)<=sizeof(char)); ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "#define BROKEN_ONE_BYTE_DIRENT_D_NAME 1" >>confdefs.h fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for /proc/pid/fd directory" >&5 $as_echo_n "checking for /proc/pid/fd directory... " >&6; } if test -d "/proc/$$/fd" ; then $as_echo "#define HAVE_PROC_PID 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 $as_echo "#define SKEY 1" >>confdefs.h LIBS="-lskey $LIBS" SKEY_MSG="yes" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for s/key support" >&5 $as_echo_n "checking for s/key support... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { char *ff = skey_keyinfo(""); ff=""; exit(0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "** Incomplete or missing s/key libraries." "$LINENO" 5 fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking if skeychallenge takes 4 arguments" >&5 $as_echo_n "checking if skeychallenge takes 4 arguments... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { (void)skeychallenge(NULL,"name","",0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define SKEYCHALLENGE_4ARG 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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; ldns="" if test "x$withval" = "xyes" ; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ldns-config", so it can be a program name with args. set dummy ${ac_tool_prefix}ldns-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_LDNSCONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $LDNSCONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_LDNSCONFIG="$LDNSCONFIG" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_LDNSCONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi LDNSCONFIG=$ac_cv_path_LDNSCONFIG if test -n "$LDNSCONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LDNSCONFIG" >&5 $as_echo "$LDNSCONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_LDNSCONFIG"; then ac_pt_LDNSCONFIG=$LDNSCONFIG # Extract the first word of "ldns-config", so it can be a program name with args. set dummy ldns-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_LDNSCONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_LDNSCONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_LDNSCONFIG="$ac_pt_LDNSCONFIG" # 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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_LDNSCONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_LDNSCONFIG=$ac_cv_path_ac_pt_LDNSCONFIG if test -n "$ac_pt_LDNSCONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_LDNSCONFIG" >&5 $as_echo "$ac_pt_LDNSCONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_LDNSCONFIG" = x; then LDNSCONFIG="no" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac LDNSCONFIG=$ac_pt_LDNSCONFIG fi else LDNSCONFIG="$ac_cv_path_LDNSCONFIG" fi if test "x$PKGCONFIG" = "xno"; then CPPFLAGS="$CPPFLAGS -I${withval}/include" LDFLAGS="$LDFLAGS -L${withval}/lib" LIBS="-lldns $LIBS" ldns=yes else LIBS="$LIBS `$LDNSCONFIG --libs`" CPPFLAGS="$CPPFLAGS `$LDNSCONFIG --cflags`" fi elif test "x$withval" != "xno" ; then CPPFLAGS="$CPPFLAGS -I${withval}/include" LDFLAGS="$LDFLAGS -L${withval}/lib" LIBS="-lldns $LIBS" ldns=yes fi # Verify that it works. if test "x$ldns" = "xyes" ; then $as_echo "#define HAVE_LDNS 1" >>confdefs.h LDNS_MSG="yes" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ldns support" >&5 $as_echo_n "checking for ldns support... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "** Incomplete or missing ldns libraries." "$LINENO" 5 fi rm -f core conftest.err conftest.$ac_objext \ 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PKGCONFIG+:} false; then : $as_echo_n "(cached) " >&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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PKGCONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKGCONFIG" >&5 $as_echo "$PKGCONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_PKGCONFIG+:} false; then : $as_echo_n "(cached) " >&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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_PKGCONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKGCONFIG" >&5 $as_echo "$ac_pt_PKGCONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_PKGCONFIG" = x; then PKGCONFIG="no" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac PKGCONFIG=$ac_pt_PKGCONFIG fi else PKGCONFIG="$ac_cv_path_PKGCONFIG" fi if test "x$PKGCONFIG" != "xno"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $PKGCONFIG knows about libedit" >&5 $as_echo_n "checking if $PKGCONFIG knows about libedit... " >&6; } if "$PKGCONFIG" libedit; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } use_pkgconfig_for_libedit=yes else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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//'` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for el_init in -ledit" >&5 $as_echo_n "checking for el_init in -ledit... " >&6; } if ${ac_cv_lib_edit_el_init+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ledit $OTHERLIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_edit_el_init=yes else ac_cv_lib_edit_el_init=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_edit_el_init" >&5 $as_echo "$ac_cv_lib_edit_el_init" >&6; } if test "x$ac_cv_lib_edit_el_init" = xyes; then : $as_echo "#define USE_LIBEDIT 1" >>confdefs.h LIBEDIT_MSG="yes" else as_fn_error $? "libedit not found" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libedit version is compatible" >&5 $as_echo_n "checking if libedit version is compatible... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int i = H_SETSIZE; el_init("", NULL, NULL, NULL); exit(0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "libedit version is not compatible" "$LINENO" 5 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; { $as_echo "$as_me:${as_lineno-$LINENO}: checking for supported audit module" >&5 $as_echo_n "checking for supported audit module... " >&6; } case "$withval" in bsm) { $as_echo "$as_me:${as_lineno-$LINENO}: result: bsm" >&5 $as_echo "bsm" >&6; } AUDIT_MODULE=bsm for ac_header in bsm/audit.h do : ac_fn_c_check_header_compile "$LINENO" "bsm/audit.h" "ac_cv_header_bsm_audit_h" " #ifdef HAVE_TIME_H # include #endif " if test "x$ac_cv_header_bsm_audit_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_BSM_AUDIT_H 1 _ACEOF else as_fn_error $? "BSM enabled and bsm/audit.h not found" "$LINENO" 5 fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getaudit in -lbsm" >&5 $as_echo_n "checking for getaudit in -lbsm... " >&6; } if ${ac_cv_lib_bsm_getaudit+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lbsm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_bsm_getaudit=yes else ac_cv_lib_bsm_getaudit=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsm_getaudit" >&5 $as_echo "$ac_cv_lib_bsm_getaudit" >&6; } if test "x$ac_cv_lib_bsm_getaudit" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBBSM 1 _ACEOF LIBS="-lbsm $LIBS" else as_fn_error $? "BSM enabled and required library not found" "$LINENO" 5 fi for ac_func in getaudit do : ac_fn_c_check_func "$LINENO" "getaudit" "ac_cv_func_getaudit" if test "x$ac_cv_func_getaudit" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GETAUDIT 1 _ACEOF else as_fn_error $? "BSM enabled and required function not found" "$LINENO" 5 fi done # These are optional for ac_func in getaudit_addr aug_get_machine do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done $as_echo "#define USE_BSM_AUDIT 1" >>confdefs.h if test "$sol2ver" -ge 11; then SSHDLIBS="$SSHDLIBS -lscf" $as_echo "#define BROKEN_BSM_API 1" >>confdefs.h fi ;; linux) { $as_echo "$as_me:${as_lineno-$LINENO}: result: linux" >&5 $as_echo "linux" >&6; } AUDIT_MODULE=linux for ac_header in libaudit.h do : ac_fn_c_check_header_mongrel "$LINENO" "libaudit.h" "ac_cv_header_libaudit_h" "$ac_includes_default" if test "x$ac_cv_header_libaudit_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBAUDIT_H 1 _ACEOF fi done SSHDLIBS="$SSHDLIBS -laudit" $as_echo "#define USE_LINUX_AUDIT 1" >>confdefs.h ;; debug) AUDIT_MODULE=debug { $as_echo "$as_me:${as_lineno-$LINENO}: result: debug" >&5 $as_echo "debug" >&6; } $as_echo "#define SSH_AUDIT_EVENTS 1" >>confdefs.h ;; no) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; *) as_fn_error $? "Unknown audit module $withval" "$LINENO" 5 ;; 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gcc >= 4.x" >&5 $as_echo_n "checking for gcc >= 4.x... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if !defined(__GNUC__) || __GNUC__ < 4 #error gcc is too old #endif _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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" { { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports compile flag -fPIE" >&5 $as_echo_n "checking if $CC supports compile flag -fPIE... " >&6; } saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $WERROR -fPIE" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-fPIE" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : if `grep -i "unrecognized option" conftest.err >/dev/null` then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$saved_CFLAGS" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } CFLAGS="$saved_CFLAGS $_define_flag" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } CFLAGS="$saved_CFLAGS" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext } { { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $LD supports link flag -pie" >&5 $as_echo_n "checking if $LD supports link flag -pie... " >&6; } saved_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $WERROR -pie" _define_flag="" test "x$_define_flag" = "x" && _define_flag="-pie" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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; long long p = n * o; printf("%d %d %d %f %f %lld %lld %lld\n", i, j, k, l, m, n, o, p); exit(0); } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } LDFLAGS="$saved_LDFLAGS $_define_flag" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } LDFLAGS="$saved_LDFLAGS" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext } # We use both -fPIE and -pie or neither. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether both -fPIE and -pie are supported" >&5 $as_echo_n "checking whether both -fPIE and -pie are supported... " >&6; } if echo "x $CFLAGS" | grep ' -fPIE' >/dev/null 2>&1 && \ echo "x $LDFLAGS" | grep ' -pie' >/dev/null 2>&1 ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 \ err \ errx \ 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 \ llabs \ login_getcapbool \ md5_crypt \ memmove \ memset_s \ mkdtemp \ 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 \ strcasestr \ 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 \ warn \ do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in mblen mbtowc nl_langinfo wcwidth do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done TEST_SSH_UTF8=${TEST_SSH_UTF8:=yes} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for utf8 locale support" >&5 $as_echo_n "checking for utf8 locale support... " >&6; } if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: assuming yes" >&5 $as_echo "$as_me: WARNING: cross compiling: assuming yes" >&2;} else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { char *loc = setlocale(LC_CTYPE, "en_US.UTF-8"); if (loc != NULL) exit(0); exit(1); ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } TEST_SSH_UTF8=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { return (isblank('a')); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : $as_echo "#define HAVE_ISBLANK 1" >>confdefs.h fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext disable_pkcs11= # Check whether --enable-pkcs11 was given. if test "${enable_pkcs11+set}" = set; then : enableval=$enable_pkcs11; if test "x$enableval" = "xno" ; then disable_pkcs11=1 fi fi # PKCS11 depends on OpenSSL. if test "x$openssl" = "xyes" && test "x$disable_pkcs11" = "x"; then # PKCS#11 support requires dlopen() and co { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5 $as_echo_n "checking for library containing dlopen... " >&6; } if ${ac_cv_search_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_dlopen=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_dlopen+:} false; then : break fi done if ${ac_cv_search_dlopen+:} false; then : else ac_cv_search_dlopen=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dlopen" >&5 $as_echo "$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" $as_echo "#define ENABLE_PKCS11 /**/" >>confdefs.h fi fi # IRIX has a const char return value for gai_strerror() for ac_func in gai_strerror do : ac_fn_c_check_func "$LINENO" "gai_strerror" "ac_cv_func_gai_strerror" if test "x$ac_cv_func_gai_strerror" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GAI_STRERROR 1 _ACEOF $as_echo "#define HAVE_GAI_STRERROR 1" >>confdefs.h cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include const char *gai_strerror(int); int main () { char *str; str = gai_strerror(0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : $as_echo "#define HAVE_CONST_GAI_STRERROR_PROTO 1" >>confdefs.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing nanosleep" >&5 $as_echo_n "checking for library containing nanosleep... " >&6; } if ${ac_cv_search_nanosleep+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_nanosleep=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_nanosleep+:} false; then : break fi done if ${ac_cv_search_nanosleep+:} false; then : else ac_cv_search_nanosleep=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_nanosleep" >&5 $as_echo "$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" $as_echo "#define HAVE_NANOSLEEP 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing clock_gettime" >&5 $as_echo_n "checking for library containing clock_gettime... " >&6; } if ${ac_cv_search_clock_gettime+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_clock_gettime=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_clock_gettime+:} false; then : break fi done if ${ac_cv_search_clock_gettime+:} false; then : else ac_cv_search_clock_gettime=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_clock_gettime" >&5 $as_echo "$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" $as_echo "#define HAVE_CLOCK_GETTIME 1" >>confdefs.h fi ac_fn_c_check_decl "$LINENO" "getrusage" "ac_cv_have_decl_getrusage" "$ac_includes_default" if test "x$ac_cv_have_decl_getrusage" = xyes; then : for ac_func in getrusage do : ac_fn_c_check_func "$LINENO" "getrusage" "ac_cv_func_getrusage" if test "x$ac_cv_func_getrusage" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GETRUSAGE 1 _ACEOF fi done fi ac_fn_c_check_decl "$LINENO" "strsep" "ac_cv_have_decl_strsep" " #ifdef HAVE_STRING_H # include #endif " if test "x$ac_cv_have_decl_strsep" = xyes; then : for ac_func in strsep do : ac_fn_c_check_func "$LINENO" "strsep" "ac_cv_func_strsep" if test "x$ac_cv_func_strsep" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRSEP 1 _ACEOF fi done fi ac_fn_c_check_decl "$LINENO" "tcsendbreak" "ac_cv_have_decl_tcsendbreak" "#include " if test "x$ac_cv_have_decl_tcsendbreak" = xyes; then : $as_echo "#define HAVE_TCSENDBREAK 1" >>confdefs.h else for ac_func in tcsendbreak do : ac_fn_c_check_func "$LINENO" "tcsendbreak" "ac_cv_func_tcsendbreak" if test "x$ac_cv_func_tcsendbreak" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_TCSENDBREAK 1 _ACEOF fi done fi ac_fn_c_check_decl "$LINENO" "h_errno" "ac_cv_have_decl_h_errno" "#include " if test "x$ac_cv_have_decl_h_errno" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_H_ERRNO $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "SHUT_RD" "ac_cv_have_decl_SHUT_RD" " #include #include " if test "x$ac_cv_have_decl_SHUT_RD" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_SHUT_RD $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "O_NONBLOCK" "ac_cv_have_decl_O_NONBLOCK" " #include #ifdef HAVE_SYS_STAT_H # include #endif #ifdef HAVE_FCNTL_H # include #endif " if test "x$ac_cv_have_decl_O_NONBLOCK" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_O_NONBLOCK $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "writev" "ac_cv_have_decl_writev" " #include #include #include " if test "x$ac_cv_have_decl_writev" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_WRITEV $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "MAXSYMLINKS" "ac_cv_have_decl_MAXSYMLINKS" " #include " if test "x$ac_cv_have_decl_MAXSYMLINKS" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_MAXSYMLINKS $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "offsetof" "ac_cv_have_decl_offsetof" " #include " if test "x$ac_cv_have_decl_offsetof" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_OFFSETOF $ac_have_decl _ACEOF # extra bits for select(2) ac_fn_c_check_decl "$LINENO" "howmany" "ac_cv_have_decl_howmany" " #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 " if test "x$ac_cv_have_decl_howmany" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_HOWMANY $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "NFDBITS" "ac_cv_have_decl_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 " if test "x$ac_cv_have_decl_NFDBITS" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_NFDBITS $ac_have_decl _ACEOF ac_fn_c_check_type "$LINENO" "fd_mask" "ac_cv_type_fd_mask" " #include #include #ifdef HAVE_SYS_SELECT_H #include #endif #ifdef HAVE_SYS_TIME_H #include #endif #ifdef HAVE_UNISTD_H #include #endif " if test "x$ac_cv_type_fd_mask" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_FD_MASK 1 _ACEOF fi for ac_func in setresuid do : ac_fn_c_check_func "$LINENO" "setresuid" "ac_cv_func_setresuid" if test "x$ac_cv_func_setresuid" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SETRESUID 1 _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking if setresuid seems to work" >&5 $as_echo_n "checking if setresuid seems to work... " >&6; } if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: not checking setresuid" >&5 $as_echo "$as_me: WARNING: cross compiling: not checking setresuid" >&2;} else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { errno=0; setresuid(0,0,0); if (errno==ENOSYS) exit(1); else exit(0); ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else $as_echo "#define BROKEN_SETRESUID 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: not implemented" >&5 $as_echo "not implemented" >&6; } fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi done for ac_func in setresgid do : ac_fn_c_check_func "$LINENO" "setresgid" "ac_cv_func_setresgid" if test "x$ac_cv_func_setresgid" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SETRESGID 1 _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking if setresgid seems to work" >&5 $as_echo_n "checking if setresgid seems to work... " >&6; } if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: not checking setresuid" >&5 $as_echo "$as_me: WARNING: cross compiling: not checking setresuid" >&2;} else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { errno=0; setresgid(0,0,0); if (errno==ENOSYS) exit(1); else exit(0); ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else $as_echo "#define BROKEN_SETRESGID 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: not implemented" >&5 $as_echo "not implemented" >&6; } fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi done for ac_func in realpath do : ac_fn_c_check_func "$LINENO" "realpath" "ac_cv_func_realpath" if test "x$ac_cv_func_realpath" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_REALPATH 1 _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking if realpath works with non-existent files" >&5 $as_echo_n "checking if realpath works with non-existent files... " >&6; } if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: assuming working" >&5 $as_echo "$as_me: WARNING: cross compiling: assuming working" >&2;} else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else $as_echo "#define BROKEN_REALPATH 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi done for ac_func in gettimeofday time do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_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=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in utmpname do : ac_fn_c_check_func "$LINENO" "utmpname" "ac_cv_func_utmpname" if test "x$ac_cv_func_utmpname" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UTMPNAME 1 _ACEOF fi done for ac_func in endutxent getutxent getutxid getutxline getutxuser pututxline do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in setutxdb setutxent utmpxname do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in getlastlogxbyname do : ac_fn_c_check_func "$LINENO" "getlastlogxbyname" "ac_cv_func_getlastlogxbyname" if test "x$ac_cv_func_getlastlogxbyname" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GETLASTLOGXBYNAME 1 _ACEOF fi done ac_fn_c_check_func "$LINENO" "daemon" "ac_cv_func_daemon" if test "x$ac_cv_func_daemon" = xyes; then : $as_echo "#define HAVE_DAEMON 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for daemon in -lbsd" >&5 $as_echo_n "checking for daemon in -lbsd... " >&6; } if ${ac_cv_lib_bsd_daemon+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lbsd $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_bsd_daemon=yes else ac_cv_lib_bsd_daemon=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_daemon" >&5 $as_echo "$ac_cv_lib_bsd_daemon" >&6; } if test "x$ac_cv_lib_bsd_daemon" = xyes; then : LIBS="$LIBS -lbsd"; $as_echo "#define HAVE_DAEMON 1" >>confdefs.h fi fi ac_fn_c_check_func "$LINENO" "getpagesize" "ac_cv_func_getpagesize" if test "x$ac_cv_func_getpagesize" = xyes; then : $as_echo "#define HAVE_GETPAGESIZE 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getpagesize in -lucb" >&5 $as_echo_n "checking for getpagesize in -lucb... " >&6; } if ${ac_cv_lib_ucb_getpagesize+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lucb $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_ucb_getpagesize=yes else ac_cv_lib_ucb_getpagesize=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ucb_getpagesize" >&5 $as_echo "$ac_cv_lib_ucb_getpagesize" >&6; } if test "x$ac_cv_lib_ucb_getpagesize" = xyes; then : LIBS="$LIBS -lucb"; $as_echo "#define HAVE_GETPAGESIZE 1" >>confdefs.h fi fi # Check for broken snprintf if test "x$ac_cv_func_snprintf" = "xyes" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether snprintf correctly terminates long strings" >&5 $as_echo_n "checking whether snprintf correctly terminates long strings... " >&6; } if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: Assuming working snprintf()" >&5 $as_echo "$as_me: WARNING: cross compiling: Assuming working snprintf()" >&2;} else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { char b[5]; snprintf(b,5,"123456789"); exit(b[4]!='\0'); ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "#define BROKEN_SNPRINTF 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: ****** Your snprintf() function is broken, complain to your vendor" >&5 $as_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.beam 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether vsnprintf returns correct values on overflow" >&5 $as_echo_n "checking whether vsnprintf returns correct values on overflow... " >&6; } if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: Assuming working vsnprintf()" >&5 $as_echo "$as_me: WARNING: cross compiling: Assuming working vsnprintf()" >&2;} else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "#define BROKEN_SNPRINTF 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: ****** Your vsnprintf() function is broken, complain to your vendor" >&5 $as_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.beam 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether snprintf can declare const char *fmt" >&5 $as_echo_n "checking whether snprintf can declare const char *fmt... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define SNPRINTF_CONST const" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "#define SNPRINTF_CONST /* not const */" >>confdefs.h 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether system supports SO_PEERCRED getsockopt" >&5 $as_echo_n "checking whether system supports SO_PEERCRED getsockopt... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { int i = SO_PEERCRED; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define HAVE_SO_PEERCRED 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for (overly) strict mkstemp" >&5 $as_echo_n "checking for (overly) strict mkstemp... " >&6; } if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define HAVE_STRICT_MKSTEMP 1" >>confdefs.h else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { char template[]="conftest.mkstemp-test"; if (mkstemp(template) == -1) exit(1); unlink(template); exit(0); ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define HAVE_STRICT_MKSTEMP 1" >>confdefs.h fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi if test ! -z "$check_for_openpty_ctty_bug"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if openpty correctly handles controlling tty" >&5 $as_echo_n "checking if openpty correctly handles controlling tty... " >&6; } if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: cross-compiling, assuming yes" >&5 $as_echo "cross-compiling, assuming yes" >&6; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "#define SSHD_ACQUIRES_CTTY 1" >>confdefs.h fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi if test "x$ac_cv_func_getaddrinfo" = "xyes" && \ test "x$check_for_hpux_broken_getaddrinfo" = "x1"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if getaddrinfo seems to work" >&5 $as_echo_n "checking if getaddrinfo seems to work... " >&6; } if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: cross-compiling, assuming yes" >&5 $as_echo "cross-compiling, assuming yes" >&6; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "#define BROKEN_GETADDRINFO 1" >>confdefs.h fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi if test "x$ac_cv_func_getaddrinfo" = "xyes" && \ test "x$check_for_aix_broken_getaddrinfo" = "x1"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if getaddrinfo seems to work" >&5 $as_echo_n "checking if getaddrinfo seems to work... " >&6; } if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: cross-compiling, assuming no" >&5 $as_echo "cross-compiling, assuming no" >&6; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define AIX_GETNAMEINFO_HACK 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "#define BROKEN_GETADDRINFO 1" >>confdefs.h fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi if test "x$ac_cv_func_getaddrinfo" = "xyes"; then ac_fn_c_check_decl "$LINENO" "AI_NUMERICSERV" "ac_cv_have_decl_AI_NUMERICSERV" "#include #include #include " if test "x$ac_cv_have_decl_AI_NUMERICSERV" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_AI_NUMERICSERV $ac_have_decl _ACEOF fi if test "x$check_for_conflicting_getspnam" = "x1"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for conflicting getspnam in shadow.h" >&5 $as_echo_n "checking for conflicting getspnam in shadow.h... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { exit(0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define GETSPNAM_CONFLICTING_DEFS 1" >>confdefs.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "x$ac_cv_func_strnvis" = "xyes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working strnvis" >&5 $as_echo_n "checking for working strnvis... " >&6; } if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: assuming broken" >&5 $as_echo "$as_me: WARNING: cross compiling: assuming broken" >&2;} $as_echo "#define BROKEN_STRNVIS 1" >>confdefs.h else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include static void sighandler(int sig) { _exit(1); } int main () { char dst[16]; signal(SIGSEGV, sighandler); if (strnvis(dst, "src", 4, 0) && strcmp(dst, "src") == 0) exit(0); exit(1) ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "#define BROKEN_STRNVIS 1" >>confdefs.h fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether getpgrp requires zero arguments" >&5 $as_echo_n "checking whether getpgrp requires zero arguments... " >&6; } if ${ac_cv_func_getpgrp_void+:} false; then : $as_echo_n "(cached) " >&6 else # Use it with a single arg. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { getpgrp (0); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_func_getpgrp_void=no else ac_cv_func_getpgrp_void=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getpgrp_void" >&5 $as_echo "$ac_cv_func_getpgrp_void" >&6; } if test $ac_cv_func_getpgrp_void = yes; then $as_echo "#define GETPGRP_VOID 1" >>confdefs.h 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 as_fn_error $? "cannot use --with-ssl-dir when OpenSSL disabled" "$LINENO" 5 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 as_fn_error $? "cannot use --with-ssl-engine when OpenSSL disabled" "$LINENO" 5 fi openssl_engine=yes fi fi if test "x$openssl" = "xyes" ; then LIBS="-lcrypto $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : $as_echo "#define HAVE_OPENSSL 1" >>confdefs.h else 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_fn_c_check_header_mongrel "$LINENO" "openssl/opensslv.h" "ac_cv_header_openssl_opensslv_h" "$ac_includes_default" if test "x$ac_cv_header_openssl_opensslv_h" = xyes; then : else as_fn_error $? "*** OpenSSL headers missing - please install first or check config.log ***" "$LINENO" 5 fi cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : $as_echo "#define HAVE_OPENSSL 1" >>confdefs.h else as_fn_error $? "*** Can't find recent OpenSSL libcrypto (see config.log for details) ***" "$LINENO" 5 fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # Determine OpenSSL header version { $as_echo "$as_me:${as_lineno-$LINENO}: checking OpenSSL header version" >&5 $as_echo_n "checking OpenSSL header version... " >&6; } if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: not checking" >&5 $as_echo "$as_me: WARNING: cross compiling: not checking" >&2;} else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_run "$LINENO"; then : ssl_header_ver=`cat conftest.sslincver` { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ssl_header_ver" >&5 $as_echo "$ssl_header_ver" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 $as_echo "not found" >&6; } as_fn_error $? "OpenSSL version header not found." "$LINENO" 5 fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi # Determine OpenSSL library version { $as_echo "$as_me:${as_lineno-$LINENO}: checking OpenSSL library version" >&5 $as_echo_n "checking OpenSSL library version... " >&6; } if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: not checking" >&5 $as_echo "$as_me: WARNING: cross compiling: not checking" >&2;} else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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, "%08lx (%s)\n", (unsigned long)SSLeay(), SSLeay_version(SSLEAY_VERSION))) < 0) exit(1); exit(0); ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ssl_library_ver=`cat conftest.ssllibver` # Check version is supported. case "$ssl_library_ver" in 10000*|0*) as_fn_error $? "OpenSSL >= 1.0.1 required (have \"$ssl_library_ver\")" "$LINENO" 5 ;; *) ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ssl_library_ver" >&5 $as_echo "$ssl_library_ver" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 $as_echo "not found" >&6; } as_fn_error $? "OpenSSL library not found." "$LINENO" 5 fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi # Sanity check OpenSSL headers { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL's headers match the library" >&5 $as_echo_n "checking whether OpenSSL's headers match the library... " >&6; } if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: not checking" >&5 $as_echo "$as_me: WARNING: cross compiling: not checking" >&2;} else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { exit(SSLeay() == OPENSSL_VERSION_NUMBER ? 0 : 1); ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if test "x$openssl_check_nonfatal" = "x"; then as_fn_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. " "$LINENO" 5 else { $as_echo "$as_me:${as_lineno-$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 $as_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.beam conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if programs using OpenSSL functions will link" >&5 $as_echo_n "checking if programs using OpenSSL functions will link... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { SSLeay_add_all_algorithms(); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } saved_LIBS="$LIBS" LIBS="$LIBS -ldl" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if programs using OpenSSL need -ldl" >&5 $as_echo_n "checking if programs using OpenSSL need -ldl... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { SSLeay_add_all_algorithms(); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } LIBS="$saved_LIBS" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext \ 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=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done if test "x$openssl_engine" = "xyes" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenSSL ENGINE support" >&5 $as_echo_n "checking for OpenSSL ENGINE support... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { ENGINE_load_builtin_engines(); ENGINE_register_all_complete(); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define USE_OPENSSL_ENGINE 1" >>confdefs.h else as_fn_error $? "OpenSSL ENGINE support not found" "$LINENO" 5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi # Check for OpenSSL without EVP_aes_{192,256}_cbc { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL has crippled AES support" >&5 $as_echo_n "checking whether OpenSSL has crippled AES support... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { exit(EVP_aes_192_cbc() == NULL || EVP_aes_256_cbc() == NULL); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define OPENSSL_LOBOTOMISED_AES 1" >>confdefs.h fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # Check for OpenSSL with EVP_aes_*ctr { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL has AES CTR via EVP" >&5 $as_echo_n "checking whether OpenSSL has AES CTR via EVP... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define OPENSSL_HAVE_EVPCTR 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext # Check for OpenSSL with EVP_aes_*gcm { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL has AES GCM via EVP" >&5 $as_echo_n "checking whether OpenSSL has AES GCM via EVP... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define OPENSSL_HAVE_EVPGCM 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } unsupported_algorithms="$unsupported_cipers \ aes128-gcm@openssh.com \ aes256-gcm@openssh.com" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing EVP_CIPHER_CTX_ctrl" >&5 $as_echo_n "checking for library containing EVP_CIPHER_CTX_ctrl... " >&6; } if ${ac_cv_search_EVP_CIPHER_CTX_ctrl+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_EVP_CIPHER_CTX_ctrl=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_EVP_CIPHER_CTX_ctrl+:} false; then : break fi done if ${ac_cv_search_EVP_CIPHER_CTX_ctrl+:} false; then : else ac_cv_search_EVP_CIPHER_CTX_ctrl=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_EVP_CIPHER_CTX_ctrl" >&5 $as_echo "$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" $as_echo "#define HAVE_EVP_CIPHER_CTX_CTRL 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if EVP_DigestUpdate returns an int" >&5 $as_echo_n "checking if EVP_DigestUpdate returns an int... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { if(EVP_DigestUpdate(NULL, NULL,0)) exit(0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "#define OPENSSL_EVP_DIGESTUPDATE_VOID 1" >>confdefs.h fi rm -f core conftest.err conftest.$ac_objext \ 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for crypt in -lcrypt" >&5 $as_echo_n "checking for crypt in -lcrypt... " >&6; } if ${ac_cv_lib_crypt_crypt+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_crypt_crypt=yes else ac_cv_lib_crypt_crypt=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypt_crypt" >&5 $as_echo "$ac_cv_lib_crypt_crypt" >&6; } if test "x$ac_cv_lib_crypt_crypt" = xyes; 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for crypt in -lcrypt" >&5 $as_echo_n "checking for crypt in -lcrypt... " >&6; } if ${ac_cv_lib_crypt_crypt+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_crypt_crypt=yes else ac_cv_lib_crypt_crypt=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypt_crypt" >&5 $as_echo "$ac_cv_lib_crypt_crypt" >&6; } if test "x$ac_cv_lib_crypt_crypt" = xyes; then : LIBS="$LIBS -lcrypt" fi fi for ac_func in crypt DES_crypt do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_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=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_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 : ac_fn_c_check_func "$LINENO" "EVP_ripemd160" "ac_cv_func_EVP_ripemd160" if test "x$ac_cv_func_EVP_ripemd160" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_EVP_RIPEMD160 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL has NID_X9_62_prime256v1" >&5 $as_echo_n "checking whether OpenSSL has NID_X9_62_prime256v1... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } enable_nistp256=1 else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL has NID_secp384r1" >&5 $as_echo_n "checking whether OpenSSL has NID_secp384r1... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } enable_nistp384=1 else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL has NID_secp521r1" >&5 $as_echo_n "checking whether OpenSSL has NID_secp521r1... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if OpenSSL's NID_secp521r1 is functional" >&5 $as_echo_n "checking if OpenSSL's NID_secp521r1 is functional... " >&6; } if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross-compiling: assuming yes" >&5 $as_echo "$as_me: WARNING: cross-compiling: assuming yes" >&2;} enable_nistp521=1 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } enable_nistp521=1 else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext \ 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 $as_echo "#define OPENSSL_HAS_ECC 1" >>confdefs.h fi if test x$enable_nistp256 = x1; then $as_echo "#define OPENSSL_HAS_NISTP256 1" >>confdefs.h 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 $as_echo "#define OPENSSL_HAS_NISTP384 1" >>confdefs.h 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 $as_echo "#define OPENSSL_HAS_NISTP521 1" >>confdefs.h 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for crypt in -lcrypt" >&5 $as_echo_n "checking for crypt in -lcrypt... " >&6; } if ${ac_cv_lib_crypt_crypt+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_crypt_crypt=yes else ac_cv_lib_crypt_crypt=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypt_crypt" >&5 $as_echo "$ac_cv_lib_crypt_crypt" >&6; } if test "x$ac_cv_lib_crypt_crypt" = xyes; then : LIBS="$LIBS -lcrypt" fi for ac_func in crypt do : ac_fn_c_check_func "$LINENO" "crypt" "ac_cv_func_crypt" if test "x$ac_cv_func_crypt" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_CRYPT 1 _ACEOF fi done fi for ac_func in \ arc4random \ arc4random_buf \ arc4random_stir \ arc4random_uniform \ do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done saved_LIBS="$LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ia_openinfo in -liaf" >&5 $as_echo_n "checking for ia_openinfo in -liaf... " >&6; } if ${ac_cv_lib_iaf_ia_openinfo+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-liaf $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_iaf_ia_openinfo=yes else ac_cv_lib_iaf_ia_openinfo=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_iaf_ia_openinfo" >&5 $as_echo "$ac_cv_lib_iaf_ia_openinfo" >&6; } if test "x$ac_cv_lib_iaf_ia_openinfo" = xyes; then : LIBS="$LIBS -liaf" for ac_func in set_id do : ac_fn_c_check_func "$LINENO" "set_id" "ac_cv_func_set_id" if test "x$ac_cv_func_set_id" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SET_ID 1 _ACEOF SSHDLIBS="$SSHDLIBS -liaf" $as_echo "#define HAVE_LIBIAF 1" >>confdefs.h fi done fi LIBS="$saved_LIBS" ### Configure cryptographic random number support # Check wheter OpenSSL seeds itself if test "x$openssl" = "xyes" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL's PRNG is internally seeded" >&5 $as_echo_n "checking whether OpenSSL's PRNG is internally seeded... " >&6; } if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: assuming yes" >&5 $as_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 confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { exit(RAND_status() == 1 ? 0 : 1); ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : OPENSSL_SEEDS_ITSELF=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam 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]*) ;; *) as_fn_error $? "You must specify a numeric port number for --with-prngd-port" "$LINENO" 5 ;; 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="" ;; /*) ;; *) as_fn_error $? "You must specify an absolute path to the entropy socket" "$LINENO" 5 ;; esac if test ! -z "$withval" ; then if test ! -z "$PRNGD_PORT" ; then as_fn_error $? "You may not specify both a PRNGD/EGD port and socket" "$LINENO" 5 fi if test ! -r "$withval" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Entropy socket is not readable" >&5 $as_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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PRNGD/EGD socket" >&5 $as_echo_n "checking for PRNGD/EGD socket... " >&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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PRNGD_SOCKET" >&5 $as_echo "$PRNGD_SOCKET" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 $as_echo "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 $as_echo "#define OPENSSL_PRNG_ONLY 1" >>confdefs.h RAND_MSG="OpenSSL internal ONLY" elif test "x$openssl" = "xno" ; then { $as_echo "$as_me:${as_lineno-$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 $as_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 as_fn_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" "$LINENO" 5 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 as_fn_error $? "PAM headers not found" "$LINENO" 5 fi saved_LIBS="$LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBDL 1 _ACEOF LIBS="-ldl $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pam_set_item in -lpam" >&5 $as_echo_n "checking for pam_set_item in -lpam... " >&6; } if ${ac_cv_lib_pam_pam_set_item+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpam $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pam_pam_set_item=yes else ac_cv_lib_pam_pam_set_item=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pam_pam_set_item" >&5 $as_echo "$ac_cv_lib_pam_pam_set_item" >&6; } if test "x$ac_cv_lib_pam_pam_set_item" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBPAM 1 _ACEOF LIBS="-lpam $LIBS" else as_fn_error $? "*** libpam missing" "$LINENO" 5 fi for ac_func in pam_getenvlist do : ac_fn_c_check_func "$LINENO" "pam_getenvlist" "ac_cv_func_pam_getenvlist" if test "x$ac_cv_func_pam_getenvlist" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_PAM_GETENVLIST 1 _ACEOF fi done for ac_func in pam_putenv do : ac_fn_c_check_func "$LINENO" "pam_putenv" "ac_cv_func_pam_putenv" if test "x$ac_cv_func_pam_putenv" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_PAM_PUTENV 1 _ACEOF fi done LIBS="$saved_LIBS" PAM_MSG="yes" SSHDLIBS="$SSHDLIBS -lpam" $as_echo "#define USE_PAM 1" >>confdefs.h 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 whether --with-pam-service was given. if test "${with_pam_service+set}" = set; then : withval=$with_pam_service; if test "x$withval" != "xno" && \ test "x$withval" != "xyes" ; then cat >>confdefs.h <<_ACEOF #define SSHD_PAM_SERVICE "$withval" _ACEOF fi fi # Check for older PAM if test "x$PAM_MSG" = "xyes" ; then # Check PAM strerror arguments (old PAM) { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pam_strerror takes only one argument" >&5 $as_echo_n "checking whether pam_strerror takes only one argument... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } else $as_echo "#define HAVE_OLD_PAM 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "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 ac_fn_c_check_decl "$LINENO" "SECCOMP_MODE_FILTER" "ac_cv_have_decl_SECCOMP_MODE_FILTER" " #include #include " if test "x$ac_cv_have_decl_SECCOMP_MODE_FILTER" = xyes; then : have_seccomp_filter=1 fi fi if test "x$have_seccomp_filter" = "x1" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking kernel for seccomp_filter support" >&5 $as_echo_n "checking kernel for seccomp_filter support... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } # Disable seccomp filter as a target have_seccomp_filter=0 fi rm -f core conftest.err conftest.$ac_objext \ 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. { $as_echo "$as_me:${as_lineno-$LINENO}: checking if select works with descriptor rlimit" >&5 $as_echo_n "checking if select works with descriptor rlimit... " >&6; } if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: assuming yes" >&5 $as_echo "$as_me: WARNING: cross compiling: assuming yes" >&2;} else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } select_works_with_rlimit=yes else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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.beam conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if setrlimit(RLIMIT_NOFILE,{0,0}) works" >&5 $as_echo_n "checking if setrlimit(RLIMIT_NOFILE,{0,0}) works... " >&6; } if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: assuming yes" >&5 $as_echo "$as_me: WARNING: cross compiling: assuming yes" >&2;} else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } rlimit_nofile_zero_works=yes else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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.beam conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if setrlimit RLIMIT_FSIZE works" >&5 $as_echo_n "checking if setrlimit RLIMIT_FSIZE works... " >&6; } if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: assuming yes" >&5 $as_echo "$as_me: WARNING: cross compiling: assuming yes" >&2;} else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "#define SANDBOX_SKIP_RLIMIT_FSIZE 1" >>confdefs.h fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam 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" && \ as_fn_error $? "pledge sandbox requires pledge(2) support" "$LINENO" 5 SANDBOX_STYLE="pledge" $as_echo "#define SANDBOX_PLEDGE 1" >>confdefs.h 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" && \ as_fn_error $? "systrace sandbox requires systrace headers and SYSTR_POLICY_KILL support" "$LINENO" 5 SANDBOX_STYLE="systrace" $as_echo "#define SANDBOX_SYSTRACE 1" >>confdefs.h 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" && \ as_fn_error $? "Darwin seatbelt sandbox requires sandbox.h and sandbox_init function" "$LINENO" 5 SANDBOX_STYLE="darwin" $as_echo "#define SANDBOX_DARWIN 1" >>confdefs.h 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" && \ as_fn_error $? "seccomp_filter sandbox not supported on $host" "$LINENO" 5 test "x$have_linux_no_new_privs" != "x1" && \ as_fn_error $? "seccomp_filter sandbox requires PR_SET_NO_NEW_PRIVS" "$LINENO" 5 test "x$have_seccomp_filter" != "x1" && \ as_fn_error $? "seccomp_filter sandbox requires seccomp headers" "$LINENO" 5 test "x$ac_cv_func_prctl" != "xyes" && \ as_fn_error $? "seccomp_filter sandbox requires prctl function" "$LINENO" 5 SANDBOX_STYLE="seccomp_filter" $as_echo "#define SANDBOX_SECCOMP_FILTER 1" >>confdefs.h 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" && \ as_fn_error $? "capsicum sandbox requires sys/capability.h header" "$LINENO" 5 test "x$ac_cv_func_cap_rights_limit" != "xyes" && \ as_fn_error $? "capsicum sandbox requires cap_rights_limit function" "$LINENO" 5 SANDBOX_STYLE="capsicum" $as_echo "#define SANDBOX_CAPSICUM 1" >>confdefs.h 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" && \ as_fn_error $? "rlimit sandbox requires setrlimit function" "$LINENO" 5 test "x$select_works_with_rlimit" != "xyes" && \ as_fn_error $? "rlimit sandbox requires select to work with rlimit" "$LINENO" 5 SANDBOX_STYLE="rlimit" $as_echo "#define SANDBOX_RLIMIT 1" >>confdefs.h elif test "x$sandbox_arg" = "xsolaris" || \ ( test -z "$sandbox_arg" && test "x$SOLARIS_PRIVS" = "xyes" ) ; then SANDBOX_STYLE="solaris" $as_echo "#define SANDBOX_SOLARIS 1" >>confdefs.h elif test -z "$sandbox_arg" || test "x$sandbox_arg" = "xno" || \ test "x$sandbox_arg" = "xnone" || test "x$sandbox_arg" = "xnull" ; then SANDBOX_STYLE="none" $as_echo "#define SANDBOX_NULL 1" >>confdefs.h else as_fn_error $? "unsupported --with-sandbox" "$LINENO" 5 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_fn_c_check_type "$LINENO" "long long" "ac_cv_type_long_long" "$ac_includes_default" if test "x$ac_cv_type_long_long" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LONG_LONG 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "unsigned long long" "ac_cv_type_unsigned_long_long" "$ac_includes_default" if test "x$ac_cv_type_unsigned_long_long" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UNSIGNED_LONG_LONG 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "long double" "ac_cv_type_long_double" "$ac_includes_default" if test "x$ac_cv_type_long_double" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LONG_DOUBLE 1 _ACEOF fi # Check datatype sizes # 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. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of short int" >&5 $as_echo_n "checking size of short int... " >&6; } if ${ac_cv_sizeof_short_int+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (short int))" "ac_cv_sizeof_short_int" "$ac_includes_default"; then : else if test "$ac_cv_type_short_int" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (short int) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_short_int=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_short_int" >&5 $as_echo "$ac_cv_sizeof_short_int" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_SHORT_INT $ac_cv_sizeof_short_int _ACEOF # 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. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5 $as_echo_n "checking size of int... " >&6; } if ${ac_cv_sizeof_int+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int" "$ac_includes_default"; then : else if test "$ac_cv_type_int" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (int) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_int=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5 $as_echo "$ac_cv_sizeof_int" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_INT $ac_cv_sizeof_int _ACEOF # 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. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long int" >&5 $as_echo_n "checking size of long int... " >&6; } if ${ac_cv_sizeof_long_int+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long int))" "ac_cv_sizeof_long_int" "$ac_includes_default"; then : else if test "$ac_cv_type_long_int" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (long int) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_long_int=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_int" >&5 $as_echo "$ac_cv_sizeof_long_int" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_LONG_INT $ac_cv_sizeof_long_int _ACEOF # 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. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long long int" >&5 $as_echo_n "checking size of long long int... " >&6; } if ${ac_cv_sizeof_long_long_int+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long int))" "ac_cv_sizeof_long_long_int" "$ac_includes_default"; then : else if test "$ac_cv_type_long_long_int" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (long long int) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_long_long_int=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long_int" >&5 $as_echo "$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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for max value of long long" >&5 $as_echo_n "checking for max value of long long... " >&6; } if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: not checking" >&5 $as_echo "$as_me: WARNING: cross compiling: not checking" >&2;} else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_run "$LINENO"; then : llong_min=`$AWK '{print $1}' conftest.llminmax` llong_max=`$AWK '{print $2}' conftest.llminmax` { $as_echo "$as_me:${as_lineno-$LINENO}: result: $llong_max" >&5 $as_echo "$llong_max" >&6; } cat >>confdefs.h <<_ACEOF #define LLONG_MAX ${llong_max}LL _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking for min value of long long" >&5 $as_echo_n "checking for min value of long long... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $llong_min" >&5 $as_echo "$llong_min" >&6; } cat >>confdefs.h <<_ACEOF #define LLONG_MIN ${llong_min}LL _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 $as_echo "not found" >&6; } fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi # More checks for data types { $as_echo "$as_me:${as_lineno-$LINENO}: checking for u_int type" >&5 $as_echo_n "checking for u_int type... " >&6; } if ${ac_cv_have_u_int+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { u_int a; a = 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have_u_int="yes" else ac_cv_have_u_int="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_u_int" >&5 $as_echo "$ac_cv_have_u_int" >&6; } if test "x$ac_cv_have_u_int" = "xyes" ; then $as_echo "#define HAVE_U_INT 1" >>confdefs.h have_u_int=1 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for intXX_t types" >&5 $as_echo_n "checking for intXX_t types... " >&6; } if ${ac_cv_have_intxx_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int8_t a; int16_t b; int32_t c; a = b = c = 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have_intxx_t="yes" else ac_cv_have_intxx_t="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_intxx_t" >&5 $as_echo "$ac_cv_have_intxx_t" >&6; } if test "x$ac_cv_have_intxx_t" = "xyes" ; then $as_echo "#define HAVE_INTXX_T 1" >>confdefs.h have_intxx_t=1 fi if (test -z "$have_intxx_t" && \ test "x$ac_cv_header_stdint_h" = "xyes") then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for intXX_t types in stdint.h" >&5 $as_echo_n "checking for intXX_t types in stdint.h... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { int8_t a; int16_t b; int32_t c; a = b = c = 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : $as_echo "#define HAVE_INTXX_T 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for int64_t type" >&5 $as_echo_n "checking for int64_t type... " >&6; } if ${ac_cv_have_int64_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have_int64_t="yes" else ac_cv_have_int64_t="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_int64_t" >&5 $as_echo "$ac_cv_have_int64_t" >&6; } if test "x$ac_cv_have_int64_t" = "xyes" ; then $as_echo "#define HAVE_INT64_T 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for u_intXX_t types" >&5 $as_echo_n "checking for u_intXX_t types... " >&6; } if ${ac_cv_have_u_intxx_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have_u_intxx_t="yes" else ac_cv_have_u_intxx_t="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_u_intxx_t" >&5 $as_echo "$ac_cv_have_u_intxx_t" >&6; } if test "x$ac_cv_have_u_intxx_t" = "xyes" ; then $as_echo "#define HAVE_U_INTXX_T 1" >>confdefs.h have_u_intxx_t=1 fi if test -z "$have_u_intxx_t" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for u_intXX_t types in sys/socket.h" >&5 $as_echo_n "checking for u_intXX_t types in sys/socket.h... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : $as_echo "#define HAVE_U_INTXX_T 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for u_int64_t types" >&5 $as_echo_n "checking for u_int64_t types... " >&6; } if ${ac_cv_have_u_int64_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { u_int64_t a; a = 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have_u_int64_t="yes" else ac_cv_have_u_int64_t="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_u_int64_t" >&5 $as_echo "$ac_cv_have_u_int64_t" >&6; } if test "x$ac_cv_have_u_int64_t" = "xyes" ; then $as_echo "#define HAVE_U_INT64_T 1" >>confdefs.h have_u_int64_t=1 fi if (test -z "$have_u_int64_t" && \ test "x$ac_cv_header_sys_bitypes_h" = "xyes") then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for u_int64_t type in sys/bitypes.h" >&5 $as_echo_n "checking for u_int64_t type in sys/bitypes.h... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { u_int64_t a; a = 1 ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : $as_echo "#define HAVE_U_INT64_T 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test -z "$have_u_intxx_t" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uintXX_t types" >&5 $as_echo_n "checking for uintXX_t types... " >&6; } if ${ac_cv_have_uintxx_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { uint8_t a; uint16_t b; uint32_t c; a = b = c = 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have_uintxx_t="yes" else ac_cv_have_uintxx_t="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_uintxx_t" >&5 $as_echo "$ac_cv_have_uintxx_t" >&6; } if test "x$ac_cv_have_uintxx_t" = "xyes" ; then $as_echo "#define HAVE_UINTXX_T 1" >>confdefs.h fi fi if (test -z "$have_uintxx_t" && \ test "x$ac_cv_header_stdint_h" = "xyes") then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uintXX_t types in stdint.h" >&5 $as_echo_n "checking for uintXX_t types in stdint.h... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { uint8_t a; uint16_t b; uint32_t c; a = b = c = 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : $as_echo "#define HAVE_UINTXX_T 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uintXX_t types in inttypes.h" >&5 $as_echo_n "checking for uintXX_t types in inttypes.h... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { uint8_t a; uint16_t b; uint32_t c; a = b = c = 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : $as_echo "#define HAVE_UINTXX_T 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for intXX_t and u_intXX_t types in sys/bitypes.h" >&5 $as_echo_n "checking for intXX_t and u_intXX_t types in sys/bitypes.h... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : $as_echo "#define HAVE_U_INTXX_T 1" >>confdefs.h $as_echo "#define HAVE_INTXX_T 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for u_char" >&5 $as_echo_n "checking for u_char... " >&6; } if ${ac_cv_have_u_char+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { u_char foo; foo = 125; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have_u_char="yes" else ac_cv_have_u_char="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_u_char" >&5 $as_echo "$ac_cv_have_u_char" >&6; } if test "x$ac_cv_have_u_char" = "xyes" ; then $as_echo "#define HAVE_U_CHAR 1" >>confdefs.h fi ac_fn_c_check_type "$LINENO" "intmax_t" "ac_cv_type_intmax_t" " #include #include " if test "x$ac_cv_type_intmax_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_INTMAX_T 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "uintmax_t" "ac_cv_type_uintmax_t" " #include #include " if test "x$ac_cv_type_uintmax_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UINTMAX_T 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "socklen_t" "ac_cv_type_socklen_t" "#include #include " if test "x$ac_cv_type_socklen_t" = xyes; then : else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socklen_t equivalent" >&5 $as_echo_n "checking for socklen_t equivalent... " >&6; } if ${curl_cv_socklen_t_equiv+:} false; then : $as_echo_n "(cached) " >&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 confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int getpeername (int, $arg2 *, $t *); int main () { $t len; getpeername(0,0,&len); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : curl_cv_socklen_t_equiv="$t" break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done done if test "x$curl_cv_socklen_t_equiv" = x; then as_fn_error $? "Cannot find a type to use in place of socklen_t" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $curl_cv_socklen_t_equiv" >&5 $as_echo "$curl_cv_socklen_t_equiv" >&6; } cat >>confdefs.h <<_ACEOF #define socklen_t $curl_cv_socklen_t_equiv _ACEOF fi ac_fn_c_check_type "$LINENO" "sig_atomic_t" "ac_cv_type_sig_atomic_t" "#include " if test "x$ac_cv_type_sig_atomic_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SIG_ATOMIC_T 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "fsblkcnt_t" "ac_cv_type_fsblkcnt_t" " #include #ifdef HAVE_SYS_BITYPES_H #include #endif #ifdef HAVE_SYS_STATFS_H #include #endif #ifdef HAVE_SYS_STATVFS_H #include #endif " if test "x$ac_cv_type_fsblkcnt_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_FSBLKCNT_T 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "fsfilcnt_t" "ac_cv_type_fsfilcnt_t" " #include #ifdef HAVE_SYS_BITYPES_H #include #endif #ifdef HAVE_SYS_STATFS_H #include #endif #ifdef HAVE_SYS_STATVFS_H #include #endif " if test "x$ac_cv_type_fsfilcnt_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_FSFILCNT_T 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "in_addr_t" "ac_cv_type_in_addr_t" "#include #include " if test "x$ac_cv_type_in_addr_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_IN_ADDR_T 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "in_port_t" "ac_cv_type_in_port_t" "#include #include " if test "x$ac_cv_type_in_port_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_IN_PORT_T 1 _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for size_t" >&5 $as_echo_n "checking for size_t... " >&6; } if ${ac_cv_have_size_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { size_t foo; foo = 1235; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have_size_t="yes" else ac_cv_have_size_t="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_size_t" >&5 $as_echo "$ac_cv_have_size_t" >&6; } if test "x$ac_cv_have_size_t" = "xyes" ; then $as_echo "#define HAVE_SIZE_T 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ssize_t" >&5 $as_echo_n "checking for ssize_t... " >&6; } if ${ac_cv_have_ssize_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { ssize_t foo; foo = 1235; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have_ssize_t="yes" else ac_cv_have_ssize_t="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_ssize_t" >&5 $as_echo "$ac_cv_have_ssize_t" >&6; } if test "x$ac_cv_have_ssize_t" = "xyes" ; then $as_echo "#define HAVE_SSIZE_T 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_t" >&5 $as_echo_n "checking for clock_t... " >&6; } if ${ac_cv_have_clock_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { clock_t foo; foo = 1235; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have_clock_t="yes" else ac_cv_have_clock_t="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_clock_t" >&5 $as_echo "$ac_cv_have_clock_t" >&6; } if test "x$ac_cv_have_clock_t" = "xyes" ; then $as_echo "#define HAVE_CLOCK_T 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sa_family_t" >&5 $as_echo_n "checking for sa_family_t... " >&6; } if ${ac_cv_have_sa_family_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { sa_family_t foo; foo = 1235; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have_sa_family_t="yes" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { sa_family_t foo; foo = 1235; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have_sa_family_t="yes" else 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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_sa_family_t" >&5 $as_echo "$ac_cv_have_sa_family_t" >&6; } if test "x$ac_cv_have_sa_family_t" = "xyes" ; then $as_echo "#define HAVE_SA_FAMILY_T 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pid_t" >&5 $as_echo_n "checking for pid_t... " >&6; } if ${ac_cv_have_pid_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { pid_t foo; foo = 1235; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have_pid_t="yes" else ac_cv_have_pid_t="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_pid_t" >&5 $as_echo "$ac_cv_have_pid_t" >&6; } if test "x$ac_cv_have_pid_t" = "xyes" ; then $as_echo "#define HAVE_PID_T 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mode_t" >&5 $as_echo_n "checking for mode_t... " >&6; } if ${ac_cv_have_mode_t+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { mode_t foo; foo = 1235; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have_mode_t="yes" else ac_cv_have_mode_t="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_mode_t" >&5 $as_echo "$ac_cv_have_mode_t" >&6; } if test "x$ac_cv_have_mode_t" = "xyes" ; then $as_echo "#define HAVE_MODE_T 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct sockaddr_storage" >&5 $as_echo_n "checking for struct sockaddr_storage... " >&6; } if ${ac_cv_have_struct_sockaddr_storage+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { struct sockaddr_storage s; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have_struct_sockaddr_storage="yes" else ac_cv_have_struct_sockaddr_storage="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_struct_sockaddr_storage" >&5 $as_echo "$ac_cv_have_struct_sockaddr_storage" >&6; } if test "x$ac_cv_have_struct_sockaddr_storage" = "xyes" ; then $as_echo "#define HAVE_STRUCT_SOCKADDR_STORAGE 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct sockaddr_in6" >&5 $as_echo_n "checking for struct sockaddr_in6... " >&6; } if ${ac_cv_have_struct_sockaddr_in6+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { struct sockaddr_in6 s; s.sin6_family = 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have_struct_sockaddr_in6="yes" else ac_cv_have_struct_sockaddr_in6="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_struct_sockaddr_in6" >&5 $as_echo "$ac_cv_have_struct_sockaddr_in6" >&6; } if test "x$ac_cv_have_struct_sockaddr_in6" = "xyes" ; then $as_echo "#define HAVE_STRUCT_SOCKADDR_IN6 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct in6_addr" >&5 $as_echo_n "checking for struct in6_addr... " >&6; } if ${ac_cv_have_struct_in6_addr+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { struct in6_addr s; s.s6_addr[0] = 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have_struct_in6_addr="yes" else ac_cv_have_struct_in6_addr="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_struct_in6_addr" >&5 $as_echo "$ac_cv_have_struct_in6_addr" >&6; } if test "x$ac_cv_have_struct_in6_addr" = "xyes" ; then $as_echo "#define HAVE_STRUCT_IN6_ADDR 1" >>confdefs.h ac_fn_c_check_member "$LINENO" "struct sockaddr_in6" "sin6_scope_id" "ac_cv_member_struct_sockaddr_in6_sin6_scope_id" " #ifdef HAVE_SYS_TYPES_H #include #endif #include " if test "x$ac_cv_member_struct_sockaddr_in6_sin6_scope_id" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID 1 _ACEOF fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct addrinfo" >&5 $as_echo_n "checking for struct addrinfo... " >&6; } if ${ac_cv_have_struct_addrinfo+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { struct addrinfo s; s.ai_flags = AI_PASSIVE; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have_struct_addrinfo="yes" else ac_cv_have_struct_addrinfo="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_struct_addrinfo" >&5 $as_echo "$ac_cv_have_struct_addrinfo" >&6; } if test "x$ac_cv_have_struct_addrinfo" = "xyes" ; then $as_echo "#define HAVE_STRUCT_ADDRINFO 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct timeval" >&5 $as_echo_n "checking for struct timeval... " >&6; } if ${ac_cv_have_struct_timeval+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct timeval tv; tv.tv_sec = 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have_struct_timeval="yes" else ac_cv_have_struct_timeval="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_struct_timeval" >&5 $as_echo "$ac_cv_have_struct_timeval" >&6; } if test "x$ac_cv_have_struct_timeval" = "xyes" ; then $as_echo "#define HAVE_STRUCT_TIMEVAL 1" >>confdefs.h have_struct_timeval=1 fi ac_fn_c_check_type "$LINENO" "struct timespec" "ac_cv_type_struct_timespec" "$ac_includes_default" if test "x$ac_cv_type_struct_timespec" = xyes; 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 : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: Assuming working snprintf()" >&5 $as_echo "$as_me: WARNING: cross compiling: Assuming working snprintf()" >&2;} else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_run "$LINENO"; then : true else $as_echo "#define BROKEN_SNPRINTF 1" >>confdefs.h fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ut_host field in utmp.h" >&5 $as_echo_n "checking for ut_host field in utmp.h... " >&6; } if eval \${$ossh_varname+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ossh_result" >&5 $as_echo "$ossh_result" >&6; } if test "x$ossh_result" = "xyes"; then $as_echo "#define HAVE_HOST_IN_UTMP 1" >>confdefs.h fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ut_host field in utmpx.h" >&5 $as_echo_n "checking for ut_host field in utmpx.h... " >&6; } if eval \${$ossh_varname+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ossh_result" >&5 $as_echo "$ossh_result" >&6; } if test "x$ossh_result" = "xyes"; then $as_echo "#define HAVE_HOST_IN_UTMPX 1" >>confdefs.h fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for syslen field in utmpx.h" >&5 $as_echo_n "checking for syslen field in utmpx.h... " >&6; } if eval \${$ossh_varname+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ossh_result" >&5 $as_echo "$ossh_result" >&6; } if test "x$ossh_result" = "xyes"; then $as_echo "#define HAVE_SYSLEN_IN_UTMPX 1" >>confdefs.h fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ut_pid field in utmp.h" >&5 $as_echo_n "checking for ut_pid field in utmp.h... " >&6; } if eval \${$ossh_varname+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ossh_result" >&5 $as_echo "$ossh_result" >&6; } if test "x$ossh_result" = "xyes"; then $as_echo "#define HAVE_PID_IN_UTMP 1" >>confdefs.h fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ut_type field in utmp.h" >&5 $as_echo_n "checking for ut_type field in utmp.h... " >&6; } if eval \${$ossh_varname+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ossh_result" >&5 $as_echo "$ossh_result" >&6; } if test "x$ossh_result" = "xyes"; then $as_echo "#define HAVE_TYPE_IN_UTMP 1" >>confdefs.h fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ut_type field in utmpx.h" >&5 $as_echo_n "checking for ut_type field in utmpx.h... " >&6; } if eval \${$ossh_varname+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ossh_result" >&5 $as_echo "$ossh_result" >&6; } if test "x$ossh_result" = "xyes"; then $as_echo "#define HAVE_TYPE_IN_UTMPX 1" >>confdefs.h fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ut_tv field in utmp.h" >&5 $as_echo_n "checking for ut_tv field in utmp.h... " >&6; } if eval \${$ossh_varname+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ossh_result" >&5 $as_echo "$ossh_result" >&6; } if test "x$ossh_result" = "xyes"; then $as_echo "#define HAVE_TV_IN_UTMP 1" >>confdefs.h fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ut_id field in utmp.h" >&5 $as_echo_n "checking for ut_id field in utmp.h... " >&6; } if eval \${$ossh_varname+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ossh_result" >&5 $as_echo "$ossh_result" >&6; } if test "x$ossh_result" = "xyes"; then $as_echo "#define HAVE_ID_IN_UTMP 1" >>confdefs.h fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ut_id field in utmpx.h" >&5 $as_echo_n "checking for ut_id field in utmpx.h... " >&6; } if eval \${$ossh_varname+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ossh_result" >&5 $as_echo "$ossh_result" >&6; } if test "x$ossh_result" = "xyes"; then $as_echo "#define HAVE_ID_IN_UTMPX 1" >>confdefs.h fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ut_addr field in utmp.h" >&5 $as_echo_n "checking for ut_addr field in utmp.h... " >&6; } if eval \${$ossh_varname+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ossh_result" >&5 $as_echo "$ossh_result" >&6; } if test "x$ossh_result" = "xyes"; then $as_echo "#define HAVE_ADDR_IN_UTMP 1" >>confdefs.h fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ut_addr field in utmpx.h" >&5 $as_echo_n "checking for ut_addr field in utmpx.h... " >&6; } if eval \${$ossh_varname+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ossh_result" >&5 $as_echo "$ossh_result" >&6; } if test "x$ossh_result" = "xyes"; then $as_echo "#define HAVE_ADDR_IN_UTMPX 1" >>confdefs.h fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ut_addr_v6 field in utmp.h" >&5 $as_echo_n "checking for ut_addr_v6 field in utmp.h... " >&6; } if eval \${$ossh_varname+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ossh_result" >&5 $as_echo "$ossh_result" >&6; } if test "x$ossh_result" = "xyes"; then $as_echo "#define HAVE_ADDR_V6_IN_UTMP 1" >>confdefs.h fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ut_addr_v6 field in utmpx.h" >&5 $as_echo_n "checking for ut_addr_v6 field in utmpx.h... " >&6; } if eval \${$ossh_varname+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ossh_result" >&5 $as_echo "$ossh_result" >&6; } if test "x$ossh_result" = "xyes"; then $as_echo "#define HAVE_ADDR_V6_IN_UTMPX 1" >>confdefs.h fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ut_exit field in utmp.h" >&5 $as_echo_n "checking for ut_exit field in utmp.h... " >&6; } if eval \${$ossh_varname+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ossh_result" >&5 $as_echo "$ossh_result" >&6; } if test "x$ossh_result" = "xyes"; then $as_echo "#define HAVE_EXIT_IN_UTMP 1" >>confdefs.h fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ut_time field in utmp.h" >&5 $as_echo_n "checking for ut_time field in utmp.h... " >&6; } if eval \${$ossh_varname+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ossh_result" >&5 $as_echo "$ossh_result" >&6; } if test "x$ossh_result" = "xyes"; then $as_echo "#define HAVE_TIME_IN_UTMP 1" >>confdefs.h fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ut_time field in utmpx.h" >&5 $as_echo_n "checking for ut_time field in utmpx.h... " >&6; } if eval \${$ossh_varname+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ossh_result" >&5 $as_echo "$ossh_result" >&6; } if test "x$ossh_result" = "xyes"; then $as_echo "#define HAVE_TIME_IN_UTMPX 1" >>confdefs.h fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ut_tv field in utmpx.h" >&5 $as_echo_n "checking for ut_tv field in utmpx.h... " >&6; } if eval \${$ossh_varname+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ossh_result" >&5 $as_echo "$ossh_result" >&6; } if test "x$ossh_result" = "xyes"; then $as_echo "#define HAVE_TV_IN_UTMPX 1" >>confdefs.h fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ac_fn_c_check_member "$LINENO" "struct stat" "st_blksize" "ac_cv_member_struct_stat_st_blksize" "$ac_includes_default" if test "x$ac_cv_member_struct_stat_st_blksize" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_STAT_ST_BLKSIZE 1 _ACEOF fi ac_fn_c_check_member "$LINENO" "struct passwd" "pw_gecos" "ac_cv_member_struct_passwd_pw_gecos" " #include #include " if test "x$ac_cv_member_struct_passwd_pw_gecos" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_PASSWD_PW_GECOS 1 _ACEOF fi ac_fn_c_check_member "$LINENO" "struct passwd" "pw_class" "ac_cv_member_struct_passwd_pw_class" " #include #include " if test "x$ac_cv_member_struct_passwd_pw_class" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_PASSWD_PW_CLASS 1 _ACEOF fi ac_fn_c_check_member "$LINENO" "struct passwd" "pw_change" "ac_cv_member_struct_passwd_pw_change" " #include #include " if test "x$ac_cv_member_struct_passwd_pw_change" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_PASSWD_PW_CHANGE 1 _ACEOF fi ac_fn_c_check_member "$LINENO" "struct passwd" "pw_expire" "ac_cv_member_struct_passwd_pw_expire" " #include #include " if test "x$ac_cv_member_struct_passwd_pw_expire" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_PASSWD_PW_EXPIRE 1 _ACEOF fi ac_fn_c_check_member "$LINENO" "struct __res_state" "retrans" "ac_cv_member_struct___res_state_retrans" " #include #if HAVE_SYS_TYPES_H # include #endif #include #include #include " if test "x$ac_cv_member_struct___res_state_retrans" = xyes; then : else $as_echo "#define __res_state state" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ss_family field in struct sockaddr_storage" >&5 $as_echo_n "checking for ss_family field in struct sockaddr_storage... " >&6; } if ${ac_cv_have_ss_family_in_struct_ss+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { struct sockaddr_storage s; s.ss_family = 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have_ss_family_in_struct_ss="yes" else ac_cv_have_ss_family_in_struct_ss="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_ss_family_in_struct_ss" >&5 $as_echo "$ac_cv_have_ss_family_in_struct_ss" >&6; } if test "x$ac_cv_have_ss_family_in_struct_ss" = "xyes" ; then $as_echo "#define HAVE_SS_FAMILY_IN_SS 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __ss_family field in struct sockaddr_storage" >&5 $as_echo_n "checking for __ss_family field in struct sockaddr_storage... " >&6; } if ${ac_cv_have___ss_family_in_struct_ss+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { struct sockaddr_storage s; s.__ss_family = 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have___ss_family_in_struct_ss="yes" else ac_cv_have___ss_family_in_struct_ss="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have___ss_family_in_struct_ss" >&5 $as_echo "$ac_cv_have___ss_family_in_struct_ss" >&6; } if test "x$ac_cv_have___ss_family_in_struct_ss" = "xyes" ; then $as_echo "#define HAVE___SS_FAMILY_IN_SS 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for msg_accrights field in struct msghdr" >&5 $as_echo_n "checking for msg_accrights field in struct msghdr... " >&6; } if ${ac_cv_have_accrights_in_msghdr+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have_accrights_in_msghdr="yes" else ac_cv_have_accrights_in_msghdr="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_accrights_in_msghdr" >&5 $as_echo "$ac_cv_have_accrights_in_msghdr" >&6; } if test "x$ac_cv_have_accrights_in_msghdr" = "xyes" ; then $as_echo "#define HAVE_ACCRIGHTS_IN_MSGHDR 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if struct statvfs.f_fsid is integral type" >&5 $as_echo_n "checking if struct statvfs.f_fsid is integral type... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if fsid_t has member val" >&5 $as_echo_n "checking if fsid_t has member val... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { fsid_t t; t.val[0] = 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define FSID_HAS_VAL 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking if f_fsid has member __val" >&5 $as_echo_n "checking if f_fsid has member __val... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { fsid_t t; t.__val[0] = 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define FSID_HAS___VAL 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for msg_control field in struct msghdr" >&5 $as_echo_n "checking for msg_control field in struct msghdr... " >&6; } if ${ac_cv_have_control_in_msghdr+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : ac_cv_have_control_in_msghdr="yes" else ac_cv_have_control_in_msghdr="no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_control_in_msghdr" >&5 $as_echo "$ac_cv_have_control_in_msghdr" >&6; } if test "x$ac_cv_have_control_in_msghdr" = "xyes" ; then $as_echo "#define HAVE_CONTROL_IN_MSGHDR 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libc defines __progname" >&5 $as_echo_n "checking if libc defines __progname... " >&6; } if ${ac_cv_libc_defines___progname+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { extern char *__progname; printf("%s", __progname); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_libc_defines___progname="yes" else ac_cv_libc_defines___progname="no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libc_defines___progname" >&5 $as_echo "$ac_cv_libc_defines___progname" >&6; } if test "x$ac_cv_libc_defines___progname" = "xyes" ; then $as_echo "#define HAVE___PROGNAME 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC implements __FUNCTION__" >&5 $as_echo_n "checking whether $CC implements __FUNCTION__... " >&6; } if ${ac_cv_cc_implements___FUNCTION__+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { printf("%s", __FUNCTION__); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_cc_implements___FUNCTION__="yes" else ac_cv_cc_implements___FUNCTION__="no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cc_implements___FUNCTION__" >&5 $as_echo "$ac_cv_cc_implements___FUNCTION__" >&6; } if test "x$ac_cv_cc_implements___FUNCTION__" = "xyes" ; then $as_echo "#define HAVE___FUNCTION__ 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC implements __func__" >&5 $as_echo_n "checking whether $CC implements __func__... " >&6; } if ${ac_cv_cc_implements___func__+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { printf("%s", __func__); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_cc_implements___func__="yes" else ac_cv_cc_implements___func__="no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cc_implements___func__" >&5 $as_echo "$ac_cv_cc_implements___func__" >&6; } if test "x$ac_cv_cc_implements___func__" = "xyes" ; then $as_echo "#define HAVE___func__ 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether va_copy exists" >&5 $as_echo_n "checking whether va_copy exists... " >&6; } if ${ac_cv_have_va_copy+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include va_list x,y; int main () { va_copy(x,y); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_have_va_copy="yes" else ac_cv_have_va_copy="no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_va_copy" >&5 $as_echo "$ac_cv_have_va_copy" >&6; } if test "x$ac_cv_have_va_copy" = "xyes" ; then $as_echo "#define HAVE_VA_COPY 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether __va_copy exists" >&5 $as_echo_n "checking whether __va_copy exists... " >&6; } if ${ac_cv_have___va_copy+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include va_list x,y; int main () { __va_copy(x,y); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_have___va_copy="yes" else ac_cv_have___va_copy="no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have___va_copy" >&5 $as_echo "$ac_cv_have___va_copy" >&6; } if test "x$ac_cv_have___va_copy" = "xyes" ; then $as_echo "#define HAVE___VA_COPY 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether getopt has optreset support" >&5 $as_echo_n "checking whether getopt has optreset support... " >&6; } if ${ac_cv_have_getopt_optreset+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { extern int optreset; optreset = 0; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_have_getopt_optreset="yes" else ac_cv_have_getopt_optreset="no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_getopt_optreset" >&5 $as_echo "$ac_cv_have_getopt_optreset" >&6; } if test "x$ac_cv_have_getopt_optreset" = "xyes" ; then $as_echo "#define HAVE_GETOPT_OPTRESET 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libc defines sys_errlist" >&5 $as_echo_n "checking if libc defines sys_errlist... " >&6; } if ${ac_cv_libc_defines_sys_errlist+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { extern const char *const sys_errlist[]; printf("%s", sys_errlist[0]); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_libc_defines_sys_errlist="yes" else ac_cv_libc_defines_sys_errlist="no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libc_defines_sys_errlist" >&5 $as_echo "$ac_cv_libc_defines_sys_errlist" >&6; } if test "x$ac_cv_libc_defines_sys_errlist" = "xyes" ; then $as_echo "#define HAVE_SYS_ERRLIST 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libc defines sys_nerr" >&5 $as_echo_n "checking if libc defines sys_nerr... " >&6; } if ${ac_cv_libc_defines_sys_nerr+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { extern int sys_nerr; printf("%i", sys_nerr); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_libc_defines_sys_nerr="yes" else ac_cv_libc_defines_sys_nerr="no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_libc_defines_sys_nerr" >&5 $as_echo "$ac_cv_libc_defines_sys_nerr" >&6; } if test "x$ac_cv_libc_defines_sys_nerr" = "xyes" ; then $as_echo "#define HAVE_SYS_NERR 1" >>confdefs.h fi # Check libraries needed by DNS fingerprint support { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing getrrsetbyname" >&5 $as_echo_n "checking for library containing getrrsetbyname... " >&6; } if ${ac_cv_search_getrrsetbyname+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_getrrsetbyname=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_getrrsetbyname+:} false; then : break fi done if ${ac_cv_search_getrrsetbyname+:} false; then : else ac_cv_search_getrrsetbyname=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_getrrsetbyname" >&5 $as_echo "$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" $as_echo "#define HAVE_GETRRSETBYNAME 1" >>confdefs.h else # Needed by our getrrsetbyname() { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing res_query" >&5 $as_echo_n "checking for library containing res_query... " >&6; } if ${ac_cv_search_res_query+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_res_query=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_res_query+:} false; then : break fi done if ${ac_cv_search_res_query+:} false; then : else ac_cv_search_res_query=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_res_query" >&5 $as_echo "$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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dn_expand" >&5 $as_echo_n "checking for library containing dn_expand... " >&6; } if ${ac_cv_search_dn_expand+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_dn_expand=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_dn_expand+:} false; then : break fi done if ${ac_cv_search_dn_expand+:} false; then : else ac_cv_search_dn_expand=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dn_expand" >&5 $as_echo "$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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if res_query will link" >&5 $as_echo_n "checking if res_query will link... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include #include int main () { res_query (0, 0, 0, 0, 0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } saved_LIBS="$LIBS" LIBS="$LIBS -lresolv" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for res_query in -lresolv" >&5 $as_echo_n "checking for res_query in -lresolv... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include #include int main () { res_query (0, 0, 0, 0, 0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else LIBS="$saved_LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext for ac_func in _getshort _getlong do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done ac_fn_c_check_decl "$LINENO" "_getshort" "ac_cv_have_decl__getshort" "#include #include " if test "x$ac_cv_have_decl__getshort" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL__GETSHORT $ac_have_decl _ACEOF ac_fn_c_check_decl "$LINENO" "_getlong" "ac_cv_have_decl__getlong" "#include #include " if test "x$ac_cv_have_decl__getlong" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL__GETLONG $ac_have_decl _ACEOF ac_fn_c_check_member "$LINENO" "HEADER" "ad" "ac_cv_member_HEADER_ad" "#include " if test "x$ac_cv_member_HEADER_ad" = xyes; then : $as_echo "#define HAVE_HEADER_AD 1" >>confdefs.h fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if struct __res_state _res is an extern" >&5 $as_echo_n "checking if struct __res_state _res is an extern... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define HAVE__RES_EXTERN 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext \ 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" $as_echo "#define WITH_SELINUX 1" >>confdefs.h SELINUX_MSG="yes" ac_fn_c_check_header_mongrel "$LINENO" "selinux/selinux.h" "ac_cv_header_selinux_selinux_h" "$ac_includes_default" if test "x$ac_cv_header_selinux_selinux_h" = xyes; then : else as_fn_error $? "SELinux support requires selinux.h header" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for setexeccon in -lselinux" >&5 $as_echo_n "checking for setexeccon in -lselinux... " >&6; } if ${ac_cv_lib_selinux_setexeccon+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lselinux $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_selinux_setexeccon=yes else ac_cv_lib_selinux_setexeccon=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_selinux_setexeccon" >&5 $as_echo "$ac_cv_lib_selinux_setexeccon" >&6; } if test "x$ac_cv_lib_selinux_setexeccon" = xyes; then : LIBSELINUX="-lselinux" LIBS="$LIBS -lselinux" else as_fn_error $? "SELinux support requires libselinux library" "$LINENO" 5 fi SSHLIBS="$SSHLIBS $LIBSELINUX" SSHDLIBS="$SSHDLIBS $LIBSELINUX" for ac_func in getseuserbyname get_default_context_with_level do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_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 $as_echo "#define KRB5 1" >>confdefs.h KRB5_MSG="yes" if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}krb5-config", so it can be a program name with args. set dummy ${ac_tool_prefix}krb5-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_KRB5CONF+:} false; then : $as_echo_n "(cached) " >&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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_KRB5CONF="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi KRB5CONF=$ac_cv_path_KRB5CONF if test -n "$KRB5CONF"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $KRB5CONF" >&5 $as_echo "$KRB5CONF" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_KRB5CONF"; then ac_pt_KRB5CONF=$KRB5CONF # Extract the first word of "krb5-config", so it can be a program name with args. set dummy krb5-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_KRB5CONF+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_KRB5CONF in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_KRB5CONF="$ac_pt_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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_KRB5CONF="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_KRB5CONF=$ac_cv_path_ac_pt_KRB5CONF if test -n "$ac_pt_KRB5CONF"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_KRB5CONF" >&5 $as_echo "$ac_pt_KRB5CONF" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_KRB5CONF" = x; then KRB5CONF="$KRB5ROOT/bin/krb5-config" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac KRB5CONF=$ac_pt_KRB5CONF fi else KRB5CONF="$ac_cv_path_KRB5CONF" fi if test -x $KRB5CONF ; then K5CFLAGS="`$KRB5CONF --cflags`" K5LIBS="`$KRB5CONF --libs`" CPPFLAGS="$CPPFLAGS $K5CFLAGS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gssapi support" >&5 $as_echo_n "checking for gssapi support... " >&6; } if $KRB5CONF | grep gssapi >/dev/null ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define GSSAPI 1" >>confdefs.h GSSCFLAGS="`$KRB5CONF --cflags gssapi`" GSSLIBS="`$KRB5CONF --libs gssapi`" CPPFLAGS="$CPPFLAGS $GSSCFLAGS" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using Heimdal" >&5 $as_echo_n "checking whether we are using Heimdal... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { char *tmp = heimdal_version; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define HEIMDAL 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using Heimdal" >&5 $as_echo_n "checking whether we are using Heimdal... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { char *tmp = heimdal_version; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define HEIMDAL 1" >>confdefs.h K5LIBS="-lkrb5" K5LIBS="$K5LIBS -lcom_err -lasn1" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for net_write in -lroken" >&5 $as_echo_n "checking for net_write in -lroken... " >&6; } if ${ac_cv_lib_roken_net_write+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lroken $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_roken_net_write=yes else ac_cv_lib_roken_net_write=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_roken_net_write" >&5 $as_echo "$ac_cv_lib_roken_net_write" >&6; } if test "x$ac_cv_lib_roken_net_write" = xyes; then : K5LIBS="$K5LIBS -lroken" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for des_cbc_encrypt in -ldes" >&5 $as_echo_n "checking for des_cbc_encrypt in -ldes... " >&6; } if ${ac_cv_lib_des_des_cbc_encrypt+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldes $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_des_des_cbc_encrypt=yes else ac_cv_lib_des_des_cbc_encrypt=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_des_des_cbc_encrypt" >&5 $as_echo "$ac_cv_lib_des_des_cbc_encrypt" >&6; } if test "x$ac_cv_lib_des_des_cbc_encrypt" = xyes; then : K5LIBS="$K5LIBS -ldes" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } K5LIBS="-lkrb5 -lk5crypto -lcom_err" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dn_expand" >&5 $as_echo_n "checking for library containing dn_expand... " >&6; } if ${ac_cv_search_dn_expand+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_dn_expand=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_dn_expand+:} false; then : break fi done if ${ac_cv_search_dn_expand+:} false; then : else ac_cv_search_dn_expand=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dn_expand" >&5 $as_echo "$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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gss_init_sec_context in -lgssapi_krb5" >&5 $as_echo_n "checking for gss_init_sec_context in -lgssapi_krb5... " >&6; } if ${ac_cv_lib_gssapi_krb5_gss_init_sec_context+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgssapi_krb5 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_gssapi_krb5_gss_init_sec_context=yes else ac_cv_lib_gssapi_krb5_gss_init_sec_context=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gssapi_krb5_gss_init_sec_context" >&5 $as_echo "$ac_cv_lib_gssapi_krb5_gss_init_sec_context" >&6; } if test "x$ac_cv_lib_gssapi_krb5_gss_init_sec_context" = xyes; then : $as_echo "#define GSSAPI 1" >>confdefs.h GSSLIBS="-lgssapi_krb5" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gss_init_sec_context in -lgssapi" >&5 $as_echo_n "checking for gss_init_sec_context in -lgssapi... " >&6; } if ${ac_cv_lib_gssapi_gss_init_sec_context+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgssapi $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_gssapi_gss_init_sec_context=yes else ac_cv_lib_gssapi_gss_init_sec_context=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gssapi_gss_init_sec_context" >&5 $as_echo "$ac_cv_lib_gssapi_gss_init_sec_context" >&6; } if test "x$ac_cv_lib_gssapi_gss_init_sec_context" = xyes; then : $as_echo "#define GSSAPI 1" >>confdefs.h GSSLIBS="-lgssapi" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gss_init_sec_context in -lgss" >&5 $as_echo_n "checking for gss_init_sec_context in -lgss... " >&6; } if ${ac_cv_lib_gss_gss_init_sec_context+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgss $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_gss_gss_init_sec_context=yes else ac_cv_lib_gss_gss_init_sec_context=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gss_gss_init_sec_context" >&5 $as_echo "$ac_cv_lib_gss_gss_init_sec_context" >&6; } if test "x$ac_cv_lib_gss_gss_init_sec_context" = xyes; then : $as_echo "#define GSSAPI 1" >>confdefs.h GSSLIBS="-lgss" else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Cannot find any suitable gss-api library - build may fail" >&5 $as_echo "$as_me: WARNING: Cannot find any suitable gss-api library - build may fail" >&2;} fi fi fi ac_fn_c_check_header_mongrel "$LINENO" "gssapi.h" "ac_cv_header_gssapi_h" "$ac_includes_default" if test "x$ac_cv_header_gssapi_h" = xyes; then : else unset ac_cv_header_gssapi_h CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include/gssapi" for ac_header in gssapi.h do : ac_fn_c_check_header_mongrel "$LINENO" "gssapi.h" "ac_cv_header_gssapi_h" "$ac_includes_default" if test "x$ac_cv_header_gssapi_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GSSAPI_H 1 _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Cannot find any suitable gss-api header - build may fail" >&5 $as_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" ac_fn_c_check_header_mongrel "$LINENO" "gssapi_krb5.h" "ac_cv_header_gssapi_krb5_h" "$ac_includes_default" if test "x$ac_cv_header_gssapi_krb5_h" = xyes; 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=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_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=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_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=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing k_hasafs" >&5 $as_echo_n "checking for library containing k_hasafs... " >&6; } if ${ac_cv_search_k_hasafs+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_k_hasafs=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_k_hasafs+:} false; then : break fi done if ${ac_cv_search_k_hasafs+:} false; then : else ac_cv_search_k_hasafs=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_k_hasafs" >&5 $as_echo "$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" $as_echo "#define USE_AFS 1" >>confdefs.h fi ac_fn_c_check_decl "$LINENO" "GSS_C_NT_HOSTBASED_SERVICE" "ac_cv_have_decl_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 " if test "x$ac_cv_have_decl_GSS_C_NT_HOSTBASED_SERVICE" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_GSS_C_NT_HOSTBASED_SERVICE $ac_have_decl _ACEOF 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=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_xauth_path+:} false; then : $as_echo_n "(cached) " >&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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_xauth_path="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $xauth_path" >&5 $as_echo "$xauth_path" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking Discovering system mail directory" >&5 $as_echo_n "checking Discovering system mail directory... " >&6; } if test "$cross_compiling" = yes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: use --with-maildir=/path/to/mail" >&5 $as_echo "$as_me: WARNING: cross compiling: use --with-maildir=/path/to/mail" >&2;} else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_run "$LINENO"; then : maildir_what=`awk -F: '{print $1}' conftest.maildir` maildir=`awk -F: '{print $2}' conftest.maildir \ | sed 's|/$||'` { $as_echo "$as_me:${as_lineno-$LINENO}: result: Using: $maildir from $maildir_what" >&5 $as_echo "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 if test "X$ac_status" = "X2";then # our test program didn't find it. Default to /var/spool/mail { $as_echo "$as_me:${as_lineno-$LINENO}: result: Using: default value of /var/spool/mail" >&5 $as_echo "Using: default value of /var/spool/mail" >&6; } cat >>confdefs.h <<_ACEOF #define MAIL_DIRECTORY "/var/spool/mail" _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: result: *** not found ***" >&5 $as_echo "*** not found ***" >&6; } fi fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi # maildir if test ! -z "$cross_compiling" && test "x$cross_compiling" = "xyes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: Disabling /dev/ptmx test" >&5 $as_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 as_ac_File=`$as_echo "ac_cv_file_"/dev/ptmx"" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for \"/dev/ptmx\"" >&5 $as_echo_n "checking for \"/dev/ptmx\"... " >&6; } if eval \${$as_ac_File+:} false; then : $as_echo_n "(cached) " >&6 else test "$cross_compiling" = yes && as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 if test -r ""/dev/ptmx""; then eval "$as_ac_File=yes" else eval "$as_ac_File=no" fi fi eval ac_res=\$$as_ac_File { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_File"\" = x"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 as_ac_File=`$as_echo "ac_cv_file_"/dev/ptc"" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for \"/dev/ptc\"" >&5 $as_echo_n "checking for \"/dev/ptc\"... " >&6; } if eval \${$as_ac_File+:} false; then : $as_echo_n "(cached) " >&6 else test "$cross_compiling" = yes && as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 if test -r ""/dev/ptc""; then eval "$as_ac_File=yes" else eval "$as_ac_File=no" fi fi eval ac_res=\$$as_ac_File { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_File"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define HAVE_DEV_PTS_AND_PTC 1 _ACEOF have_dev_ptc=1 fi else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: Disabling /dev/ptc test" >&5 $as_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 ;; *) as_fn_error $? "invalid man type: $withval" "$LINENO" 5 ;; 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_NROFF+:} false; then : $as_echo_n "(cached) " >&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 as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_NROFF="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NROFF" >&5 $as_echo "$NROFF" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 $as_echo "#define HAVE_MD5_PASSWORDS 1" >>confdefs.h 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 $as_echo "#define DISABLE_SHADOW 1" >>confdefs.h disable_shadow=yes fi fi if test -z "$disable_shadow" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the systems has expire shadow information" >&5 $as_echo_n "checking if the systems has expire shadow information... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct spwd sp; int main () { sp.sp_expire = sp.sp_lstchg = sp.sp_inact = 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sp_expire_available=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test "x$sp_expire_available" = "xyes" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define HAS_SHADOW_EXPIRE 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi # Use ip address instead of hostname in $DISPLAY if test ! -z "$IPADDR_IN_DISPLAY" ; then DISPLAY_HACK_MSG="yes" $as_echo "#define IPADDR_IN_DISPLAY 1" >>confdefs.h 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 $as_echo "#define IPADDR_IN_DISPLAY 1" >>confdefs.h 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 { $as_echo "$as_me:${as_lineno-$LINENO}: /etc/default/login handling disabled" >&5 $as_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 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: not checking /etc/default/login" >&5 $as_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 as_ac_File=`$as_echo "ac_cv_file_"/etc/default/login"" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for \"/etc/default/login\"" >&5 $as_echo_n "checking for \"/etc/default/login\"... " >&6; } if eval \${$as_ac_File+:} false; then : $as_echo_n "(cached) " >&6 else test "$cross_compiling" = yes && as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 if test -r ""/etc/default/login""; then eval "$as_ac_File=yes" else eval "$as_ac_File=no" fi fi eval ac_res=\$$as_ac_File { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_File"\" = x"yes"; then : external_path_file=/etc/default/login fi if test "x$external_path_file" = "x/etc/default/login"; then $as_echo "#define HAVE_ETC_DEFAULT_LOGIN 1" >>confdefs.h 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 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --with-default-path=PATH has no effect on this system. Edit /etc/login.conf instead." >&5 $as_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 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --with-default-path=PATH will only be used if PATH is not defined in $external_path_file ." >&5 $as_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 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Make sure the path to scp is in /etc/login.conf" >&5 $as_echo "$as_me: WARNING: Make sure the path to scp is in /etc/login.conf" >&2;} else if test ! -z "$external_path_file" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: If PATH is defined in $external_path_file, ensure the path to scp is included, otherwise scp will not work." >&5 $as_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 confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_run "$LINENO"; then : user_path=`cat conftest.stdpath` else 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.beam 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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: Adding $t_bindir to USER_PATH so scp will work" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we need to convert IPv4 in IPv6-mapped addresses" >&5 $as_echo_n "checking if we need to convert IPv4 in IPv6-mapped addresses... " >&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 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define IPV4_IN_IPV6 1" >>confdefs.h IPV4_IN6_HACK_MSG="yes" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else if test "x$inet6_default_4in6" = "xyes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes (default)" >&5 $as_echo "yes (default)" >&6; } $as_echo "#define IPV4_IN_IPV6 1" >>confdefs.h IPV4_IN6_HACK_MSG="yes" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no (default)" >&5 $as_echo "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 $as_echo "#define BSD_AUTH 1" >>confdefs.h 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 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: ** no $piddir directory on this system **" >&5 $as_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 $as_echo "#define DISABLE_LASTLOG 1" >>confdefs.h fi fi # Check whether --enable-utmp was given. if test "${enable_utmp+set}" = set; then : enableval=$enable_utmp; if test "x$enableval" = "xno" ; then $as_echo "#define DISABLE_UTMP 1" >>confdefs.h fi fi # Check whether --enable-utmpx was given. if test "${enable_utmpx+set}" = set; then : enableval=$enable_utmpx; if test "x$enableval" = "xno" ; then $as_echo "#define DISABLE_UTMPX 1" >>confdefs.h fi fi # Check whether --enable-wtmp was given. if test "${enable_wtmp+set}" = set; then : enableval=$enable_wtmp; if test "x$enableval" = "xno" ; then $as_echo "#define DISABLE_WTMP 1" >>confdefs.h fi fi # Check whether --enable-wtmpx was given. if test "${enable_wtmpx+set}" = set; then : enableval=$enable_wtmpx; if test "x$enableval" = "xno" ; then $as_echo "#define DISABLE_WTMPX 1" >>confdefs.h fi fi # Check whether --enable-libutil was given. if test "${enable_libutil+set}" = set; then : enableval=$enable_libutil; if test "x$enableval" = "xno" ; then $as_echo "#define DISABLE_LOGIN 1" >>confdefs.h fi fi # Check whether --enable-pututline was given. if test "${enable_pututline+set}" = set; then : enableval=$enable_pututline; if test "x$enableval" = "xno" ; then $as_echo "#define DISABLE_PUTUTLINE 1" >>confdefs.h fi fi # Check whether --enable-pututxline was given. if test "${enable_pututxline+set}" = set; then : enableval=$enable_pututxline; if test "x$enableval" = "xno" ; then $as_echo "#define DISABLE_PUTUTXLINE 1" >>confdefs.h fi fi # Check whether --with-lastlog was given. if test "${with_lastlog+set}" = set; then : withval=$with_lastlog; if test "x$withval" = "xno" ; then $as_echo "#define DISABLE_LASTLOG 1" >>confdefs.h elif test -n "$withval" && test "x${withval}" != "xyes"; then conf_lastlog_location=$withval fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if your system defines LASTLOG_FILE" >&5 $as_echo_n "checking if your system defines LASTLOG_FILE... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if your system defines _PATH_LASTLOG" >&5 $as_echo_n "checking if your system defines _PATH_LASTLOG... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: ** Cannot find lastlog **" >&5 $as_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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if your system defines UTMP_FILE" >&5 $as_echo_n "checking if your system defines UTMP_FILE... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #ifdef HAVE_PATHS_H # include #endif int main () { char *utmp = UTMP_FILE; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 $as_echo "#define DISABLE_UTMP 1" >>confdefs.h fi fi fi if test -n "$conf_utmp_location"; then cat >>confdefs.h <<_ACEOF #define CONF_UTMP_FILE "$conf_utmp_location" _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if your system defines WTMP_FILE" >&5 $as_echo_n "checking if your system defines WTMP_FILE... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #ifdef HAVE_PATHS_H # include #endif int main () { char *wtmp = WTMP_FILE; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 $as_echo "#define DISABLE_WTMP 1" >>confdefs.h fi fi fi if test -n "$conf_wtmp_location"; then cat >>confdefs.h <<_ACEOF #define CONF_WTMP_FILE "$conf_wtmp_location" _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if your system defines WTMPX_FILE" >&5 $as_echo_n "checking if your system defines WTMPX_FILE... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* 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 if ac_fn_c_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 $as_echo "#define DISABLE_WTMPX 1" >>confdefs.h fi else cat >>confdefs.h <<_ACEOF #define CONF_WTMPX_FILE "$conf_wtmpx_location" _ACEOF fi if test ! -z "$blibpath" ; then LDFLAGS="$LDFLAGS $blibflags$blibpath" { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Please check and edit blibpath in LDFLAGS in Makefile" >&5 $as_echo "$as_me: WARNING: Please check and edit blibpath in LDFLAGS in Makefile" >&2;} fi ac_fn_c_check_member "$LINENO" "struct lastlog" "ll_line" "ac_cv_member_struct_lastlog_ll_line" " #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 " if test "x$ac_cv_member_struct_lastlog_ll_line" = xyes; then : else if test x$SKIP_DISABLE_LASTLOG_DEFINE != "xyes" ; then $as_echo "#define DISABLE_LASTLOG 1" >>confdefs.h fi fi ac_fn_c_check_member "$LINENO" "struct utmp" "ut_line" "ac_cv_member_struct_utmp_ut_line" " #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 " if test "x$ac_cv_member_struct_utmp_ut_line" = xyes; then : else $as_echo "#define DISABLE_UTMP 1" >>confdefs.h $as_echo "#define DISABLE_WTMP 1" >>confdefs.h fi CFLAGS="$CFLAGS $werror_flags" if test "x$ac_cv_func_getaddrinfo" != "xyes" ; then TEST_SSH_IPV6=no else TEST_SSH_IPV6=yes fi ac_fn_c_check_decl "$LINENO" "BROKEN_GETADDRINFO" "ac_cv_have_decl_BROKEN_GETADDRINFO" "$ac_includes_default" if test "x$ac_cv_have_decl_BROKEN_GETADDRINFO" = xyes; then : TEST_SSH_IPV6=no fi TEST_SSH_IPV6=$TEST_SSH_IPV6 TEST_SSH_UTF8=$TEST_SSH_UTF8 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_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; 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 if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_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= U= 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=`$as_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. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $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} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## 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=: # Pre-4.2 versions of Zsh do 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_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } 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.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= 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 $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith 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 if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # 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 ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac 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 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then 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 -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_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 || $as_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" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # 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 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=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.69. 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 case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent 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_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ OpenSSH config.status Portable configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 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' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. 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=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= 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 ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_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. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append 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 || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # 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" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; 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= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries 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[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # 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. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[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="$ac_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 || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append 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 '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; 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 || $as_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"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_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 || ac_write_fail=1 # 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= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 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 || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;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 " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_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 "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # 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 || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} 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 " libldns support: $LDNS_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.5p1/config.h.in010064400017500001750000001330051306372320400135010ustar00djmdjm/* config.h.in. Generated from configure.ac by autoheader. */ /* Define if building universal (internal helper macro) */ #undef AC_APPLE_UNIVERSAL_BUILD /* 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 /* 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 /* strnvis detected broken */ #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 to 1 if you have the `err' function. */ #undef HAVE_ERR /* Define to 1 if you have the `errx' function. */ #undef HAVE_ERRX /* Define to 1 if you have the header file. */ #undef HAVE_ERR_H /* 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_LANGINFO_H /* 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 `llabs' function. */ #undef HAVE_LLABS /* 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 `mbtowc' function. */ #undef HAVE_MBTOWC /* 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 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 `nl_langinfo' function. */ #undef HAVE_NL_LANGINFO /* 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 `setpflags' function. */ #undef HAVE_SETPFLAGS /* 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 `strcasestr' function. */ #undef HAVE_STRCASESTR /* 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 a member of `struct passwd'. */ #undef HAVE_STRUCT_PASSWD_PW_CHANGE /* Define to 1 if `pw_class' is a member of `struct passwd'. */ #undef HAVE_STRUCT_PASSWD_PW_CLASS /* Define to 1 if `pw_expire' is a member of `struct passwd'. */ #undef HAVE_STRUCT_PASSWD_PW_EXPIRE /* Define to 1 if `pw_gecos' is a 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 a 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 a 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_PTRACE_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 `warn' function. */ #undef HAVE_WARN /* Define to 1 if you have the header file. */ #undef HAVE_WCHAR_H /* Define to 1 if you have the `wcwidth' function. */ #undef HAVE_WCWIDTH /* 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 systems need a utmpx entry for /bin/login to work */ #undef LOGIN_NEEDS_UTMPX /* 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 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 home page for this package. */ #undef PACKAGE_URL /* 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 /* sshd PAM service name */ #undef SSHD_PAM_SERVICE /* 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 WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD # if defined __BIG_ENDIAN__ # define WORDS_BIGENDIAN 1 # endif #else # ifndef WORDS_BIGENDIAN # undef WORDS_BIGENDIAN # endif #endif /* Define if xauth is found in your path */ #undef XAUTH_PATH /* Enable large inode numbers on Mac OS X 10.5. */ #ifndef _DARWIN_USE_64_BIT_INODE # define _DARWIN_USE_64_BIT_INODE 1 #endif /* 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