Project import
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a0699aa --- /dev/null +++ b/Makefile
@@ -0,0 +1,114 @@ +# +# Copyright (c) 2010-2011 Nest, Inc. +# All rights reserved. +# +# This document is the property of Nest. It is considered +# confidential and proprietary information. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Nest. +# +# Description: +# This file is the makefile for the Open Secure Shell (SSH) +# client and server. +# + +BuildConfigSpecialized := No +BuildProductSpecialized := No + +include pre.mak + +PackageName := openssh + +PackageExtension := tar.gz +PackageSeparator := - + +PackagePatchArgs := + +PackageArchive := $(PackageName).$(PackageExtension) +PackageSourceDir := $(PackageName)$(PackageSeparator)$(PackageVersion) + +PackageBuildMakefile = $(call GenerateBuildPaths,Makefile) + +CleanPaths += $(PackageLicenseFile) + +OpenSSLDir := sw/tps/openssl +OpenSSLSearchPath := $(call GenerateResultPaths,$(OpenSSLDir),usr) +TcpWrappersDir := sw/tps/tcp_wrappers +TcpWrappersSearchPath := $(call GenerateResultPaths,$(TcpWrappersDir),usr) +ZlibDir := sw/tps/zlib +ZlibSearchPath := $(call GenerateResultPaths,$(ZlibDir),usr) + +all: $(PackageDefaultGoal) + +# Generate the package license contents. + +$(PackageSourceDir)/LICENCE: source + +$(PackageLicenseFile): $(PackageSourceDir)/LICENCE + $(copy-result) + +# Extract the source from the archive and apply patches, if any. + +$(PackageSourceDir): $(PackageArchive) $(PackagePatchPaths) + $(expand-and-patch-package) + +# Prepare the sources. + +.PHONY: source +source: | $(PackageSourceDir) + +# Patch the sources, if necessary. + +.PHONY: patch +patch: source + +# Generate the package's build makefile + +$(PackageBuildMakefile): | $(PackageSourceDir) $(BuildDirectory) + $(Verbose)cd $(BuildDirectory) && \ + $(CURDIR)/$(PackageSourceDir)/configure \ + CC="$(CC)" AR=$(AR) RANLIB=$(RANLIB) STRIP=$(STRIP) \ + INSTALL="$(INSTALL) $(INSTALLFLAGS)" \ + --build=$(HostTuple) \ + --host=$(TargetTuple) \ + --prefix=/usr \ + --sysconfdir=/etc/ssh \ + --disable-strip \ + --with-ssl-dir=$(OpenSSLSearchPath) \ + --with-tcp-wrappers=$(TcpWrappersSearchPath) \ + --with-zlib=$(ZlibSearchPath) + +# Configure the source for building. + +.PHONY: configure +configure: source $(PackageBuildMakefile) + +# Build the source. +# +# We have to unset MAKEFLAGS since they confuse the package build otherwise. + +.PHONY: build +build: configure + $(Verbose)unset MAKEFLAGS && \ + $(MAKE) $(JOBSFLAG) -C $(BuildDirectory) \ + all + +# Stage the build to a temporary installation area. +# +# We have to unset MAKEFLAGS since they confuse the package build otherwise. + +.PHONY: stage +stage: build | $(ResultDirectory) + $(Verbose)unset MAKEFLAGS && \ + $(MAKE) $(JOBSFLAG) -C $(BuildDirectory) \ + DESTDIR=$(ResultDirectory) \ + install-nokeys + +clean: + $(Verbose)$(RM) $(RMFLAGS) -r $(PackageSourceDir) + $(Verbose)$(RM) $(RMFLAGS) -r $(BuildDirectory) + $(Verbose)$(RM) $(RMFLAGS) -r $(ResultDirectory) + +include post.mak
diff --git a/openssh-6.0p1/CREDITS b/openssh-6.0p1/CREDITS new file mode 100644 index 0000000..eaf105a --- /dev/null +++ b/openssh-6.0p1/CREDITS
@@ -0,0 +1,105 @@ +Tatu Ylonen <ylo@cs.hut.fi> - Creator of SSH + +Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, +Theo de Raadt, and Dug Song - Creators of OpenSSH + +Ahsan Rashid <arms@sco.com> - UnixWare long passwords +Alain St-Denis <Alain.St-Denis@ec.gc.ca> - Irix fix +Alexandre Oliva <oliva@lsd.ic.unicamp.br> - AIX fixes +Andre Lucas <andre@ae-35.com> - new login code, many fixes +Andreas Steinmetz <ast@domdv.de> - Shadow password expiry support +Andrew McGill <andrewm@datrix.co.za> - SCO fixes +Andrew Morgan <morgan@transmeta.com> - PAM bugfixes +Andrew Stribblehill <a.d.stribblehill@durham.ac.uk> - Bugfixes +Andy Sloane <andy@guildsoftware.com> - bugfixes +Aran Cox <acox@cv.telegroup.com> - SCO bugfixes +Arkadiusz Miskiewicz <misiek@pld.org.pl> - IPv6 compat fixes +Ben Lindstrom <mouring@eviladmin.org> - NeXT support +Ben Taylor <bent@clark.net> - Solaris debugging and fixes +Bratislav ILICH <bilic@zepter.ru> - Configure fix +Charles Levert <charles@comm.polymtl.ca> - SunOS 4 & bug fixes +Chip Salzenberg <chip@valinux.com> - Assorted patches +Chris Adams <cmadams@hiwaay.net> - OSF SIA support +Chris Saia <csaia@wtower.com> - SuSE packaging +Chris, the Young One <cky@pobox.com> - Password auth fixes +Christos Zoulas <christos@zoulas.com> - Autoconf fixes +Chun-Chung Chen <cjj@u.washington.edu> - RPM fixes +Corinna Vinschen <vinschen@redhat.com> - Cygwin support +Chad Mynhier <mynhier@interstel.net> - Solaris Process Contract support +Dan Brosemer <odin@linuxfreak.com> - Autoconf support, build fixes +Darren Hall <dhall@virage.org> - AIX patches +Darren Tucker <dtucker@zip.com.au> - AIX BFF package scripts +David Agraz <dagraz@jahoopa.com> - Build fixes +David Del Piero <David.DelPiero@qed.qld.gov.au> - bug fixes +David Hesprich <darkgrue@gue-tech.org> - Configure fixes +David Rankin <drankin@bohemians.lexington.ky.us> - libwrap, AIX, NetBSD fixes +Dag-Erling Smørgrav <des at freebsd.org> - Challenge-Response PAM code. +Dhiraj Gulati <dgulati@sco.com> - UnixWare long passwords +Ed Eden <ede370@stl.rural.usda.gov> - configure fixes +Garrick James <garrick@james.net> - configure fixes +Gary E. Miller <gem@rellim.com> - SCO support +Ged Lodder <lodder@yacc.com.au> - HPUX fixes and enhancements +Gert Doering <gd@hilb1.medat.de> - bug and portability fixes +HARUYAMA Seigo <haruyama@unixuser.org> - Translations & doc fixes +Hideaki YOSHIFUJI <yoshfuji@ecei.tohoku.ac.jp> - IPv6 and bug fixes +Hiroshi Takekawa <takekawa@sr3.t.u-tokyo.ac.jp> - Configure fixes +Holger Trapp <Holger.Trapp@Informatik.TU-Chemnitz.DE> - KRB4/AFS config patch +IWAMURO Motonori <iwa@mmp.fujitsu.co.jp> - bugfixes +Jani Hakala <jahakala@cc.jyu.fi> - Patches +Jarno Huuskonen <jhuuskon@hytti.uku.fi> - Bugfixes +Jim Knoble <jmknoble@pobox.com> - Many patches +Jonchen (email unknown) - the original author of PAM support of SSH +Juergen Keil <jk@tools.de> - scp bugfixing +KAMAHARA Junzo <kamahara@cc.kshosen.ac.jp> - Configure fixes +Kees Cook <cook@cpoint.net> - scp fixes +Kenji Miyake <kenji@miyake.org> - Configure fixes +Kevin Cawlfield <cawlfiel@us.ibm.com> - AIX fixes. +Kevin O'Connor <kevin_oconnor@standardandpoors.com> - RSAless operation +Kevin Steves <stevesk@pobox.com> - HP support, bugfixes, improvements +Kiyokazu SUTO <suto@ks-and-ks.ne.jp> - Bugfixes +Larry Jones <larry.jones@sdrc.com> - Bugfixes +Lutz Jaenicke <Lutz.Jaenicke@aet.TU-Cottbus.DE> - Bugfixes +Marc G. Fournier <marc.fournier@acadiau.ca> - Solaris patches +Mark D. Baushke <mdb@juniper.net> - bug fixes +Martin Johansson <fatbob@acc.umu.se> - Linux fixes +Mark D. Roth <roth+openssh@feep.net> - Features, bug fixes +Mark Miller <markm@swoon.net> - Bugfixes +Matt Richards <v2matt@btv.ibm.com> - AIX patches +Michael Steffens <michael_steffens at hp.com> - HP-UX fixes +Michael Stone <mstone@cs.loyola.edu> - Irix enhancements +Nakaji Hiroyuki <nakaji@tutrp.tut.ac.jp> - Sony News-OS patch +Nalin Dahyabhai <nalin.dahyabhai@pobox.com> - PAM environment patch +Nate Itkin <nitkin@europa.com> - SunOS 4.1.x fixes +Niels Kristian Bech Jensen <nkbj@image.dk> - Assorted patches +Pavel Kankovsky <peak@argo.troja.mff.cuni.cz> - Security fixes +Pavel Troller <patrol@omni.sinus.cz> - Bugfixes +Pekka Savola <pekkas@netcore.fi> - Bugfixes +Peter Kocks <peter.kocks@baygate.com> - Makefile fixes +Peter Stuge <stuge@cdy.org> - mdoc2man.awk script +Phil Hands <phil@hands.com> - Debian scripts, assorted patches +Phil Karn <karn@ka9q.ampr.org> - Autoconf fixes +Philippe WILLEM <Philippe.WILLEM@urssaf.fr> - Bugfixes +Phill Camp <P.S.S.Camp@ukc.ac.uk> - login code fix +Rip Loomis <loomisg@cist.saic.com> - Solaris package support, fixes +Robert Dahlem <Robert.Dahlem at siemens.com> - Reliant Unix fixes +Roumen Petrov <openssh@roumenpetrov.info> - Compile & configure fixes +SAKAI Kiyotaka <ksakai@kso.netwk.ntt-at.co.jp> - Multiple bugfixes +Simon Wilkinson <sxw@dcs.ed.ac.uk> - PAM fixes, Compat with MIT KrbV +Solar Designer <solar@openwall.com> - many patches and technical assistance +Svante Signell <svante.signell@telia.com> - Bugfixes +Thomas Neumann <tom@smart.ruhr.de> - Shadow passwords +Tim Rice <tim@multitalents.net> - Portability & SCO fixes +Tobias Oetiker <oetiker@ee.ethz.ch> - Bugfixes +Tom Bertelson's <tbert@abac.com> - AIX auth fixes +Tor-Ake Fransson <torake@hotmail.com> - AIX support +Tudor Bosman <tudorb@jm.nu> - MD5 password support +Udo Schweigert <ust@cert.siemens.de> - ReliantUNIX support +Wendy Palm <wendyp at cray.com> - Cray support. +Zack Weinberg <zack@wolery.cumb.org> - GNOME askpass enhancement + +Apologies to anyone I have missed. + +Damien Miller <djm@mindrot.org> + +$Id: CREDITS,v 1.81 2006/08/30 17:24:41 djm Exp $ +
diff --git a/openssh-6.0p1/ChangeLog b/openssh-6.0p1/ChangeLog new file mode 100644 index 0000000..5df7618 --- /dev/null +++ b/openssh-6.0p1/ChangeLog
@@ -0,0 +1,2054 @@ +20120420 + - (djm) [contrib/caldera/openssh.spec contrib/redhat/openssh.spec] + [contrib/suse/openssh.spec] Update for release 6.0 + - (djm) [README] Update URL to release notes. + - (djm) Release openssh-6.0 + +20120419 + - (djm) [configure.ac] Fix compilation error on FreeBSD, whose libutil + contains openpty() but not login() + +20120404 + - (djm) [Makefile.in configure.ac sandbox-seccomp-filter.c] Add sandbox + mode for Linux's new seccomp filter; patch from Will Drewry; feedback + and ok dtucker@ + +20120330 + - (dtucker) [contrib/redhat/openssh.spec] Bug #1992: remove now-gone WARNING + file from spec file. From crighter at nuclioss com. + - (djm) [entropy.c] bz#1991: relax OpenSSL version test to allow running + openssh binaries on a newer fix release than they were compiled on. + with and ok dtucker@ + - (djm) [openbsd-compat/bsd-cygwin_util.h] #undef _WIN32 to avoid incorrect + assumptions when building on Cygwin; patch from Corinna Vinschen + +20120309 + - (djm) [openbsd-compat/port-linux.c] bz#1960: fix crash on SELinux + systems where sshd is run in te wrong context. Patch from Sven + Vermeulen; ok dtucker@ + - (djm) [packet.c] bz#1963: Fix IPQoS not being set on non-mapped v4-in-v6 + addressed connections. ok dtucker@ + +20120224 + - (dtucker) [audit-bsm.c configure.ac] bug #1968: enable workarounds for BSM + audit breakage in Solaris 11. Patch from Magnus Johansson. + +20120215 + - (tim) [openbsd-compat/bsd-misc.h sshd.c] Fix conflicting return type for + unsetenv due to rev 1.14 change to setenv.c. Cast unsetenv to void in sshd.c + ok dtucker@ + - (tim) [defines.h] move chunk introduced in 1.125 before MAXPATHLEN so + it actually works. + - (tim) [regress/keytype.sh] stderr redirection needs to be inside back quote + to work. Spotted by Angel Gonzalez + +20120214 + - (djm) [openbsd-compat/bsd-cygwin_util.c] Add PROGRAMFILES to list of + preserved Cygwin environment variables; from Corinna Vinschen + +20120211 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2012/01/05 00:16:56 + [monitor.c] + memleak on error path + - djm@cvs.openbsd.org 2012/01/07 21:11:36 + [mux.c] + fix double-free in new session handler + - miod@cvs.openbsd.org 2012/01/08 13:17:11 + [ssh-ecdsa.c] + Fix memory leak in ssh_ecdsa_verify(); from Loganaden Velvindron, + ok markus@ + - miod@cvs.openbsd.org 2012/01/16 20:34:09 + [ssh-pkcs11-client.c] + Fix a memory leak in pkcs11_rsa_private_encrypt(), reported by Jan Klemkow. + While there, be sure to buffer_clear() between send_msg() and recv_msg(). + ok markus@ + - dtucker@cvs.openbsd.org 2012/01/18 21:46:43 + [clientloop.c] + Ensure that $DISPLAY contains only valid characters before using it to + extract xauth data so that it can't be used to play local shell + metacharacter games. Report from r00t_ati at ihteam.net, ok markus. + - markus@cvs.openbsd.org 2012/01/25 19:26:43 + [packet.c] + do not permit SSH2_MSG_SERVICE_REQUEST/ACCEPT during rekeying; + ok dtucker@, djm@ + - markus@cvs.openbsd.org 2012/01/25 19:36:31 + [authfile.c] + memleak in key_load_file(); from Jan Klemkow + - markus@cvs.openbsd.org 2012/01/25 19:40:09 + [packet.c packet.h] + packet_read_poll() is not used anymore. + - markus@cvs.openbsd.org 2012/02/09 20:00:18 + [version.h] + move from 6.0-beta to 6.0 + +20120206 + - (djm) [ssh-keygen.c] Don't fail in do_gen_all_hostkeys on platforms + that don't support ECC. Patch from Phil Oleson + +20111219 + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2011/12/02 00:41:56 + [mux.c] + fix bz#1948: ssh -f doesn't fork for multiplexed connection. + ok dtucker@ + - djm@cvs.openbsd.org 2011/12/02 00:43:57 + [mac.c] + fix bz#1934: newer OpenSSL versions will require HMAC_CTX_Init before + HMAC_init (this change in policy seems insane to me) + ok dtucker@ + - djm@cvs.openbsd.org 2011/12/04 23:16:12 + [mux.c] + revert: + > revision 1.32 + > date: 2011/12/02 00:41:56; author: djm; state: Exp; lines: +4 -1 + > fix bz#1948: ssh -f doesn't fork for multiplexed connection. + > ok dtucker@ + it interacts badly with ControlPersist + - djm@cvs.openbsd.org 2011/12/07 05:44:38 + [auth2.c dh.c packet.c roaming.h roaming_client.c roaming_common.c] + fix some harmless and/or unreachable int overflows; + reported Xi Wang, ok markus@ + +20111125 + - OpenBSD CVS Sync + - oga@cvs.openbsd.org 2011/11/16 12:24:28 + [sftp.c] + Don't leak list in complete_cmd_parse if there are no commands found. + Discovered when I was ``borrowing'' this code for something else. + ok djm@ + +20111121 + - (dtucker) [configure.ac] Set _FORTIFY_SOURCE. ok djm@ + +20111104 + - (dtucker) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2011/10/18 05:15:28 + [ssh.c] + ssh(1): skip attempting to create ~/.ssh when -F is passed; ok markus@ + - djm@cvs.openbsd.org 2011/10/18 23:37:42 + [ssh-add.c] + add -k to usage(); reminded by jmc@ + - djm@cvs.openbsd.org 2011/10/19 00:06:10 + [moduli.c] + s/tmpfile/tmp/ to make this -Wshadow clean + - djm@cvs.openbsd.org 2011/10/19 10:39:48 + [umac.c] + typo in comment; patch from Michael W. Bombardieri + - djm@cvs.openbsd.org 2011/10/24 02:10:46 + [ssh.c] + bz#1943: unbreak stdio forwarding when ControlPersist is in user - ssh + was incorrectly requesting the forward in both the control master and + slave. skip requesting it in the master to fix. ok markus@ + - djm@cvs.openbsd.org 2011/10/24 02:13:13 + [session.c] + bz#1859: send tty break to pty master instead of (probably already + closed) slave side; "looks good" markus@ + - dtucker@cvs.openbsd.org 011/11/04 00:09:39 + [moduli] + regenerated moduli file; ok deraadt + - (dtucker) [INSTALL LICENCE configure.ac openbsd-compat/Makefile.in + openbsd-compat/getrrsetbyname-ldns.c openbsd-compat/getrrsetbyname.c] + bz 1320: Add optional support for LDNS, a BSD licensed DNS resolver library + which supports DNSSEC. Patch from Simon Vallet (svallet at genoscope cns fr) + with some rework from myself and djm. ok djm. + +20111025 + - (dtucker) [contrib/cygwin/Makefile] Continue if installing a doc file + fails. Patch from Corinna Vinschen. + +20111018 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2011/10/04 14:17:32 + [sftp-glob.c] + silence error spam for "ls */foo" in directory with files; bz#1683 + - dtucker@cvs.openbsd.org 2011/10/16 11:02:46 + [moduli.c ssh-keygen.1 ssh-keygen.c] + Add optional checkpoints for moduli screening. feedback & ok deraadt + - jmc@cvs.openbsd.org 2011/10/16 15:02:41 + [ssh-keygen.c] + put -K in the right place (usage()); + - stsp@cvs.openbsd.org 2011/10/16 15:51:39 + [moduli.c] + add missing includes to unbreak tree; fix from rpointel + - djm@cvs.openbsd.org 2011/10/18 04:58:26 + [auth-options.c key.c] + remove explict search for \0 in packet strings, this job is now done + implicitly by buffer_get_cstring; ok markus + - djm@cvs.openbsd.org 2011/10/18 05:00:48 + [ssh-add.1 ssh-add.c] + new "ssh-add -k" option to load plain keys (skipping certificates); + "looks ok" markus@ + +20111001 + - (dtucker) [openbsd-compat/mktemp.c] Fix compiler warning. ok djm + - (dtucker) OpenBSD CVS Sync + - dtucker@cvs.openbsd.org 2011/09/23 00:22:04 + [channels.c auth-options.c servconf.c channels.h sshd.8] + Add wildcard support to PermitOpen, allowing things like "PermitOpen + localhost:*". bz #1857, ok djm markus. + - markus@cvs.openbsd.org 2011/09/23 07:45:05 + [mux.c readconf.h channels.h compat.h compat.c ssh.c readconf.c channels.c + version.h] + unbreak remote portforwarding with dynamic allocated listen ports: + 1) send the actual listen port in the open message (instead of 0). + this allows multiple forwardings with a dynamic listen port + 2) update the matching permit-open entry, so we can identify where + to connect to + report: den at skbkontur.ru and P. Szczygielski + feedback and ok djm@ + - djm@cvs.openbsd.org 2011/09/25 05:44:47 + [auth2-pubkey.c] + improve the AuthorizedPrincipalsFile debug log message to include + file and line number + - dtucker@cvs.openbsd.org 2011/09/30 00:47:37 + [sshd.c] + don't attempt privsep cleanup when not using privsep; ok markus@ + - djm@cvs.openbsd.org 2011/09/30 21:22:49 + [sshd.c] + fix inverted test that caused logspam; spotted by henning@ + +20110929 + - (djm) [configure.ac defines.h] No need to detect sizeof(char); patch + from des AT des.no + - (dtucker) [configure.ac openbsd-compat/Makefile.in + openbsd-compat/strnlen.c] Add strnlen to the compat library. + +20110923 + - (djm) [openbsd-compat/getcwd.c] Remove OpenBSD rcsid marker since we no + longer want to sync this file (OpenBSD uses a __getcwd syscall now, we + want this longhand version) + - (djm) [openbsd-compat/getgrouplist.c] Remove OpenBSD rcsid marker: the + upstream version is YPified and we don't want this + - (djm) [openbsd-compat/mktemp.c] forklift upgrade to -current version. + The file was totally rewritten between what we had in tree and -current. + - (djm) [openbsd-compat/sha2.c openbsd-compat/sha2.h] Remove OpenBSD rcsid + marker. The upstream API has changed (function and structure names) + enough to put it out of sync with other providers of this interface. + - (djm) [openbsd-compat/setenv.c] Forklift upgrade, including inclusion + of static __findenv() function from upstream setenv.c + - OpenBSD CVS Sync + - millert@cvs.openbsd.org 2006/05/05 15:27:38 + [openbsd-compat/strlcpy.c] + Convert do {} while loop -> while {} for clarity. No binary change + on most architectures. From Oliver Smith. OK deraadt@ and henning@ + - tobias@cvs.openbsd.org 2007/10/21 11:09:30 + [openbsd-compat/mktemp.c] + Comment fix about time consumption of _gettemp. + FreeBSD did this in revision 1.20. + OK deraadt@, krw@ + - deraadt@cvs.openbsd.org 2008/07/22 21:47:45 + [openbsd-compat/mktemp.c] + use arc4random_uniform(); ok djm millert + - millert@cvs.openbsd.org 2008/08/21 16:54:44 + [openbsd-compat/mktemp.c] + Remove useless code, the kernel will set errno appropriately if an + element in the path does not exist. OK deraadt@ pvalchev@ + - otto@cvs.openbsd.org 2008/12/09 19:38:38 + [openbsd-compat/inet_ntop.c] + fix inet_ntop(3) prototype; ok millert@ libc to be bumbed very soon + +20110922 + - OpenBSD CVS Sync + - pyr@cvs.openbsd.org 2011/05/12 07:15:10 + [openbsd-compat/glob.c] + When the max number of items for a directory has reached GLOB_LIMIT_READDIR + an error is returned but closedir() is not called. + spotted and fix provided by Frank Denis obsd-tech@pureftpd.org + ok otto@, millert@ + - stsp@cvs.openbsd.org 2011/09/20 10:18:46 + [glob.c] + In glob(3), limit recursion during matching attempts. Similar to + fnmatch fix. Also collapse consecutive '*' (from NetBSD). + ok miod deraadt + - djm@cvs.openbsd.org 2011/09/22 06:27:29 + [glob.c] + fix GLOB_KEEPSTAT without GLOB_NOSORT; the implicit sort was being + applied only to the gl_pathv vector and not the corresponding gl_statv + array. reported in OpenSSH bz#1935; feedback and okay matthew@ + - djm@cvs.openbsd.org 2011/08/26 01:45:15 + [ssh.1] + Add some missing ssh_config(5) options that can be used in ssh(1)'s + -o argument. Patch from duclare AT guu.fi + - djm@cvs.openbsd.org 2011/09/05 05:56:13 + [scp.1 sftp.1] + mention ControlPersist and KbdInteractiveAuthentication in the -o + verbiage in these pages too (prompted by jmc@) + - djm@cvs.openbsd.org 2011/09/05 05:59:08 + [misc.c] + fix typo in IPQoS parsing: there is no "AF14" class, but there is + an "AF21" class. Spotted by giesen AT snickers.org; ok markus stevesk + - jmc@cvs.openbsd.org 2011/09/05 07:01:44 + [scp.1] + knock out a useless Ns; + - deraadt@cvs.openbsd.org 2011/09/07 02:18:31 + [ssh-keygen.1] + typo (they vs the) found by Lawrence Teo + - djm@cvs.openbsd.org 2011/09/09 00:43:00 + [ssh_config.5 sshd_config.5] + fix typo in IPQoS parsing: there is no "AF14" class, but there is + an "AF21" class. Spotted by giesen AT snickers.org; ok markus stevesk + - djm@cvs.openbsd.org 2011/09/09 00:44:07 + [PROTOCOL.mux] + MUX_C_CLOSE_FWD includes forward type in message (though it isn't + implemented anyway) + - djm@cvs.openbsd.org 2011/09/09 22:37:01 + [scp.c] + suppress adding '--' to remote commandlines when the first argument + does not start with '-'. saves breakage on some difficult-to-upgrade + embedded/router platforms; feedback & ok dtucker ok markus + - djm@cvs.openbsd.org 2011/09/09 22:38:21 + [sshd.c] + kill the preauth privsep child on fatal errors in the monitor; + ok markus@ + - djm@cvs.openbsd.org 2011/09/09 22:46:44 + [channels.c channels.h clientloop.h mux.c ssh.c] + support for cancelling local and remote port forwards via the multiplex + socket. Use ssh -O cancel -L xx:xx:xx -R yy:yy:yy user@host" to request + the cancellation of the specified forwardings; ok markus@ + - markus@cvs.openbsd.org 2011/09/10 22:26:34 + [channels.c channels.h clientloop.c ssh.1] + support cancellation of local/dynamic forwardings from ~C commandline; + ok & feedback djm@ + - okan@cvs.openbsd.org 2011/09/11 06:59:05 + [ssh.1] + document new -O cancel command; ok djm@ + - markus@cvs.openbsd.org 2011/09/11 16:07:26 + [sftp-client.c] + fix leaks in do_hardlink() and do_readlink(); bz#1921 + from Loganaden Velvindron + - markus@cvs.openbsd.org 2011/09/12 08:46:15 + [sftp-client.c] + fix leak in do_lsreaddir(); ok djm + - djm@cvs.openbsd.org 2011/09/22 06:29:03 + [sftp.c] + don't let remote_glob() implicitly sort its results in do_globbed_ls() - + in all likelihood, they will be resorted anyway + +20110909 + - (dtucker) [entropy.h] Bug #1932: remove old definition of init_rng. From + Colin Watson. + +20110906 + - (djm) [README version.h] Correct version + - (djm) [contrib/redhat/openssh.spec] Correct restorcon => restorecon + - (djm) Respin OpenSSH-5.9p1 release + +20110905 + - (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec] + [contrib/suse/openssh.spec] Update version numbers. + +20110904 + - (djm) [regress/connect-privsep.sh regress/test-exec.sh] demote fatal + regress errors for the sandbox to warnings. ok tim dtucker + - (dtucker) [ssh-keygen.c ssh-pkcs11.c] Bug #1929: add null implementations + ofsh-pkcs11.cpkcs_init and pkcs_terminate for building without dlopen + support. + +20110829 + - (djm) [openbsd-compat/port-linux.c] Suppress logging when attempting + to switch SELinux context away from unconfined_t, based on patch from + Jan Chadima; bz#1919 ok dtucker@ + +20110827 + - (dtucker) [auth-skey.c] Add log.h to fix build --with-skey. + +20110818 + - (tim) [configure.ac] Typo in error message spotted by Andy Tsouladze + +20110817 + - (tim) [mac.c myproposal.h] Wrap SHA256 and SHA512 in ifdefs for + OpenSSL 0.9.7. ok djm + - (djm) [ openbsd-compat/bsd-cygwin_util.c openbsd-compat/bsd-cygwin_util.h] + binary_pipe is no longer required on Cygwin; patch from Corinna Vinschen + - (djm) [configure.ac] error out if the host lacks the necessary bits for + an explicitly requested sandbox type + - (djm) [contrib/ssh-copy-id] Missing backlslash; spotted by + bisson AT archlinux.org + - (djm) OpenBSD CVS Sync + - dtucker@cvs.openbsd.org 2011/06/03 05:35:10 + [regress/cfgmatch.sh] + use OBJ to find test configs, patch from Tim Rice + - markus@cvs.openbsd.org 2011/06/30 22:44:43 + [regress/connect-privsep.sh] + test with sandbox enabled; ok djm@ + - djm@cvs.openbsd.org 2011/08/02 01:23:41 + [regress/cipher-speed.sh regress/try-ciphers.sh] + add SHA256/SHA512 based HMAC modes + - (djm) [regress/cipher-speed.sh regress/try-ciphers.sh] disable HMAC-SHA2 + MAC tests for platforms that hack EVP_SHA2 support + +20110812 + - (dtucker) [openbsd-compat/port-linux.c] Bug 1924: Improve selinux context + change error by reporting old and new context names Patch from + jchadima at redhat. + - (djm) [contrib/redhat/openssh.spec contrib/redhat/sshd.init] + [contrib/suse/openssh.spec contrib/suse/rc.sshd] Updated RHEL and SLES + init scrips from imorgan AT nas.nasa.gov; bz#1920 + - (djm) [contrib/ssh-copy-id] Fix failure for cases where the path to the + identify file contained whitespace. bz#1828 patch from gwenael.lambrouin + AT gmail.com; ok dtucker@ + +20110807 + - (dtucker) OpenBSD CVS Sync + - jmc@cvs.openbsd.org 2008/06/26 06:59:39 + [moduli.5] + tweak previous; + - sobrado@cvs.openbsd.org 2009/10/28 08:56:54 + [moduli.5] + "Diffie-Hellman" is the usual spelling for the cryptographic protocol + first published by Whitfield Diffie and Martin Hellman in 1976. + ok jmc@ + - jmc@cvs.openbsd.org 2010/10/14 20:41:28 + [moduli.5] + probabalistic -> probabilistic; from naddy + - dtucker@cvs.openbsd.org 2011/08/07 12:55:30 + [sftp.1] + typo, fix from Laurent Gautrot + +20110805 + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2011/06/23 23:35:42 + [monitor.c] + ignore EINTR errors from poll() + - tedu@cvs.openbsd.org 2011/07/06 18:09:21 + [authfd.c] + bzero the agent address. the kernel was for a while very cranky about + these things. evne though that's fixed, always good to initialize + memory. ok deraadt djm + - djm@cvs.openbsd.org 2011/07/29 14:42:45 + [sandbox-systrace.c] + fail open(2) with EPERM rather than SIGKILLing the whole process. libc + will call open() to do strerror() when NLS is enabled; + feedback and ok markus@ + - markus@cvs.openbsd.org 2011/08/01 19:18:15 + [gss-serv.c] + prevent post-auth resource exhaustion (int overflow leading to 4GB malloc); + report Adam Zabrock; ok djm@, deraadt@ + - djm@cvs.openbsd.org 2011/08/02 01:22:11 + [mac.c myproposal.h ssh.1 ssh_config.5 sshd.8 sshd_config.5] + Add new SHA256 and SHA512 based HMAC modes from + http://www.ietf.org/id/draft-dbider-sha2-mac-for-ssh-02.txt + Patch from mdb AT juniper.net; feedback and ok markus@ + - djm@cvs.openbsd.org 2011/08/02 23:13:01 + [version.h] + crank now, release later + - djm@cvs.openbsd.org 2011/08/02 23:15:03 + [ssh.c] + typo in comment + +20110624 + - (djm) [configure.ac Makefile.in sandbox-darwin.c] Add a sandbox for + Darwin/OS X using sandbox_init() + setrlimit(); feedback and testing + markus@ + +20110623 + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2011/06/22 21:47:28 + [servconf.c] + reuse the multistate option arrays to pretty-print options for "sshd -T" + - djm@cvs.openbsd.org 2011/06/22 21:57:01 + [servconf.c servconf.h sshd.c sshd_config.5] + [configure.ac Makefile.in] + introduce sandboxing of the pre-auth privsep child using systrace(4). + + This introduces a new "UsePrivilegeSeparation=sandbox" option for + sshd_config that applies mandatory restrictions on the syscalls the + privsep child can perform. This prevents a compromised privsep child + from being used to attack other hosts (by opening sockets and proxying) + or probing local kernel attack surface. + + The sandbox is implemented using systrace(4) in unsupervised "fast-path" + mode, where a list of permitted syscalls is supplied. Any syscall not + on the list results in SIGKILL being sent to the privsep child. Note + that this requires a kernel with the new SYSTR_POLICY_KILL option. + + UsePrivilegeSeparation=sandbox will become the default in the future + so please start testing it now. + + feedback dtucker@; ok markus@ + - djm@cvs.openbsd.org 2011/06/22 22:08:42 + [channels.c channels.h clientloop.c clientloop.h mux.c ssh.c] + hook up a channel confirm callback to warn the user then requested X11 + forwarding was refused by the server; ok markus@ + - djm@cvs.openbsd.org 2011/06/23 09:34:13 + [sshd.c ssh-sandbox.h sandbox.h sandbox-rlimit.c sandbox-systrace.c] + [sandbox-null.c] + rename sandbox.h => ssh-sandbox.h to make things easier for portable + - (djm) [sandbox-null.c] Dummy sandbox for platforms that don't support + setrlimit(2) + +20110620 + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2011/06/04 00:10:26 + [ssh_config.5] + explain IdentifyFile's semantics a little better, prompted by bz#1898 + ok dtucker jmc + - markus@cvs.openbsd.org 2011/06/14 22:49:18 + [authfile.c] + make sure key_parse_public/private_rsa1() no longer consumes its input + buffer. fixes ssh-add for passphrase-protected ssh1-keys; + noted by naddy@; ok djm@ + - djm@cvs.openbsd.org 2011/06/17 21:44:31 + [log.c log.h monitor.c monitor.h monitor_wrap.c monitor_wrap.h sshd.c] + make the pre-auth privsep slave log via a socketpair shared with the + monitor rather than /var/empty/dev/log; ok dtucker@ deraadt@ markus@ + - djm@cvs.openbsd.org 2011/06/17 21:46:16 + [sftp-server.c] + the protocol version should be unsigned; bz#1913 reported by mb AT + smartftp.com + - djm@cvs.openbsd.org 2011/06/17 21:47:35 + [servconf.c] + factor out multi-choice option parsing into a parse_multistate label + and some support structures; ok dtucker@ + - djm@cvs.openbsd.org 2011/06/17 21:57:25 + [clientloop.c] + setproctitle for a mux master that has been gracefully stopped; + bz#1911 from Bert.Wesarg AT googlemail.com + +20110603 + - (dtucker) [README version.h contrib/caldera/openssh.spec + contrib/redhat/openssh.spec contrib/suse/openssh.spec] Pull the version + bumps from the 5.8p2 branch into HEAD. ok djm. + - (tim) [configure.ac defines.h] Run test program to detect system mail + directory. Add --with-maildir option to override. Fixed OpenServer 6 + getting it wrong. Fixed many systems having MAIL=/var/mail//username + ok dtucker + - (dtucker) [monitor.c] Remove the !HAVE_SOCKETPAIR case. We use socketpair + unconditionally in other places and the survey data we have does not show + any systems that use it. "nuke it" djm@ + - (djm) [configure.ac] enable setproctitle emulation for OS X + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2011/06/03 00:54:38 + [ssh.c] + bz#1883 - setproctitle() to identify mux master; patch from Bert.Wesarg + AT googlemail.com; ok dtucker@ + NB. includes additional portability code to enable setproctitle emulation + on platforms that don't support it. + - dtucker@cvs.openbsd.org 2011/06/03 01:37:40 + [ssh-agent.c] + Check current parent process ID against saved one to determine if the parent + has exited, rather than attempting to send a zero signal, since the latter + won't work if the parent has changed privs. bz#1905, patch from Daniel Kahn + Gillmor, ok djm@ + - dtucker@cvs.openbsd.org 2011/05/31 02:01:58 + [regress/dynamic-forward.sh] + back out revs 1.6 and 1.5 since it's not reliable + - dtucker@cvs.openbsd.org 2011/05/31 02:03:34 + [regress/dynamic-forward.sh] + work around startup and teardown races; caught by deraadt + - dtucker@cvs.openbsd.org 2011/06/03 00:29:52 + [regress/dynamic-forward.sh] + Retry establishing the port forwarding after a small delay, should make + the tests less flaky when the previous test is slow to shut down and free + up the port. + - (tim) [regress/cfgmatch.sh] Build/test out of tree fix. + +20110529 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2011/05/23 03:30:07 + [auth-rsa.c auth.c auth.h auth2-pubkey.c monitor.c monitor_wrap.c] + [pathnames.h servconf.c servconf.h sshd.8 sshd_config sshd_config.5] + allow AuthorizedKeysFile to specify multiple files, separated by spaces. + Bring back authorized_keys2 as a default search path (to avoid breaking + existing users of this file), but override this in sshd_config so it will + be no longer used on fresh installs. Maybe in 2015 we can remove it + entierly :) + + feedback and ok markus@ dtucker@ + - djm@cvs.openbsd.org 2011/05/23 03:33:38 + [auth.c] + make secure_filename() spam debug logs less + - djm@cvs.openbsd.org 2011/05/23 03:52:55 + [sshconnect.c] + remove extra newline + - jmc@cvs.openbsd.org 2011/05/23 07:10:21 + [sshd.8 sshd_config.5] + tweak previous; ok djm + - djm@cvs.openbsd.org 2011/05/23 07:24:57 + [authfile.c] + read in key comments for v.2 keys (though note that these are not + passed over the agent protocol); bz#439, based on patch from binder + AT arago.de; ok markus@ + - djm@cvs.openbsd.org 2011/05/24 07:15:47 + [readconf.c readconf.h ssh.c ssh_config.5 sshconnect.c sshconnect2.c] + Remove undocumented legacy options UserKnownHostsFile2 and + GlobalKnownHostsFile2 by making UserKnownHostsFile/GlobalKnownHostsFile + accept multiple paths per line and making their defaults include + known_hosts2; ok markus + - djm@cvs.openbsd.org 2011/05/23 03:31:31 + [regress/cfgmatch.sh] + include testing of multiple/overridden AuthorizedKeysFiles + refactor to simply daemon start/stop and get rid of racy constructs + +20110520 + - (djm) [session.c] call setexeccon() before executing passwd for pw + changes; bz#1891 reported by jchadima AT redhat.com; ok dtucker@ + - (djm) [aclocal.m4 configure.ac] since gcc-4.x ignores all -Wno-options + options, we should corresponding -W-option when trying to determine + whether it is accepted. Also includes a warning fix on the program + fragment uses (bad main() return type). + bz#1900 and bz#1901 reported by g.esp AT free.fr; ok dtucker@ + - (djm) [servconf.c] remove leftover droppings of AuthorizedKeysFile2 + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2011/05/15 08:09:01 + [authfd.c monitor.c serverloop.c] + use FD_CLOEXEC consistently; patch from zion AT x96.org + - djm@cvs.openbsd.org 2011/05/17 07:13:31 + [key.c] + fatal() if asked to generate a legacy ECDSA cert (these don't exist) + and fix the regress test that was trying to generate them :) + - djm@cvs.openbsd.org 2011/05/20 00:55:02 + [servconf.c] + the options TrustedUserCAKeys, RevokedKeysFile, AuthorizedKeysFile + and AuthorizedPrincipalsFile were not being correctly applied in + Match blocks, despite being overridable there; ok dtucker@ + - dtucker@cvs.openbsd.org 2011/05/20 02:00:19 + [servconf.c] + Add comment documenting what should be after the preauth check. ok djm + - djm@cvs.openbsd.org 2011/05/20 03:25:45 + [monitor.c monitor_wrap.c servconf.c servconf.h] + use a macro to define which string options to copy between configs + for Match. This avoids problems caused by forgetting to keep three + code locations in perfect sync and ordering + + "this is at once beautiful and horrible" + ok dtucker@ + - djm@cvs.openbsd.org 2011/05/17 07:13:31 + [regress/cert-userkey.sh] + fatal() if asked to generate a legacy ECDSA cert (these don't exist) + and fix the regress test that was trying to generate them :) + - djm@cvs.openbsd.org 2011/05/20 02:43:36 + [cert-hostkey.sh] + another attempt to generate a v00 ECDSA key that broke the test + ID sync only - portable already had this somehow + - dtucker@cvs.openbsd.org 2011/05/20 05:19:50 + [dynamic-forward.sh] + Prevent races in dynamic forwarding test; ok djm + - dtucker@cvs.openbsd.org 2011/05/20 06:32:30 + [dynamic-forward.sh] + fix dumb error in dynamic-forward test + +20110515 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2011/05/05 05:12:08 + [mux.c] + gracefully fall back when ControlPath is too large for a + sockaddr_un. ok markus@ as part of a larger diff + - dtucker@cvs.openbsd.org 2011/05/06 01:03:35 + [sshd_config] + clarify language about overriding defaults. bz#1892, from Petr Cerny + - djm@cvs.openbsd.org 2011/05/06 01:09:53 + [sftp.1] + mention that IPv6 addresses must be enclosed in square brackets; + bz#1845 + - djm@cvs.openbsd.org 2011/05/06 02:05:41 + [sshconnect2.c] + fix memory leak; bz#1849 ok dtucker@ + - djm@cvs.openbsd.org 2011/05/06 21:14:05 + [packet.c packet.h] + set traffic class for IPv6 traffic as we do for IPv4 TOS; + patch from lionel AT mamane.lu via Colin Watson in bz#1855; + ok markus@ + - djm@cvs.openbsd.org 2011/05/06 21:18:02 + [ssh.c ssh_config.5] + add a %L expansion (short-form of the local host name) for ControlPath; + sync some more expansions with LocalCommand; ok markus@ + - djm@cvs.openbsd.org 2011/05/06 21:31:38 + [readconf.c ssh_config.5] + support negated Host matching, e.g. + + Host *.example.org !c.example.org + User mekmitasdigoat + + Will match "a.example.org", "b.example.org", but not "c.example.org" + ok markus@ + - djm@cvs.openbsd.org 2011/05/06 21:34:32 + [clientloop.c mux.c readconf.c readconf.h ssh.c ssh_config.5] + Add a RequestTTY ssh_config option to allow configuration-based + control over tty allocation (like -t/-T); ok markus@ + - djm@cvs.openbsd.org 2011/05/06 21:38:58 + [ssh.c] + fix dropping from previous diff + - djm@cvs.openbsd.org 2011/05/06 22:20:10 + [PROTOCOL.mux] + fix numbering; from bert.wesarg AT googlemail.com + - jmc@cvs.openbsd.org 2011/05/07 23:19:39 + [ssh_config.5] + - tweak previous + - come consistency fixes + ok djm + - jmc@cvs.openbsd.org 2011/05/07 23:20:25 + [ssh.1] + +.It RequestTTY + - djm@cvs.openbsd.org 2011/05/08 12:52:01 + [PROTOCOL.mux clientloop.c clientloop.h mux.c] + improve our behaviour when TTY allocation fails: if we are in + RequestTTY=auto mode (the default), then do not treat at TTY + allocation error as fatal but rather just restore the local TTY + to cooked mode and continue. This is more graceful on devices that + never allocate TTYs. + + If RequestTTY is set to "yes" or "force", then failure to allocate + a TTY is fatal. + + ok markus@ + - djm@cvs.openbsd.org 2011/05/10 05:46:46 + [authfile.c] + despam debug() logs by detecting that we are trying to load a private key + in key_try_load_public() and returning early; ok markus@ + - djm@cvs.openbsd.org 2011/05/11 04:47:06 + [auth.c auth.h auth2-pubkey.c pathnames.h servconf.c servconf.h] + remove support for authorized_keys2; it is a relic from the early days + of protocol v.2 support and has been undocumented for many years; + ok markus@ + - djm@cvs.openbsd.org 2011/05/13 00:05:36 + [authfile.c] + warn on unexpected key type in key_parse_private_type() + - (djm) [packet.c] unbreak portability #endif + +20110510 + - (dtucker) [openbsd-compat/openssl-compat.{c,h}] Bug #1882: fix + --with-ssl-engine which was broken with the change from deprecated + SSLeay_add_all_algorithms(). ok djm + +20110506 + - (dtucker) [openbsd-compat/regress/closefromtest.c] Bug #1875: add prototype + for closefrom() in test code. Report from Dan Wallis via Gentoo. + +20110505 + - (djm) [defines.h] Move up include of netinet/ip.h for IPTOS + definitions. From des AT des.no + - (djm) [Makefile.in WARNING.RNG aclocal.m4 buildpkg.sh.in configure.ac] + [entropy.c ssh-add.c ssh-agent.c ssh-keygen.c ssh-keyscan.c] + [ssh-keysign.c ssh-pkcs11-helper.c ssh-rand-helper.8 ssh-rand-helper.c] + [ssh.c ssh_prng_cmds.in sshd.c contrib/aix/buildbff.sh] + [regress/README.regress] Remove ssh-rand-helper and all its + tentacles. PRNGd seeding has been rolled into entropy.c directly. + Thanks to tim@ for testing on affected platforms. + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2011/03/10 02:52:57 + [auth2-gss.c auth2.c auth.h] + allow GSSAPI authentication to detect when a server-side failure causes + authentication failure and don't count such failures against MaxAuthTries; + bz#1244 from simon AT sxw.org.uk; ok markus@ before lock + - okan@cvs.openbsd.org 2011/03/15 10:36:02 + [ssh-keyscan.c] + use timerclear macro + ok djm@ + - stevesk@cvs.openbsd.org 2011/03/23 15:16:22 + [ssh-keygen.1 ssh-keygen.c] + Add -A option. For each of the key types (rsa1, rsa, dsa and ecdsa) + 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 will be used by /etc/rc to generate + new host keys. Idea from deraadt. + ok deraadt + - stevesk@cvs.openbsd.org 2011/03/23 16:24:56 + [ssh-keygen.1] + -q not used in /etc/rc now so remove statement. + - stevesk@cvs.openbsd.org 2011/03/23 16:50:04 + [ssh-keygen.c] + remove -d, documentation removed >10 years ago; ok markus + - jmc@cvs.openbsd.org 2011/03/24 15:29:30 + [ssh-keygen.1] + zap trailing whitespace; + - stevesk@cvs.openbsd.org 2011/03/24 22:14:54 + [ssh-keygen.c] + use strcasecmp() for "clear" cert permission option also; ok djm + - stevesk@cvs.openbsd.org 2011/03/29 18:54:17 + [misc.c misc.h servconf.c] + print ipqos friendly string for sshd -T; ok markus + # sshd -Tf sshd_config|grep ipqos + ipqos lowdelay throughput + - djm@cvs.openbsd.org 2011/04/12 04:23:50 + [ssh-keygen.c] + fix -Wshadow + - djm@cvs.openbsd.org 2011/04/12 05:32:49 + [sshd.c] + exit with 0 status on SIGTERM; bz#1879 + - djm@cvs.openbsd.org 2011/04/13 04:02:48 + [ssh-keygen.1] + improve wording; bz#1861 + - djm@cvs.openbsd.org 2011/04/13 04:09:37 + [ssh-keygen.1] + mention valid -b sizes for ECDSA keys; bz#1862 + - djm@cvs.openbsd.org 2011/04/17 22:42:42 + [PROTOCOL.mux clientloop.c clientloop.h mux.c ssh.1 ssh.c] + allow graceful shutdown of multiplexing: request that a mux server + removes its listener socket and refuse future multiplexing requests; + ok markus@ + - djm@cvs.openbsd.org 2011/04/18 00:46:05 + [ssh-keygen.c] + certificate options are supposed to be packed in lexical order of + option name (though we don't actually enforce this at present). + Move one up that was out of sequence + - djm@cvs.openbsd.org 2011/05/04 21:15:29 + [authfile.c authfile.h ssh-add.c] + allow "ssh-add - < key"; feedback and ok markus@ + - (tim) [configure.ac] Add AC_LANG_SOURCE to OPENSSH_CHECK_CFLAG_COMPILE + so autoreconf 2.68 is happy. + - (tim) [defines.h] Deal with platforms that do not have S_IFSOCK ok djm@ + +20110221 + - (dtucker) [contrib/cygwin/ssh-host-config] From Corinna: revamp of the + Cygwin-specific service installer script ssh-host-config. The actual + functionality is the same, the revisited version is just more + exact when it comes to check for problems which disallow to run + certain aspects of the script. So, part of this script and the also + rearranged service helper script library "csih" is to check if all + the tools required to run the script are available on the system. + The new script also is more thorough to inform the user why the + script failed. Patch from vinschen at redhat com. + +20110218 + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2011/02/16 00:31:14 + [ssh-keysign.c] + make hostbased auth with ECDSA keys work correctly. Based on patch + by harvey.eneman AT oracle.com in bz#1858; ok markus@ (pre-lock) + +20110206 + - (dtucker) [openbsd-compat/port-linux.c] Bug #1851: fix syntax error in + selinux code. Patch from Leonardo Chiquitto + - (dtucker) [contrib/cygwin/ssh-{host,user}-config] Add ECDSA key + generation and simplify. Patch from Corinna Vinschen. + +20110204 + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2011/01/31 21:42:15 + [PROTOCOL.mux] + cut'n'pasto; from bert.wesarg AT googlemail.com + - djm@cvs.openbsd.org 2011/02/04 00:44:21 + [key.c] + fix uninitialised nonce variable; reported by Mateusz Kocielski + - djm@cvs.openbsd.org 2011/02/04 00:44:43 + [version.h] + openssh-5.8 + - (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec] + [contrib/suse/openssh.spec] update versions in docs and spec files. + - Release OpenSSH 5.8p1 + +20110128 + - (djm) [openbsd-compat/port-linux.c] Check whether SELinux is enabled + before attempting setfscreatecon(). Check whether matchpathcon() + succeeded before using its result. Patch from cjwatson AT debian.org; + bz#1851 + +20110127 + - (tim) [config.guess config.sub] Sync with upstream. + - (tim) [configure.ac] Consistent M4 quoting throughout, updated obsolete + AC_TRY_COMPILE with AC_COMPILE_IFELSE, updated obsolete AC_TRY_LINK with + AC_LINK_IFELSE, updated obsolete AC_TRY_RUN with AC_RUN_IFELSE, misc white + space changes for consistency/readability. Makes autoconf 2.68 happy. + "Nice work" djm + +20110125 + - (djm) [configure.ac Makefile.in ssh.c openbsd-compat/port-linux.c + openbsd-compat/port-linux.h] Move SELinux-specific code from ssh.c to + port-linux.c to avoid compilation errors. Add -lselinux to ssh when + building with SELinux support to avoid linking failure; report from + amk AT spamfence.net; ok dtucker + +20110122 + - (dtucker) [configure.ac openbsd-compat/openssl-compat.{c,h}] Add + RSA_get_default_method() for the benefit of openssl versions that don't + have it (at least openssl-engine-0.9.6b). Found and tested by Kevin Brott, + ok djm@. + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2011/01/22 09:18:53 + [version.h] + crank to OpenSSH-5.7 + - (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec] + [contrib/suse/openssh.spec] update versions in docs and spec files. + - (djm) Release 5.7p1 + +20110119 + - (tim) [contrib/caldera/openssh.spec] Use CFLAGS from Makefile instead + of RPM so build completes. Signatures were changed to .asc since 4.1p1. + - (djm) [configure.ac] Disable ECC on OpenSSL <0.9.8g. Releases prior to + 0.9.8 lacked it, and 0.9.8a through 0.9.8d have proven buggy in pre- + release testing (random crashes and failure to load ECC keys). + ok dtucker@ + +20110117 + - (djm) [regress/Makefile] use $TEST_SSH_KEYGEN instead of the one in + $PATH, fix cleanup of droppings; reported by openssh AT + roumenpetrov.info; ok dtucker@ + - (djm) [regress/agent-ptrace.sh] Fix false failure on OS X by adding + its unique snowflake of a gdb error to the ones we look for. + - (djm) [regress/agent-getpeereid.sh] leave stdout attached when running + ssh-add to avoid $SUDO failures on Linux + - (dtucker) [openbsd-compat/port-linux.c] Bug #1838: Add support for the new + Linux OOM-killer magic values that changed in 2.6.36 kernels, with fallback + to the old values. Feedback from vapier at gentoo org and djm, ok djm. + - (djm) [configure.ac regress/agent-getpeereid.sh regress/multiplex.sh] + [regress/sftp-glob.sh regress/test-exec.sh] Rework how feature tests are + disabled on platforms that do not support them; add a "config_defined()" + shell function that greps for defines in config.h and use them to decide + on feature tests. + Convert a couple of existing grep's over config.h to use the new function + Add a define "FILESYSTEM_NO_BACKSLASH" for filesystem that can't represent + backslash characters in filenames, enable it for Cygwin and use it to turn + of tests for quotes backslashes in sftp-glob.sh. + based on discussion with vinschen AT redhat.com and dtucker@; ok dtucker@ + - (tim) [regress/agent-getpeereid.sh] shell portability fix. + - (dtucker) [openbsd-compat/port-linux.c] Fix minor bug caught by -Werror on + the tinderbox. + - (dtucker) [LICENCE Makefile.in audit-bsm.c audit-linux.c audit.c audit.h + configure.ac defines.h loginrec.c] Bug #1402: add linux audit subsystem + support, based on patches from Tomas Mraz and jchadima at redhat. + +20110116 + - (dtucker) [Makefile.in configure.ac regress/kextype.sh] Skip sha256-based + on configurations that don't have it. + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2011/01/16 11:50:05 + [clientloop.c] + Use atomicio when flushing protocol 1 std{out,err} buffers at + session close. This was a latent bug exposed by setting a SIGCHLD + handler and spotted by kevin.brott AT gmail.com; ok dtucker@ + - djm@cvs.openbsd.org 2011/01/16 11:50:36 + [sshconnect.c] + reset the SIGPIPE handler when forking to execute child processes; + ok dtucker@ + - djm@cvs.openbsd.org 2011/01/16 12:05:59 + [clientloop.c] + a couple more tweaks to the post-close protocol 1 stderr/stdout flush: + now that we use atomicio(), convert them from while loops to if statements + add test and cast to compile cleanly with -Wsigned + +20110114 + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2011/01/13 21:54:53 + [mux.c] + correct error messages; patch from bert.wesarg AT googlemail.com + - djm@cvs.openbsd.org 2011/01/13 21:55:25 + [PROTOCOL.mux] + correct protocol names and add a couple of missing protocol number + defines; patch from bert.wesarg AT googlemail.com + - (djm) [Makefile.in] Use shell test to disable ecdsa key generating in + host-key-force target rather than a substitution that is replaced with a + comment so that the Makefile.in is still a syntactically valid Makefile + (useful to run the distprep target) + - (tim) [regress/cert-hostkey.sh] Typo. Missing $ on variable name. + - (tim) [regress/cert-hostkey.sh] Add missing TEST_SSH_ECC guard around some + ecdsa bits. + +20110113 + - (djm) [misc.c] include time.h for nanosleep() prototype + - (tim) [Makefile.in] test the ECC bits if we have the capability. ok djm + - (tim) [Makefile.in configure.ac opensshd.init.in] Add support for generating + ecdsa keys. ok djm. + - (djm) [entropy.c] cast OPENSSL_VERSION_NUMBER to u_long to avoid + gcc warning on platforms where it defaults to int + - (djm) [regress/Makefile] add a few more generated files to the clean + target + - (djm) [myproposal.h] Fix reversed OPENSSL_VERSION_NUMBER test and bad + #define that was causing diffie-hellman-group-exchange-sha256 to be + incorrectly disabled + - (djm) [regress/kextype.sh] Testing diffie-hellman-group-exchange-sha256 + should not depend on ECC support + +20110112 + - OpenBSD CVS Sync + - nicm@cvs.openbsd.org 2010/10/08 21:48:42 + [openbsd-compat/glob.c] + Extend GLOB_LIMIT to cover readdir and stat and bump the malloc limit + from ARG_MAX to 64K. + Fixes glob-using programs (notably ftp) able to be triggered to hit + resource limits. + Idea from a similar NetBSD change, original problem reported by jasper@. + ok millert tedu jasper + - djm@cvs.openbsd.org 2011/01/12 01:53:14 + avoid some integer overflows mostly with GLOB_APPEND and GLOB_DOOFFS + and sanity check arguments (these will be unnecessary when we switch + struct glob members from being type into to size_t in the future); + "looks ok" tedu@ feedback guenther@ + - (djm) [configure.ac] Turn on -Wno-unused-result for gcc >= 4.4 to avoid + silly warnings on write() calls we don't care succeed or not. + - (djm) [configure.ac] Fix broken test for gcc >= 4.4 with per-compiler + flag tests that don't depend on gcc version at all; suggested by and + ok dtucker@ + +20110111 + - (tim) [regress/host-expand.sh] Fix for building outside of read only + source tree. + - (djm) [platform.c] Some missing includes that show up under -Werror + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2011/01/08 10:51:51 + [clientloop.c] + use host and not options.hostname, as the latter may have unescaped + substitution characters + - djm@cvs.openbsd.org 2011/01/11 06:06:09 + [sshlogin.c] + fd leak on error paths; from zinovik@ + NB. Id sync only; we use loginrec.c that was also audited and fixed + recently + - djm@cvs.openbsd.org 2011/01/11 06:13:10 + [clientloop.c ssh-keygen.c sshd.c] + some unsigned long long casts that make things a bit easier for + portable without resorting to dropping PRIu64 formats everywhere + +20110109 + - (djm) [Makefile.in] list ssh_host_ecdsa key in PATHSUBS; spotted by + openssh AT roumenpetrov.info + +20110108 + - (djm) [regress/keytype.sh] s/echo -n/echon/ to repair failing regress + test on OSX and others. Reported by imorgan AT nas.nasa.gov + +20110107 + - (djm) [regress/cert-hostkey.sh regress/cert-userkey.sh] fix shell test + for no-ECC case. Patch from cristian.ionescu-idbohrn AT axis.com + - djm@cvs.openbsd.org 2011/01/06 22:23:53 + [ssh.c] + unbreak %n expansion in LocalCommand; patch from bert.wesarg AT + googlemail.com; ok markus@ + - djm@cvs.openbsd.org 2011/01/06 22:23:02 + [clientloop.c] + when exiting due to ServerAliveTimeout, mention the hostname that caused + it (useful with backgrounded controlmaster) + - djm@cvs.openbsd.org 2011/01/06 22:46:21 + [regress/Makefile regress/host-expand.sh] + regress test for LocalCommand %n expansion from bert.wesarg AT + googlemail.com; ok markus@ + - djm@cvs.openbsd.org 2011/01/06 23:01:35 + [sshconnect.c] + reset SIGCHLD handler to SIG_DFL when execuring LocalCommand; + ok markus@ + +20110106 + - (djm) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2010/12/08 22:46:03 + [scp.1 scp.c] + add a new -3 option to scp: Copies between two remote hosts are + transferred through the local host. Without this option the data + is copied directly between the two remote hosts. ok djm@ (bugzilla #1837) + - jmc@cvs.openbsd.org 2010/12/09 14:13:33 + [scp.1 scp.c] + scp.1: grammer fix + scp.c: add -3 to usage() + - markus@cvs.openbsd.org 2010/12/14 11:59:06 + [sshconnect.c] + don't mention key type in key-changed-warning, since we also print + this warning if a new key type appears. ok djm@ + - djm@cvs.openbsd.org 2010/12/15 00:49:27 + [readpass.c] + fix ControlMaster=ask regression + reset SIGCHLD handler before fork (and restore it after) so we don't miss + the the askpass child's exit status. Correct test for exit status/signal to + account for waitpid() failure; with claudio@ ok claudio@ markus@ + - djm@cvs.openbsd.org 2010/12/24 21:41:48 + [auth-options.c] + don't send the actual forced command in a debug message; ok markus deraadt + - otto@cvs.openbsd.org 2011/01/04 20:44:13 + [ssh-keyscan.c] + handle ecdsa-sha2 with various key lengths; hint and ok djm@ + +20110104 + - (djm) [configure.ac Makefile.in] Use mandoc as preferred manpage + formatter if it is present, followed by nroff and groff respectively. + Fixes distprep target on OpenBSD (which has bumped groff/nroff to ports + in favour of mandoc). feedback and ok tim + +20110103 + - (djm) [Makefile.in] revert local hack I didn't intend to commit + +20110102 + - (djm) [loginrec.c] Fix some fd leaks on error paths. ok dtucker + - (djm) [configure.ac] Check whether libdes is needed when building + with Heimdal krb5 support. On OpenBSD this library no longer exists, + so linking it unconditionally causes a build failure; ok dtucker + +20101226 + - (dtucker) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2010/12/08 04:02:47 + [ssh_config.5 sshd_config.5] + explain that IPQoS arguments are separated by whitespace; iirc requested + by jmc@ a while back + +20101205 + - (dtucker) openbsd-compat/openssl-compat.c] remove sleep leftover from + debugging. Spotted by djm. + - (dtucker) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2010/12/03 23:49:26 + [schnorr.c] + check that g^x^q === 1 mod p; recommended by JPAKE author Feng Hao + (this code is still disabled, but apprently people are treating it as + a reference implementation) + - djm@cvs.openbsd.org 2010/12/03 23:55:27 + [auth-rsa.c] + move check for revoked keys to run earlier (in auth_rsa_key_allowed) + bz#1829; patch from ldv AT altlinux.org; ok markus@ + - djm@cvs.openbsd.org 2010/12/04 00:18:01 + [sftp-server.c sftp.1 sftp-client.h sftp.c PROTOCOL sftp-client.c] + add a protocol extension to support a hard link operation. It is + available through the "ln" command in the client. The old "ln" + behaviour of creating a symlink is available using its "-s" option + or through the preexisting "symlink" command; based on a patch from + miklos AT szeredi.hu in bz#1555; ok markus@ + - djm@cvs.openbsd.org 2010/12/04 13:31:37 + [hostfile.c] + fix fd leak; spotted and ok dtucker + - djm@cvs.openbsd.org 2010/12/04 00:21:19 + [regress/sftp-cmds.sh] + adjust for hard-link support + - (dtucker) [regress/Makefile] Id sync. + +20101204 + - (djm) [openbsd-compat/bindresvport.c] Use arc4random_uniform(range) + instead of (arc4random() % range) + - (dtucker) [configure.ac moduli.c openbsd-compat/openssl-compat.{c,h}] Add + shims for the new, non-deprecated OpenSSL key generation functions for + platforms that don't have the new interfaces. + +20101201 + - OpenBSD CVS Sync + - deraadt@cvs.openbsd.org 2010/11/20 05:12:38 + [auth2-pubkey.c] + clean up cases of ;; + - djm@cvs.openbsd.org 2010/11/21 01:01:13 + [clientloop.c misc.c misc.h ssh-agent.1 ssh-agent.c] + honour $TMPDIR for client xauth and ssh-agent temporary directories; + feedback and ok markus@ + - djm@cvs.openbsd.org 2010/11/21 10:57:07 + [authfile.c] + Refactor internals of private key loading and saving to work on memory + buffers rather than directly on files. This will make a few things + easier to do in the future; ok markus@ + - djm@cvs.openbsd.org 2010/11/23 02:35:50 + [auth.c] + use strict_modes already passed as function argument over referencing + global options.strict_modes + - djm@cvs.openbsd.org 2010/11/23 23:57:24 + [clientloop.c] + avoid NULL deref on receiving a channel request on an unknown or invalid + channel; report bz#1842 from jchadima AT redhat.com; ok dtucker@ + - djm@cvs.openbsd.org 2010/11/24 01:24:14 + [channels.c] + remove a debug() that pollutes stderr on client connecting to a server + in debug mode (channel_close_fds is called transitively from the session + code post-fork); bz#1719, ok dtucker + - djm@cvs.openbsd.org 2010/11/25 04:10:09 + [session.c] + replace close() loop for fds 3->64 with closefrom(); + ok markus deraadt dtucker + - djm@cvs.openbsd.org 2010/11/26 05:52:49 + [scp.c] + Pass through ssh command-line flags and options when doing remote-remote + transfers, e.g. to enable agent forwarding which is particularly useful + in this case; bz#1837 ok dtucker@ + - markus@cvs.openbsd.org 2010/11/29 18:57:04 + [authfile.c] + correctly load comment for encrypted rsa1 keys; + report/fix Joachim Schipper; ok djm@ + - djm@cvs.openbsd.org 2010/11/29 23:45:51 + [auth.c hostfile.c hostfile.h ssh.c ssh_config.5 sshconnect.c] + [sshconnect.h sshconnect2.c] + automatically order the hostkeys requested by the client based on + which hostkeys are already recorded in known_hosts. This avoids + hostkey warnings when connecting to servers with new ECDSA keys + that are preferred by default; with markus@ + +20101124 + - (dtucker) [platform.c session.c] Move the getluid call out of session.c and + into the platform-specific code Only affects SCO, tested by and ok tim@. + - (djm) [loginrec.c] Relax permission requirement on btmp logs to allow + group read/write. ok dtucker@ + - (dtucker) [packet.c] Remove redundant local declaration of "int tos". + - (djm) [defines.h] Add IP DSCP defines + +20101122 + - (dtucker) Bug #1840: fix warning when configuring --with-ssl-engine, patch + from vapier at gentoo org. + +20101120 + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2010/11/05 02:46:47 + [packet.c] + whitespace KNF + - djm@cvs.openbsd.org 2010/11/10 01:33:07 + [kexdhc.c kexdhs.c kexgexc.c kexgexs.c key.c moduli.c] + use only libcrypto APIs that are retained with OPENSSL_NO_DEPRECATED. + these have been around for years by this time. ok markus + - djm@cvs.openbsd.org 2010/11/13 23:27:51 + [clientloop.c misc.c misc.h packet.c packet.h readconf.c readconf.h] + [servconf.c servconf.h session.c ssh.c ssh_config.5 sshd_config.5] + allow ssh and sshd to set arbitrary TOS/DSCP/QoS values instead of + hardcoding lowdelay/throughput. + + bz#1733 patch from philipp AT redfish-solutions.com; ok markus@ deraadt@ + - jmc@cvs.openbsd.org 2010/11/15 07:40:14 + [ssh_config.5] + libary -> library; + - jmc@cvs.openbsd.org 2010/11/18 15:01:00 + [scp.1 sftp.1 ssh.1 sshd_config.5] + add IPQoS to the various -o lists, and zap some trailing whitespace; + +20101111 + - (djm) [servconf.c ssh-add.c ssh-keygen.c] don't look for ECDSA keys on + platforms that don't support ECC. Fixes some spurious warnings reported + by tim@ + +20101109 + - (tim) [regress/kextype.sh] Not all platforms have time in /usr/bin. + Feedback from dtucker@ + - (tim) [configure.ac openbsd-compat/bsd-misc.h openbsd-compat/bsd-misc.c] Add + support for platforms missing isblank(). ok djm@ + +20101108 + - (tim) [regress/Makefile] Fixes to allow building/testing outside source + tree. + - (tim) [regress/kextype.sh] Shell portability fix. + +20101107 + - (dtucker) [platform.c] includes.h instead of defines.h so that we get + the correct typedefs. + +20101105 + - (djm) [loginrec.c loginrec.h] Use correct uid_t/pid_t types instead of + int. Should fix bz#1817 cleanly; ok dtucker@ + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2010/09/22 12:26:05 + [regress/Makefile regress/kextype.sh] + regress test for each of the key exchange algorithms that we support + - djm@cvs.openbsd.org 2010/10/28 11:22:09 + [authfile.c key.c key.h ssh-keygen.c] + fix a possible NULL deref on loading a corrupt ECDH key + + store ECDH group information in private keys files as "named groups" + rather than as a set of explicit group parameters (by setting + the OPENSSL_EC_NAMED_CURVE flag). This makes for shorter key files and + retrieves the group's OpenSSL NID that we need for various things. + - jmc@cvs.openbsd.org 2010/10/28 18:33:28 + [scp.1 ssh-add.1 ssh-keygen.1 ssh.1 ssh_config.5 sshd.8 sshd_config.5] + knock out some "-*- nroff -*-" lines; + - djm@cvs.openbsd.org 2010/11/04 02:45:34 + [sftp-server.c] + umask should be parsed as octal. reported by candland AT xmission.com; + ok markus@ + - (dtucker) [configure.ac platform.{c,h} session.c + openbsd-compat/port-solaris.{c,h}] Bug #1824: Add Solaris Project support. + Patch from cory.erickson at csu mnscu edu with a bit of rework from me. + ok djm@ + - (dtucker) [platform.c platform.h session.c] Add a platform hook to run + after the user's groups are established and move the selinux calls into it. + - (dtucker) [platform.c session.c] Move the AIX setpcred+chroot hack into + platform.c + - (dtucker) [platform.c session.c] Move the BSDI setpgrp into platform.c. + - (dtucker) [platform.c] Only call setpgrp on BSDI if running as root to + retain previous behavior. + - (dtucker) [platform.c session.c] Move the PAM credential establishment for + the LOGIN_CAP case into platform.c. + - (dtucker) platform.c session.c] Move the USE_LIBIAF fragment into + platform.c + - (dtucker) [platform.c session.c] Move aix_usrinfo frament into platform.c. + - (dtucker) [platform.c session.c] Move irix setusercontext fragment into + platform.c. + - (dtucker) [platform.c session.c] Move PAM credential establishment for the + non-LOGIN_CAP case into platform.c. + - (dtucker) [platform.c platform.h session.c] Move the Cygwin special-case + check into platform.c + - (dtucker) [regress/keytype.sh] Import new test. + - (dtucker) [Makefile configure.ac regress/Makefile regress/keytype.sh] + Import recent changes to regress/Makefile, pass a flag to enable ECC tests + from configure through to regress/Makefile and use it in the tests. + - (dtucker) [regress/kextype.sh] Add missing "test". + - (dtucker) [regress/kextype.sh] Make sha256 test depend on ECC. This is not + strictly correct since while ECC requires sha256 the reverse is not true + however it does prevent spurious test failures. + - (dtucker) [platform.c] Need servconf.h and extern options. + +20101025 + - (tim) [openbsd-compat/glob.h] Remove sys/cdefs.h include that came with + 1.12 to unbreak Solaris build. + ok djm@ + - (dtucker) [defines.h] Use SIZE_T_MAX for SIZE_MAX for platforms that have a + native one. + +20101024 + - (dtucker) [includes.h] Add missing ifdef GLOB_HAS_GL_STATV to fix build. + - (dtucker) [regress/cert-hostkey.sh] Disable ECC-based tests on platforms + which don't have ECC support in libcrypto. + - (dtucker) [regress/cert-userkey.sh] Disable ECC-based tests on platforms + which don't have ECC support in libcrypto. + - (dtucker) [defines.h] Add SIZE_MAX for the benefit of platforms that don't + have it. + - (dtucker) OpenBSD CVS Sync + - sthen@cvs.openbsd.org 2010/10/23 22:06:12 + [sftp.c] + escape '[' in filename tab-completion; fix a type while there. + ok djm@ + +20101021 + - OpenBSD CVS Sync + - dtucker@cvs.openbsd.org 2010/10/12 02:22:24 + [mux.c] + Typo in confirmation message. bz#1827, patch from imorgan at + nas nasa gov + - djm@cvs.openbsd.org 2010/08/31 12:24:09 + [regress/cert-hostkey.sh regress/cert-userkey.sh] + tests for ECDSA certificates + +20101011 + - (djm) [canohost.c] Zero a4 instead of addr to better match type. + bz#1825, reported by foo AT mailinator.com + - (djm) [sshconnect.c] Need signal.h for prototype for kill(2) + +20101011 + - (djm) [configure.ac] Use = instead of == in shell tests. Patch from + dr AT vasco.com + +20101007 + - (djm) [ssh-agent.c] Fix type for curve name. + - (djm) OpenBSD CVS Sync + - matthew@cvs.openbsd.org 2010/09/24 13:33:00 + [misc.c misc.h configure.ac openbsd-compat/openbsd-compat.h] + [openbsd-compat/timingsafe_bcmp.c] + Add timingsafe_bcmp(3) to libc, mention that it's already in the + kernel in kern(9), and remove it from OpenSSH. + ok deraadt@, djm@ + NB. re-added under openbsd-compat/ for portable OpenSSH + - djm@cvs.openbsd.org 2010/09/25 09:30:16 + [sftp.c configure.ac openbsd-compat/glob.c openbsd-compat/glob.h] + make use of new glob(3) GLOB_KEEPSTAT extension to save extra server + rountrips to fetch per-file stat(2) information. + NB. update openbsd-compat/ glob(3) implementation from OpenBSD libc to + match. + - djm@cvs.openbsd.org 2010/09/26 22:26:33 + [sftp.c] + when performing an "ls" in columnated (short) mode, only call + ioctl(TIOCGWINSZ) once to get the window width instead of per- + filename + - djm@cvs.openbsd.org 2010/09/30 11:04:51 + [servconf.c] + prevent free() of string in .rodata when overriding AuthorizedKeys in + a Match block; patch from rein AT basefarm.no + - djm@cvs.openbsd.org 2010/10/01 23:05:32 + [cipher-3des1.c cipher-bf1.c cipher-ctr.c openbsd-compat/openssl-compat.h] + adapt to API changes in openssl-1.0.0a + NB. contains compat code to select correct API for older OpenSSL + - djm@cvs.openbsd.org 2010/10/05 05:13:18 + [sftp.c sshconnect.c] + use default shell /bin/sh if $SHELL is ""; ok markus@ + - djm@cvs.openbsd.org 2010/10/06 06:39:28 + [clientloop.c ssh.c sshconnect.c sshconnect.h] + kill proxy command on fatal() (we already kill it on clean exit); + ok markus@ + - djm@cvs.openbsd.org 2010/10/06 21:10:21 + [sshconnect.c] + swapped args to kill(2) + - (djm) [openbsd-compat/glob.c] restore ARG_MAX compat code. + - (djm) [cipher-acss.c] Add missing header. + - (djm) [openbsd-compat/Makefile.in] Actually link timingsafe_bcmp + +20100924 + - (djm) OpenBSD CVS Sync + - naddy@cvs.openbsd.org 2010/09/10 15:19:29 + [ssh-keygen.1] + * mention ECDSA in more places + * less repetition in FILES section + * SSHv1 keys are still encrypted with 3DES + help and ok jmc@ + - djm@cvs.openbsd.org 2010/09/11 21:44:20 + [ssh.1] + mention RFC 5656 for ECC stuff + - jmc@cvs.openbsd.org 2010/09/19 21:30:05 + [sftp.1] + more wacky macro fixing; + - djm@cvs.openbsd.org 2010/09/20 04:41:47 + [ssh.c] + install a SIGCHLD handler to reap expiried child process; ok markus@ + - djm@cvs.openbsd.org 2010/09/20 04:50:53 + [jpake.c schnorr.c] + check that received values are smaller than the group size in the + disabled and unfinished J-PAKE code. + avoids catastrophic security failure found by Sebastien Martini + - djm@cvs.openbsd.org 2010/09/20 04:54:07 + [jpake.c] + missing #include + - djm@cvs.openbsd.org 2010/09/20 07:19:27 + [mux.c] + "atomically" create the listening mux socket by binding it on a temorary + name and then linking it into position after listen() has succeeded. + this allows the mux clients to determine that the server socket is + either ready or stale without races. stale server sockets are now + automatically removed + ok deraadt + - djm@cvs.openbsd.org 2010/09/22 05:01:30 + [kex.c kex.h kexecdh.c kexecdhc.c kexecdhs.c readconf.c readconf.h] + [servconf.c servconf.h ssh_config.5 sshconnect2.c sshd.c sshd_config.5] + add a KexAlgorithms knob to the client and server configuration to allow + selection of which key exchange methods are used by ssh(1) and sshd(8) + and their order of preference. + ok markus@ + - jmc@cvs.openbsd.org 2010/09/22 08:30:08 + [ssh.1 ssh_config.5] + ssh.1: add kexalgorithms to the -o list + ssh_config.5: format the kexalgorithms in a more consistent + (prettier!) way + ok djm + - djm@cvs.openbsd.org 2010/09/22 22:58:51 + [atomicio.c atomicio.h misc.c misc.h scp.c sftp-client.c] + [sftp-client.h sftp.1 sftp.c] + add an option per-read/write callback to atomicio + + factor out bandwidth limiting code from scp(1) into a generic bandwidth + limiter that can be attached using the atomicio callback mechanism + + add a bandwidth limit option to sftp(1) using the above + "very nice" markus@ + - jmc@cvs.openbsd.org 2010/09/23 13:34:43 + [sftp.c] + add [-l limit] to usage(); + - jmc@cvs.openbsd.org 2010/09/23 13:36:46 + [scp.1 sftp.1] + add KexAlgorithms to the -o list; + +20100910 + - (dtucker) [openbsd-compat/port-linux.c] Check is_selinux_enabled for exact + return code since it can apparently return -1 under some conditions. From + openssh bugs werbittewas de, ok djm@ + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2010/08/31 12:33:38 + [ssh-add.c ssh-agent.c ssh-keygen.c ssh-keysign.c ssh.c sshd.c] + reintroduce commit from tedu@, which I pulled out for release + engineering: + OpenSSL_add_all_algorithms is the name of the function we have a + man page for, so use that. ok djm + - jmc@cvs.openbsd.org 2010/08/31 17:40:54 + [ssh-agent.1] + fix some macro abuse; + - jmc@cvs.openbsd.org 2010/08/31 21:14:58 + [ssh.1] + small text tweak to accommodate previous; + - naddy@cvs.openbsd.org 2010/09/01 15:21:35 + [servconf.c] + pick up ECDSA host key by default; ok djm@ + - markus@cvs.openbsd.org 2010/09/02 16:07:25 + [ssh-keygen.c] + permit -b 256, 384 or 521 as key size for ECDSA; ok djm@ + - markus@cvs.openbsd.org 2010/09/02 16:08:39 + [ssh.c] + unbreak ControlPersist=yes for ControlMaster=yes; ok djm@ + - naddy@cvs.openbsd.org 2010/09/02 17:21:50 + [ssh-keygen.c] + Switch ECDSA default key size to 256 bits, which according to RFC5656 + should still be better than our current RSA-2048 default. + ok djm@, markus@ + - jmc@cvs.openbsd.org 2010/09/03 11:09:29 + [scp.1] + add an EXIT STATUS section for /usr/bin; + - jmc@cvs.openbsd.org 2010/09/04 09:38:34 + [ssh-add.1 ssh.1] + two more EXIT STATUS sections; + - naddy@cvs.openbsd.org 2010/09/06 17:10:19 + [sshd_config] + add ssh_host_ecdsa_key to /etc; from Mattieu Baptiste + <mattieu.b@gmail.com> + ok deraadt@ + - djm@cvs.openbsd.org 2010/09/08 03:54:36 + [authfile.c] + typo + - deraadt@cvs.openbsd.org 2010/09/08 04:13:31 + [compress.c] + work around name-space collisions some buggy compilers (looking at you + gcc, at least in earlier versions, but this does not forgive your current + transgressions) seen between zlib and openssl + ok djm + - djm@cvs.openbsd.org 2010/09/09 10:45:45 + [kex.c kex.h kexecdh.c key.c key.h monitor.c ssh-ecdsa.c] + ECDH/ECDSA compliance fix: these methods vary the hash function they use + (SHA256/384/512) depending on the length of the curve in use. The previous + code incorrectly used SHA256 in all cases. + + This fix will cause authentication failure when using 384 or 521-bit curve + keys if one peer hasn't been upgraded and the other has. (256-bit curve + keys work ok). In particular you may need to specify HostkeyAlgorithms + when connecting to a server that has not been upgraded from an upgraded + client. + + ok naddy@ + - (djm) [authfd.c authfile.c bufec.c buffer.h configure.ac kex.h kexecdh.c] + [kexecdhc.c kexecdhs.c key.c key.h myproposal.h packet.c readconf.c] + [ssh-agent.c ssh-ecdsa.c ssh-keygen.c ssh.c] Disable ECDH and ECDSA on + platforms that don't have the requisite OpenSSL support. ok dtucker@ + - (dtucker) [kex.h key.c packet.h ssh-agent.c ssh.c] A few more ECC ifdefs + for missing headers and compiler warnings. + +20100831 + - OpenBSD CVS Sync + - jmc@cvs.openbsd.org 2010/08/08 19:36:30 + [ssh-keysign.8 ssh.1 sshd.8] + use the same template for all FILES sections; i.e. -compact/.Pp where we + have multiple items, and .Pa for path names; + - tedu@cvs.openbsd.org 2010/08/12 23:34:39 + [ssh-add.c ssh-agent.c ssh-keygen.c ssh-keysign.c ssh.c sshd.c] + OpenSSL_add_all_algorithms is the name of the function we have a man page + for, so use that. ok djm + - djm@cvs.openbsd.org 2010/08/16 04:06:06 + [ssh-add.c ssh-agent.c ssh-keygen.c ssh-keysign.c ssh.c sshd.c] + backout previous temporarily; discussed with deraadt@ + - djm@cvs.openbsd.org 2010/08/31 09:58:37 + [auth-options.c auth1.c auth2.c bufaux.c buffer.h kex.c key.c packet.c] + [packet.h ssh-dss.c ssh-rsa.c] + Add buffer_get_cstring() and related functions that verify that the + string extracted from the buffer contains no embedded \0 characters* + This prevents random (possibly malicious) crap from being appended to + strings where it would not be noticed if the string is used with + a string(3) function. + + Use the new API in a few sensitive places. + + * actually, we allow a single one at the end of the string for now because + we don't know how many deployed implementations get this wrong, but don't + count on this to remain indefinitely. + - djm@cvs.openbsd.org 2010/08/31 11:54:45 + [PROTOCOL PROTOCOL.agent PROTOCOL.certkeys auth2-jpake.c authfd.c] + [authfile.c buffer.h dns.c kex.c kex.h key.c key.h monitor.c] + [monitor_wrap.c myproposal.h packet.c packet.h pathnames.h readconf.c] + [ssh-add.1 ssh-add.c ssh-agent.1 ssh-agent.c ssh-keygen.1 ssh-keygen.c] + [ssh-keyscan.1 ssh-keyscan.c ssh-keysign.8 ssh.1 ssh.c ssh2.h] + [ssh_config.5 sshconnect.c sshconnect2.c sshd.8 sshd.c sshd_config.5] + [uuencode.c uuencode.h bufec.c kexecdh.c kexecdhc.c kexecdhs.c ssh-ecdsa.c] + Implement Elliptic Curve Cryptography modes for key exchange (ECDH) and + host/user keys (ECDSA) as specified by RFC5656. ECDH and ECDSA offer + better performance than plain DH and DSA at the same equivalent symmetric + key length, as well as much shorter keys. + + Only the mandatory sections of RFC5656 are implemented, specifically the + three REQUIRED curves nistp256, nistp384 and nistp521 and only ECDH and + ECDSA. Point compression (optional in RFC5656 is NOT implemented). + + Certificate host and user keys using the new ECDSA key types are supported. + + Note that this code has not been tested for interoperability and may be + subject to change. + + feedback and ok markus@ + - (djm) [Makefile.in] Add new ECC files + - (djm) [bufec.c kexecdh.c kexecdhc.c kexecdhs.c ssh-ecdsa.c] include + includes.h + +20100827 + - (dtucker) [contrib/redhat/sshd.init] Bug #1810: initlog is deprecated, + remove. Patch from martynas at venck us + +20100823 + - (djm) Release OpenSSH-5.6p1 + +20100816 + - (dtucker) [configure.ac openbsd-compat/Makefile.in + openbsd-compat/openbsd-compat.h openbsd-compat/strptime.c] Add strptime to + the compat library which helps on platforms like old IRIX. Based on work + by djm, tested by Tom Christensen. + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2010/08/12 21:49:44 + [ssh.c] + close any extra file descriptors inherited from parent at start and + reopen stdin/stdout to /dev/null when forking for ControlPersist. + + prevents tools that fork and run a captive ssh for communication from + failing to exit when the ssh completes while they wait for these fds to + close. The inherited fds may persist arbitrarily long if a background + mux master has been started by ControlPersist. cvs and scp were effected + by this. + + "please commit" markus@ + - (djm) [regress/README.regress] typo + +20100812 + - (tim) [regress/login-timeout.sh regress/reconfigure.sh regress/reexec.sh + regress/test-exec.sh] Under certain conditions when testing with sudo + tests would fail because the pidfile could not be read by a regular user. + "cat: cannot open ...../regress/pidfile: Permission denied (error 13)" + Make sure cat is run by $SUDO. no objection from me. djm@ + - (tim) [auth.c] add cast to quiet compiler. Change only affects SVR5 systems. + +20100809 + - (djm) bz#1561: don't bother setting IFF_UP on tun(4) device if it is + already set. Makes FreeBSD user openable tunnels useful; patch from + richard.burakowski+ossh AT mrburak.net, ok dtucker@ + - (dtucker) bug #1530: strip trailing ":" from hostname in ssh-copy-id. + based in part on a patch from Colin Watson, ok djm@ + +20100809 + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2010/08/08 16:26:42 + [version.h] + crank to 5.6 + - (djm) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec] + [contrib/suse/openssh.spec] Crank version numbers + +20100805 + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2010/08/04 05:37:01 + [ssh.1 ssh_config.5 sshd.8] + Remove mentions of weird "addr/port" alternate address format for IPv6 + addresses combinations. It hasn't worked for ages and we have supported + the more commen "[addr]:port" format for a long time. ok jmc@ markus@ + - djm@cvs.openbsd.org 2010/08/04 05:40:39 + [PROTOCOL.certkeys ssh-keygen.c] + tighten the rules for certificate encoding by requiring that options + appear in lexical order and make our ssh-keygen comply. ok markus@ + - djm@cvs.openbsd.org 2010/08/04 05:42:47 + [auth.c auth2-hostbased.c authfile.c authfile.h ssh-keysign.8] + [ssh-keysign.c ssh.c] + enable certificates for hostbased authentication, from Iain Morgan; + "looks ok" markus@ + - djm@cvs.openbsd.org 2010/08/04 05:49:22 + [authfile.c] + commited the wrong version of the hostbased certificate diff; this + version replaces some strlc{py,at} verbosity with xasprintf() at + the request of markus@ + - djm@cvs.openbsd.org 2010/08/04 06:07:11 + [ssh-keygen.1 ssh-keygen.c] + Support CA keys in PKCS#11 tokens; feedback and ok markus@ + - djm@cvs.openbsd.org 2010/08/04 06:08:40 + [ssh-keysign.c] + clean for -Wuninitialized (Id sync only; portable had this change) + - djm@cvs.openbsd.org 2010/08/05 13:08:42 + [channels.c] + Fix a trio of bugs in the local/remote window calculation for datagram + data channels (i.e. TunnelForward): + + Calculate local_consumed correctly in channel_handle_wfd() by measuring + the delta to buffer_len(c->output) from when we start to when we finish. + The proximal problem here is that the output_filter we use in portable + modified the length of the dequeued datagram (to futz with the headers + for !OpenBSD). + + In channel_output_poll(), don't enqueue datagrams that won't fit in the + peer's advertised packet size (highly unlikely to ever occur) or which + won't fit in the peer's remaining window (more likely). + + In channel_input_data(), account for the 4-byte string header in + datagram packets that we accept from the peer and enqueue in c->output. + + report, analysis and testing 2/3 cases from wierbows AT us.ibm.com; + "looks good" markus@ + +20100803 + - (dtucker) [monitor.c] Bug #1795: Initialize the values to be returned from + PAM to sane values in case the PAM method doesn't write to them. Spotted by + Bitman Zhou, ok djm@. + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2010/07/16 04:45:30 + [ssh-keygen.c] + avoid bogus compiler warning + - djm@cvs.openbsd.org 2010/07/16 14:07:35 + [ssh-rsa.c] + more timing paranoia - compare all parts of the expected decrypted + data before returning. AFAIK not exploitable in the SSH protocol. + "groovy" deraadt@ + - djm@cvs.openbsd.org 2010/07/19 03:16:33 + [sftp-client.c] + bz#1797: fix swapped args in upload_dir_internal(), breaking recursive + upload depth checks and causing verbose printing of transfers to always + be turned on; patch from imorgan AT nas.nasa.gov + - djm@cvs.openbsd.org 2010/07/19 09:15:12 + [clientloop.c readconf.c readconf.h ssh.c ssh_config.5] + add a "ControlPersist" option that automatically starts a background + ssh(1) multiplex master when connecting. This connection can stay alive + indefinitely, or can be set to automatically close after a user-specified + duration of inactivity. bz#1330 - patch by dwmw2 AT infradead.org, but + further hacked on by wmertens AT cisco.com, apb AT cequrux.com, + martin-mindrot-bugzilla AT earth.li and myself; "looks ok" markus@ + - djm@cvs.openbsd.org 2010/07/21 02:10:58 + [misc.c] + sync timingsafe_bcmp() with the one dempsky@ committed to sys/lib/libkern + - dtucker@cvs.openbsd.org 2010/07/23 08:49:25 + [ssh.1] + Ciphers is documented in ssh_config(5) these days + +20100819 + - (dtucker) [contrib/ssh-copy-ud.1] Bug #1786: update ssh-copy-id.1 with more + details about its behaviour WRT existing directories. Patch from + asguthrie at gmail com, ok djm. + +20100716 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2010/07/02 04:32:44 + [misc.c] + unbreak strdelim() skipping past quoted strings, e.g. + AllowUsers "blah blah" blah + was broken; report and fix in bz#1757 from bitman.zhou AT centrify.com + ok dtucker; + - djm@cvs.openbsd.org 2010/07/12 22:38:52 + [ssh.c] + Make ExitOnForwardFailure work with fork-after-authentication ("ssh -f") + for protocol 2. ok markus@ + - djm@cvs.openbsd.org 2010/07/12 22:41:13 + [ssh.c ssh_config.5] + expand %h to the hostname in ssh_config Hostname options. While this + sounds useless, it is actually handy for working with unqualified + hostnames: + + Host *.* + Hostname %h + Host * + Hostname %h.example.org + + "I like it" markus@ + - djm@cvs.openbsd.org 2010/07/13 11:52:06 + [auth-rsa.c channels.c jpake.c key.c misc.c misc.h monitor.c] + [packet.c ssh-rsa.c] + implement a timing_safe_cmp() function to compare memory without leaking + timing information by short-circuiting like memcmp() and use it for + some of the more sensitive comparisons (though nothing high-value was + readily attackable anyway); "looks ok" markus@ + - djm@cvs.openbsd.org 2010/07/13 23:13:16 + [auth-rsa.c channels.c jpake.c key.c misc.c misc.h monitor.c packet.c] + [ssh-rsa.c] + s/timing_safe_cmp/timingsafe_bcmp/g + - jmc@cvs.openbsd.org 2010/07/14 17:06:58 + [ssh.1] + finally ssh synopsis looks nice again! this commit just removes a ton of + hacks we had in place to make it work with old groff; + - schwarze@cvs.openbsd.org 2010/07/15 21:20:38 + [ssh-keygen.1] + repair incorrect block nesting, which screwed up indentation; + problem reported and fix OK by jmc@ + +20100714 + - (tim) [contrib/redhat/openssh.spec] Bug 1796: Test for skip_x11_askpass + (line 77) should have been for no_x11_askpass. + +20100702 + - (djm) OpenBSD CVS Sync + - jmc@cvs.openbsd.org 2010/06/26 00:57:07 + [ssh_config.5] + tweak previous; + - djm@cvs.openbsd.org 2010/06/26 23:04:04 + [ssh.c] + oops, forgot to #include <canohost.h>; spotted and patch from chl@ + - djm@cvs.openbsd.org 2010/06/29 23:15:30 + [ssh-keygen.1 ssh-keygen.c] + allow import (-i) and export (-e) of PEM and PKCS#8 encoded keys; + bz#1749; ok markus@ + - djm@cvs.openbsd.org 2010/06/29 23:16:46 + [auth2-pubkey.c sshd_config.5] + allow key options (command="..." and friends) in AuthorizedPrincipals; + ok markus@ + - jmc@cvs.openbsd.org 2010/06/30 07:24:25 + [ssh-keygen.1] + tweak previous; + - jmc@cvs.openbsd.org 2010/06/30 07:26:03 + [ssh-keygen.c] + sort usage(); + - jmc@cvs.openbsd.org 2010/06/30 07:28:34 + [sshd_config.5] + tweak previous; + - millert@cvs.openbsd.org 2010/07/01 13:06:59 + [scp.c] + Fix a longstanding problem where if you suspend scp at the + password/passphrase prompt the terminal mode is not restored. + OK djm@ + - phessler@cvs.openbsd.org 2010/06/27 19:19:56 + [regress/Makefile] + fix how we run the tests so we can successfully use SUDO='sudo -E' + in our env + - djm@cvs.openbsd.org 2010/06/29 23:59:54 + [cert-userkey.sh] + regress tests for key options in AuthorizedPrincipals + +20100627 + - (tim) [openbsd-compat/port-uw.c] Reorder includes. auth-options.h now needs + key.h. + +20100626 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2010/05/21 05:00:36 + [misc.c] + colon() returns char*, so s/return (0)/return NULL/ + - markus@cvs.openbsd.org 2010/06/08 21:32:19 + [ssh-pkcs11.c] + check length of value returned C_GetAttributValue for != 0 + from mdrtbugzilla@codefive.co.uk; bugzilla #1773; ok dtucker@ + - djm@cvs.openbsd.org 2010/06/17 07:07:30 + [mux.c] + Correct sizing of object to be allocated by calloc(), replacing + sizeof(state) with sizeof(*state). This worked by accident since + the struct contained a single int at present, but could have broken + in the future. patch from hyc AT symas.com + - djm@cvs.openbsd.org 2010/06/18 00:58:39 + [sftp.c] + unbreak ls in working directories that contains globbing characters in + their pathnames. bz#1655 reported by vgiffin AT apple.com + - djm@cvs.openbsd.org 2010/06/18 03:16:03 + [session.c] + Missing check for chroot_director == "none" (we already checked against + NULL); bz#1564 from Jan.Pechanec AT Sun.COM + - djm@cvs.openbsd.org 2010/06/18 04:43:08 + [sftp-client.c] + fix memory leak in do_realpath() error path; bz#1771, patch from + anicka AT suse.cz + - djm@cvs.openbsd.org 2010/06/22 04:22:59 + [servconf.c sshd_config.5] + expose some more sshd_config options inside Match blocks: + AuthorizedKeysFile AuthorizedPrincipalsFile + HostbasedUsesNameFromPacketOnly PermitTunnel + bz#1764; feedback from imorgan AT nas.nasa.gov; ok dtucker@ + - djm@cvs.openbsd.org 2010/06/22 04:32:06 + [ssh-keygen.c] + standardise error messages when attempting to open private key + files to include "progname: filename: error reason" + bz#1783; ok dtucker@ + - djm@cvs.openbsd.org 2010/06/22 04:49:47 + [auth.c] + queue auth debug messages for bad ownership or permissions on the user's + keyfiles. These messages will be sent after the user has successfully + authenticated (where our client will display them with LogLevel=debug). + bz#1554; ok dtucker@ + - djm@cvs.openbsd.org 2010/06/22 04:54:30 + [ssh-keyscan.c] + replace verbose and overflow-prone Linebuf code with read_keyfile_line() + based on patch from joachim AT joachimschipper.nl; bz#1565; ok dtucker@ + - djm@cvs.openbsd.org 2010/06/22 04:59:12 + [session.c] + include the user name on "subsystem request for ..." log messages; + bz#1571; ok dtucker@ + - djm@cvs.openbsd.org 2010/06/23 02:59:02 + [ssh-keygen.c] + fix printing of extensions in v01 certificates that I broke in r1.190 + - djm@cvs.openbsd.org 2010/06/25 07:14:46 + [channels.c mux.c readconf.c readconf.h ssh.h] + bz#1327: remove hardcoded limit of 100 permitopen clauses and port + forwards per direction; ok markus@ stevesk@ + - djm@cvs.openbsd.org 2010/06/25 07:20:04 + [channels.c session.c] + bz#1750: fix requirement for /dev/null inside ChrootDirectory for + internal-sftp accidentally introduced in r1.253 by removing the code + that opens and dup /dev/null to stderr and modifying the channels code + to read stderr but discard it instead; ok markus@ + - djm@cvs.openbsd.org 2010/06/25 08:46:17 + [auth1.c auth2-none.c] + skip the initial check for access with an empty password when + PermitEmptyPasswords=no; bz#1638; ok markus@ + - djm@cvs.openbsd.org 2010/06/25 23:10:30 + [ssh.c] + log the hostname and address that we connected to at LogLevel=verbose + after authentication is successful to mitigate "phishing" attacks by + servers with trusted keys that accept authentication silently and + automatically before presenting fake password/passphrase prompts; + "nice!" markus@ + - djm@cvs.openbsd.org 2010/06/25 23:10:30 + [ssh.c] + log the hostname and address that we connected to at LogLevel=verbose + after authentication is successful to mitigate "phishing" attacks by + servers with trusted keys that accept authentication silently and + automatically before presenting fake password/passphrase prompts; + "nice!" markus@ + +20100622 + - (djm) [loginrec.c] crank LINFO_NAMESIZE (username length) to 512 + bz#1579; ok dtucker + +20100618 + - (djm) [contrib/ssh-copy-id] Update key file explicitly under ~ + rather than assuming that $CWD == $HOME. bz#1500, patch from + timothy AT gelter.com + +20100617 + - (tim) [contrib/cygwin/README] Remove a reference to the obsolete + minires-devel package, and to add the reference to the libedit-devel + package since CYgwin now provides libedit. Patch from Corinna Vinschen. + +20100521 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2010/05/07 11:31:26 + [regress/Makefile regress/cert-userkey.sh] + regress tests for AuthorizedPrincipalsFile and "principals=" key option. + feedback and ok markus@ + - djm@cvs.openbsd.org 2010/05/11 02:58:04 + [auth-rsa.c] + don't accept certificates marked as "cert-authority" here; ok markus@ + - djm@cvs.openbsd.org 2010/05/14 00:47:22 + [ssh-add.c] + check that the certificate matches the corresponding private key before + grafting it on + - djm@cvs.openbsd.org 2010/05/14 23:29:23 + [channels.c channels.h mux.c ssh.c] + Pause the mux channel while waiting for reply from aynch callbacks. + Prevents misordering of replies if new requests arrive while waiting. + + Extend channel open confirm callback to allow signalling failure + conditions as well as success. Use this to 1) fix a memory leak, 2) + start using the above pause mechanism and 3) delay sending a success/ + failure message on mux slave session open until we receive a reply from + the server. + + motivated by and with feedback from markus@ + - markus@cvs.openbsd.org 2010/05/16 12:55:51 + [PROTOCOL.mux clientloop.h mux.c readconf.c readconf.h ssh.1 ssh.c] + mux support for remote forwarding with dynamic port allocation, + use with + LPORT=`ssh -S muxsocket -R0:localhost:25 -O forward somehost` + feedback and ok djm@ + - djm@cvs.openbsd.org 2010/05/20 11:25:26 + [auth2-pubkey.c] + fix logspam when key options (from="..." especially) deny non-matching + keys; reported by henning@ also bz#1765; ok markus@ dtucker@ + - djm@cvs.openbsd.org 2010/05/20 23:46:02 + [PROTOCOL.certkeys auth-options.c ssh-keygen.c] + Move the permit-* options to the non-critical "extensions" field for v01 + certificates. The logic is that if another implementation fails to + implement them then the connection just loses features rather than fails + outright. + + ok markus@ + +20100511 + - (dtucker) [Makefile.in] Bug #1770: Link libopenbsd-compat twice to solve + circular dependency problem on old or odd platforms. From Tom Lane, ok + djm@. + - (djm) [openbsd-compat/openssl-compat.h] Fix build breakage on older + libcrypto by defining OPENSSL_[DR]SA_MAX_MODULUS_BITS if they aren't + already. ok dtucker@ + +20100510 + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2010/04/23 01:47:41 + [ssh-keygen.c] + bz#1740: display a more helpful error message when $HOME is + inaccessible while trying to create .ssh directory. Based on patch + from jchadima AT redhat.com; ok dtucker@ + - djm@cvs.openbsd.org 2010/04/23 22:27:38 + [mux.c] + set "detach_close" flag when registering channel cleanup callbacks. + This causes the channel to close normally when its fds close and + hangs when terminating a mux slave using ~. bz#1758; ok markus@ + - djm@cvs.openbsd.org 2010/04/23 22:42:05 + [session.c] + set stderr to /dev/null for subsystems rather than just closing it. + avoids hangs if a subsystem or shell initialisation writes to stderr. + bz#1750; ok markus@ + - djm@cvs.openbsd.org 2010/04/23 22:48:31 + [ssh-keygen.c] + refuse to generate keys longer than OPENSSL_[RD]SA_MAX_MODULUS_BITS, + since we would refuse to use them anyway. bz#1516; ok dtucker@ + - djm@cvs.openbsd.org 2010/04/26 22:28:24 + [sshconnect2.c] + bz#1502: authctxt.success is declared as an int, but passed by + reference to function that accepts sig_atomic_t*. Convert it to + the latter; ok markus@ dtucker@ + - djm@cvs.openbsd.org 2010/05/01 02:50:50 + [PROTOCOL.certkeys] + typo; jmeltzer@ + - dtucker@cvs.openbsd.org 2010/05/05 04:22:09 + [sftp.c] + restore mput and mget which got lost in the tab-completion changes. + found by Kenneth Whitaker, ok djm@ + - djm@cvs.openbsd.org 2010/05/07 11:30:30 + [auth-options.c auth-options.h auth.c auth.h auth2-pubkey.c] + [key.c servconf.c servconf.h sshd.8 sshd_config.5] + add some optional indirection to matching of principal names listed + in certificates. Currently, a certificate must include the a user's name + to be accepted for authentication. This change adds the ability to + specify a list of certificate principal names that are acceptable. + + When authenticating using a CA trusted through ~/.ssh/authorized_keys, + this adds a new principals="name1[,name2,...]" key option. + + For CAs listed through sshd_config's TrustedCAKeys option, a new config + option "AuthorizedPrincipalsFile" specifies a per-user file containing + the list of acceptable names. + + If either option is absent, the current behaviour of requiring the + username to appear in principals continues to apply. + + These options are useful for role accounts, disjoint account namespaces + and "user@realm"-style naming policies in certificates. + + feedback and ok markus@ + - jmc@cvs.openbsd.org 2010/05/07 12:49:17 + [sshd_config.5] + tweak previous; + +20100423 + - (dtucker) [configure.ac] Bug #1756: Check for the existence of a lib64 dir + in the openssl install directory (some newer openssl versions do this on at + least some amd64 platforms). + +20100418 + - OpenBSD CVS Sync + - jmc@cvs.openbsd.org 2010/04/16 06:45:01 + [ssh_config.5] + tweak previous; ok djm + - jmc@cvs.openbsd.org 2010/04/16 06:47:04 + [ssh-keygen.1 ssh-keygen.c] + tweak previous; ok djm + - djm@cvs.openbsd.org 2010/04/16 21:14:27 + [sshconnect.c] + oops, %r => remote username, not %u + - djm@cvs.openbsd.org 2010/04/16 01:58:45 + [regress/cert-hostkey.sh regress/cert-userkey.sh] + regression tests for v01 certificate format + includes interop tests for v00 certs + - (dtucker) [contrib/aix/buildbff.sh] Fix creation of ssh_prng_cmds.default + file. + +20100416 + - (djm) Release openssh-5.5p1 + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2010/03/26 03:13:17 + [bufaux.c] + allow buffer_get_int_ret/buffer_get_int64_ret to take a NULL pointer + argument to allow skipping past values in a buffer + - jmc@cvs.openbsd.org 2010/03/26 06:54:36 + [ssh.1] + tweak previous; + - jmc@cvs.openbsd.org 2010/03/27 14:26:55 + [ssh_config.5] + tweak previous; ok dtucker + - djm@cvs.openbsd.org 2010/04/10 00:00:16 + [ssh.c] + bz#1746 - suppress spurious tty warning when using -O and stdin + is not a tty; ok dtucker@ markus@ + - djm@cvs.openbsd.org 2010/04/10 00:04:30 + [sshconnect.c] + fix terminology: we didn't find a certificate in known_hosts, we found + a CA key + - djm@cvs.openbsd.org 2010/04/10 02:08:44 + [clientloop.c] + bz#1698: kill channel when pty allocation requests fail. Fixed + stuck client if the server refuses pty allocation. + ok dtucker@ "think so" markus@ + - djm@cvs.openbsd.org 2010/04/10 02:10:56 + [sshconnect2.c] + show the key type that we are offering in debug(), helps distinguish + between certs and plain keys as the path to the private key is usually + the same. + - djm@cvs.openbsd.org 2010/04/10 05:48:16 + [mux.c] + fix NULL dereference; from matthew.haub AT alumni.adelaide.edu.au + - djm@cvs.openbsd.org 2010/04/14 22:27:42 + [ssh_config.5 sshconnect.c] + expand %r => remote username in ssh_config:ProxyCommand; + ok deraadt markus + - markus@cvs.openbsd.org 2010/04/15 20:32:55 + [ssh-pkcs11.c] + retry lookup for private key if there's no matching key with CKA_SIGN + attribute enabled; this fixes fixes MuscleCard support (bugzilla #1736) + ok djm@ + - djm@cvs.openbsd.org 2010/04/16 01:47:26 + [PROTOCOL.certkeys auth-options.c auth-options.h auth-rsa.c] + [auth2-pubkey.c authfd.c key.c key.h myproposal.h ssh-add.c] + [ssh-agent.c ssh-dss.c ssh-keygen.1 ssh-keygen.c ssh-rsa.c] + [sshconnect.c sshconnect2.c sshd.c] + revised certificate format ssh-{dss,rsa}-cert-v01@openssh.com with the + following changes: + + move the nonce field to the beginning of the certificate where it can + better protect against chosen-prefix attacks on the signature hash + + Rename "constraints" field to "critical options" + + Add a new non-critical "extensions" field + + Add a serial number + + The older format is still support for authentication and cert generation + (use "ssh-keygen -t v00 -s ca_key ..." to generate a v00 certificate) + + ok markus@
diff --git a/openssh-6.0p1/INSTALL b/openssh-6.0p1/INSTALL new file mode 100644 index 0000000..7c60469 --- /dev/null +++ b/openssh-6.0p1/INSTALL
@@ -0,0 +1,269 @@ +1. Prerequisites +---------------- + +You will need working installations of Zlib and OpenSSL. + +Zlib 1.1.4 or 1.2.1.2 or greater (ealier 1.2.x versions have problems): +http://www.gzip.org/zlib/ + +OpenSSL 0.9.6 or greater: +http://www.openssl.org/ + +(OpenSSL 0.9.5a is partially supported, but some ciphers (SSH protocol 1 +Blowfish) do not work correctly.) + +The remaining items are optional. + +NB. If you operating system supports /dev/random, you should configure +OpenSSL to use it. OpenSSH relies on OpenSSL's direct support of +/dev/random, 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: + +The Entropy Gathering Daemon (EGD) is supported if you have a system which +lacks /dev/random and don't want to use OpenSSH's internal entropy collection. + +http://www.lothar.com/tech/crypto/ + +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 <jmknoble@pobox.com> has written an excellent X11 +passphrase requester. This is maintained separately at: + +http://www.jmknoble.net/software/x11-ssh-askpass/ + +TCP Wrappers: + +If you wish to use the TCP wrappers functionality you will need at least +tcpd.h and libwrap.a, either in the standard include and library paths, +or in the directory specified by --with-tcp-wrappers. Version 7.6 is +known to work. + +http://ftp.porcupine.org/pub/security/index.html + +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.61 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-tcp-wrappers will enable TCP Wrappers (/etc/hosts.allow|deny) +support. + +--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 OpenSSL libraries +are installed. + +--with-ssl-engine enables OpenSSL's (hardware) ENGINE support + +--with-4in6 Check for IPv4 in IPv6 mapped addresses and convert them to +real (AF_INET) IPv4 addresses. Works around some quirks on Linux. + +If you need to pass special options to the compiler or linker, you +can specify these as environment variables before running ./configure. +For example: + +CFLAGS="-O -m486" LDFLAGS="-s" LIBS="-lrubbish" LD="/usr/foo/ld" ./configure + +3. Configuration +---------------- + +The runtime configuration files are installed by in ${prefix}/etc or +whatever you specified as your --sysconfdir (/usr/local/etc by default). + +The default configuration should be instantly usable, though you should +review it to ensure that it matches your security requirements. + +To generate a host key, run "make host-key". Alternately you can do so +manually using the following commands: + + ssh-keygen -t rsa1 -f /etc/ssh/ssh_host_key -N "" + ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N "" + ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key -N "" + +Replacing /etc/ssh with the correct path to the configuration directory. +(${prefix}/etc or whatever you specified with --sysconfdir during +configuration) + +If you have configured OpenSSH with EGD support, ensure that EGD is +running and has collected some Entropy. + +For more information on configuration, please refer to the manual pages +for sshd, ssh and ssh-agent. + +4. (Optional) Send survey +------------------------- + +$ make survey +[check the contents of the file "survey" to ensure there's no information +that you consider sensitive] +$ make send-survey + +This will send configuration information for the currently configured +host to a survey address. This will help determine which configurations +are actually in use, and what valid combinations of configure options +exist. The raw data is available only to the OpenSSH developers, however +summary data may be published. + +5. Problems? +------------ + +If you experience problems compiling, installing or running OpenSSH. +Please refer to the "reporting bugs" section of the webpage at +http://www.openssh.com/ + + +$Id: INSTALL,v 1.87 2011/11/04 00:25:25 dtucker Exp $
diff --git a/openssh-6.0p1/LICENCE b/openssh-6.0p1/LICENCE new file mode 100644 index 0000000..f523871 --- /dev/null +++ b/openssh-6.0p1/LICENCE
@@ -0,0 +1,340 @@ +This file is part of the OpenSSH software. + +The licences which components of this software fall under are as +follows. First, we will summarize and say that all components +are under a BSD licence, or a licence more free than that. + +OpenSSH contains no GPL code. + +1) + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + + [Tatu continues] + * However, I am not implying to give any licenses to any patents or + * copyrights held by third parties, and the software includes parts that + * are not under my direct control. As far as I know, all included + * source code is used in accordance with the relevant license agreements + * and can be used freely for any purpose (the GNU license being the most + * restrictive); see below for details. + + [However, none of that term is relevant at this point in time. All of + these restrictively licenced software components which he talks about + have been removed from OpenSSH, i.e., + + - RSA is no longer included, found in the OpenSSL library + - IDEA is no longer included, its use is deprecated + - DES is now external, in the OpenSSL library + - GMP is no longer used, and instead we call BN code from OpenSSL + - Zlib is now external, in a library + - The make-ssh-known-hosts script is no longer included + - TSS has been removed + - MD5 is now external, in the OpenSSL library + - RC4 support has been replaced with ARC4 support from OpenSSL + - Blowfish is now external, in the OpenSSL library + + [The licence continues] + + Note that any information and cryptographic algorithms used in this + software are publicly available on the Internet and at any major + bookstore, scientific library, and patent office worldwide. More + information can be found e.g. at "http://www.cs.hut.fi/crypto". + + The legal status of this program is some combination of all these + permissions and restrictions. Use only at your own responsibility. + You will be responsible for any legal consequences yourself; I am not + making any claims whether possessing or using this is legal or not in + your country, and I am not taking any responsibility on your behalf. + + + NO WARRANTY + + BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY + FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN + OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES + PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED + OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS + TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE + PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, + REPAIR OR CORRECTION. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING + WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR + REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, + INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING + OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED + TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY + YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER + PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE + POSSIBILITY OF SUCH DAMAGES. + +2) + The 32-bit CRC compensation attack detector in deattack.c was + contributed by CORE SDI S.A. under a BSD-style license. + + * Cryptographic attack detector for ssh - source code + * + * Copyright (c) 1998 CORE SDI S.A., Buenos Aires, Argentina. + * + * All rights reserved. Redistribution and use in source and binary + * forms, with or without modification, are permitted provided that + * this copyright notice is retained. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES ARE DISCLAIMED. IN NO EVENT SHALL CORE SDI S.A. BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR + * CONSEQUENTIAL DAMAGES RESULTING FROM THE USE OR MISUSE OF THIS + * SOFTWARE. + * + * Ariel Futoransky <futo@core-sdi.com> + * <http://www.core-sdi.com> + +3) + ssh-keyscan was contributed by David Mazieres under a BSD-style + license. + + * Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>. + * + * Modification and redistribution in source and binary forms is + * permitted provided that due credit is given to the author and the + * OpenBSD project by leaving this copyright notice intact. + +4) + The Rijndael implementation by Vincent Rijmen, Antoon Bosselaers + and Paulo Barreto is in the public domain and distributed + with the following license: + + * @version 3.0 (December 2000) + * + * Optimised ANSI C code for the Rijndael cipher (now AES) + * + * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be> + * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be> + * @author Paulo Barreto <paulo.barreto@terra.com.br> + * + * This code is hereby placed in the public domain. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +5) + One component of the ssh source code is under a 3-clause BSD license, + held by the University of California, since we pulled these parts from + original Berkeley code. + + * Copyright (c) 1983, 1990, 1992, 1993, 1995 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + +6) + Remaining components of the software are provided under a standard + 2-term BSD licence with the following names as copyright holders: + + Markus Friedl + Theo de Raadt + Niels Provos + Dug Song + Aaron Campbell + Damien Miller + Kevin Steves + Daniel Kouril + Wesley Griffin + Per Allansson + Nils Nordman + Simon Wilkinson + + Portable OpenSSH additionally includes code from the following copyright + holders, also under the 2-term BSD license: + + Ben Lindstrom + Tim Rice + Andre Lucas + Chris Adams + Corinna Vinschen + Cray Inc. + Denis Parker + Gert Doering + Jakob Schlyter + Jason Downs + Juha Yrjölä + Michael Stone + Networks Associates Technology, Inc. + Solar Designer + Todd C. Miller + Wayne Schroeder + William Jones + Darren Tucker + Sun Microsystems + The SCO Group + 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): + * <phk@login.dknet.dk> wrote this file. As long as you retain this + * notice you can do whatever you want with this stuff. If we meet + * some day, and you think this stuff is worth it, you can buy me a + * beer in return. Poul-Henning Kamp + + b) snprintf replacement + + * Copyright Patrick Powell 1995 + * This code is based on code written by Patrick Powell + * (papowell@astart.com) It may be used for any purpose as long as this + * notice remains intact on all source code distributions + + c) Compatibility code (openbsd-compat) + + Apart from the previously mentioned licenses, various pieces of code + in the openbsd-compat/ subdirectory are licensed as follows: + + Some code is licensed under a 3-term BSD license, to the following + copyright holders: + + Todd C. Miller + Theo de Raadt + Damien Miller + Eric P. Allman + The Regents of the University of California + Constantin S. Svintsoff + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + + Some code is licensed under an ISC-style license, to the following + copyright holders: + + Internet Software Consortium. + Todd C. Miller + Reyk Floeter + Chad Mynhier + + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE + * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Some code is licensed under a MIT-style license to the following + copyright holders: + + Free Software Foundation, Inc. + + * Permission is hereby granted, free of charge, to any person obtaining a * + * copy of this software and associated documentation files (the * + * "Software"), to deal in the Software without restriction, including * + * without limitation the rights to use, copy, modify, merge, publish, * + * distribute, distribute with modifications, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the Software is * + * furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included * + * in all copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * + * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + * * + * Except as contained in this notice, the name(s) of the above copyright * + * holders shall not be used in advertising or otherwise to promote the * + * sale, use or other dealings in this Software without prior written * + * authorization. * + ****************************************************************************/ + + +------ +$OpenBSD: LICENCE,v 1.19 2004/08/30 09:18:08 markus Exp $
diff --git a/openssh-6.0p1/Makefile.in b/openssh-6.0p1/Makefile.in new file mode 100644 index 0000000..566f58f --- /dev/null +++ b/openssh-6.0p1/Makefile.in
@@ -0,0 +1,443 @@ +# $Id: Makefile.in,v 1.326 2012/04/04 01:27:57 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@ + +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@ +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) + +LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \ + canohost.o channels.o cipher.o cipher-acss.o cipher-aes.o \ + cipher-bf1.o cipher-ctr.o cipher-3des1.o cleanup.o \ + compat.o compress.o crc32.o deattack.o fatal.o hostfile.o \ + log.o match.o md-sha256.o moduli.o nchan.o packet.o \ + readpass.o rsa.o ttymodes.o xmalloc.o addrmatch.o \ + atomicio.o key.o dispatch.o kex.o mac.o uidswap.o uuencode.o misc.o \ + monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \ + kexdh.o kexgex.o kexdhc.o kexgexc.o bufec.o kexecdh.o kexecdhc.o \ + msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o jpake.o \ + schnorr.o ssh-pkcs11.o + +SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ + sshconnect.o sshconnect1.o sshconnect2.o mux.o \ + roaming_common.o roaming_client.o + +SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ + audit.o audit-bsm.o audit-linux.o platform.o \ + sshpty.o sshlogin.o servconf.o serverloop.o \ + auth.o auth1.o auth2.o auth-options.o session.o \ + auth-chall.o auth2-chall.o groupaccess.o \ + auth-skey.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ + auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-jpake.o \ + monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o kexecdhs.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 \ + roaming_common.o roaming_serv.o \ + sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ + sandbox-seccomp-filter.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|/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) + +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 $< + +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) + +sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS) + $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) + +scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o + $(LD) -o $@ scp.o progressmeter.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-add.o + $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-agent.o 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 roaming_dummy.o readconf.o + $(LD) -o $@ ssh-keysign.o readconf.o roaming_dummy.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 roaming_dummy.o + $(LD) -o $@ ssh-keyscan.o roaming_dummy.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} | $(AWK) -f $(srcdir)/mdoc2man.awk > $@; \ + else \ + $(FIXPATHSCMD) $${manpage} > $@; \ + 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 + +clean: regressclean + rm -f *.o *.a $(TARGETS) logintest config.cache config.log + rm -f *.out core survey + (cd openbsd-compat && $(MAKE) clean) + +distclean: regressclean + rm -f *.o *.a $(TARGETS) logintest config.cache config.log + rm -f *.out core opensshd.init openssh.xml + rm -f Makefile buildpkg.sh config.h config.status + rm -f survey.sh openbsd-compat/regress/Makefile *~ + rm -rf autom4te.cache + (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 + -rm -f $(DESTDIR)$(bindir)/slogin + ln -s ./ssh$(EXEEXT) $(DESTDIR)$(bindir)/slogin + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 + ln -s ./ssh.1 $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 + +install-sysconf: + if [ ! -d $(DESTDIR)$(sysconfdir) ]; then \ + $(srcdir)/mkinstalldirs $(DESTDIR)$(sysconfdir); \ + fi + @if [ ! -f $(DESTDIR)$(sysconfdir)/ssh_config ]; then \ + $(INSTALL) -m 644 ssh_config.out $(DESTDIR)$(sysconfdir)/ssh_config; \ + else \ + echo "$(DESTDIR)$(sysconfdir)/ssh_config already exists, install will not overwrite"; \ + fi + @if [ ! -f $(DESTDIR)$(sysconfdir)/sshd_config ]; then \ + $(INSTALL) -m 644 sshd_config.out $(DESTDIR)$(sysconfdir)/sshd_config; \ + else \ + echo "$(DESTDIR)$(sysconfdir)/sshd_config already exists, install will not overwrite"; \ + fi + @if [ ! -f $(DESTDIR)$(sysconfdir)/moduli ]; then \ + if [ -f $(DESTDIR)$(sysconfdir)/primes ]; then \ + echo "moving $(DESTDIR)$(sysconfdir)/primes to $(DESTDIR)$(sysconfdir)/moduli"; \ + mv "$(DESTDIR)$(sysconfdir)/primes" "$(DESTDIR)$(sysconfdir)/moduli"; \ + else \ + $(INSTALL) -m 644 moduli.out $(DESTDIR)$(sysconfdir)/moduli; \ + fi ; \ + else \ + echo "$(DESTDIR)$(sysconfdir)/moduli already exists, install will not overwrite"; \ + fi + +host-key: ssh-keygen$(EXEEXT) + @if [ -z "$(DESTDIR)" ] ; then \ + if [ -f "$(sysconfdir)/ssh_host_key" ] ; then \ + echo "$(sysconfdir)/ssh_host_key already exists, skipping." ; \ + else \ + ./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 \ + ./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 \ + ./ssh-keygen -t rsa -f $(sysconfdir)/ssh_host_rsa_key -N "" ; \ + fi ; \ + if [ -z "@COMMENT_OUT_ECC@" ] ; then \ + if [ -f $(sysconfdir)/ssh_host_ecdsa_key ] ; then \ + echo "$(sysconfdir)/ssh_host_ecdsa_key already exists, skipping." ; \ + else \ + ./ssh-keygen -t ecdsa -f $(sysconfdir)/ssh_host_ecdsa_key -N "" ; \ + fi ; \ + fi ; \ + fi ; + +host-key-force: ssh-keygen$(EXEEXT) + ./ssh-keygen -t rsa1 -f $(DESTDIR)$(sysconfdir)/ssh_host_key -N "" + ./ssh-keygen -t dsa -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key -N "" + ./ssh-keygen -t rsa -f $(DESTDIR)$(sysconfdir)/ssh_host_rsa_key -N "" + test -z "@COMMENT_OUT_ECC@" && ./ssh-keygen -t ecdsa -f $(DESTDIR)$(sysconfdir)/ssh_host_ecdsa_key -N "" + +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)/slogin + -rm -f $(DESTDIR)$(bindir)/ssh$(EXEEXT) + -rm -f $(DESTDIR)$(bindir)/scp$(EXEEXT) + -rm -f $(DESTDIR)$(bindir)/ssh-add$(EXEEXT) + -rm -f $(DESTDIR)$(bindir)/ssh-agent$(EXEEXT) + -rm -f $(DESTDIR)$(bindir)/ssh-keygen$(EXEEXT) + -rm -f $(DESTDIR)$(bindir)/ssh-keyscan$(EXEEXT) + -rm -f $(DESTDIR)$(bindir)/sftp$(EXEEXT) + -rm -f $(DESTDIR)$(sbindir)/sshd$(EXEEXT) + -rm -r $(DESTDIR)$(SFTP_SERVER)$(EXEEXT) + -rm -f $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT) + -rm -f $(DESTDIR)$(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 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 + +tests interop-tests: $(TARGETS) + BUILDDIR=`pwd`; \ + [ -d `pwd`/regress ] || mkdir -p `pwd`/regress; \ + [ -f `pwd`/regress/Makefile ] || \ + ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile ; \ + TEST_SHELL="@TEST_SHELL@"; \ + TEST_SSH_SSH="$${BUILDDIR}/ssh"; \ + TEST_SSH_SSHD="$${BUILDDIR}/sshd"; \ + TEST_SSH_SSHAGENT="$${BUILDDIR}/ssh-agent"; \ + TEST_SSH_SSHADD="$${BUILDDIR}/ssh-add"; \ + TEST_SSH_SSHKEYGEN="$${BUILDDIR}/ssh-keygen"; \ + TEST_SSH_SSHPKCS11HELPER="$${BUILDDIR}/ssh-pkcs11-helper"; \ + TEST_SSH_SSHKEYSCAN="$${BUILDDIR}/ssh-keyscan"; \ + TEST_SSH_SFTP="$${BUILDDIR}/sftp"; \ + TEST_SSH_SFTPSERVER="$${BUILDDIR}/sftp-server"; \ + TEST_SSH_PLINK="plink"; \ + TEST_SSH_PUTTYGEN="puttygen"; \ + TEST_SSH_CONCH="conch"; \ + TEST_SSH_IPV6="@TEST_SSH_IPV6@" ; \ + TEST_SSH_ECC="@TEST_SSH_ECC@" ; \ + TEST_SSH_SHA256="@TEST_SSH_SHA256@" ; \ + cd $(srcdir)/regress || exit $$?; \ + $(MAKE) \ + .OBJDIR="$${BUILDDIR}/regress" \ + .CURDIR="`pwd`" \ + BUILDDIR="$${BUILDDIR}" \ + OBJ="$${BUILDDIR}/regress/" \ + PATH="$${BUILDDIR}:$${PATH}" \ + TEST_SHELL="$${TEST_SHELL}" \ + TEST_SSH_SSH="$${TEST_SSH_SSH}" \ + TEST_SSH_SSHD="$${TEST_SSH_SSHD}" \ + TEST_SSH_SSHAGENT="$${TEST_SSH_SSHAGENT}" \ + TEST_SSH_SSHADD="$${TEST_SSH_SSHADD}" \ + TEST_SSH_SSHKEYGEN="$${TEST_SSH_SSHKEYGEN}" \ + TEST_SSH_SSHPKCS11HELPER="$${TEST_SSH_SSHPKCS11HELPER}" \ + TEST_SSH_SSHKEYSCAN="$${TEST_SSH_SSHKEYSCAN}" \ + TEST_SSH_SFTP="$${TEST_SSH_SFTP}" \ + TEST_SSH_SFTPSERVER="$${TEST_SSH_SFTPSERVER}" \ + TEST_SSH_PLINK="$${TEST_SSH_PLINK}" \ + TEST_SSH_PUTTYGEN="$${TEST_SSH_PUTTYGEN}" \ + TEST_SSH_CONCH="$${TEST_SSH_CONCH}" \ + TEST_SSH_IPV6="$${TEST_SSH_IPV6}" \ + TEST_SSH_ECC="$${TEST_SSH_ECC}" \ + TEST_SSH_SHA256="$${TEST_SSH_SHA256}" \ + 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 <survey + +package: $(CONFIGFILES) $(MANPAGES) $(TARGETS) + if [ "@MAKE_PACKAGE_SUPPORTED@" = yes ]; then \ + sh buildpkg.sh; \ + fi +
diff --git a/openssh-6.0p1/OVERVIEW b/openssh-6.0p1/OVERVIEW new file mode 100644 index 0000000..2e1cc0b --- /dev/null +++ b/openssh-6.0p1/OVERVIEW
@@ -0,0 +1,168 @@ +[Note: This file has not been updated for OpenSSH versions after +OpenSSH-1.2 and should be considered OBSOLETE. It has been left in +the distribution because some of its information may still be useful +to developers.] + +This document is intended for those who wish to read the ssh source +code. This tries to give an overview of the structure of the code. + +Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi> +Updated 17 Nov 1995. +Updated 19 Oct 1999 for OpenSSH-1.2 +Updated 20 May 2001 note obsolete for > OpenSSH-1.2 + +The software consists of ssh (client), sshd (server), scp, sdist, and +the auxiliary programs ssh-keygen, ssh-agent, ssh-add, and +make-ssh-known-hosts. The main program for each of these is in a .c +file with the same name. + +There are some subsystems/abstractions that are used by a number of +these programs. + + Buffer manipulation routines + + - These provide an arbitrary size buffer, where data can be appended. + Data can be consumed from either end. The code is used heavily + throughout ssh. The basic buffer manipulation functions are in + buffer.c (header buffer.h), and additional code to manipulate specific + data types is in bufaux.c. + + Compression Library + + - Ssh uses the GNU GZIP compression library (ZLIB). + + Encryption/Decryption + + - Ssh contains several encryption algorithms. These are all + accessed through the cipher.h interface. The interface code is + in cipher.c, and the implementations are in libc. + + Multiple Precision Integer Library + + - Uses the SSLeay BIGNUM sublibrary. + + Random Numbers + + - Uses arc4random() and such. + + RSA key generation, encryption, decryption + + - Ssh uses the RSA routines in libssl. + + RSA key files + + - RSA keys are stored in files with a special format. The code to + read/write these files is in authfile.c. The files are normally + encrypted with a passphrase. The functions to read passphrases + are in readpass.c (the same code is used to read passwords). + + Binary packet protocol + + - The ssh binary packet protocol is implemented in packet.c. The + code in packet.c does not concern itself with packet types or their + execution; it contains code to build packets, to receive them and + extract data from them, and the code to compress and/or encrypt + packets. CRC code comes from crc32.c. + + - The code in packet.c calls the buffer manipulation routines + (buffer.c, bufaux.c), compression routines (compress.c, zlib), + and the encryption routines. + + X11, TCP/IP, and Agent forwarding + + - Code for various types of channel forwarding is in channels.c. + The file defines a generic framework for arbitrary communication + channels inside the secure channel, and uses this framework to + implement X11 forwarding, TCP/IP forwarding, and authentication + agent forwarding. + The new, Protocol 1.5, channel close implementation is in nchan.c + + Authentication agent + + - Code to communicate with the authentication agent is in authfd.c. + + Authentication methods + + - Code for various authentication methods resides in auth-*.c + (auth-passwd.c, auth-rh-rsa.c, auth-rhosts.c, auth-rsa.c). This + code is linked into the server. The routines also manipulate + known hosts files using code in hostfile.c. Code in canohost.c + is used to retrieve the canonical host name of the remote host. + Code in match.c is used to match host names. + + - In the client end, authentication code is in sshconnect.c. It + reads Passwords/passphrases using code in readpass.c. It reads + RSA key files with authfile.c. It communicates the + authentication agent using authfd.c. + + The ssh client + + - The client main program is in ssh.c. It first parses arguments + and reads configuration (readconf.c), then calls ssh_connect (in + sshconnect.c) to open a connection to the server (possibly via a + proxy), and performs authentication (ssh_login in sshconnect.c). + It then makes any pty, forwarding, etc. requests. It may call + code in ttymodes.c to encode current tty modes. Finally it + calls client_loop in clientloop.c. This does the real work for + the session. + + - The client is suid root. It tries to temporarily give up this + rights while reading the configuration data. The root + privileges are only used to make the connection (from a + privileged socket). Any extra privileges are dropped before + calling ssh_login. + + Pseudo-tty manipulation and tty modes + + - Code to allocate and use a pseudo tty is in pty.c. Code to + encode and set terminal modes is in ttymodes.c. + + Logging in (updating utmp, lastlog, etc.) + + - The code to do things that are done when a user logs in are in + login.c. This includes things such as updating the utmp, wtmp, + and lastlog files. Some of the code is in sshd.c. + + Writing to the system log and terminal + + - The programs use the functions fatal(), log(), debug(), error() + in many places to write messages to system log or user's + terminal. The implementation that logs to system log is in + log-server.c; it is used in the server program. The other + programs use an implementation that sends output to stderr; it + is in log-client.c. The definitions are in ssh.h. + + The sshd server (daemon) + + - The sshd daemon starts by processing arguments and reading the + configuration file (servconf.c). It then reads the host key, + starts listening for connections, and generates the server key. + The server key will be regenerated every hour by an alarm. + + - When the server receives a connection, it forks, disables the + regeneration alarm, and starts communicating with the client. + They first perform identification string exchange, then + negotiate encryption, then perform authentication, preparatory + operations, and finally the server enters the normal session + mode by calling server_loop in serverloop.c. This does the real + work, calling functions in other modules. + + - The code for the server is in sshd.c. It contains a lot of + stuff, including: + - server main program + - waiting for connections + - processing new connection + - authentication + - preparatory operations + - building up the execution environment for the user program + - starting the user program. + + Auxiliary files + + - There are several other files in the distribution that contain + various auxiliary routines: + ssh.h the main header file for ssh (various definitions) + uidswap.c uid-swapping + xmalloc.c "safe" malloc routines + +$OpenBSD: OVERVIEW,v 1.11 2006/08/03 03:34:41 deraadt Exp $
diff --git a/openssh-6.0p1/PROTOCOL b/openssh-6.0p1/PROTOCOL new file mode 100644 index 0000000..c281960 --- /dev/null +++ b/openssh-6.0p1/PROTOCOL
@@ -0,0 +1,294 @@ +This documents OpenSSH's deviations and extensions to the published SSH +protocol. + +Note that OpenSSH's sftp and sftp-server implement revision 3 of the SSH +filexfer protocol described in: + +http://www.openssh.com/txt/draft-ietf-secsh-filexfer-02.txt + +Newer versions of the draft will not be supported, though some features +are individually implemented as extensions described below. + +The protocol used by OpenSSH's ssh-agent is described in the file +PROTOCOL.agent + +1. Transport protocol changes + +1.1. transport: Protocol 2 MAC algorithm "umac-64@openssh.com" + +This is a new transport-layer MAC method using the UMAC algorithm +(rfc4418). This method is identical to the "umac-64" method documented +in: + +http://www.openssh.com/txt/draft-miller-secsh-umac-01.txt + +1.2. transport: Protocol 2 compression algorithm "zlib@openssh.com" + +This transport-layer compression method uses the zlib compression +algorithm (identical to the "zlib" method in rfc4253), but delays the +start of compression until after authentication has completed. This +avoids exposing compression code to attacks from unauthenticated users. + +The method is documented in: + +http://www.openssh.com/txt/draft-miller-secsh-compression-delayed-00.txt + +1.3. transport: New public key algorithms "ssh-rsa-cert-v00@openssh.com", + "ssh-dsa-cert-v00@openssh.com", + "ecdsa-sha2-nistp256-cert-v01@openssh.com", + "ecdsa-sha2-nistp384-cert-v01@openssh.com" and + "ecdsa-sha2-nistp521-cert-v01@openssh.com" + +OpenSSH introduces new public key algorithms to support certificate +authentication for users and hostkeys. 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. + +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. + +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". + +$OpenBSD: PROTOCOL,v 1.17 2010/12/04 00:18:01 djm Exp $
diff --git a/openssh-6.0p1/PROTOCOL.agent b/openssh-6.0p1/PROTOCOL.agent new file mode 100644 index 0000000..de94d03 --- /dev/null +++ b/openssh-6.0p1/PROTOCOL.agent
@@ -0,0 +1,560 @@ +This 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_IDENTITY. + +The agent will reply with a SSH_AGENT_SUCCESS if the key has been +successfully added or a SSH_AGENT_FAILURE if an error occurred. + +2.2.3 Add protocol 2 key + +The OpenSSH agent supports DSA, ECDSA and RSA keys for protocol 2. DSA +keys may be added using the following request + + byte SSH2_AGENTC_ADD_IDENTITY or + SSH2_AGENTC_ADD_ID_CONSTRAINED + string "ssh-dss" + mpint dsa_p + mpint dsa_q + mpint dsa_g + mpint dsa_public_key + mpint dsa_private_key + string key_comment + constraint[] key_constraints + +DSA certificates may be added with: + byte SSH2_AGENTC_ADD_IDENTITY or + SSH2_AGENTC_ADD_ID_CONSTRAINED + string "ssh-dss-cert-v00@openssh.com" + string certificate + mpint dsa_private_key + string key_comment + constraint[] key_constraints + +ECDSA keys may be added using the following request + + byte SSH2_AGENTC_ADD_IDENTITY or + SSH2_AGENTC_ADD_ID_CONSTRAINED + string "ecdsa-sha2-nistp256" | + "ecdsa-sha2-nistp384" | + "ecdsa-sha2-nistp521" + string ecdsa_curve_name + string ecdsa_public_key + mpint ecdsa_private + string key_comment + constraint[] key_constraints + +ECDSA certificates may be added with: + byte SSH2_AGENTC_ADD_IDENTITY or + SSH2_AGENTC_ADD_ID_CONSTRAINED + string "ecdsa-sha2-nistp256-cert-v01@openssh.com" | + "ecdsa-sha2-nistp384-cert-v01@openssh.com" | + "ecdsa-sha2-nistp521-cert-v01@openssh.com" + string certificate + mpint ecdsa_private_key + string key_comment + constraint[] key_constraints + +RSA keys may be added with this request: + + byte SSH2_AGENTC_ADD_IDENTITY or + SSH2_AGENTC_ADD_ID_CONSTRAINED + string "ssh-rsa" + mpint rsa_n + mpint rsa_e + mpint rsa_d + mpint rsa_iqmp + mpint rsa_p + mpint rsa_q + string key_comment + constraint[] key_constraints + +RSA certificates may be added with this request: + + byte SSH2_AGENTC_ADD_IDENTITY or + SSH2_AGENTC_ADD_ID_CONSTRAINED + string "ssh-rsa-cert-v00@openssh.com" + string certificate + mpint rsa_d + mpint rsa_iqmp + mpint rsa_p + mpint rsa_q + string key_comment + constraint[] key_constraints + +Note that the 'rsa_p' and 'rsa_q' parameters are sent in the reverse +order to the protocol 1 add keys message. As with the corresponding +protocol 1 "add key" request, the private key is overspecified to avoid +redundant processing. + +For DSA, ECDSA and RSA key add requests, "key_constraints" may only be +present if the request type is SSH2_AGENTC_ADD_ID_CONSTRAINED. + +The agent will reply with a SSH_AGENT_SUCCESS if the key has been +successfully added or a SSH_AGENT_FAILURE if an error occurred. + +2.2.4 Loading keys from a smartcard + +The OpenSSH agent may have optional smartcard support built in to it. If +so, it supports an operation to load keys from a smartcard. Technically, +only the public components of the keys are loaded into the agent so +this operation really arranges for future private key operations to be +delegated to the smartcard. + + byte SSH_AGENTC_ADD_SMARTCARD_KEY or + SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED + string reader_id + string pin + constraint[] key_constraints + +"reader_id" is an identifier to a smartcard reader and "pin" +is a PIN or passphrase used to unlock the private key(s) on the +device. "key_constraints" may only be present if the request type is +SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED. + +This operation may load all SSH keys that are unlocked using the +"pin" on the specified reader. The type of key loaded (protocol 1 +or protocol 2) will be specified by the smartcard itself, it is not +client-specified. + +The agent will reply with a SSH_AGENT_SUCCESS if one or more keys have +been successfully loaded or a SSH_AGENT_FAILURE if an error occurred. +The agent will also return SSH_AGENT_FAILURE if it does not support +smartcards. + +2.3 Removing multiple keys + +A client may request that an agent delete all protocol 1 keys using the +following request: + + byte SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES + +This message requests the deletion of all protocol 2 keys: + + byte SSH2_AGENTC_REMOVE_ALL_IDENTITIES + +On success, the agent will delete all keys of the requested type and +reply with a SSH_AGENT_SUCCESS message. If an error occurred, the agent +will reply with SSH_AGENT_FAILURE. + +Note that, to delete all keys (both protocol 1 and 2), a client +must send both a SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES and a +SSH2_AGENTC_REMOVE_ALL_IDENTITIES request. + +2.4 Removing specific keys + +2.4.1 Removing a protocol 1 key + +Removal of a protocol 1 key may be requested with the following message: + + byte SSH_AGENTC_REMOVE_RSA_IDENTITY + uint32 key_bits + mpint1 rsa_e + mpint1 rsa_n + +Note that key_bits is strictly redundant, as it may be inferred by the +length of rsa_n. + +The agent will delete any private key matching the specified public key +and return SSH_AGENT_SUCCESS. If no such key was found, the agent will +return SSH_AGENT_FAILURE. + +2.4.2 Removing a protocol 2 key + +Protocol 2 keys may be removed with the following request: + + byte SSH2_AGENTC_REMOVE_IDENTITY + string key_blob + +Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key +Algorithms" for any of the supported protocol 2 key types. + +The agent will delete any private key matching the specified public key +and return SSH_AGENT_SUCCESS. If no such key was found, the agent will +return SSH_AGENT_FAILURE. + +2.4.3 Removing keys loaded from a smartcard + +A client may request that a server remove one or more smartcard-hosted +keys using this message: + + byte SSH_AGENTC_REMOVE_SMARTCARD_KEY + string reader_id + string pin + +"reader_id" the an identifier to a smartcard reader and "pin" is a PIN +or passphrase used to unlock the private key(s) on the device. + +When this message is received, and if the agent supports +smartcard-hosted keys, it will delete all keys that are hosted on the +specified smartcard that may be accessed with the given "pin". + +The agent will reply with a SSH_AGENT_SUCCESS if one or more keys have +been successfully removed or a SSH_AGENT_FAILURE if an error occurred. +The agent will also return SSH_AGENT_FAILURE if it does not support +smartcards. + +2.5 Requesting a list of known keys + +An agent may be requested to list which keys it holds. Different +requests exist for protocol 1 and protocol 2 keys. + +2.5.1 Requesting a list of protocol 1 keys + +To request a list of protocol 1 keys that are held in the agent, a +client may send the following message: + + byte SSH_AGENTC_REQUEST_RSA_IDENTITIES + +The agent will reply with the following message: + + byte SSH_AGENT_RSA_IDENTITIES_ANSWER + uint32 num_keys + +Followed by zero or more consecutive keys, encoded as: + + uint32 bits + mpint1 rsa_e + mpint1 rsa_n + string key_comment + +2.5.2 Requesting a list of protocol 2 keys + +A client may send the following message to request a list of +protocol 2 keys that are stored in the agent: + + byte SSH2_AGENTC_REQUEST_IDENTITIES + +The agent will reply with the following message header: + + byte SSH2_AGENT_IDENTITIES_ANSWER + uint32 num_keys + +Followed by zero or more consecutive keys, encoded as: + + string key_blob + string key_comment + +Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key +Algorithms" for any of the supported protocol 2 key types. + +2.6 Private key operations + +The purpose of the agent is to perform private key operations, such as +signing and encryption without requiring a passphrase to unlock the +key and without allowing the private key itself to be exposed. There +are separate requests for the protocol 1 and protocol 2 private key +operations. + +2.6.1 Protocol 1 private key challenge + +The private key operation used in version 1 of the SSH protocol is +decrypting a challenge that has been encrypted with a public key. +It may be requested using this message: + + byte SSH_AGENTC_RSA_CHALLENGE + uint32 ignored + mpint1 rsa_e + mpint1 rsa_n + mpint1 encrypted_challenge + byte[16] session_id + uint32 response_type /* must be 1 */ + +"rsa_e" and "rsa_n" are used to identify which private key to use. +"encrypted_challenge" is a challenge blob that has (presumably) +been encrypted with the public key and must be in the range +1 <= encrypted_challenge < 2^256. "session_id" is the SSH protocol 1 +session ID (computed from the server host key, the server semi-ephemeral +key and the session cookie). + +"ignored" and "response_type" exist for compatibility with legacy +implementations. "response_type" must be equal to 1; other response +types are not supported. + +On receiving this request, the server decrypts the "encrypted_challenge" +using the private key matching the supplied (rsa_e, rsa_n) values. For +the response derivation, the decrypted challenge is represented as an +unsigned, big-endian integer encoded in a 32 byte buffer (i.e. values +smaller than 2^248 will have leading 0 bytes). + +The response value is then calculated as: + + response = MD5(decrypted_challenge || session_id) + +and returned in the following message + + byte SSH_AGENT_RSA_RESPONSE + byte[16] response + +If the agent cannot find the key specified by the supplied (rsa_e, +rsa_n) then it will return SSH_AGENT_FAILURE. + +2.6.2 Protocol 2 private key signature request + +A client may use the following message to request signing of data using +a protocol 2 key: + + byte SSH2_AGENTC_SIGN_REQUEST + string key_blob + string data + uint32 flags + +Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key +Algorithms" for any of the supported protocol 2 key types. "flags" is +a bit-mask, but at present only one possible value is defined (see below +for its meaning): + + SSH_AGENT_OLD_SIGNATURE 1 + +Upon receiving this request, the agent will look up the private key that +corresponds to the public key contained in key_blob. It will use this +private key to sign the "data" and produce a signature blob using the +key type-specific method described in RFC 4253 section 6.6 "Public Key +Algorithms". + +An exception to this is for "ssh-dss" keys where the "flags" word +contains the value SSH_AGENT_OLD_SIGNATURE. In this case, a legacy +signature encoding is used in lieu of the standard one. In this case, +the DSA signature blob is encoded as: + + byte[40] signature + +The signature will be returned in the response message: + + byte SSH2_AGENT_SIGN_RESPONSE + string signature_blob + +If the agent cannot find the key specified by the supplied key_blob then +it will return SSH_AGENT_FAILURE. + +2.7 Locking or unlocking an agent + +The agent supports temporary locking with a passphrase to suspend +processing of sensitive operations until it has been unlocked with the +same passphrase. To lock an agent, a client send the following request: + + byte SSH_AGENTC_LOCK + string passphrase + +Upon receipt of this message and if the agent is not already locked, +it will suspend processing requests and return a SSH_AGENT_SUCCESS +reply. If the agent is already locked, it will return SSH_AGENT_FAILURE. + +While locked, the agent will refuse all requests except +SSH_AGENTC_UNLOCK, SSH_AGENTC_REQUEST_RSA_IDENTITIES and +SSH2_AGENTC_REQUEST_IDENTITIES. The "request identities" requests are +treated specially by a locked agent: it will always return an empty list +of keys. + +To unlock an agent, a client may request: + + byte SSH_AGENTC_UNLOCK + string passphrase + +If the passphrase matches and the agent is locked, then it will resume +processing all requests and return SSH_AGENT_SUCCESS. If the agent +is not locked or the passphrase does not match then it will return +SSH_AGENT_FAILURE. + +Locking and unlocking affects both protocol 1 and protocol 2 keys. + +3. Protocol message numbers + +3.1 Requests from client to agent for protocol 1 key operations + + SSH_AGENTC_REQUEST_RSA_IDENTITIES 1 + SSH_AGENTC_RSA_CHALLENGE 3 + SSH_AGENTC_ADD_RSA_IDENTITY 7 + SSH_AGENTC_REMOVE_RSA_IDENTITY 8 + SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES 9 + SSH_AGENTC_ADD_RSA_ID_CONSTRAINED 24 + +3.2 Requests from client to agent for protocol 2 key operations + + SSH2_AGENTC_REQUEST_IDENTITIES 11 + SSH2_AGENTC_SIGN_REQUEST 13 + SSH2_AGENTC_ADD_IDENTITY 17 + SSH2_AGENTC_REMOVE_IDENTITY 18 + SSH2_AGENTC_REMOVE_ALL_IDENTITIES 19 + SSH2_AGENTC_ADD_ID_CONSTRAINED 25 + +3.3 Key-type independent requests from client to agent + + SSH_AGENTC_ADD_SMARTCARD_KEY 20 + SSH_AGENTC_REMOVE_SMARTCARD_KEY 21 + SSH_AGENTC_LOCK 22 + SSH_AGENTC_UNLOCK 23 + SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED 26 + +3.4 Generic replies from agent to client + + SSH_AGENT_FAILURE 5 + SSH_AGENT_SUCCESS 6 + +3.5 Replies from agent to client for protocol 1 key operations + + SSH_AGENT_RSA_IDENTITIES_ANSWER 2 + SSH_AGENT_RSA_RESPONSE 4 + +3.6 Replies from agent to client for protocol 2 key operations + + SSH2_AGENT_IDENTITIES_ANSWER 12 + SSH2_AGENT_SIGN_RESPONSE 14 + +3.7 Key constraint identifiers + + SSH_AGENT_CONSTRAIN_LIFETIME 1 + SSH_AGENT_CONSTRAIN_CONFIRM 2 + +$OpenBSD: PROTOCOL.agent,v 1.6 2010/08/31 11:54:45 djm Exp $
diff --git a/openssh-6.0p1/PROTOCOL.certkeys b/openssh-6.0p1/PROTOCOL.certkeys new file mode 100644 index 0000000..2f97649 --- /dev/null +++ b/openssh-6.0p1/PROTOCOL.certkeys
@@ -0,0 +1,256 @@ +This document describes a simple public-key certificate authentication +system for use by SSH. + +Background +---------- + +The SSH protocol currently supports a simple public key authentication +mechanism. Unlike other public key implementations, SSH eschews the use +of X.509 certificates and uses raw keys. This approach has some benefits +relating to simplicity of configuration and minimisation of attack +surface, but it does not support the important use-cases of centrally +managed, passwordless authentication and centrally certified host keys. + +These protocol extensions build on the simple public key authentication +system already in SSH to allow certificate-based authentication. The +certificates used are not traditional X.509 certificates, with numerous +options and complex encoding rules, but something rather more minimal: a +key, some identity information and usage options that have been signed +with some other trusted key. + +A sshd server may be configured to allow authentication via certified +keys, by extending the existing ~/.ssh/authorized_keys mechanism to +allow specification of certification authority keys in addition to +raw user keys. The ssh client will support automatic verification of +acceptance of certified host keys, by adding a similar ability to +specify CA keys in ~/.ssh/known_hosts. + +Certified keys are represented using new key types: + + ssh-rsa-cert-v01@openssh.com + ssh-dss-cert-v01@openssh.com + ecdsa-sha2-nistp256-cert-v01@openssh.com + ecdsa-sha2-nistp384-cert-v01@openssh.com + ecdsa-sha2-nistp521-cert-v01@openssh.com + +These include certification information along with the public key +that is used to sign challenges. ssh-keygen performs the CA signing +operation. + +Protocol extensions +------------------- + +The SSH wire protocol includes several extensibility mechanisms. +These modifications shall take advantage of namespaced public key +algorithm names to add support for certificate authentication without +breaking the protocol - implementations that do not support the +extensions will simply ignore them. + +Authentication using the new key formats described below proceeds +using the existing SSH "publickey" authentication method described +in RFC4252 section 7. + +New public key formats +---------------------- + +The certificate key types take a similar high-level format (note: data +types and encoding are as per RFC4251 section 5). The serialised wire +encoding of these certificates is also used for storing them on disk. + +#define SSH_CERT_TYPE_USER 1 +#define SSH_CERT_TYPE_HOST 2 + +RSA certificate + + string "ssh-rsa-cert-v01@openssh.com" + string nonce + mpint e + mpint n + uint64 serial + uint32 type + string key id + string valid principals + uint64 valid after + uint64 valid before + string critical options + string extensions + string reserved + string signature key + string signature + +DSA certificate + + string "ssh-dss-cert-v01@openssh.com" + string nonce + mpint p + mpint q + mpint g + mpint y + uint64 serial + uint32 type + string key id + string valid principals + uint64 valid after + uint64 valid before + string critical options + string extensions + string reserved + string signature key + string signature + +ECDSA certificate + + string "ecdsa-sha2-nistp256@openssh.com" | + "ecdsa-sha2-nistp384@openssh.com" | + "ecdsa-sha2-nistp521@openssh.com" + string nonce + string curve + string public_key + uint64 serial + uint32 type + string key id + string valid principals + uint64 valid after + uint64 valid before + string critical options + string extensions + string reserved + string signature key + string signature + +The nonce field is a CA-provided random bitstring of arbitrary length +(but typically 16 or 32 bytes) included to make attacks that depend on +inducing collisions in the signature hash infeasible. + +e and n are the RSA exponent and public modulus respectively. + +p, q, g, y are the DSA parameters as described in FIPS-186-2. + +curve and public key are respectively the ECDSA "[identifier]" and "Q" +defined in section 3.1 of RFC5656. + +serial is an optional certificate serial number set by the CA to +provide an abbreviated way to refer to certificates from that CA. +If a CA does not wish to number its certificates it must set this +field to zero. + +type specifies whether this certificate is for identification of a user +or a host using a SSH_CERT_TYPE_... value. + +key id is a free-form text field that is filled in by the CA at the time +of signing; the intention is that the contents of this field are used to +identify the identity principal in log messages. + +"valid principals" is a string containing zero or more principals as +strings packed inside it. These principals list the names for which this +certificate is valid; hostnames for SSH_CERT_TYPE_HOST certificates and +usernames for SSH_CERT_TYPE_USER certificates. As a special case, a +zero-length "valid principals" field means the certificate is valid for +any principal of the specified type. XXX DNS wildcards? + +"valid after" and "valid before" specify a validity period for the +certificate. Each represents a time in seconds since 1970-01-01 +00:00:00. A certificate is considered valid if: + + valid after <= current time < valid before + +criticial options is a set of zero or more key options encoded as +below. All such options are "critical" in the sense that an implementation +must refuse to authorise a key that has an unrecognised option. + +extensions is a set of zero or more optional extensions. These extensions +are not critical, and an implementation that encounters one that it does +not recognise may safely ignore it. + +The reserved field is currently unused and is ignored in this version of +the protocol. + +signature key contains the CA key used to sign the certificate. +The valid key types for CA keys are ssh-rsa, ssh-dss and the ECDSA types +ecdsa-sha2-nistp256, ecdsa-sha2-nistp384, ecdsa-sha2-nistp521. "Chained" +certificates, where the signature key type is a certificate type itself +are NOT supported. Note that it is possible for a RSA certificate key to +be signed by a DSS or ECDSA CA key and vice-versa. + +signature is computed over all preceding fields from the initial string +up to, and including the signature key. Signatures are computed and +encoded according to the rules defined for the CA's public key algorithm +(RFC4253 section 6.6 for ssh-rsa and ssh-dss, RFC5656 for the ECDSA +types). + +Critical options +---------------- + +The critical options section of the certificate specifies zero or more +options on the certificates validity. The format of this field +is a sequence of zero or more tuples: + + string name + string data + +Options must be lexically ordered by "name" if they appear in the +sequence. + +The name field identifies the option and the data field encodes +option-specific information (see below). All options are +"critical", if an implementation does not recognise a option +then the validating party should refuse to accept the certificate. + +The supported options and the contents and structure of their +data fields are: + +Name Format Description +----------------------------------------------------------------------------- +force-command string Specifies a command that is executed + (replacing any the user specified on the + ssh command-line) whenever this key is + used for authentication. + +source-address string Comma-separated list of source addresses + from which this certificate is accepted + for authentication. Addresses are + specified in CIDR format (nn.nn.nn.nn/nn + or hhhh::hhhh/nn). + If this option is not present then + certificates may be presented from any + source address. + +Extensions +---------- + +The extensions section of the certificate specifies zero or more +non-critical certificate extensions. The encoding and ordering of +extensions in this field is identical to that of the critical options. +If an implementation does not recognise an extension, then it should +ignore it. + +The supported extensions and the contents and structure of their data +fields are: + +Name Format Description +----------------------------------------------------------------------------- +permit-X11-forwarding empty Flag indicating that X11 forwarding + should be permitted. X11 forwarding will + be refused if this option is absent. + +permit-agent-forwarding empty Flag indicating that agent forwarding + should be allowed. Agent forwarding + must not be permitted unless this + option is present. + +permit-port-forwarding empty Flag indicating that port-forwarding + should be allowed. If this option is + not present then no port forwarding will + be allowed. + +permit-pty empty Flag indicating that PTY allocation + should be permitted. In the absence of + this option PTY allocation will be + disabled. + +permit-user-rc empty Flag indicating that execution of + ~/.ssh/rc should be permitted. Execution + of this script will not be permitted if + this option is not present. + +$OpenBSD: PROTOCOL.certkeys,v 1.8 2010/08/31 11:54:45 djm Exp $
diff --git a/openssh-6.0p1/PROTOCOL.mux b/openssh-6.0p1/PROTOCOL.mux new file mode 100644 index 0000000..49cbe5b --- /dev/null +++ b/openssh-6.0p1/PROTOCOL.mux
@@ -0,0 +1,222 @@ +This 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 + string listen port + string connect host + string connect port + +forwarding type may be MUX_FWD_LOCAL, MUX_FWD_REMOTE, MUX_FWD_DYNAMIC. + +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 + string listen port + string connect host + string 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.8 2011/09/09 00:44:07 djm Exp $
diff --git a/openssh-6.0p1/README b/openssh-6.0p1/README new file mode 100644 index 0000000..ad2adc4 --- /dev/null +++ b/openssh-6.0p1/README
@@ -0,0 +1,65 @@ +See http://www.openssh.com/txt/release-6.0 for the release notes. + +- A Japanese translation of this document and of the OpenSSH FAQ is +- available at http://www.unixuser.org/~haruyama/security/openssh/index.html +- Thanks to HARUYAMA Seigo <haruyama@unixuser.org> + +This is the port of OpenBSD's excellent OpenSSH[0] to Linux and other +Unices. + +OpenSSH is based on the last free version of Tatu Ylonen's sample +implementation with all patent-encumbered algorithms removed (to +external libraries), all known security bugs fixed, new features +reintroduced and many other clean-ups. OpenSSH has been created by +Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo de Raadt, +and Dug Song. It has a homepage at http://www.openssh.com/ + +This port consists of the re-introduction of autoconf support, PAM +support, EGD[1]/PRNGD[2] support and replacements for OpenBSD library +functions that are (regrettably) absent from other unices. This port +has been best tested on AIX, Cygwin, HP-UX, Linux, MacOS/X, +NetBSD, OpenBSD, OpenServer, Solaris, Unicos, and UnixWare. + +This version actively tracks changes in the OpenBSD CVS repository. + +The PAM support is now more functional than the popular packages of +commercial ssh-1.2.x. It checks "account" and "session" modules for +all logins, not just when using password authentication. + +OpenSSH depends on Zlib[3], OpenSSL[4] and optionally PAM[5]. + +There is now several mailing lists for this port of OpenSSH. Please +refer to http://www.openssh.com/list.html for details on how to join. + +Please send bug reports and patches to the mailing list +openssh-unix-dev@mindrot.org. The list is open to posting by +unsubscribed users.Code contribution are welcomed, but please follow the +OpenBSD style guidelines[6]. + +Please refer to the INSTALL document for information on how to install +OpenSSH on your system. There are a number of differences between this +port of OpenSSH and F-Secure SSH 1.x, please refer to the OpenSSH FAQ[7] +for details and general tips. + +Damien Miller <djm@mindrot.org> + +Miscellania - + +This version of OpenSSH is based upon code retrieved from the OpenBSD +CVS repository which in turn was based on the last free sample +implementation released by Tatu Ylonen. + +References - + +[0] http://www.openssh.com/faq.html +[1] http://www.lothar.com/tech/crypto/ +[2] http://www.aet.tu-cottbus.de/personen/jaenicke/postfix_tls/prngd.html +[3] http://www.gzip.org/zlib/ +[4] http://www.openssl.org/ +[5] http://www.openpam.org + http://www.kernel.org/pub/linux/libs/pam/ + (PAM also is standard on Solaris and HP-UX 11) +[6] http://www.openbsd.org/cgi-bin/man.cgi?query=style&sektion=9 +[7] http://www.openssh.com/faq.html + +$Id: README,v 1.80 2012/04/20 04:11:04 djm Exp $
diff --git a/openssh-6.0p1/README.dns b/openssh-6.0p1/README.dns new file mode 100644 index 0000000..9787918 --- /dev/null +++ b/openssh-6.0p1/README.dns
@@ -0,0 +1,47 @@ +How to verify host keys using OpenSSH and DNS +--------------------------------------------- + +OpenSSH contains support for verifying host keys using DNS as described in +draft-ietf-secsh-dns-05.txt. The document contains very brief instructions +on how to use this feature. Configuring DNS is out of the scope of this +document. + + +(1) Server: Generate and publish the DNS RR + +To create a DNS resource record (RR) containing a fingerprint of the +public host key, use the following command: + + ssh-keygen -r hostname -f keyfile -g + +where "hostname" is your fully qualified hostname and "keyfile" is the +file containing the public host key file. If you have multiple keys, +you should generate one RR for each key. + +In the example above, ssh-keygen will print the fingerprint in a +generic DNS RR format parsable by most modern name server +implementations. If your nameserver has support for the SSHFP RR +you can omit the -g flag and ssh-keygen will print a standard SSHFP RR. + +To publish the fingerprint using the DNS you must add the generated RR +to your DNS zone file and sign your zone. + + +(2) Client: Enable ssh to verify host keys using DNS + +To enable the ssh client to verify host keys using DNS, you have to +add the following option to the ssh configuration file +($HOME/.ssh/config or /etc/ssh/ssh_config): + + VerifyHostKeyDNS yes + +Upon connection the client will try to look up the fingerprint RR +using DNS. If the fingerprint received from the DNS server matches +the remote host key, the user will be notified. + + + Jakob Schlyter + Wesley Griffin + + +$OpenBSD: README.dns,v 1.2 2003/10/14 19:43:23 jakob Exp $
diff --git a/openssh-6.0p1/README.platform b/openssh-6.0p1/README.platform new file mode 100644 index 0000000..d198232 --- /dev/null +++ b/openssh-6.0p1/README.platform
@@ -0,0 +1,96 @@ +This file contains notes about OpenSSH on specific platforms. + +AIX +--- +As of OpenSSH 3.8p1, sshd will now honour an accounts password expiry +settings, where previously it did not. Because of this, it's possible for +sites that have used OpenSSH's sshd exclusively to have accounts which +have passwords expired longer than the inactive time (ie the "Weeks between +password EXPIRATION and LOCKOUT" setting in SMIT or the maxexpired +chuser attribute). + +Accounts in this state must have their passwords reset manually by the +administrator. As a precaution, it is recommended that the administrative +passwords be reset before upgrading from OpenSSH <3.8. + +As of OpenSSH 4.0, configure will attempt to detect if your version +and maintenance level of AIX has a working getaddrinfo, and will use it +if found. This will enable IPv6 support. If for some reason configure +gets it wrong, or if you want to build binaries to work on earlier MLs +than the build host then you can add "-DBROKEN_GETADDRINFO" to CFLAGS +to force the previous IPv4-only behaviour. + +IPv6 known to work: 5.1ML7 5.2ML2 5.2ML5 +IPv6 known broken: 4.3.3ML11 5.1ML4 + +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. + + +Cygwin +------ +To build on Cygwin, OpenSSH requires the following packages: +gcc, gcc-mingw-core, mingw-runtime, binutils, make, openssl, +openssl-devel, zlib, minres, minires-devel. + + +Darwin and MacOS X +------------------ +Darwin does not provide a tun(4) driver required for OpenSSH-based +virtual private networks. The BSD manpage still exists, but the driver +has been removed in recent releases of Darwin and MacOS X. + +Nevertheless, tunnel support is known to work with Darwin 8 and +MacOS X 10.4 in Point-to-Point (Layer 3) and Ethernet (Layer 2) mode +using a third party driver. More information is available at: + http://www-user.rhrk.uni-kl.de/~nissler/tuntap/ + + +Linux +----- + +Some Linux distributions (including Red Hat/Fedora/CentOS) include +headers and library links in the -devel RPMs rather than the main +binary RPMs. If you get an error about headers, or complaining about a +missing prerequisite then you may need to install the equivalent +development packages. On Redhat based distros these may be openssl-devel, +zlib-devel and pam-devel, on Debian based distros these may be +libssl-dev, libz-dev and libpam-dev. + + +Solaris +------- +If you enable BSM auditing on Solaris, you need to update audit_event(4) +for praudit(1m) to give sensible output. The following line needs to be +added to /etc/security/audit_event: + + 32800:AUE_openssh:OpenSSH login:lo + +The BSM audit event range available for third party TCB applications is +32768 - 65535. Event number 32800 has been choosen for AUE_openssh. +There is no official registry of 3rd party event numbers, so if this +number is already in use on your system, you may change it at build time +by configure'ing --with-cflags=-DAUE_openssh=32801 then rebuilding. + + +Platforms using PAM +------------------- +As of OpenSSH 4.3p1, sshd will no longer check /etc/nologin itself when +PAM is enabled. To maintain existing behaviour, pam_nologin should be +added to sshd's session stack which will prevent users from starting shell +sessions. Alternatively, pam_nologin can be added to either the auth or +account stacks which will prevent authentication entirely, but will still +return the output from pam_nologin to the client. + + +$Id: README.platform,v 1.10 2009/08/28 23:14:48 dtucker Exp $
diff --git a/openssh-6.0p1/README.privsep b/openssh-6.0p1/README.privsep new file mode 100644 index 0000000..f565e72 --- /dev/null +++ b/openssh-6.0p1/README.privsep
@@ -0,0 +1,63 @@ +Privilege separation, or privsep, is method in OpenSSH by which +operations that require root privilege are performed by a separate +privileged monitor process. Its purpose is to prevent privilege +escalation by containing corruption to an unprivileged process. +More information is available at: + http://www.citi.umich.edu/u/provos/ssh/privsep.html + +Privilege separation is now enabled by default; see the +UsePrivilegeSeparation option in sshd_config(5). + +On systems which lack mmap or anonymous (MAP_ANON) memory mapping, +compression must be disabled in order for privilege separation to +function. + +When privsep is enabled, during the pre-authentication phase sshd will +chroot(2) to "/var/empty" and change its privileges to the "sshd" user +and its primary group. sshd is a pseudo-account that should not be +used by other daemons, and must be locked and should contain a +"nologin" or invalid shell. + +You should do something like the following to prepare the privsep +preauth environment: + + # mkdir /var/empty + # chown root:sys /var/empty + # chmod 755 /var/empty + # groupadd sshd + # useradd -g sshd -c 'sshd privsep' -d /var/empty -s /bin/false sshd + +/var/empty should not contain any files. + +configure supports the following options to change the default +privsep user and chroot directory: + + --with-privsep-path=xxx Path for privilege separation chroot + --with-privsep-user=user Specify non-privileged user for privilege separation + +Privsep requires operating system support for file descriptor passing. +Compression will be disabled on systems without a working mmap MAP_ANON. + +PAM-enabled OpenSSH is known to function with privsep on AIX, FreeBSD, +HP-UX (including Trusted Mode), Linux, NetBSD and Solaris. + +On Cygwin, Tru64 Unix, OpenServer, and Unicos only the pre-authentication +part of privsep is supported. Post-authentication privsep is disabled +automatically (so you won't see the additional process mentioned below). + +Note that for a normal interactive login with a shell, enabling privsep +will require 1 additional process per login session. + +Given the following process listing (from HP-UX): + + UID PID PPID C STIME TTY TIME COMMAND + root 1005 1 0 10:45:17 ? 0:08 /opt/openssh/sbin/sshd -u0 + root 6917 1005 0 15:19:16 ? 0:00 sshd: stevesk [priv] + stevesk 6919 6917 0 15:19:17 ? 0:03 sshd: stevesk@2 + stevesk 6921 6919 0 15:19:17 pts/2 0:00 -bash + +process 1005 is the sshd process listening for new connections. +process 6917 is the privileged monitor process, 6919 is the user owned +sshd process and 6921 is the shell process. + +$Id: README.privsep,v 1.16 2005/06/04 23:21:41 djm Exp $
diff --git a/openssh-6.0p1/README.tun b/openssh-6.0p1/README.tun new file mode 100644 index 0000000..5e1cb07 --- /dev/null +++ b/openssh-6.0p1/README.tun
@@ -0,0 +1,132 @@ +How to use OpenSSH-based virtual private networks +------------------------------------------------- + +OpenSSH contains support for VPN tunneling using the tun(4) network +tunnel pseudo-device which is available on most platforms, either for +layer 2 or 3 traffic. + +The following brief instructions on how to use this feature use +a network configuration specific to the OpenBSD operating system. + +(1) Server: Enable support for SSH tunneling + +To enable the ssh server to accept tunnel requests from the client, you +have to add the following option to the ssh server configuration file +(/etc/ssh/sshd_config): + + PermitTunnel yes + +Restart the server or send the hangup signal (SIGHUP) to let the server +reread it's configuration. + +(2) Server: Restrict client access and assign the tunnel + +The OpenSSH server simply uses the file /root/.ssh/authorized_keys to +restrict the client to connect to a specified tunnel and to +automatically start the related interface configuration command. These +settings are optional but recommended: + + tunnel="1",command="sh /etc/netstart tun1" ssh-rsa ... reyk@openbsd.org + +(3) Client: Configure the local network tunnel interface + +Use the hostname.if(5) interface-specific configuration file to set up +the network tunnel configuration with OpenBSD. For example, use the +following configuration in /etc/hostname.tun0 to set up the layer 3 +tunnel on the client: + + inet 192.168.5.1 255.255.255.252 192.168.5.2 + +OpenBSD also supports layer 2 tunneling over the tun device by adding +the link0 flag: + + inet 192.168.1.78 255.255.255.0 192.168.1.255 link0 + +Layer 2 tunnels can be used in combination with an Ethernet bridge(4) +interface, like the following example for /etc/bridgename.bridge0: + + add tun0 + add sis0 + up + +(4) Client: Configure the OpenSSH client + +To establish tunnel forwarding for connections to a specified +remote host by default, use the following ssh client configuration for +the privileged user (in /root/.ssh/config): + + Host sshgateway + Tunnel yes + TunnelDevice 0:any + PermitLocalCommand yes + LocalCommand sh /etc/netstart tun0 + +A more complicated configuration is possible to establish a tunnel to +a remote host which is not directly accessible by the client. +The following example describes a client configuration to connect to +the remote host over two ssh hops in between. It uses the OpenSSH +ProxyCommand in combination with the nc(1) program to forward the final +ssh tunnel destination over multiple ssh sessions. + + Host access.somewhere.net + User puffy + Host dmzgw + User puffy + ProxyCommand ssh access.somewhere.net nc dmzgw 22 + Host sshgateway + Tunnel Ethernet + TunnelDevice 0:any + PermitLocalCommand yes + LocalCommand sh /etc/netstart tun0 + ProxyCommand ssh dmzgw nc sshgateway 22 + +The following network plan illustrates the previous configuration in +combination with layer 2 tunneling and Ethernet bridging. + ++--------+ ( ) +----------------------+ +| Client |------( Internet )-----| access.somewhere.net | ++--------+ ( ) +----------------------+ + : 192.168.1.78 | + :............................. +-------+ + Forwarded ssh connection : | dmzgw | + Layer 2 tunnel : +-------+ + : | + : | + : +------------+ + :......| sshgateway | + | +------------+ +--- real connection Bridge -> | +----------+ +... "virtual connection" [ X ]--------| somehost | +[X] switch +----------+ + 192.168.1.25 + +(5) Client: Connect to the server and establish the tunnel + +Finally connect to the OpenSSH server to establish the tunnel by using +the following command: + + ssh sshgateway + +It is also possible to tell the client to fork into the background after +the connection has been successfully established: + + ssh -f sshgateway true + +Without the ssh configuration done in step (4), it is also possible +to use the following command lines: + + ssh -fw 0:1 sshgateway true + ifconfig tun0 192.168.5.1 192.168.5.2 netmask 255.255.255.252 + +Using OpenSSH tunnel forwarding is a simple way to establish secure +and ad hoc virtual private networks. Possible fields of application +could be wireless networks or administrative VPN tunnels. + +Nevertheless, ssh tunneling requires some packet header overhead and +runs on top of TCP. It is still suggested to use the IP Security +Protocol (IPSec) for robust and permanent VPN connections and to +interconnect corporate networks. + + Reyk Floeter + +$OpenBSD: README.tun,v 1.4 2006/03/28 00:12:31 deraadt Exp $
diff --git a/openssh-6.0p1/TODO b/openssh-6.0p1/TODO new file mode 100644 index 0000000..e8aaa4b --- /dev/null +++ b/openssh-6.0p1/TODO
@@ -0,0 +1,86 @@ +Documentation: + +- Update the docs + - Update README + - Update INSTALL + - Merge INSTALL & README.privsep + +- Install FAQ? + +- General FAQ on S/Key, TIS, RSA, RSA2, DSA, etc and suggestions on when it + would be best to use them. + +- Create a Documentation/ directory? + +Programming: + +- Grep for 'XXX' comments and fix + +- Link order is incorrect for some systems using Kerberos 4 and AFS. Result + is multiple inclusion of DES symbols. Holger Trapp + <holger.trapp@hrz.tu-chemnitz.de> reports that changing the configure + generated link order from: + -lresolv -lkrb -lz -lnsl -lutil -lkafs -lkrb -ldes -lcrypto + to: + -lresolv -lkrb -lz -lnsl -lutil -lcrypto -lkafs -lkrb -ldes + fixing the problem. + +- Write a test program that calls stat() to search for EGD/PRNGd socket + rather than use the (non-portable) "test -S". + +- More platforms for for setproctitle() emulation (testing needed) + +- Improve PAM ChallengeResponseAuthentication + - Informational messages + - Use different PAM service name for kbdint vs regular auth (suggest from + Solar Designer) + - Ability to select which ChallengeResponseAuthentications may be used + and order to try them in e.g. "ChallengeResponseAuthentication skey, pam" + +- Complete Tru64 SIA support + - It looks like we could merge it into the password auth code to cut down + on diff size. Maybe PAM password auth too? + +- Finish integrating kernel-level auditing code for IRIX and SOLARIS + (Gilbert.r.loomis@saic.com) + +- 64-bit builds on HP-UX 11.X (stevesk@pobox.com): + - utmp/wtmp get corrupted (something in loginrec?) + - can't build with PAM (no 64-bit libpam yet) + +Clean up configure/makefiles: +- Clean up configure.ac - There are a few double #defined variables + left to do. HAVE_LOGIN is one of them. Consider NOT looking for + information in wtmpx or utmpx or any of that stuff if it's not detected + from the start + +- Replace the whole u_intXX_t evilness in acconfig.h with something better??? + - Do it in configure.ac + +- Consider splitting the u_intXX_t test for sys/bitype.h into seperate test + to allow people to (right/wrongfully) link against Bind directly. + +- Consider splitting configure.ac into seperate files which do logically + similar tests. E.g move all the type detection stuff into one file, + entropy related stuff into another. + +Packaging: +- HP-UX: Provide DEPOT package scripts. + (gilbert.r.loomis@saic.com) + +PrivSep Issues: +- mmap() issues. + + /dev/zero solution (Solaris) + + No/broken MAP_ANON (Irix) + + broken /dev/zero parse (Linux) +- PAM + + See above PAM notes +- AIX + + usrinfo() does not set TTY, but only required for legacy systems. Works + with PrivSep. +- OSF + + SIA is broken +- Cygwin + + Privsep for Pre-auth only (no fd passing) + +$Id: TODO,v 1.58 2004/12/06 11:40:11 dtucker Exp $
diff --git a/openssh-6.0p1/aclocal.m4 b/openssh-6.0p1/aclocal.m4 new file mode 100644 index 0000000..9bdea5e --- /dev/null +++ b/openssh-6.0p1/aclocal.m4
@@ -0,0 +1,94 @@ +dnl $Id: aclocal.m4,v 1.8 2011/05/20 01:45:25 djm Exp $ +dnl +dnl OpenSSH-specific autoconf macros +dnl + +dnl OSSH_CHECK_CFLAG_COMPILE(check_flag[, define_flag]) +dnl Check that $CC accepts a flag 'check_flag'. If it is supported append +dnl 'define_flag' to $CFLAGS. If 'define_flag' is not specified, then append +dnl 'check_flag'. +AC_DEFUN([OSSH_CHECK_CFLAG_COMPILE], [{ + AC_MSG_CHECKING([if $CC supports $1]) + saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $1" + _define_flag="$2" + test "x$_define_flag" = "x" && _define_flag="$1" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int main(void) { return 0; }]])], + [ AC_MSG_RESULT([yes]) + CFLAGS="$saved_CFLAGS $_define_flag"], + [ AC_MSG_RESULT([no]) + CFLAGS="$saved_CFLAGS" ] + ) +}]) + + +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 <sys/types.h> + #include <sys/socket.h> + + int getpeername (int, $arg2 *, $t *); + ],[ + $t len; + getpeername(0,0,&len); + ],[ + curl_cv_socklen_t_equiv="$t" + break + ]) + done + done + + if test "x$curl_cv_socklen_t_equiv" = x; then + AC_MSG_ERROR([Cannot find a type to use in place of socklen_t]) + fi + ]) + AC_MSG_RESULT($curl_cv_socklen_t_equiv) + AC_DEFINE_UNQUOTED(socklen_t, $curl_cv_socklen_t_equiv, + [type to use in place of socklen_t if not defined])], + [#include <sys/types.h> +#include <sys/socket.h>]) +]) +
diff --git a/openssh-6.0p1/acss.c b/openssh-6.0p1/acss.c new file mode 100644 index 0000000..86e2c01 --- /dev/null +++ b/openssh-6.0p1/acss.c
@@ -0,0 +1,267 @@ +/* $Id: acss.c,v 1.4 2006/07/24 04:51:01 djm Exp $ */ +/* + * Copyright (c) 2004 The OpenBSD project + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#include <string.h> + +#include <openssl/evp.h> + +#if !defined(EVP_CTRL_SET_ACSS_MODE) && (OPENSSL_VERSION_NUMBER >= 0x00906000L) + +#include "acss.h" + +/* decryption sbox */ +static unsigned char sboxdec[] = { + 0x33, 0x73, 0x3b, 0x26, 0x63, 0x23, 0x6b, 0x76, + 0x3e, 0x7e, 0x36, 0x2b, 0x6e, 0x2e, 0x66, 0x7b, + 0xd3, 0x93, 0xdb, 0x06, 0x43, 0x03, 0x4b, 0x96, + 0xde, 0x9e, 0xd6, 0x0b, 0x4e, 0x0e, 0x46, 0x9b, + 0x57, 0x17, 0x5f, 0x82, 0xc7, 0x87, 0xcf, 0x12, + 0x5a, 0x1a, 0x52, 0x8f, 0xca, 0x8a, 0xc2, 0x1f, + 0xd9, 0x99, 0xd1, 0x00, 0x49, 0x09, 0x41, 0x90, + 0xd8, 0x98, 0xd0, 0x01, 0x48, 0x08, 0x40, 0x91, + 0x3d, 0x7d, 0x35, 0x24, 0x6d, 0x2d, 0x65, 0x74, + 0x3c, 0x7c, 0x34, 0x25, 0x6c, 0x2c, 0x64, 0x75, + 0xdd, 0x9d, 0xd5, 0x04, 0x4d, 0x0d, 0x45, 0x94, + 0xdc, 0x9c, 0xd4, 0x05, 0x4c, 0x0c, 0x44, 0x95, + 0x59, 0x19, 0x51, 0x80, 0xc9, 0x89, 0xc1, 0x10, + 0x58, 0x18, 0x50, 0x81, 0xc8, 0x88, 0xc0, 0x11, + 0xd7, 0x97, 0xdf, 0x02, 0x47, 0x07, 0x4f, 0x92, + 0xda, 0x9a, 0xd2, 0x0f, 0x4a, 0x0a, 0x42, 0x9f, + 0x53, 0x13, 0x5b, 0x86, 0xc3, 0x83, 0xcb, 0x16, + 0x5e, 0x1e, 0x56, 0x8b, 0xce, 0x8e, 0xc6, 0x1b, + 0xb3, 0xf3, 0xbb, 0xa6, 0xe3, 0xa3, 0xeb, 0xf6, + 0xbe, 0xfe, 0xb6, 0xab, 0xee, 0xae, 0xe6, 0xfb, + 0x37, 0x77, 0x3f, 0x22, 0x67, 0x27, 0x6f, 0x72, + 0x3a, 0x7a, 0x32, 0x2f, 0x6a, 0x2a, 0x62, 0x7f, + 0xb9, 0xf9, 0xb1, 0xa0, 0xe9, 0xa9, 0xe1, 0xf0, + 0xb8, 0xf8, 0xb0, 0xa1, 0xe8, 0xa8, 0xe0, 0xf1, + 0x5d, 0x1d, 0x55, 0x84, 0xcd, 0x8d, 0xc5, 0x14, + 0x5c, 0x1c, 0x54, 0x85, 0xcc, 0x8c, 0xc4, 0x15, + 0xbd, 0xfd, 0xb5, 0xa4, 0xed, 0xad, 0xe5, 0xf4, + 0xbc, 0xfc, 0xb4, 0xa5, 0xec, 0xac, 0xe4, 0xf5, + 0x39, 0x79, 0x31, 0x20, 0x69, 0x29, 0x61, 0x70, + 0x38, 0x78, 0x30, 0x21, 0x68, 0x28, 0x60, 0x71, + 0xb7, 0xf7, 0xbf, 0xa2, 0xe7, 0xa7, 0xef, 0xf2, + 0xba, 0xfa, 0xb2, 0xaf, 0xea, 0xaa, 0xe2, 0xff +}; + +/* encryption sbox */ +static unsigned char sboxenc[] = { + 0x33, 0x3b, 0x73, 0x15, 0x53, 0x5b, 0x13, 0x75, + 0x3d, 0x35, 0x7d, 0x1b, 0x5d, 0x55, 0x1d, 0x7b, + 0x67, 0x6f, 0x27, 0x81, 0xc7, 0xcf, 0x87, 0x21, + 0x69, 0x61, 0x29, 0x8f, 0xc9, 0xc1, 0x89, 0x2f, + 0xe3, 0xeb, 0xa3, 0x05, 0x43, 0x4b, 0x03, 0xa5, + 0xed, 0xe5, 0xad, 0x0b, 0x4d, 0x45, 0x0d, 0xab, + 0xea, 0xe2, 0xaa, 0x00, 0x4a, 0x42, 0x0a, 0xa0, + 0xe8, 0xe0, 0xa8, 0x02, 0x48, 0x40, 0x08, 0xa2, + 0x3e, 0x36, 0x7e, 0x14, 0x5e, 0x56, 0x1e, 0x74, + 0x3c, 0x34, 0x7c, 0x16, 0x5c, 0x54, 0x1c, 0x76, + 0x6a, 0x62, 0x2a, 0x80, 0xca, 0xc2, 0x8a, 0x20, + 0x68, 0x60, 0x28, 0x82, 0xc8, 0xc0, 0x88, 0x22, + 0xee, 0xe6, 0xae, 0x04, 0x4e, 0x46, 0x0e, 0xa4, + 0xec, 0xe4, 0xac, 0x06, 0x4c, 0x44, 0x0c, 0xa6, + 0xe7, 0xef, 0xa7, 0x01, 0x47, 0x4f, 0x07, 0xa1, + 0xe9, 0xe1, 0xa9, 0x0f, 0x49, 0x41, 0x09, 0xaf, + 0x63, 0x6b, 0x23, 0x85, 0xc3, 0xcb, 0x83, 0x25, + 0x6d, 0x65, 0x2d, 0x8b, 0xcd, 0xc5, 0x8d, 0x2b, + 0x37, 0x3f, 0x77, 0x11, 0x57, 0x5f, 0x17, 0x71, + 0x39, 0x31, 0x79, 0x1f, 0x59, 0x51, 0x19, 0x7f, + 0xb3, 0xbb, 0xf3, 0x95, 0xd3, 0xdb, 0x93, 0xf5, + 0xbd, 0xb5, 0xfd, 0x9b, 0xdd, 0xd5, 0x9d, 0xfb, + 0xba, 0xb2, 0xfa, 0x90, 0xda, 0xd2, 0x9a, 0xf0, + 0xb8, 0xb0, 0xf8, 0x92, 0xd8, 0xd0, 0x98, 0xf2, + 0x6e, 0x66, 0x2e, 0x84, 0xce, 0xc6, 0x8e, 0x24, + 0x6c, 0x64, 0x2c, 0x86, 0xcc, 0xc4, 0x8c, 0x26, + 0x3a, 0x32, 0x7a, 0x10, 0x5a, 0x52, 0x1a, 0x70, + 0x38, 0x30, 0x78, 0x12, 0x58, 0x50, 0x18, 0x72, + 0xbe, 0xb6, 0xfe, 0x94, 0xde, 0xd6, 0x9e, 0xf4, + 0xbc, 0xb4, 0xfc, 0x96, 0xdc, 0xd4, 0x9c, 0xf6, + 0xb7, 0xbf, 0xf7, 0x91, 0xd7, 0xdf, 0x97, 0xf1, + 0xb9, 0xb1, 0xf9, 0x9f, 0xd9, 0xd1, 0x99, 0xff +}; + +static unsigned char reverse[] = { + 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, + 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, + 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, + 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, + 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, + 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, + 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, + 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, + 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, + 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, + 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, + 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, + 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, + 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, + 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, + 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, + 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, + 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, + 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, + 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, + 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, + 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, + 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, + 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, + 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, + 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, + 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, + 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, + 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, + 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, + 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, + 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff +}; + +/* + * Two linear feedback shift registers are used: + * + * lfsr17: polynomial of degree 17, primitive modulo 2 (listed in Schneier) + * x^15 + x + 1 + * lfsr25: polynomial of degree 25, not know if primitive modulo 2 + * x^13 + x^5 + x^4 + x^1 + 1 + * + * Output bits are discarded, instead the feedback bits are added to produce + * the cipher stream. Depending on the mode, feedback bytes may be inverted + * bit-wise before addition. + * + * The lfsrs are seeded with bytes from the raw key: + * + * lfsr17: byte 0[0:7] at bit 9 + * byte 1[0:7] at bit 0 + * + * lfsr25: byte 2[0:4] at bit 16 + * byte 2[5:7] at bit 22 + * byte 3[0:7] at bit 8 + * byte 4[0:7] at bit 0 + * + * To prevent 0 cycles, 1's are inject at bit 8 in lfrs17 and bit 21 in + * lfsr25. + * + */ + +int +acss(ACSS_KEY *key, unsigned long len, const unsigned char *in, + unsigned char *out) +{ + unsigned long i; + unsigned long lfsr17tmp, lfsr25tmp, lfsrsumtmp; + + lfsrsumtmp = lfsr17tmp = lfsr25tmp = 0; + + /* keystream is sum of lfsrs */ + for (i = 0; i < len; i++) { + lfsr17tmp = key->lfsr17 ^ (key->lfsr17 >> 14); + key->lfsr17 = (key->lfsr17 >> 8) + ^ (lfsr17tmp << 9) + ^ (lfsr17tmp << 12) + ^ (lfsr17tmp << 15); + key->lfsr17 &= 0x1ffff; /* 17 bit LFSR */ + + lfsr25tmp = key->lfsr25 + ^ (key->lfsr25 >> 3) + ^ (key->lfsr25 >> 4) + ^ (key->lfsr25 >> 12); + key->lfsr25 = (key->lfsr25 >> 8) ^ (lfsr25tmp << 17); + key->lfsr25 &= 0x1ffffff; /* 25 bit LFSR */ + + lfsrsumtmp = key->lfsrsum; + + /* addition */ + switch (key->mode) { + case ACSS_AUTHENTICATE: + case ACSS_DATA: + key->lfsrsum = 0xff & ~(key->lfsr17 >> 9); + key->lfsrsum += key->lfsr25 >> 17; + break; + case ACSS_SESSIONKEY: + key->lfsrsum = key->lfsr17 >> 9; + key->lfsrsum += key->lfsr25 >> 17; + break; + case ACSS_TITLEKEY: + key->lfsrsum = key->lfsr17 >> 9; + key->lfsrsum += 0xff & ~(key->lfsr25 >> 17); + break; + default: + return 1; + } + key->lfsrsum += (lfsrsumtmp >> 8); + + if (key->encrypt) { + out[i] = sboxenc[(in[i] ^ key->lfsrsum) & 0xff]; + } else { + out[i] = (sboxdec[in[i]] ^ key->lfsrsum) & 0xff; + } + } + + return 0; +} + +static void +acss_seed(ACSS_KEY *key) +{ + int i; + + /* if available, mangle with subkey */ + if (key->subkey_avilable) { + for (i = 0; i < ACSS_KEYSIZE; i++) + key->seed[i] = reverse[key->data[i] ^ key->subkey[i]]; + } else { + for (i = 0; i < ACSS_KEYSIZE; i++) + key->seed[i] = reverse[key->data[i]]; + } + + /* seed lfsrs */ + key->lfsr17 = key->seed[1] + | (key->seed[0] << 9) + | (1 << 8); /* inject 1 at bit 9 */ + key->lfsr25 = key->seed[4] + | (key->seed[3] << 8) + | ((key->seed[2] & 0x1f) << 16) + | ((key->seed[2] & 0xe0) << 17) + | (1 << 21); /* inject 1 at bit 22 */ + + key->lfsrsum = 0; +} + +void +acss_setkey(ACSS_KEY *key, const unsigned char *data, int enc, int mode) +{ + memcpy(key->data, data, sizeof(key->data)); + memset(key->subkey, 0, sizeof(key->subkey)); + + if (enc != -1) + key->encrypt = enc; + key->mode = mode; + key->subkey_avilable = 0; + + acss_seed(key); +} + +void +acss_setsubkey(ACSS_KEY *key, const unsigned char *subkey) +{ + memcpy(key->subkey, subkey, sizeof(key->subkey)); + key->subkey_avilable = 1; + acss_seed(key); +} +#endif
diff --git a/openssh-6.0p1/acss.h b/openssh-6.0p1/acss.h new file mode 100644 index 0000000..91b4895 --- /dev/null +++ b/openssh-6.0p1/acss.h
@@ -0,0 +1,47 @@ +/* $Id: acss.h,v 1.2 2004/02/06 04:22:43 dtucker Exp $ */ +/* + * Copyright (c) 2004 The OpenBSD project + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _ACSS_H_ +#define _ACSS_H_ + +/* 40bit key */ +#define ACSS_KEYSIZE 5 + +/* modes of acss */ +#define ACSS_AUTHENTICATE 0 +#define ACSS_SESSIONKEY 1 +#define ACSS_TITLEKEY 2 +#define ACSS_DATA 3 + +typedef struct acss_key_st { + unsigned int lfsr17; /* current state of lfsrs */ + unsigned int lfsr25; + unsigned int lfsrsum; + unsigned char seed[ACSS_KEYSIZE]; + unsigned char data[ACSS_KEYSIZE]; + unsigned char subkey[ACSS_KEYSIZE]; + int encrypt; /* XXX make these bit flags? */ + int mode; + int seeded; + int subkey_avilable; +} ACSS_KEY; + +void acss_setkey(ACSS_KEY *, const unsigned char *, int, int); +void acss_setsubkey(ACSS_KEY *, const unsigned char *); +int acss(ACSS_KEY *, unsigned long, const unsigned char *, unsigned char *); + +#endif /* ifndef _ACSS_H_ */
diff --git a/openssh-6.0p1/addrmatch.c b/openssh-6.0p1/addrmatch.c new file mode 100644 index 0000000..5b6773c --- /dev/null +++ b/openssh-6.0p1/addrmatch.c
@@ -0,0 +1,500 @@ +/* $OpenBSD: addrmatch.c,v 1.5 2010/02/26 20:29:54 djm Exp $ */ + +/* + * Copyright (c) 2004-2008 Damien Miller <djm@mindrot.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +#include <netdb.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> + +#include "match.h" +#include "log.h" +#include "xmalloc.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 < sizeof(*in4)) + return -1; + xa->af = AF_INET; + memcpy(&xa->v4, &in4->sin_addr, sizeof(xa->v4)); + break; + case AF_INET6: + if (slen < sizeof(*in6)) + return -1; + xa->af = AF_INET6; + memcpy(&xa->v6, &in6->sin6_addr, sizeof(xa->v6)); +#ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID + xa->scope_id = in6->sin6_scope_id; +#endif + break; + default: + return -1; + } + + return 0; +} + +/* + * Calculate a netmask of length 'l' for address family 'af' and + * store it in 'n'. + * Returns 0 on success, -1 on failure. + */ +static int +addr_netmask(int af, u_int l, struct xaddr *n) +{ + int i; + + if (masklen_valid(af, l) != 0 || n == NULL) + return -1; + + memset(n, '\0', sizeof(*n)); + switch (af) { + case AF_INET: + n->af = AF_INET; + if (l == 0) + return 0; + n->v4.s_addr = htonl((0xffffffff << (32 - l)) & 0xffffffff); + return 0; + case AF_INET6: + n->af = AF_INET6; + for (i = 0; i < 4 && l >= 32; i++, l -= 32) + n->addr32[i] = 0xffffffffU; + if (i < 4 && l != 0) + n->addr32[i] = htonl((0xffffffff << (32 - l)) & + 0xffffffff); + return 0; + default: + return -1; + } +} + +/* + * Perform logical AND of addresses 'a' and 'b', storing result in 'dst'. + * Returns 0 on success, -1 on failure. + */ +static int +addr_and(struct xaddr *dst, const struct xaddr *a, const struct xaddr *b) +{ + int i; + + if (dst == NULL || a == NULL || b == NULL || a->af != b->af) + return -1; + + memcpy(dst, a, sizeof(*dst)); + switch (a->af) { + case AF_INET: + dst->v4.s_addr &= b->v4.s_addr; + return 0; + case AF_INET6: + dst->scope_id = a->scope_id; + for (i = 0; i < 4; i++) + dst->addr32[i] &= b->addr32[i]; + return 0; + default: + return -1; + } +} + +/* + * Compare addresses 'a' and 'b' + * Return 0 if addresses are identical, -1 if (a < b) or 1 if (a > b) + */ +static int +addr_cmp(const struct xaddr *a, const struct xaddr *b) +{ + int i; + + if (a->af != b->af) + return a->af == AF_INET6 ? 1 : -1; + + switch (a->af) { + case AF_INET: + if (a->v4.s_addr == b->v4.s_addr) + return 0; + return ntohl(a->v4.s_addr) > ntohl(b->v4.s_addr) ? 1 : -1; + case AF_INET6: + for (i = 0; i < 16; i++) + if (a->addr8[i] - b->addr8[i] != 0) + return a->addr8[i] > b->addr8[i] ? 1 : -1; + if (a->scope_id == b->scope_id) + return 0; + return a->scope_id > b->scope_id ? 1 : -1; + default: + return -1; + } +} + +/* + * Parse string address 'p' into 'n' + * Returns 0 on success, -1 on failure. + */ +static int +addr_pton(const char *p, struct xaddr *n) +{ + struct addrinfo hints, *ai; + + memset(&hints, '\0', sizeof(hints)); + hints.ai_flags = AI_NUMERICHOST; + + if (p == NULL || getaddrinfo(p, NULL, &hints, &ai) != 0) + return -1; + + if (ai == NULL || ai->ai_addr == NULL) + return -1; + + if (n != NULL && + addr_sa_to_xaddr(ai->ai_addr, ai->ai_addrlen, n) == -1) { + freeaddrinfo(ai); + return -1; + } + + freeaddrinfo(ai); + return 0; +} + +/* + * Perform bitwise negation of address + * Returns 0 on success, -1 on failure. + */ +static int +addr_invert(struct xaddr *n) +{ + int i; + + if (n == NULL) + return (-1); + + switch (n->af) { + case AF_INET: + n->v4.s_addr = ~n->v4.s_addr; + return (0); + case AF_INET6: + for (i = 0; i < 4; i++) + n->addr32[i] = ~n->addr32[i]; + return (0); + default: + return (-1); + } +} + +/* + * Calculate a netmask of length 'l' for address family 'af' and + * store it in 'n'. + * Returns 0 on success, -1 on failure. + */ +static int +addr_hostmask(int af, u_int l, struct xaddr *n) +{ + if (addr_netmask(af, l, n) == -1 || addr_invert(n) == -1) + return (-1); + return (0); +} + +/* + * Test whether address 'a' is all zeros (i.e. 0.0.0.0 or ::) + * Returns 0 on if address is all-zeros, -1 if not all zeros or on failure. + */ +static int +addr_is_all0s(const struct xaddr *a) +{ + int i; + + switch (a->af) { + case AF_INET: + return (a->v4.s_addr == 0 ? 0 : -1); + case AF_INET6:; + for (i = 0; i < 4; i++) + if (a->addr32[i] != 0) + return (-1); + return (0); + default: + return (-1); + } +} + +/* + * Test whether host portion of address 'a', as determined by 'masklen' + * is all zeros. + * Returns 0 on if host portion of address is all-zeros, + * -1 if not all zeros or on failure. + */ +static int +addr_host_is_all0s(const struct xaddr *a, u_int masklen) +{ + struct xaddr tmp_addr, tmp_mask, tmp_result; + + memcpy(&tmp_addr, a, sizeof(tmp_addr)); + if (addr_hostmask(a->af, masklen, &tmp_mask) == -1) + return (-1); + if (addr_and(&tmp_result, &tmp_addr, &tmp_mask) == -1) + return (-1); + return (addr_is_all0s(&tmp_result)); +} + +/* + * Parse a CIDR address (x.x.x.x/y or xxxx:yyyy::/z). + * Return -1 on parse error, -2 on inconsistency or 0 on success. + */ +static int +addr_pton_cidr(const char *p, struct xaddr *n, u_int *l) +{ + struct xaddr tmp; + long unsigned int masklen = 999; + char addrbuf[64], *mp, *cp; + + /* Don't modify argument */ + if (p == NULL || strlcpy(addrbuf, p, sizeof(addrbuf)) > sizeof(addrbuf)) + return -1; + + if ((mp = strchr(addrbuf, '/')) != NULL) { + *mp = '\0'; + mp++; + masklen = strtoul(mp, &cp, 10); + if (*mp == '\0' || *cp != '\0' || masklen > 128) + return -1; + } + + if (addr_pton(addrbuf, &tmp) == -1) + return -1; + + if (mp == NULL) + masklen = addr_unicast_masklen(tmp.af); + if (masklen_valid(tmp.af, masklen) == -1) + return -2; + if (addr_host_is_all0s(&tmp, masklen) != 0) + return -2; + + if (n != NULL) + memcpy(n, &tmp, sizeof(*n)); + if (l != NULL) + *l = masklen; + + return 0; +} + +static int +addr_netmatch(const struct xaddr *host, const struct xaddr *net, u_int masklen) +{ + struct xaddr tmp_mask, tmp_result; + + if (host->af != net->af) + return -1; + + if (addr_netmask(host->af, masklen, &tmp_mask) == -1) + return -1; + if (addr_and(&tmp_result, host, &tmp_mask) == -1) + return -1; + return addr_cmp(&tmp_result, net); +} + +/* + * Match "addr" against list pattern list "_list", which may contain a + * mix of CIDR addresses and old-school wildcards. + * + * If addr is NULL, then no matching is performed, but _list is parsed + * and checked for well-formedness. + * + * Returns 1 on match found (never returned when addr == NULL). + * Returns 0 on if no match found, or no errors found when addr == NULL. + * Returns -1 on negated match found (never returned when addr == NULL). + * Returns -2 on invalid list entry. + */ +int +addr_match_list(const char *addr, const char *_list) +{ + char *list, *cp, *o; + struct xaddr try_addr, match_addr; + u_int masklen, neg; + int ret = 0, r; + + if (addr != NULL && addr_pton(addr, &try_addr) != 0) { + debug2("%s: couldn't parse address %.100s", __func__, addr); + return 0; + } + if ((o = list = strdup(_list)) == NULL) + return -1; + while ((cp = strsep(&list, ",")) != NULL) { + neg = *cp == '!'; + if (neg) + cp++; + if (*cp == '\0') { + ret = -2; + break; + } + /* Prefer CIDR address matching */ + r = addr_pton_cidr(cp, &match_addr, &masklen); + if (r == -2) { + error("Inconsistent mask length for " + "network \"%.100s\"", cp); + ret = -2; + break; + } else if (r == 0) { + if (addr != NULL && addr_netmatch(&try_addr, + &match_addr, masklen) == 0) { + foundit: + if (neg) { + ret = -1; + break; + } + ret = 1; + } + continue; + } else { + /* If CIDR parse failed, try wildcard string match */ + if (addr != NULL && match_pattern(addr, cp) == 1) + goto foundit; + } + } + xfree(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; + } + } + xfree(o); + + return ret; +}
diff --git a/openssh-6.0p1/atomicio.c b/openssh-6.0p1/atomicio.c new file mode 100644 index 0000000..601b3c3 --- /dev/null +++ b/openssh-6.0p1/atomicio.c
@@ -0,0 +1,165 @@ +/* $OpenBSD: atomicio.c,v 1.26 2010/09/22 22:58:51 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 <sys/param.h> +#include <sys/uio.h> + +#include <errno.h> +#ifdef HAVE_POLL_H +#include <poll.h> +#else +# ifdef HAVE_SYS_POLL_H +# include <sys/poll.h> +# endif +#endif +#include <string.h> +#include <unistd.h> + +#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; + + pfd.fd = fd; + pfd.events = f == read ? POLLIN : POLLOUT; + while (n > pos) { + res = (f) (fd, s + pos, n - pos); + switch (res) { + case -1: + if (errno == EINTR) + continue; + if (errno == EAGAIN || errno == EWOULDBLOCK) { + (void)poll(&pfd, 1, -1); + continue; + } + return 0; + case 0: + errno = EPIPE; + return pos; + default: + pos += (size_t)res; + if (cb != NULL && cb(cb_arg, (size_t)res) == -1) { + errno = EINTR; + return pos; + } + } + } + return pos; +} + +size_t +atomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n) +{ + return atomicio6(f, fd, _s, n, NULL, NULL); +} + +/* + * ensure all of data on socket comes through. f==readv || f==writev + */ +size_t +atomiciov6(ssize_t (*f) (int, const struct iovec *, int), int fd, + const struct iovec *_iov, int iovcnt, + int (*cb)(void *, size_t), void *cb_arg) +{ + size_t pos = 0, rem; + ssize_t res; + struct iovec iov_array[IOV_MAX], *iov = iov_array; + struct pollfd pfd; + + if (iovcnt > IOV_MAX) { + errno = EINVAL; + return 0; + } + /* Make a copy of the iov array because we may modify it below */ + memcpy(iov, _iov, iovcnt * sizeof(*_iov)); + +#ifndef BROKEN_READV_COMPARISON + pfd.fd = fd; + pfd.events = f == readv ? POLLIN : POLLOUT; +#endif + for (; iovcnt > 0 && iov[0].iov_len > 0;) { + res = (f) (fd, iov, iovcnt); + switch (res) { + case -1: + if (errno == EINTR) + continue; + if (errno == EAGAIN || errno == EWOULDBLOCK) { +#ifndef BROKEN_READV_COMPARISON + (void)poll(&pfd, 1, -1); +#endif + continue; + } + return 0; + case 0: + errno = EPIPE; + return pos; + default: + rem = (size_t)res; + pos += rem; + /* skip completed iov entries */ + while (iovcnt > 0 && rem >= iov[0].iov_len) { + rem -= iov[0].iov_len; + iov++; + iovcnt--; + } + /* This shouldn't happen... */ + if (rem > 0 && (iovcnt <= 0 || rem > iov[0].iov_len)) { + errno = EFAULT; + return 0; + } + if (iovcnt == 0) + break; + /* update pointer in partially complete iov */ + iov[0].iov_base = ((char *)iov[0].iov_base) + rem; + iov[0].iov_len -= rem; + } + if (cb != NULL && cb(cb_arg, (size_t)res) == -1) { + errno = EINTR; + return pos; + } + } + return pos; +} + +size_t +atomiciov(ssize_t (*f) (int, const struct iovec *, int), int fd, + const struct iovec *_iov, int iovcnt) +{ + return atomiciov6(f, fd, _iov, iovcnt, NULL, NULL); +}
diff --git a/openssh-6.0p1/atomicio.h b/openssh-6.0p1/atomicio.h new file mode 100644 index 0000000..0d728ac --- /dev/null +++ b/openssh-6.0p1/atomicio.h
@@ -0,0 +1,51 @@ +/* $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 */
diff --git a/openssh-6.0p1/audit-bsm.c b/openssh-6.0p1/audit-bsm.c new file mode 100644 index 0000000..6135591 --- /dev/null +++ b/openssh-6.0p1/audit-bsm.c
@@ -0,0 +1,457 @@ +/* $Id: audit-bsm.c,v 1.8 2012/02/23 23:40:43 dtucker Exp $ */ + +/* + * TODO + * + * - deal with overlap between this and sys_auth_allowed_user + * sys_auth_record_login and record_failed_login. + */ + +/* + * Copyright 1988-2002 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +/* #pragma ident "@(#)bsmaudit.c 1.1 01/09/17 SMI" */ + +#include "includes.h" +#if defined(USE_BSM_AUDIT) + +#include <sys/types.h> + +#include <errno.h> +#include <netdb.h> +#include <stdarg.h> +#include <string.h> +#include <unistd.h> + +#ifdef BROKEN_BSM_API +#include <libscf.h> +#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 <bsm/audit.h> +#include <bsm/libbsm.h> +#include <bsm/audit_uevents.h> +#include <bsm/audit_record.h> +#include <locale.h> + +#if defined(HAVE_GETAUDIT_ADDR) +#define AuditInfoStruct auditinfo_addr +#define AuditInfoTermID au_tid_addr_t +#define 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 */
diff --git a/openssh-6.0p1/audit-linux.c b/openssh-6.0p1/audit-linux.c new file mode 100644 index 0000000..b3ee2f4 --- /dev/null +++ b/openssh-6.0p1/audit-linux.c
@@ -0,0 +1,126 @@ +/* $Id: audit-linux.c,v 1.1 2011/01/17 10:15:30 dtucker Exp $ */ + +/* + * Copyright 2010 Red Hat, Inc. All rights reserved. + * Use is subject to license terms. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Red Hat author: Jan F. Chadima <jchadima@redhat.com> + */ + +#include "includes.h" +#if defined(USE_LINUX_AUDIT) +#include <libaudit.h> +#include <unistd.h> +#include <string.h> + +#include "log.h" +#include "audit.h" +#include "canohost.h" + +const char* audit_username(void); + +int +linux_audit_record_event(int uid, const char *username, + const char *hostname, const char *ip, const char *ttyn, int success) +{ + int audit_fd, rc, saved_errno; + + audit_fd = audit_open(); + if (audit_fd < 0) { + if (errno == EINVAL || errno == EPROTONOSUPPORT || + errno == EAFNOSUPPORT) + return 1; /* No audit support in kernel */ + else + return 0; /* Must prevent login */ + } + rc = audit_log_acct_message(audit_fd, AUDIT_USER_LOGIN, + NULL, "login", username ? username : "(unknown)", + username == NULL ? uid : -1, hostname, ip, ttyn, success); + saved_errno = errno; + close(audit_fd); + /* + * Do not report error if the error is EPERM and sshd is run as non + * root user. + */ + if ((rc == -EPERM) && (geteuid() != 0)) + rc = 0; + errno = saved_errno; + return (rc >= 0); +} + +/* Below is the sshd audit API code */ + +void +audit_connection_from(const char *host, int port) +{ +} + /* not implemented */ + +void +audit_run_command(const char *command) +{ + /* not implemented */ +} + +void +audit_session_open(struct logininfo *li) +{ + if (linux_audit_record_event(li->uid, NULL, li->hostname, + NULL, li->line, 1) == 0) + fatal("linux_audit_write_entry failed: %s", strerror(errno)); +} + +void +audit_session_close(struct logininfo *li) +{ + /* not implemented */ +} + +void +audit_event(ssh_audit_event_t event) +{ + switch(event) { + case SSH_AUTH_SUCCESS: + case SSH_CONNECTION_CLOSE: + case SSH_NOLOGIN: + case SSH_LOGIN_EXCEED_MAXTRIES: + case SSH_LOGIN_ROOT_DENIED: + break; + + case SSH_AUTH_FAIL_NONE: + case SSH_AUTH_FAIL_PASSWD: + case SSH_AUTH_FAIL_KBDINT: + case SSH_AUTH_FAIL_PUBKEY: + case SSH_AUTH_FAIL_HOSTBASED: + case SSH_AUTH_FAIL_GSSAPI: + case SSH_INVALID_USER: + linux_audit_record_event(-1, audit_username(), NULL, + get_remote_ipaddr(), "sshd", 0); + break; + + default: + debug("%s: unhandled event %d", __func__, event); + } +} + +#endif /* USE_LINUX_AUDIT */
diff --git a/openssh-6.0p1/audit.c b/openssh-6.0p1/audit.c new file mode 100644 index 0000000..ced57fa --- /dev/null +++ b/openssh-6.0p1/audit.c
@@ -0,0 +1,186 @@ +/* $Id: audit.c,v 1.6 2011/01/17 10:15:30 dtucker Exp $ */ + +/* + * Copyright (c) 2004, 2005 Darren Tucker. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#include <stdarg.h> +#include <string.h> + +#ifdef SSH_AUDIT_EVENTS + +#include "audit.h" +#include "log.h" +#include "key.h" +#include "hostfile.h" +#include "auth.h" + +/* + * Care must be taken when using this since it WILL NOT be initialized when + * audit_connection_from() is called and MAY NOT be initialized when + * audit_event(CONNECTION_ABANDON) is called. Test for NULL before using. + */ +extern Authctxt *the_authctxt; + +/* Maybe add the audit class to struct Authmethod? */ +ssh_audit_event_t +audit_classify_auth(const char *method) +{ + if (strcmp(method, "none") == 0) + return SSH_AUTH_FAIL_NONE; + else if (strcmp(method, "password") == 0) + return SSH_AUTH_FAIL_PASSWD; + else if (strcmp(method, "publickey") == 0 || + strcmp(method, "rsa") == 0) + return SSH_AUTH_FAIL_PUBKEY; + else if (strncmp(method, "keyboard-interactive", 20) == 0 || + strcmp(method, "challenge-response") == 0) + return SSH_AUTH_FAIL_KBDINT; + else if (strcmp(method, "hostbased") == 0 || + strcmp(method, "rhosts-rsa") == 0) + return SSH_AUTH_FAIL_HOSTBASED; + else if (strcmp(method, "gssapi-with-mic") == 0) + return SSH_AUTH_FAIL_GSSAPI; + else + return SSH_AUDIT_UNKNOWN; +} + +/* helper to return supplied username */ +const char * +audit_username(void) +{ + static const char unknownuser[] = "(unknown user)"; + static const char invaliduser[] = "(invalid user)"; + + if (the_authctxt == NULL || the_authctxt->user == NULL) + return (unknownuser); + if (!the_authctxt->valid) + return (invaliduser); + return (the_authctxt->user); +} + +const char * +audit_event_lookup(ssh_audit_event_t ev) +{ + int i; + static struct event_lookup_struct { + ssh_audit_event_t event; + const char *name; + } event_lookup[] = { + {SSH_LOGIN_EXCEED_MAXTRIES, "LOGIN_EXCEED_MAXTRIES"}, + {SSH_LOGIN_ROOT_DENIED, "LOGIN_ROOT_DENIED"}, + {SSH_AUTH_SUCCESS, "AUTH_SUCCESS"}, + {SSH_AUTH_FAIL_NONE, "AUTH_FAIL_NONE"}, + {SSH_AUTH_FAIL_PASSWD, "AUTH_FAIL_PASSWD"}, + {SSH_AUTH_FAIL_KBDINT, "AUTH_FAIL_KBDINT"}, + {SSH_AUTH_FAIL_PUBKEY, "AUTH_FAIL_PUBKEY"}, + {SSH_AUTH_FAIL_HOSTBASED, "AUTH_FAIL_HOSTBASED"}, + {SSH_AUTH_FAIL_GSSAPI, "AUTH_FAIL_GSSAPI"}, + {SSH_INVALID_USER, "INVALID_USER"}, + {SSH_NOLOGIN, "NOLOGIN"}, + {SSH_CONNECTION_CLOSE, "CONNECTION_CLOSE"}, + {SSH_CONNECTION_ABANDON, "CONNECTION_ABANDON"}, + {SSH_AUDIT_UNKNOWN, "AUDIT_UNKNOWN"} + }; + + for (i = 0; event_lookup[i].event != SSH_AUDIT_UNKNOWN; i++) + if (event_lookup[i].event == ev) + break; + return(event_lookup[i].name); +} + +# ifndef CUSTOM_SSH_AUDIT_EVENTS +/* + * Null implementations of audit functions. + * These get used if SSH_AUDIT_EVENTS is defined but no audit module is enabled. + */ + +/* + * Called after a connection has been accepted but before any authentication + * has been attempted. + */ +void +audit_connection_from(const char *host, int port) +{ + debug("audit connection from %s port %d euid %d", host, port, + (int)geteuid()); +} + +/* + * Called when various events occur (see audit.h for a list of possible + * events and what they mean). + */ +void +audit_event(ssh_audit_event_t event) +{ + debug("audit event euid %d user %s event %d (%s)", geteuid(), + audit_username(), event, audit_event_lookup(event)); +} + +/* + * Called when a user session is started. Argument is the tty allocated to + * the session, or NULL if no tty was allocated. + * + * Note that this may be called multiple times if multiple sessions are used + * within a single connection. + */ +void +audit_session_open(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 */
diff --git a/openssh-6.0p1/audit.h b/openssh-6.0p1/audit.h new file mode 100644 index 0000000..92ede5b --- /dev/null +++ b/openssh-6.0p1/audit.h
@@ -0,0 +1,57 @@ +/* $Id: audit.h,v 1.4 2011/01/17 10:15:30 dtucker Exp $ */ + +/* + * Copyright (c) 2004, 2005 Darren Tucker. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SSH_AUDIT_H +# define _SSH_AUDIT_H + +#include "loginrec.h" + +enum ssh_audit_event_type { + SSH_LOGIN_EXCEED_MAXTRIES, + SSH_LOGIN_ROOT_DENIED, + SSH_AUTH_SUCCESS, + SSH_AUTH_FAIL_NONE, + SSH_AUTH_FAIL_PASSWD, + SSH_AUTH_FAIL_KBDINT, /* keyboard-interactive or challenge-response */ + SSH_AUTH_FAIL_PUBKEY, /* ssh2 pubkey or ssh1 rsa */ + SSH_AUTH_FAIL_HOSTBASED, /* ssh2 hostbased or ssh1 rhostsrsa */ + SSH_AUTH_FAIL_GSSAPI, + SSH_INVALID_USER, + SSH_NOLOGIN, /* denied by /etc/nologin, not implemented */ + SSH_CONNECTION_CLOSE, /* closed after attempting auth or session */ + SSH_CONNECTION_ABANDON, /* closed without completing auth */ + SSH_AUDIT_UNKNOWN +}; +typedef enum ssh_audit_event_type ssh_audit_event_t; + +void audit_connection_from(const char *, int); +void audit_event(ssh_audit_event_t); +void audit_session_open(struct logininfo *); +void audit_session_close(struct logininfo *); +void audit_run_command(const char *); +ssh_audit_event_t audit_classify_auth(const char *); + +#endif /* _SSH_AUDIT_H */
diff --git a/openssh-6.0p1/auth-bsdauth.c b/openssh-6.0p1/auth-bsdauth.c new file mode 100644 index 0000000..0b3262b --- /dev/null +++ b/openssh-6.0p1/auth-bsdauth.c
@@ -0,0 +1,138 @@ +/* $OpenBSD: auth-bsdauth.c,v 1.11 2007/09/21 08:15:29 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 <sys/types.h> + +#include <stdarg.h> + +#ifdef BSD_AUTH +#include "xmalloc.h" +#include "key.h" +#include "hostfile.h" +#include "auth.h" +#include "log.h" +#include "buffer.h" +#ifdef GSSAPI +#include "ssh-gss.h" +#endif +#include "monitor_wrap.h" + +static void * +bsdauth_init_ctx(Authctxt *authctxt) +{ + return authctxt; +} + +int +bsdauth_query(void *ctx, char **name, char **infotxt, + u_int *numprompts, char ***prompts, u_int **echo_on) +{ + Authctxt *authctxt = ctx; + char *challenge = NULL; + + if (authctxt->as != NULL) { + debug2("bsdauth_query: try reuse session"); + challenge = auth_getitem(authctxt->as, AUTHV_CHALLENGE); + if (challenge == NULL) { + auth_close(authctxt->as); + authctxt->as = NULL; + } + } + + if (challenge == NULL) { + debug2("bsdauth_query: new bsd auth session"); + debug3("bsdauth_query: style %s", + authctxt->style ? authctxt->style : "<default>"); + authctxt->as = auth_userchallenge(authctxt->user, + authctxt->style, "auth-ssh", &challenge); + if (authctxt->as == NULL) + challenge = NULL; + debug2("bsdauth_query: <%s>", challenge ? challenge : "empty"); + } + + if (challenge == NULL) + return -1; + + *name = xstrdup(""); + *infotxt = xstrdup(""); + *numprompts = 1; + *prompts = xcalloc(*numprompts, sizeof(char *)); + *echo_on = xcalloc(*numprompts, sizeof(u_int)); + (*prompts)[0] = xstrdup(challenge); + + return 0; +} + +int +bsdauth_respond(void *ctx, u_int numresponses, char **responses) +{ + Authctxt *authctxt = ctx; + int authok; + + if (!authctxt->valid) + return -1; + + if (authctxt->as == 0) + error("bsdauth_respond: no bsd auth session"); + + if (numresponses != 1) + return -1; + + authok = auth_userresponse(authctxt->as, responses[0], 0); + authctxt->as = NULL; + debug3("bsdauth_respond: <%s> = <%d>", responses[0], authok); + + return (authok == 0) ? -1 : 0; +} + +static void +bsdauth_free_ctx(void *ctx) +{ + Authctxt *authctxt = ctx; + + if (authctxt && authctxt->as) { + auth_close(authctxt->as); + authctxt->as = NULL; + } +} + +KbdintDevice bsdauth_device = { + "bsdauth", + bsdauth_init_ctx, + bsdauth_query, + bsdauth_respond, + bsdauth_free_ctx +}; + +KbdintDevice mm_bsdauth_device = { + "bsdauth", + bsdauth_init_ctx, + mm_bsdauth_query, + mm_bsdauth_respond, + bsdauth_free_ctx +}; +#endif
diff --git a/openssh-6.0p1/auth-chall.c b/openssh-6.0p1/auth-chall.c new file mode 100644 index 0000000..919b1ea --- /dev/null +++ b/openssh-6.0p1/auth-chall.c
@@ -0,0 +1,123 @@ +/* $OpenBSD: auth-chall.c,v 1.12 2006/08/03 03:34:41 deraadt Exp $ */ +/* + * Copyright (c) 2001 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#include <sys/types.h> + +#include <stdarg.h> + +#include "xmalloc.h" +#include "key.h" +#include "hostfile.h" +#include "auth.h" +#include "log.h" +#include "servconf.h" + +/* limited protocol v1 interface to kbd-interactive authentication */ + +extern KbdintDevice *devices[]; +static KbdintDevice *device; +extern ServerOptions options; + +char * +get_challenge(Authctxt *authctxt) +{ + char *challenge, *name, *info, **prompts; + u_int i, numprompts; + u_int *echo_on; + +#ifdef USE_PAM + if (!options.use_pam) + remove_kbdint_device("pam"); +#endif + + device = devices[0]; /* we always use the 1st device for protocol 1 */ + if (device == NULL) + return NULL; + if ((authctxt->kbdintctxt = device->init_ctx(authctxt)) == NULL) + return NULL; + if (device->query(authctxt->kbdintctxt, &name, &info, + &numprompts, &prompts, &echo_on)) { + device->free_ctx(authctxt->kbdintctxt); + authctxt->kbdintctxt = NULL; + return NULL; + } + if (numprompts < 1) + fatal("get_challenge: numprompts < 1"); + challenge = xstrdup(prompts[0]); + for (i = 0; i < numprompts; i++) + xfree(prompts[i]); + xfree(prompts); + xfree(name); + xfree(echo_on); + xfree(info); + + return (challenge); +} +int +verify_response(Authctxt *authctxt, const char *response) +{ + char *resp[1], *name, *info, **prompts; + u_int i, numprompts, *echo_on; + int authenticated = 0; + + if (device == NULL) + return 0; + if (authctxt->kbdintctxt == NULL) + return 0; + resp[0] = (char *)response; + switch (device->respond(authctxt->kbdintctxt, 1, resp)) { + case 0: /* Success */ + authenticated = 1; + break; + case 1: /* Postponed - retry with empty query for PAM */ + if ((device->query(authctxt->kbdintctxt, &name, &info, + &numprompts, &prompts, &echo_on)) != 0) + break; + if (numprompts == 0 && + device->respond(authctxt->kbdintctxt, 0, resp) == 0) + authenticated = 1; + + for (i = 0; i < numprompts; i++) + xfree(prompts[i]); + xfree(prompts); + xfree(name); + xfree(echo_on); + xfree(info); + break; + } + device->free_ctx(authctxt->kbdintctxt); + authctxt->kbdintctxt = NULL; + return authenticated; +} +void +abandon_challenge_response(Authctxt *authctxt) +{ + if (authctxt->kbdintctxt != NULL) { + device->free_ctx(authctxt->kbdintctxt); + authctxt->kbdintctxt = NULL; + } +}
diff --git a/openssh-6.0p1/auth-krb5.c b/openssh-6.0p1/auth-krb5.c new file mode 100644 index 0000000..d019fe2 --- /dev/null +++ b/openssh-6.0p1/auth-krb5.c
@@ -0,0 +1,256 @@ +/* $OpenBSD: auth-krb5.c,v 1.19 2006/08/03 03:34:41 deraadt Exp $ */ +/* + * Kerberos v5 authentication and ticket-passing routines. + * + * $FreeBSD: src/crypto/openssh/auth-krb5.c,v 1.6 2001/02/13 16:58:04 assar Exp $ + */ +/* + * Copyright (c) 2002 Daniel Kouril. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#include <sys/types.h> +#include <pwd.h> +#include <stdarg.h> + +#include "xmalloc.h" +#include "ssh.h" +#include "ssh1.h" +#include "packet.h" +#include "log.h" +#include "buffer.h" +#include "servconf.h" +#include "uidswap.h" +#include "key.h" +#include "hostfile.h" +#include "auth.h" + +#ifdef KRB5 +#include <errno.h> +#include <unistd.h> +#include <string.h> +#include <krb5.h> + +extern ServerOptions options; + +static int +krb5_init(void *context) +{ + Authctxt *authctxt = (Authctxt *)context; + krb5_error_code problem; + + if (authctxt->krb5_ctx == NULL) { + problem = krb5_init_context(&authctxt->krb5_ctx); + if (problem) + return (problem); + } + return (0); +} + +int +auth_krb5_password(Authctxt *authctxt, const char *password) +{ +#ifndef HEIMDAL + krb5_creds creds; + krb5_principal server; +#endif + krb5_error_code problem; + krb5_ccache ccache = NULL; + int len; + char *client, *platform_client; + + /* 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 + problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_mcc_ops, &ccache); + if (problem) + goto out; + + problem = krb5_cc_initialize(authctxt->krb5_ctx, ccache, + authctxt->krb5_user); + if (problem) + goto out; + + restore_uid(); + + problem = krb5_verify_user(authctxt->krb5_ctx, authctxt->krb5_user, + ccache, password, 1, NULL); + + temporarily_use_uid(authctxt->pw); + + if (problem) + goto out; + + problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_fcc_ops, + &authctxt->krb5_fwd_ccache); + if (problem) + goto out; + + problem = krb5_cc_copy_cache(authctxt->krb5_ctx, ccache, + authctxt->krb5_fwd_ccache); + krb5_cc_destroy(authctxt->krb5_ctx, ccache); + ccache = NULL; + if (problem) + goto out; + +#else + problem = krb5_get_init_creds_password(authctxt->krb5_ctx, &creds, + authctxt->krb5_user, (char *)password, NULL, NULL, 0, NULL, NULL); + if (problem) + goto out; + + problem = krb5_sname_to_principal(authctxt->krb5_ctx, NULL, NULL, + KRB5_NT_SRV_HST, &server); + if (problem) + goto out; + + restore_uid(); + problem = krb5_verify_init_creds(authctxt->krb5_ctx, &creds, server, + NULL, NULL, NULL); + krb5_free_principal(authctxt->krb5_ctx, server); + temporarily_use_uid(authctxt->pw); + if (problem) + goto out; + + if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, client)) { + problem = -1; + goto out; + } + + problem = ssh_krb5_cc_gen(authctxt->krb5_ctx, &authctxt->krb5_fwd_ccache); + if (problem) + goto out; + + problem = krb5_cc_initialize(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache, + authctxt->krb5_user); + if (problem) + goto out; + + problem= krb5_cc_store_cred(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache, + &creds); + if (problem) + goto out; +#endif + + authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache); + + len = strlen(authctxt->krb5_ticket_file) + 6; + authctxt->krb5_ccname = xmalloc(len); + snprintf(authctxt->krb5_ccname, len, "FILE:%s", + authctxt->krb5_ticket_file); + +#ifdef USE_PAM + if (options.use_pam) + do_pam_putenv("KRB5CCNAME", authctxt->krb5_ccname); +#endif + + out: + restore_uid(); + + if (platform_client != NULL) + xfree(platform_client); + + if (problem) { + if (ccache) + krb5_cc_destroy(authctxt->krb5_ctx, ccache); + + if (authctxt->krb5_ctx != NULL && problem!=-1) + debug("Kerberos password authentication failed: %s", + krb5_get_err_text(authctxt->krb5_ctx, problem)); + else + debug("Kerberos password authentication failed: %d", + problem); + + krb5_cleanup_proc(authctxt); + + if (options.kerberos_or_local_passwd) + return (-1); + else + return (0); + } + return (authctxt->valid ? 1 : 0); +} + +void +krb5_cleanup_proc(Authctxt *authctxt) +{ + debug("krb5_cleanup_proc called"); + if (authctxt->krb5_fwd_ccache) { + krb5_cc_destroy(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache); + authctxt->krb5_fwd_ccache = NULL; + } + if (authctxt->krb5_user) { + krb5_free_principal(authctxt->krb5_ctx, authctxt->krb5_user); + authctxt->krb5_user = NULL; + } + if (authctxt->krb5_ctx) { + krb5_free_context(authctxt->krb5_ctx); + authctxt->krb5_ctx = NULL; + } +} + +#ifndef HEIMDAL +krb5_error_code +ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) { + int tmpfd, ret; + char ccname[40]; + mode_t old_umask; + + ret = snprintf(ccname, sizeof(ccname), + "FILE:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid()); + if (ret < 0 || (size_t)ret >= sizeof(ccname)) + return ENOMEM; + + old_umask = umask(0177); + tmpfd = mkstemp(ccname + strlen("FILE:")); + umask(old_umask); + if (tmpfd == -1) { + logit("mkstemp(): %.100s", strerror(errno)); + return errno; + } + + if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) { + logit("fchmod(): %.100s", strerror(errno)); + close(tmpfd); + return errno; + } + close(tmpfd); + + return (krb5_cc_resolve(ctx, ccname, ccache)); +} +#endif /* !HEIMDAL */ +#endif /* KRB5 */
diff --git a/openssh-6.0p1/auth-options.c b/openssh-6.0p1/auth-options.c new file mode 100644 index 0000000..0e67bd8 --- /dev/null +++ b/openssh-6.0p1/auth-options.c
@@ -0,0 +1,635 @@ +/* $OpenBSD: auth-options.c,v 1.56 2011/10/18 04:58:26 djm Exp $ */ +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ + +#include "includes.h" + +#include <sys/types.h> + +#include <netdb.h> +#include <pwd.h> +#include <string.h> +#include <stdio.h> +#include <stdarg.h> + +#include "openbsd-compat/sys-queue.h" +#include "xmalloc.h" +#include "match.h" +#include "log.h" +#include "canohost.h" +#include "buffer.h" +#include "channels.h" +#include "servconf.h" +#include "misc.h" +#include "key.h" +#include "auth-options.h" +#include "hostfile.h" +#include "auth.h" +#ifdef GSSAPI +#include "ssh-gss.h" +#endif +#include "monitor_wrap.h" + +/* 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; + xfree(ce->s); + xfree(ce); + } + if (forced_command) { + xfree(forced_command); + forced_command = NULL; + } + if (authorized_principals) { + xfree(authorized_principals); + authorized_principals = NULL; + } + forced_tun_device = -1; + channel_clear_permitted_opens(); +} + +/* + * return 1 if access is granted, 0 if not. + * side effect: sets key option flags + */ +int +auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) +{ + const char *cp; + int i; + + /* reset options */ + auth_clear_options(); + + if (!opts) + return 1; + + while (*opts && *opts != ' ' && *opts != '\t') { + cp = "cert-authority"; + if (strncasecmp(opts, cp, strlen(cp)) == 0) { + key_is_cert_authority = 1; + opts += strlen(cp); + goto next_option; + } + cp = "no-port-forwarding"; + if (strncasecmp(opts, cp, strlen(cp)) == 0) { + auth_debug_add("Port forwarding disabled."); + no_port_forwarding_flag = 1; + opts += strlen(cp); + goto next_option; + } + cp = "no-agent-forwarding"; + if (strncasecmp(opts, cp, strlen(cp)) == 0) { + auth_debug_add("Agent forwarding disabled."); + no_agent_forwarding_flag = 1; + opts += strlen(cp); + goto next_option; + } + cp = "no-X11-forwarding"; + if (strncasecmp(opts, cp, strlen(cp)) == 0) { + auth_debug_add("X11 forwarding disabled."); + no_x11_forwarding_flag = 1; + opts += strlen(cp); + goto next_option; + } + cp = "no-pty"; + if (strncasecmp(opts, cp, strlen(cp)) == 0) { + auth_debug_add("Pty allocation disabled."); + no_pty_flag = 1; + opts += strlen(cp); + goto next_option; + } + cp = "no-user-rc"; + if (strncasecmp(opts, cp, strlen(cp)) == 0) { + auth_debug_add("User rc file execution disabled."); + no_user_rc = 1; + opts += strlen(cp); + goto next_option; + } + cp = "command=\""; + if (strncasecmp(opts, cp, strlen(cp)) == 0) { + opts += strlen(cp); + if (forced_command != NULL) + xfree(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); + xfree(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); + if (authorized_principals != NULL) + xfree(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); + xfree(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 (options.permit_user_env && + strncasecmp(opts, cp, strlen(cp)) == 0) { + char *s; + struct envstring *new_envstring; + + opts += strlen(cp); + s = xmalloc(strlen(opts) + 1); + i = 0; + while (*opts) { + if (*opts == '"') + break; + if (*opts == '\\' && opts[1] == '"') { + opts += 2; + s[i++] = '"'; + continue; + } + s[i++] = *opts++; + } + if (!*opts) { + debug("%.100s, line %lu: missing end quote", + file, linenum); + auth_debug_add("%.100s, line %lu: missing end quote", + file, linenum); + xfree(s); + goto bad_option; + } + s[i] = '\0'; + auth_debug_add("Adding to environment: %.900s", s); + debug("Adding to environment: %.900s", s); + opts++; + new_envstring = xmalloc(sizeof(struct envstring)); + new_envstring->s = s; + new_envstring->next = custom_environment; + custom_environment = new_envstring; + goto next_option; + } + cp = "from=\""; + if (strncasecmp(opts, cp, strlen(cp)) == 0) { + const char *remote_ip = get_remote_ipaddr(); + const char *remote_host = get_canonical_hostname( + options.use_dns); + char *patterns = xmalloc(strlen(opts) + 1); + + opts += strlen(cp); + i = 0; + while (*opts) { + if (*opts == '"') + break; + if (*opts == '\\' && opts[1] == '"') { + opts += 2; + patterns[i++] = '"'; + continue; + } + patterns[i++] = *opts++; + } + if (!*opts) { + debug("%.100s, line %lu: missing end quote", + file, linenum); + auth_debug_add("%.100s, line %lu: missing end quote", + file, linenum); + xfree(patterns); + goto bad_option; + } + patterns[i] = '\0'; + opts++; + switch (match_host_and_ip(remote_host, remote_ip, + patterns)) { + case 1: + xfree(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: + xfree(patterns); + logit("Authentication tried for %.100s with " + "correct key but not from a permitted " + "host (host=%.200s, ip=%.200s).", + pw->pw_name, remote_host, remote_ip); + auth_debug_add("Your host '%.200s' is not " + "permitted to use this key for login.", + remote_host); + 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); + xfree(patterns); + goto bad_option; + } + patterns[i] = '\0'; + opts++; + p = patterns; + host = hpdelim(&p); + if (host == NULL || strlen(host) >= NI_MAXHOST) { + debug("%.100s, line %lu: Bad permitopen " + "specification <%.100s>", file, linenum, + patterns); + auth_debug_add("%.100s, line %lu: " + "Bad permitopen specification", file, + linenum); + xfree(patterns); + goto bad_option; + } + host = cleanhostname(host); + if (p == NULL || (port = 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); + xfree(patterns); + goto bad_option; + } + if (options.allow_tcp_forwarding) + channel_add_permitted_opens(host, port); + xfree(patterns); + goto next_option; + } + cp = "tunnel=\""; + if (strncasecmp(opts, cp, strlen(cp)) == 0) { + char *tun = NULL; + opts += strlen(cp); + tun = xmalloc(strlen(opts) + 1); + i = 0; + while (*opts) { + if (*opts == '"') + break; + tun[i++] = *opts++; + } + if (!*opts) { + debug("%.100s, line %lu: missing end quote", + file, linenum); + auth_debug_add("%.100s, line %lu: missing end quote", + file, linenum); + xfree(tun); + forced_tun_device = -1; + goto bad_option; + } + tun[i] = '\0'; + forced_tun_device = a2tun(tun, NULL); + xfree(tun); + if (forced_tun_device == SSH_TUNID_ERR) { + debug("%.100s, line %lu: invalid tun device", + file, linenum); + auth_debug_add("%.100s, line %lu: invalid tun device", + file, linenum); + forced_tun_device = -1; + goto bad_option; + } + auth_debug_add("Forced tun device: %d", forced_tun_device); + opts++; + goto next_option; + } +next_option: + /* + * Skip the comma, and move to the next option + * (or break out if there are no more). + */ + if (!*opts) + fatal("Bugs in auth-options.c option processing."); + if (*opts == ' ' || *opts == '\t') + break; /* End of options. */ + if (*opts != ',') + goto bad_option; + opts++; + /* Process the next option. */ + } + + /* 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(u_char *optblob, size_t optblob_len, struct passwd *pw, + u_int which, int crit, + int *cert_no_port_forwarding_flag, + int *cert_no_agent_forwarding_flag, + int *cert_no_x11_forwarding_flag, + int *cert_no_pty_flag, + int *cert_no_user_rc, + char **cert_forced_command, + int *cert_source_address_done) +{ + char *command, *allowed; + const char *remote_ip; + u_char *name = NULL, *data_blob = NULL; + u_int nlen, dlen, clen; + Buffer c, data; + int ret = -1, found; + + buffer_init(&data); + + /* Make copy to avoid altering original */ + buffer_init(&c); + buffer_append(&c, optblob, optblob_len); + + while (buffer_len(&c) > 0) { + if ((name = buffer_get_cstring_ret(&c, &nlen)) == NULL || + (data_blob = buffer_get_string_ret(&c, &dlen)) == NULL) { + error("Certificate options corrupt"); + goto out; + } + buffer_append(&data, data_blob, dlen); + debug3("found certificate option \"%.100s\" len %u", + name, dlen); + 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 ((command = buffer_get_cstring_ret(&data, + &clen)) == NULL) { + error("Certificate constraint \"%s\" " + "corrupt", name); + goto out; + } + if (*cert_forced_command != NULL) { + error("Certificate has multiple " + "force-command options"); + xfree(command); + goto out; + } + *cert_forced_command = command; + found = 1; + } + if (strcmp(name, "source-address") == 0) { + if ((allowed = buffer_get_cstring_ret(&data, + &clen)) == NULL) { + error("Certificate constraint " + "\"%s\" corrupt", name); + goto out; + } + if ((*cert_source_address_done)++) { + error("Certificate has multiple " + "source-address options"); + xfree(allowed); + goto out; + } + remote_ip = get_remote_ipaddr(); + switch (addr_match_cidr_list(remote_ip, + allowed)) { + case 1: + /* accepted */ + xfree(allowed); + 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); + xfree(allowed); + goto out; + case -1: + error("Certificate source-address " + "contents invalid"); + xfree(allowed); + 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 (buffer_len(&data) != 0) { + error("Certificate option \"%s\" corrupt " + "(extra data)", name); + goto out; + } + buffer_clear(&data); + xfree(name); + xfree(data_blob); + name = data_blob = NULL; + } + /* successfully parsed all options */ + ret = 0; + + out: + if (ret != 0 && + cert_forced_command != NULL && + *cert_forced_command != NULL) { + xfree(*cert_forced_command); + *cert_forced_command = NULL; + } + if (name != NULL) + xfree(name); + if (data_blob != NULL) + xfree(data_blob); + buffer_free(&data); + buffer_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(Key *k, struct passwd *pw) +{ + int cert_no_port_forwarding_flag = 1; + int cert_no_agent_forwarding_flag = 1; + int cert_no_x11_forwarding_flag = 1; + int cert_no_pty_flag = 1; + int cert_no_user_rc = 1; + char *cert_forced_command = NULL; + int cert_source_address_done = 0; + + if (key_cert_is_legacy(k)) { + /* All options are in the one field for v00 certs */ + if (parse_option_list(buffer_ptr(&k->cert->critical), + buffer_len(&k->cert->critical), pw, + OPTIONS_CRITICAL|OPTIONS_EXTENSIONS, 1, + &cert_no_port_forwarding_flag, + &cert_no_agent_forwarding_flag, + &cert_no_x11_forwarding_flag, + &cert_no_pty_flag, + &cert_no_user_rc, + &cert_forced_command, + &cert_source_address_done) == -1) + return -1; + } else { + /* Separate options and extensions for v01 certs */ + if (parse_option_list(buffer_ptr(&k->cert->critical), + buffer_len(&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(buffer_ptr(&k->cert->extensions), + buffer_len(&k->cert->extensions), pw, + OPTIONS_EXTENSIONS, 1, + &cert_no_port_forwarding_flag, + &cert_no_agent_forwarding_flag, + &cert_no_x11_forwarding_flag, + &cert_no_pty_flag, + &cert_no_user_rc, + NULL, NULL) == -1) + return -1; + } + + no_port_forwarding_flag |= cert_no_port_forwarding_flag; + no_agent_forwarding_flag |= cert_no_agent_forwarding_flag; + no_x11_forwarding_flag |= cert_no_x11_forwarding_flag; + no_pty_flag |= cert_no_pty_flag; + no_user_rc |= cert_no_user_rc; + /* CA-specified forced command supersedes key option */ + if (cert_forced_command != NULL) { + if (forced_command != NULL) + xfree(forced_command); + forced_command = cert_forced_command; + } + return 0; +} +
diff --git a/openssh-6.0p1/auth-options.h b/openssh-6.0p1/auth-options.h new file mode 100644 index 0000000..7455c94 --- /dev/null +++ b/openssh-6.0p1/auth-options.h
@@ -0,0 +1,40 @@ +/* $OpenBSD: auth-options.h,v 1.20 2010/05/07 11:30:29 djm Exp $ */ + +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ + +#ifndef 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(Key *, struct passwd *); + +#endif
diff --git a/openssh-6.0p1/auth-pam.c b/openssh-6.0p1/auth-pam.c new file mode 100644 index 0000000..675006e --- /dev/null +++ b/openssh-6.0p1/auth-pam.c
@@ -0,0 +1,1221 @@ +/*- + * 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 <djm@mindrot.org> + * Copyright (c) 2003,2004 Darren Tucker <dtucker@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. + */ + +/* Based on $FreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des Exp $ */ +#include "includes.h" + +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/wait.h> + +#include <errno.h> +#include <signal.h> +#include <stdarg.h> +#include <string.h> +#include <unistd.h> + +#ifdef USE_PAM +#if defined(HAVE_SECURITY_PAM_APPL_H) +#include <security/pam_appl.h> +#elif defined (HAVE_PAM_PAM_APPL_H) +#include <pam/pam_appl.h> +#endif + +/* OpenGroup RFC86.0 and XSSO specify no "const" on arguments */ +#ifdef PAM_SUN_CODEBASE +# define sshpam_const /* Solaris, HP-UX, AIX */ +#else +# define sshpam_const const /* LinuxPAM, OpenPAM */ +#endif + +/* Ambiguity in spec: is it an array of pointers or a pointer to an array? */ +#ifdef PAM_SUN_CODEBASE +# define PAM_MSG_MEMBER(msg, n, member) ((*(msg))[(n)].member) +#else +# define PAM_MSG_MEMBER(msg, n, member) ((msg)[(n)]->member) +#endif + +#include "xmalloc.h" +#include "buffer.h" +#include "key.h" +#include "hostfile.h" +#include "auth.h" +#include "auth-pam.h" +#include "canohost.h" +#include "log.h" +#include "msg.h" +#include "packet.h" +#include "misc.h" +#include "servconf.h" +#include "ssh2.h" +#include "auth-options.h" +#ifdef GSSAPI +#include "ssh-gss.h" +#endif +#include "monitor_wrap.h" + +extern ServerOptions options; +extern Buffer loginmsg; +extern int compat20; +extern u_int utmp_len; + +/* so we don't silently change behaviour */ +#ifdef USE_POSIX_THREADS +# error "USE_POSIX_THREADS replaced by UNSUPPORTED_POSIX_THREADS_HACK" +#endif + +/* + * Formerly known as USE_POSIX_THREADS, using this is completely unsupported + * and generally a bad idea. Use at own risk and do not expect support if + * this breaks. + */ +#ifdef UNSUPPORTED_POSIX_THREADS_HACK +#include <pthread.h> +/* + * Avoid namespace clash when *not* using pthreads for systems *with* + * pthreads, which unconditionally define pthread_t via sys/types.h + * (e.g. Linux) + */ +typedef pthread_t sp_pthread_t; +#else +typedef pid_t sp_pthread_t; +#endif + +struct pam_ctxt { + sp_pthread_t pam_thread; + int pam_psock; + int pam_csock; + int pam_done; +}; + +static void sshpam_free_ctx(void *); +static struct pam_ctxt *cleanup_ctxt; + +#ifndef UNSUPPORTED_POSIX_THREADS_HACK +/* + * Simulate threads with processes. + */ + +static int sshpam_thread_status = -1; +static mysig_t sshpam_oldsig; + +static void +sshpam_sigchld_handler(int sig) +{ + signal(SIGCHLD, SIG_DFL); + if (cleanup_ctxt == NULL) + return; /* handler called after PAM cleanup, shouldn't happen */ + if (waitpid(cleanup_ctxt->pam_thread, &sshpam_thread_status, WNOHANG) + <= 0) { + /* PAM thread has not exitted, privsep slave must have */ + kill(cleanup_ctxt->pam_thread, SIGTERM); + if (waitpid(cleanup_ctxt->pam_thread, &sshpam_thread_status, 0) + <= 0) + return; /* could not wait */ + } + if (WIFSIGNALED(sshpam_thread_status) && + WTERMSIG(sshpam_thread_status) == SIGTERM) + return; /* terminated by pthread_cancel */ + if (!WIFEXITED(sshpam_thread_status)) + sigdie("PAM: authentication thread exited unexpectedly"); + if (WEXITSTATUS(sshpam_thread_status) != 0) + sigdie("PAM: authentication thread exited uncleanly"); +} + +/* ARGSUSED */ +static void +pthread_exit(void *value) +{ + _exit(0); +} + +/* ARGSUSED */ +static int +pthread_create(sp_pthread_t *thread, const void *attr, + void *(*thread_start)(void *), void *arg) +{ + pid_t pid; + struct pam_ctxt *ctx = arg; + + sshpam_thread_status = -1; + switch ((pid = fork())) { + case -1: + error("fork(): %s", strerror(errno)); + return (-1); + case 0: + close(ctx->pam_psock); + ctx->pam_psock = -1; + thread_start(arg); + _exit(1); + default: + *thread = pid; + close(ctx->pam_csock); + ctx->pam_csock = -1; + sshpam_oldsig = signal(SIGCHLD, sshpam_sigchld_handler); + return (0); + } +} + +static int +pthread_cancel(sp_pthread_t thread) +{ + signal(SIGCHLD, sshpam_oldsig); + return (kill(thread, SIGTERM)); +} + +/* ARGSUSED */ +static int +pthread_join(sp_pthread_t thread, void **value) +{ + int status; + + if (sshpam_thread_status != -1) + return (sshpam_thread_status); + signal(SIGCHLD, sshpam_oldsig); + waitpid(thread, &status, 0); + return (status); +} +#endif + + +static pam_handle_t *sshpam_handle = NULL; +static int sshpam_err = 0; +static int sshpam_authenticated = 0; +static int sshpam_session_open = 0; +static int sshpam_cred_established = 0; +static int sshpam_account_status = -1; +static char **sshpam_env = NULL; +static Authctxt *sshpam_authctxt = NULL; +static const char *sshpam_password = NULL; +static char badpw[] = "\b\n\r\177INCORRECT"; + +/* Some PAM implementations don't implement this */ +#ifndef HAVE_PAM_GETENVLIST +static char ** +pam_getenvlist(pam_handle_t *pamh) +{ + /* + * XXX - If necessary, we can still support envrionment passing + * for platforms without pam_getenvlist by searching for known + * env vars (e.g. KRB5CCNAME) from the PAM environment. + */ + return NULL; +} +#endif + +/* + * Some platforms, notably Solaris, do not enforce password complexity + * rules during pam_chauthtok() if the real uid of the calling process + * is 0, on the assumption that it's being called by "passwd" run by root. + * This wraps pam_chauthtok and sets/restore the real uid so PAM will do + * the right thing. + */ +#ifdef SSHPAM_CHAUTHTOK_NEEDS_RUID +static int +sshpam_chauthtok_ruid(pam_handle_t *pamh, int flags) +{ + int result; + + if (sshpam_authctxt == NULL) + fatal("PAM: sshpam_authctxt not initialized"); + if (setreuid(sshpam_authctxt->pw->pw_uid, -1) == -1) + fatal("%s: setreuid failed: %s", __func__, strerror(errno)); + result = pam_chauthtok(pamh, flags); + if (setreuid(0, -1) == -1) + fatal("%s: setreuid failed: %s", __func__, strerror(errno)); + return result; +} +# define pam_chauthtok(a,b) (sshpam_chauthtok_ruid((a), (b))) +#endif + +void +sshpam_password_change_required(int reqd) +{ + debug3("%s %d", __func__, reqd); + if (sshpam_authctxt == NULL) + fatal("%s: PAM authctxt not initialized", __func__); + sshpam_authctxt->force_pwchange = reqd; + if (reqd) { + no_port_forwarding_flag |= 2; + no_agent_forwarding_flag |= 2; + no_x11_forwarding_flag |= 2; + } else { + no_port_forwarding_flag &= ~2; + no_agent_forwarding_flag &= ~2; + no_x11_forwarding_flag &= ~2; + } +} + +/* Import regular and PAM environment from subprocess */ +static void +import_environments(Buffer *b) +{ + char *env; + u_int i, num_env; + int err; + + debug3("PAM: %s entering", __func__); + +#ifndef UNSUPPORTED_POSIX_THREADS_HACK + /* Import variables set by do_pam_account */ + sshpam_account_status = buffer_get_int(b); + sshpam_password_change_required(buffer_get_int(b)); + + /* Import environment from subprocess */ + num_env = buffer_get_int(b); + if (num_env > 1024) + fatal("%s: received %u environment variables, expected <= 1024", + __func__, num_env); + sshpam_env = xcalloc(num_env + 1, sizeof(*sshpam_env)); + debug3("PAM: num env strings %d", num_env); + for(i = 0; i < num_env; i++) + sshpam_env[i] = buffer_get_string(b, NULL); + + sshpam_env[num_env] = NULL; + + /* Import PAM environment from subprocess */ + num_env = buffer_get_int(b); + debug("PAM: num PAM env strings %d", num_env); + for(i = 0; i < num_env; i++) { + env = buffer_get_string(b, NULL); + +#ifdef HAVE_PAM_PUTENV + /* Errors are not fatal here */ + if ((err = pam_putenv(sshpam_handle, env)) != PAM_SUCCESS) { + error("PAM: pam_putenv: %s", + pam_strerror(sshpam_handle, sshpam_err)); + } +#endif + } +#endif +} + +/* + * Conversation function for authentication thread. + */ +static int +sshpam_thread_conv(int n, sshpam_const struct pam_message **msg, + struct pam_response **resp, void *data) +{ + Buffer buffer; + struct pam_ctxt *ctxt; + struct pam_response *reply; + int i; + + debug3("PAM: %s entering, %d messages", __func__, n); + *resp = NULL; + + if (data == NULL) { + error("PAM: conversation function passed a null context"); + return (PAM_CONV_ERR); + } + ctxt = data; + if (n <= 0 || n > PAM_MAX_NUM_MSG) + return (PAM_CONV_ERR); + + if ((reply = calloc(n, sizeof(*reply))) == NULL) + return (PAM_CONV_ERR); + + buffer_init(&buffer); + for (i = 0; i < n; ++i) { + switch (PAM_MSG_MEMBER(msg, i, msg_style)) { + case PAM_PROMPT_ECHO_OFF: + buffer_put_cstring(&buffer, + PAM_MSG_MEMBER(msg, i, msg)); + if (ssh_msg_send(ctxt->pam_csock, + PAM_MSG_MEMBER(msg, i, msg_style), &buffer) == -1) + goto fail; + if (ssh_msg_recv(ctxt->pam_csock, &buffer) == -1) + goto fail; + if (buffer_get_char(&buffer) != PAM_AUTHTOK) + goto fail; + reply[i].resp = buffer_get_string(&buffer, NULL); + break; + case PAM_PROMPT_ECHO_ON: + buffer_put_cstring(&buffer, + PAM_MSG_MEMBER(msg, i, msg)); + if (ssh_msg_send(ctxt->pam_csock, + PAM_MSG_MEMBER(msg, i, msg_style), &buffer) == -1) + goto fail; + if (ssh_msg_recv(ctxt->pam_csock, &buffer) == -1) + goto fail; + if (buffer_get_char(&buffer) != PAM_AUTHTOK) + goto fail; + reply[i].resp = buffer_get_string(&buffer, NULL); + break; + case PAM_ERROR_MSG: + buffer_put_cstring(&buffer, + PAM_MSG_MEMBER(msg, i, msg)); + if (ssh_msg_send(ctxt->pam_csock, + PAM_MSG_MEMBER(msg, i, msg_style), &buffer) == -1) + goto fail; + break; + case PAM_TEXT_INFO: + buffer_put_cstring(&buffer, + PAM_MSG_MEMBER(msg, i, msg)); + if (ssh_msg_send(ctxt->pam_csock, + PAM_MSG_MEMBER(msg, i, msg_style), &buffer) == -1) + goto fail; + break; + default: + goto fail; + } + buffer_clear(&buffer); + } + buffer_free(&buffer); + *resp = reply; + return (PAM_SUCCESS); + + fail: + for(i = 0; i < n; i++) { + if (reply[i].resp != NULL) + xfree(reply[i].resp); + } + xfree(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"); + + pam_get_item(sshpam_handle, PAM_USER, + (sshpam_const void **)ptr_pam_user); + + environ[0] = NULL; + if (tz != NULL) + if (setenv("TZ", tz, 1) == -1) + error("PAM: could not set TZ environment: %s", + strerror(errno)); + + if (sshpam_authctxt != NULL) { + setproctitle("%s [pam]", + sshpam_authctxt->valid ? pam_user : "unknown"); + } +#endif + + sshpam_conv.conv = sshpam_thread_conv; + sshpam_conv.appdata_ptr = ctxt; + + if (sshpam_authctxt == NULL) + fatal("%s: PAM authctxt not initialized", __func__); + + buffer_init(&buffer); + sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, + (const void *)&sshpam_conv); + if (sshpam_err != PAM_SUCCESS) + goto auth_fail; + sshpam_err = pam_authenticate(sshpam_handle, flags); + if (sshpam_err != PAM_SUCCESS) + goto auth_fail; + + if (compat20) { + if (!do_pam_account()) { + sshpam_err = PAM_ACCT_EXPIRED; + goto auth_fail; + } + if (sshpam_authctxt->force_pwchange) { + sshpam_err = pam_chauthtok(sshpam_handle, + PAM_CHANGE_EXPIRED_AUTHTOK); + if (sshpam_err != PAM_SUCCESS) + goto auth_fail; + sshpam_password_change_required(0); + } + } + + buffer_put_cstring(&buffer, "OK"); + +#ifndef UNSUPPORTED_POSIX_THREADS_HACK + /* Export variables set by do_pam_account */ + buffer_put_int(&buffer, sshpam_account_status); + buffer_put_int(&buffer, sshpam_authctxt->force_pwchange); + + /* Export any environment strings set in child */ + for(i = 0; environ[i] != NULL; i++) + ; /* Count */ + buffer_put_int(&buffer, i); + for(i = 0; environ[i] != NULL; i++) + buffer_put_cstring(&buffer, environ[i]); + + /* Export any environment strings set by PAM in child */ + env_from_pam = pam_getenvlist(sshpam_handle); + for(i = 0; env_from_pam != NULL && env_from_pam[i] != NULL; i++) + ; /* Count */ + buffer_put_int(&buffer, i); + for(i = 0; env_from_pam != NULL && env_from_pam[i] != NULL; i++) + buffer_put_cstring(&buffer, env_from_pam[i]); +#endif /* UNSUPPORTED_POSIX_THREADS_HACK */ + + /* XXX - can't do much about an error here */ + ssh_msg_send(ctxt->pam_csock, sshpam_err, &buffer); + buffer_free(&buffer); + pthread_exit(NULL); + + auth_fail: + buffer_put_cstring(&buffer, + pam_strerror(sshpam_handle, sshpam_err)); + /* XXX - can't do much about an error here */ + if (sshpam_err == PAM_ACCT_EXPIRED) + ssh_msg_send(ctxt->pam_csock, PAM_ACCT_EXPIRED, &buffer); + else + ssh_msg_send(ctxt->pam_csock, PAM_AUTH_ERR, &buffer); + buffer_free(&buffer); + pthread_exit(NULL); + + return (NULL); /* Avoid warning for non-pthread case */ +} + +void +sshpam_thread_cleanup(void) +{ + struct pam_ctxt *ctxt = cleanup_ctxt; + + debug3("PAM: %s entering", __func__); + if (ctxt != NULL && ctxt->pam_thread != 0) { + pthread_cancel(ctxt->pam_thread); + pthread_join(ctxt->pam_thread, NULL); + close(ctxt->pam_psock); + close(ctxt->pam_csock); + memset(ctxt, 0, sizeof(*ctxt)); + cleanup_ctxt = NULL; + } +} + +static int +sshpam_null_conv(int n, sshpam_const struct pam_message **msg, + struct pam_response **resp, void *data) +{ + debug3("PAM: %s entering, %d messages", __func__, n); + return (PAM_CONV_ERR); +} + +static struct pam_conv null_conv = { sshpam_null_conv, NULL }; + +static int +sshpam_store_conv(int n, sshpam_const struct pam_message **msg, + struct pam_response **resp, void *data) +{ + struct pam_response *reply; + int i; + size_t len; + + debug3("PAM: %s called with %d messages", __func__, n); + *resp = NULL; + + if (n <= 0 || n > PAM_MAX_NUM_MSG) + return (PAM_CONV_ERR); + + if ((reply = calloc(n, sizeof(*reply))) == NULL) + return (PAM_CONV_ERR); + + for (i = 0; i < n; ++i) { + switch (PAM_MSG_MEMBER(msg, i, msg_style)) { + case PAM_ERROR_MSG: + case PAM_TEXT_INFO: + len = strlen(PAM_MSG_MEMBER(msg, i, msg)); + buffer_append(&loginmsg, PAM_MSG_MEMBER(msg, i, msg), len); + buffer_append(&loginmsg, "\n", 1 ); + reply[i].resp_retcode = PAM_SUCCESS; + break; + default: + goto fail; + } + } + *resp = reply; + return (PAM_SUCCESS); + + fail: + for(i = 0; i < n; i++) { + if (reply[i].resp != NULL) + xfree(reply[i].resp); + } + xfree(reply); + return (PAM_CONV_ERR); +} + +static struct pam_conv store_conv = { sshpam_store_conv, NULL }; + +void +sshpam_cleanup(void) +{ + if (sshpam_handle == NULL || (use_privsep && !mm_is_monitor())) + return; + debug("PAM: cleanup"); + pam_set_item(sshpam_handle, PAM_CONV, (const void *)&null_conv); + if (sshpam_session_open) { + debug("PAM: closing session"); + pam_close_session(sshpam_handle, PAM_SILENT); + sshpam_session_open = 0; + } + if (sshpam_cred_established) { + debug("PAM: deleting credentials"); + pam_setcred(sshpam_handle, PAM_DELETE_CRED); + sshpam_cred_established = 0; + } + sshpam_authenticated = 0; + pam_end(sshpam_handle, sshpam_err); + sshpam_handle = NULL; +} + +static int +sshpam_init(Authctxt *authctxt) +{ + extern char *__progname; + const char *pam_rhost, *pam_user, *user = authctxt->user; + const char **ptr_pam_user = &pam_user; + + if (sshpam_handle != NULL) { + /* We already have a PAM context; check if the user matches */ + sshpam_err = pam_get_item(sshpam_handle, + PAM_USER, (sshpam_const void **)ptr_pam_user); + if (sshpam_err == PAM_SUCCESS && strcmp(user, pam_user) == 0) + return (0); + pam_end(sshpam_handle, sshpam_err); + sshpam_handle = NULL; + } + debug("PAM: initializing for \"%s\"", user); + sshpam_err = + pam_start(SSHD_PAM_SERVICE, user, &store_conv, &sshpam_handle); + sshpam_authctxt = authctxt; + + if (sshpam_err != PAM_SUCCESS) { + pam_end(sshpam_handle, sshpam_err); + sshpam_handle = NULL; + return (-1); + } + pam_rhost = get_remote_name_or_ip(utmp_len, options.use_dns); + debug("PAM: setting PAM_RHOST to \"%s\"", pam_rhost); + sshpam_err = pam_set_item(sshpam_handle, PAM_RHOST, pam_rhost); + if (sshpam_err != PAM_SUCCESS) { + pam_end(sshpam_handle, sshpam_err); + sshpam_handle = NULL; + return (-1); + } +#ifdef PAM_TTY_KLUDGE + /* + * Some silly PAM modules (e.g. pam_time) require a TTY to operate. + * sshd doesn't set the tty until too late in the auth process and + * may not even set one (for tty-less connections) + */ + debug("PAM: setting PAM_TTY to \"ssh\""); + sshpam_err = pam_set_item(sshpam_handle, PAM_TTY, "ssh"); + if (sshpam_err != PAM_SUCCESS) { + pam_end(sshpam_handle, sshpam_err); + sshpam_handle = NULL; + return (-1); + } +#endif + return (0); +} + +static void * +sshpam_init_ctx(Authctxt *authctxt) +{ + struct pam_ctxt *ctxt; + int socks[2]; + + debug3("PAM: %s entering", __func__); + /* + * Refuse to start if we don't have PAM enabled or do_pam_account + * has previously failed. + */ + if (!options.use_pam || sshpam_account_status == 0) + return NULL; + + /* Initialize PAM */ + if (sshpam_init(authctxt) == -1) { + error("PAM: initialization failed"); + return (NULL); + } + + ctxt = xcalloc(1, sizeof *ctxt); + + /* Start the authentication thread */ + if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, socks) == -1) { + error("PAM: failed create sockets: %s", strerror(errno)); + xfree(ctxt); + return (NULL); + } + ctxt->pam_psock = socks[0]; + ctxt->pam_csock = socks[1]; + if (pthread_create(&ctxt->pam_thread, NULL, sshpam_thread, ctxt) == -1) { + error("PAM: failed to start authentication thread: %s", + strerror(errno)); + close(socks[0]); + close(socks[1]); + xfree(ctxt); + return (NULL); + } + cleanup_ctxt = ctxt; + return (ctxt); +} + +static int +sshpam_query(void *ctx, char **name, char **info, + u_int *num, char ***prompts, u_int **echo_on) +{ + Buffer buffer; + struct pam_ctxt *ctxt = ctx; + size_t plen; + u_char type; + char *msg; + size_t len, mlen; + + debug3("PAM: %s entering", __func__); + buffer_init(&buffer); + *name = xstrdup(""); + *info = xstrdup(""); + *prompts = xmalloc(sizeof(char *)); + **prompts = NULL; + plen = 0; + *echo_on = xmalloc(sizeof(u_int)); + while (ssh_msg_recv(ctxt->pam_psock, &buffer) == 0) { + type = buffer_get_char(&buffer); + msg = buffer_get_string(&buffer, NULL); + mlen = strlen(msg); + switch (type) { + case PAM_PROMPT_ECHO_ON: + case PAM_PROMPT_ECHO_OFF: + *num = 1; + len = plen + mlen + 1; + **prompts = xrealloc(**prompts, 1, len); + strlcpy(**prompts + plen, msg, len - plen); + plen += mlen; + **echo_on = (type == PAM_PROMPT_ECHO_ON); + xfree(msg); + return (0); + case PAM_ERROR_MSG: + case PAM_TEXT_INFO: + /* accumulate messages */ + len = plen + mlen + 2; + **prompts = xrealloc(**prompts, 1, len); + strlcpy(**prompts + plen, msg, len - plen); + plen += mlen; + strlcat(**prompts + plen, "\n", len - plen); + plen++; + xfree(msg); + break; + case PAM_ACCT_EXPIRED: + sshpam_account_status = 0; + /* FALLTHROUGH */ + case PAM_AUTH_ERR: + debug3("PAM: %s", pam_strerror(sshpam_handle, type)); + if (**prompts != NULL && strlen(**prompts) != 0) { + *info = **prompts; + **prompts = NULL; + *num = 0; + **echo_on = 0; + ctxt->pam_done = -1; + xfree(msg); + return 0; + } + /* FALLTHROUGH */ + case PAM_SUCCESS: + if (**prompts != NULL) { + /* drain any accumulated messages */ + debug("PAM: %s", **prompts); + buffer_append(&loginmsg, **prompts, + strlen(**prompts)); + xfree(**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; + xfree(msg); + return (0); + } + error("PAM: %s for %s%.100s from %.100s", msg, + sshpam_authctxt->valid ? "" : "illegal user ", + sshpam_authctxt->user, + get_remote_name_or_ip(utmp_len, options.use_dns)); + /* FALLTHROUGH */ + default: + *num = 0; + **echo_on = 0; + xfree(msg); + ctxt->pam_done = -1; + return (-1); + } + } + return (-1); +} + +/* XXX - see also comment in auth-chall.c:verify_response */ +static int +sshpam_respond(void *ctx, u_int num, char **resp) +{ + Buffer buffer; + struct pam_ctxt *ctxt = ctx; + + debug2("PAM: %s entering, %u responses", __func__, num); + switch (ctxt->pam_done) { + case 1: + sshpam_authenticated = 1; + return (0); + case 0: + break; + default: + return (-1); + } + if (num != 1) { + error("PAM: expected one response, got %u", num); + return (-1); + } + buffer_init(&buffer); + if (sshpam_authctxt->valid && + (sshpam_authctxt->pw->pw_uid != 0 || + options.permit_root_login == PERMIT_YES)) + buffer_put_cstring(&buffer, *resp); + else + buffer_put_cstring(&buffer, badpw); + if (ssh_msg_send(ctxt->pam_psock, PAM_AUTHTOK, &buffer) == -1) { + buffer_free(&buffer); + return (-1); + } + buffer_free(&buffer); + return (1); +} + +static void +sshpam_free_ctx(void *ctxtp) +{ + struct pam_ctxt *ctxt = ctxtp; + + debug3("PAM: %s entering", __func__); + sshpam_thread_cleanup(); + xfree(ctxt); + /* + * We don't call sshpam_cleanup() here because we may need the PAM + * handle at a later stage, e.g. when setting up a session. It's + * still on the cleanup list, so pam_end() *will* be called before + * the server process terminates. + */ +} + +KbdintDevice sshpam_device = { + "pam", + sshpam_init_ctx, + sshpam_query, + sshpam_respond, + sshpam_free_ctx +}; + +KbdintDevice mm_sshpam_device = { + "pam", + mm_sshpam_init_ctx, + mm_sshpam_query, + mm_sshpam_respond, + mm_sshpam_free_ctx +}; + +/* + * This replaces auth-pam.c + */ +void +start_pam(Authctxt *authctxt) +{ + if (!options.use_pam) + fatal("PAM: initialisation requested when UsePAM=no"); + + if (sshpam_init(authctxt) == -1) + fatal("PAM: initialisation failed"); +} + +void +finish_pam(void) +{ + sshpam_cleanup(); +} + +u_int +do_pam_account(void) +{ + debug("%s: called", __func__); + if (sshpam_account_status != -1) + return (sshpam_account_status); + + sshpam_err = pam_acct_mgmt(sshpam_handle, 0); + debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err, + pam_strerror(sshpam_handle, sshpam_err)); + + if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) { + sshpam_account_status = 0; + return (sshpam_account_status); + } + + if (sshpam_err == PAM_NEW_AUTHTOK_REQD) + sshpam_password_change_required(1); + + sshpam_account_status = 1; + return (sshpam_account_status); +} + +void +do_pam_set_tty(const char *tty) +{ + if (tty != NULL) { + debug("PAM: setting PAM_TTY to \"%s\"", tty); + sshpam_err = pam_set_item(sshpam_handle, PAM_TTY, tty); + if (sshpam_err != PAM_SUCCESS) + fatal("PAM: failed to set PAM_TTY: %s", + pam_strerror(sshpam_handle, sshpam_err)); + } +} + +void +do_pam_setcred(int init) +{ + sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, + (const void *)&store_conv); + if (sshpam_err != PAM_SUCCESS) + fatal("PAM: failed to set PAM_CONV: %s", + pam_strerror(sshpam_handle, sshpam_err)); + if (init) { + debug("PAM: establishing credentials"); + sshpam_err = pam_setcred(sshpam_handle, PAM_ESTABLISH_CRED); + } else { + debug("PAM: reinitializing credentials"); + sshpam_err = pam_setcred(sshpam_handle, PAM_REINITIALIZE_CRED); + } + if (sshpam_err == PAM_SUCCESS) { + sshpam_cred_established = 1; + return; + } + if (sshpam_authenticated) + fatal("PAM: pam_setcred(): %s", + pam_strerror(sshpam_handle, sshpam_err)); + else + debug("PAM: pam_setcred(): %s", + pam_strerror(sshpam_handle, sshpam_err)); +} + +static int +sshpam_tty_conv(int n, sshpam_const struct pam_message **msg, + struct pam_response **resp, void *data) +{ + char input[PAM_MAX_MSG_SIZE]; + struct pam_response *reply; + int i; + + debug3("PAM: %s called with %d messages", __func__, n); + + *resp = NULL; + + if (n <= 0 || n > PAM_MAX_NUM_MSG || !isatty(STDIN_FILENO)) + return (PAM_CONV_ERR); + + if ((reply = calloc(n, sizeof(*reply))) == NULL) + return (PAM_CONV_ERR); + + for (i = 0; i < n; ++i) { + switch (PAM_MSG_MEMBER(msg, i, msg_style)) { + case PAM_PROMPT_ECHO_OFF: + reply[i].resp = + read_passphrase(PAM_MSG_MEMBER(msg, i, msg), + RP_ALLOW_STDIN); + reply[i].resp_retcode = PAM_SUCCESS; + break; + case PAM_PROMPT_ECHO_ON: + fprintf(stderr, "%s\n", PAM_MSG_MEMBER(msg, i, msg)); + if (fgets(input, sizeof input, stdin) == NULL) + input[0] = '\0'; + if ((reply[i].resp = strdup(input)) == NULL) + goto fail; + reply[i].resp_retcode = PAM_SUCCESS; + break; + case PAM_ERROR_MSG: + case PAM_TEXT_INFO: + fprintf(stderr, "%s\n", PAM_MSG_MEMBER(msg, i, msg)); + reply[i].resp_retcode = PAM_SUCCESS; + break; + default: + goto fail; + } + } + *resp = reply; + return (PAM_SUCCESS); + + fail: + for(i = 0; i < n; i++) { + if (reply[i].resp != NULL) + xfree(reply[i].resp); + } + xfree(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); + xfree(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++) + xfree(*envp); + xfree(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++) { + if (reply[i].resp != NULL) + xfree(reply[i].resp); + } + xfree(reply); + return (PAM_CONV_ERR); +} + +static struct pam_conv passwd_conv = { sshpam_passwd_conv, NULL }; + +/* + * Attempt password authentication via PAM + */ +int +sshpam_auth_passwd(Authctxt *authctxt, const char *password) +{ + int flags = (options.permit_empty_passwd == 0 ? + PAM_DISALLOW_NULL_AUTHTOK : 0); + + if (!options.use_pam || sshpam_handle == NULL) + fatal("PAM: %s called when PAM disabled or failed to " + "initialise.", __func__); + + sshpam_password = password; + sshpam_authctxt = authctxt; + + /* + * If the user logging in is invalid, or is root but is not permitted + * by PermitRootLogin, use an invalid password to prevent leaking + * information via timing (eg if the PAM config has a delay on fail). + */ + if (!authctxt->valid || (authctxt->pw->pw_uid == 0 && + options.permit_root_login != PERMIT_YES)) + sshpam_password = badpw; + + sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, + (const void *)&passwd_conv); + if (sshpam_err != PAM_SUCCESS) + fatal("PAM: %s: failed to set PAM_CONV: %s", __func__, + pam_strerror(sshpam_handle, sshpam_err)); + + sshpam_err = pam_authenticate(sshpam_handle, flags); + sshpam_password = NULL; + if (sshpam_err == PAM_SUCCESS && authctxt->valid) { + debug("PAM: password authentication accepted for %.100s", + authctxt->user); + return 1; + } else { + debug("PAM: password authentication failed for %.100s: %s", + authctxt->valid ? authctxt->user : "an illegal user", + pam_strerror(sshpam_handle, sshpam_err)); + return 0; + } +} +#endif /* USE_PAM */
diff --git a/openssh-6.0p1/auth-pam.h b/openssh-6.0p1/auth-pam.h new file mode 100644 index 0000000..a1a2b52 --- /dev/null +++ b/openssh-6.0p1/auth-pam.h
@@ -0,0 +1,50 @@ +/* $Id: auth-pam.h,v 1.27 2004/09/11 12:17:26 dtucker Exp $ */ + +/* + * Copyright (c) 2000 Damien Miller. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" +#ifdef USE_PAM + +#if !defined(SSHD_PAM_SERVICE) +# define SSHD_PAM_SERVICE __progname +#endif + +void start_pam(Authctxt *); +void finish_pam(void); +u_int do_pam_account(void); +void do_pam_session(void); +void do_pam_set_tty(const char *); +void do_pam_setcred(int ); +void do_pam_chauthtok(void); +int do_pam_putenv(char *, char *); +char ** fetch_pam_environment(void); +char ** fetch_pam_child_environment(void); +void free_pam_environment(char **); +void sshpam_thread_cleanup(void); +void sshpam_cleanup(void); +int sshpam_auth_passwd(Authctxt *, const char *); +int is_pam_session_open(void); + +#endif /* USE_PAM */
diff --git a/openssh-6.0p1/auth-passwd.c b/openssh-6.0p1/auth-passwd.c new file mode 100644 index 0000000..b1c6ce0 --- /dev/null +++ b/openssh-6.0p1/auth-passwd.c
@@ -0,0 +1,214 @@ +/* $OpenBSD: auth-passwd.c,v 1.43 2007/09/21 08:15:29 djm Exp $ */ +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * Password authentication. This file contains the functions to check whether + * the password is valid for the user. + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + * + * Copyright (c) 1999 Dug Song. All rights reserved. + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#include <sys/types.h> + +#include <pwd.h> +#include <stdio.h> +#include <string.h> +#include <stdarg.h> + +#include "packet.h" +#include "buffer.h" +#include "log.h" +#include "servconf.h" +#include "key.h" +#include "hostfile.h" +#include "auth.h" +#include "auth-options.h" + +extern Buffer loginmsg; +extern ServerOptions options; + +#ifdef HAVE_LOGIN_CAP +extern login_cap_t *lc; +#endif + + +#define DAY (24L * 60 * 60) /* 1 day in seconds */ +#define TWO_WEEKS (2L * 7 * DAY) /* 2 weeks in seconds */ + +void +disable_forwarding(void) +{ + no_port_forwarding_flag = 1; + no_agent_forwarding_flag = 1; + no_x11_forwarding_flag = 1; +} + +/* + * Tries to authenticate the user using password. Returns true if + * authentication succeeds. + */ +int +auth_password(Authctxt *authctxt, const char *password) +{ + struct passwd * pw = authctxt->pw; + int result, ok = authctxt->valid; +#if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE) + static int expire_checked = 0; +#endif + +#ifndef HAVE_CYGWIN + if (pw->pw_uid == 0 && options.permit_root_login != PERMIT_YES) + ok = 0; +#endif + if (*password == '\0' && options.permit_empty_passwd == 0) + return 0; + +#ifdef KRB5 + if (options.kerberos_authentication == 1) { + int ret = auth_krb5_password(authctxt, password); + if (ret == 1 || ret == 0) + return ret && ok; + /* Fall back to ordinary passwd authentication. */ + } +#endif +#ifdef HAVE_CYGWIN + { + HANDLE hToken = cygwin_logon_user(pw, password); + + if (hToken == INVALID_HANDLE_VALUE) + return 0; + cygwin_set_impersonation_token(hToken); + return ok; + } +#endif +#ifdef USE_PAM + if (options.use_pam) + return (sshpam_auth_passwd(authctxt, password) && ok); +#endif +#if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE) + if (!expire_checked) { + expire_checked = 1; + if (auth_shadow_pwexpired(authctxt)) + authctxt->force_pwchange = 1; + } +#endif + result = sys_auth_passwd(authctxt, password); + if (authctxt->force_pwchange) + disable_forwarding(); + return (result && ok); +} + +#ifdef BSD_AUTH +static void +warn_expiry(Authctxt *authctxt, auth_session_t *as) +{ + char buf[256]; + quad_t pwtimeleft, actimeleft, daysleft, pwwarntime, acwarntime; + + pwwarntime = acwarntime = TWO_WEEKS; + + pwtimeleft = auth_check_change(as); + actimeleft = auth_check_expire(as); +#ifdef HAVE_LOGIN_CAP + if (authctxt->valid) { + pwwarntime = login_getcaptime(lc, "password-warn", TWO_WEEKS, + TWO_WEEKS); + acwarntime = login_getcaptime(lc, "expire-warn", TWO_WEEKS, + TWO_WEEKS); + } +#endif + if (pwtimeleft != 0 && pwtimeleft < pwwarntime) { + daysleft = pwtimeleft / DAY + 1; + snprintf(buf, sizeof(buf), + "Your password will expire in %lld day%s.\n", + daysleft, daysleft == 1 ? "" : "s"); + buffer_append(&loginmsg, buf, strlen(buf)); + } + if (actimeleft != 0 && actimeleft < acwarntime) { + daysleft = actimeleft / DAY + 1; + snprintf(buf, sizeof(buf), + "Your account will expire in %lld day%s.\n", + daysleft, daysleft == 1 ? "" : "s"); + buffer_append(&loginmsg, buf, strlen(buf)); + } +} + +int +sys_auth_passwd(Authctxt *authctxt, const char *password) +{ + struct passwd *pw = authctxt->pw; + auth_session_t *as; + static int expire_checked = 0; + + as = auth_usercheck(pw->pw_name, authctxt->style, "auth-ssh", + (char *)password); + if (as == NULL) + return (0); + if (auth_getstate(as) & AUTH_PWEXPIRED) { + auth_close(as); + disable_forwarding(); + authctxt->force_pwchange = 1; + return (1); + } else { + if (!expire_checked) { + expire_checked = 1; + warn_expiry(authctxt, as); + } + return (auth_close(as)); + } +} +#elif !defined(CUSTOM_SYS_AUTH_PASSWD) +int +sys_auth_passwd(Authctxt *authctxt, const char *password) +{ + struct passwd *pw = authctxt->pw; + char *encrypted_password; + + /* Just use the supplied fake password if authctxt is invalid */ + char *pw_password = authctxt->valid ? shadow_pw(pw) : pw->pw_passwd; + + /* Check for users with no password. */ + if (strcmp(pw_password, "") == 0 && strcmp(password, "") == 0) + return (1); + + /* Encrypt the candidate password using the proper salt. */ + encrypted_password = xcrypt(password, + (pw_password[0] && pw_password[1]) ? pw_password : "xx"); + + /* + * Authentication is accepted if the encrypted passwords + * are identical. + */ + return (strcmp(encrypted_password, pw_password) == 0); +} +#endif
diff --git a/openssh-6.0p1/auth-rh-rsa.c b/openssh-6.0p1/auth-rh-rsa.c new file mode 100644 index 0000000..b21a0f4 --- /dev/null +++ b/openssh-6.0p1/auth-rh-rsa.c
@@ -0,0 +1,103 @@ +/* $OpenBSD: auth-rh-rsa.c,v 1.43 2010/03/04 10:36:03 djm Exp $ */ +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * Rhosts or /etc/hosts.equiv authentication combined with RSA host + * authentication. + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ + +#include "includes.h" + +#include <sys/types.h> + +#include <pwd.h> +#include <stdarg.h> + +#include "packet.h" +#include "uidswap.h" +#include "log.h" +#include "buffer.h" +#include "servconf.h" +#include "key.h" +#include "hostfile.h" +#include "pathnames.h" +#include "auth.h" +#include "canohost.h" +#ifdef GSSAPI +#include "ssh-gss.h" +#endif +#include "monitor_wrap.h" + +/* import */ +extern ServerOptions options; + +int +auth_rhosts_rsa_key_allowed(struct passwd *pw, char *cuser, char *chost, + Key *client_host_key) +{ + HostStatus host_status; + + if (auth_key_is_revoked(client_host_key)) + return 0; + + /* Check if we would accept it using rhosts authentication. */ + if (!auth_rhosts(pw, cuser)) + return 0; + + host_status = check_key_in_hostfiles(pw, client_host_key, + chost, _PATH_SSH_SYSTEM_HOSTFILE, + options.ignore_user_known_hosts ? NULL : _PATH_SSH_USER_HOSTFILE); + + return (host_status == HOST_OK); +} + +/* + * Tries to authenticate the user using the .rhosts file and the host using + * its host key. Returns true if authentication succeeds. + */ +int +auth_rhosts_rsa(Authctxt *authctxt, char *cuser, Key *client_host_key) +{ + char *chost; + struct passwd *pw = authctxt->pw; + + debug("Trying rhosts with RSA host authentication for client user %.100s", + cuser); + + if (!authctxt->valid || client_host_key == NULL || + client_host_key->rsa == NULL) + return 0; + + chost = (char *)get_canonical_hostname(options.use_dns); + debug("Rhosts RSA authentication: canonical host %.900s", chost); + + if (!PRIVSEP(auth_rhosts_rsa_key_allowed(pw, cuser, chost, client_host_key))) { + debug("Rhosts with RSA host authentication denied: unknown or invalid host key"); + packet_send_debug("Your host key cannot be verified: unknown or invalid host key."); + return 0; + } + /* A matching host key was found and is known. */ + + /* Perform the challenge-response dialog with the client for the host key. */ + if (!auth_rsa_challenge_dialog(client_host_key)) { + logit("Client on %.800s failed to respond correctly to host authentication.", + chost); + return 0; + } + /* + * We have authenticated the user using .rhosts or /etc/hosts.equiv, + * and the host using RSA. We accept the authentication. + */ + + verbose("Rhosts with RSA host authentication accepted for %.100s, %.100s on %.700s.", + pw->pw_name, cuser, chost); + packet_send_debug("Rhosts with RSA host authentication accepted."); + return 1; +}
diff --git a/openssh-6.0p1/auth-rhosts.c b/openssh-6.0p1/auth-rhosts.c new file mode 100644 index 0000000..06ae7f0 --- /dev/null +++ b/openssh-6.0p1/auth-rhosts.c
@@ -0,0 +1,321 @@ +/* $OpenBSD: auth-rhosts.c,v 1.44 2010/03/07 11:57:13 dtucker Exp $ */ +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * Rhosts authentication. This file contains code to check whether to admit + * the login based on rhosts authentication. This file also processes + * /etc/hosts.equiv. + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ + +#include "includes.h" + +#include <sys/types.h> +#include <sys/stat.h> + +#ifdef HAVE_NETGROUP_H +# include <netgroup.h> +#endif +#include <pwd.h> +#include <stdio.h> +#include <string.h> +#include <stdarg.h> +#include <fcntl.h> +#include <unistd.h> + +#include "packet.h" +#include "buffer.h" +#include "uidswap.h" +#include "pathnames.h" +#include "log.h" +#include "servconf.h" +#include "canohost.h" +#include "key.h" +#include "hostfile.h" +#include "auth.h" +#include "misc.h" + +/* import */ +extern ServerOptions options; +extern int use_privsep; + +/* + * This function processes an rhosts-style file (.rhosts, .shosts, or + * /etc/hosts.equiv). This returns true if authentication can be granted + * based on the file, and returns zero otherwise. + */ + +static int +check_rhosts_file(const char *filename, const char *hostname, + const char *ipaddr, const char *client_user, + const char *server_user) +{ + FILE *f; + char buf[1024]; /* Must not be larger than host, user, dummy below. */ + 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 be at least as big as buf to avoid overflows. */ + char hostbuf[1024], userbuf[1024], dummy[1024], *host, *user, *cp; + int negated; + + for (cp = buf; *cp == ' ' || *cp == '\t'; cp++) + ; + if (*cp == '#' || *cp == '\n' || !*cp) + continue; + + /* + * NO_PLUS is supported at least on OSF/1. We skip it (we + * don't ever support the plus syntax). + */ + if (strncmp(cp, "NO_PLUS", 7) == 0) + continue; + + /* + * This should be safe because each buffer is as big as the + * whole string, and thus cannot be overwritten. + */ + switch (sscanf(buf, "%1023s %1023s %1023s", hostbuf, userbuf, + dummy)) { + case 0: + auth_debug_add("Found empty line in %.100s.", filename); + continue; + case 1: + /* Host name only. */ + strlcpy(userbuf, server_user, sizeof(userbuf)); + break; + case 2: + /* Got both host and user name. */ + break; + case 3: + auth_debug_add("Found garbage in %.100s.", filename); + continue; + default: + /* Weird... */ + continue; + } + + host = hostbuf; + user = userbuf; + negated = 0; + + /* Process negated host names, or positive netgroups. */ + if (host[0] == '-') { + negated = 1; + host++; + } else if (host[0] == '+') + host++; + + if (user[0] == '-') { + negated = 1; + user++; + } else if (user[0] == '+') + user++; + + /* Check for empty host/user names (particularly '+'). */ + if (!host[0] || !user[0]) { + /* We come here if either was '+' or '-'. */ + auth_debug_add("Ignoring wild host/user names in %.100s.", + filename); + continue; + } + /* Verify that host name matches. */ + if (host[0] == '@') { + if (!innetgr(host + 1, hostname, NULL, NULL) && + !innetgr(host + 1, ipaddr, NULL, NULL)) + continue; + } else if (strcasecmp(host, hostname) && strcmp(host, ipaddr) != 0) + continue; /* Different hostname. */ + + /* Verify that user name matches. */ + if (user[0] == '@') { + if (!innetgr(user + 1, NULL, client_user, NULL)) + continue; + } else if (strcmp(user, client_user) != 0) + continue; /* Different username. */ + + /* Found the user and host. */ + fclose(f); + + /* If the entry was negated, deny access. */ + if (negated) { + auth_debug_add("Matched negative entry in %.100s.", + filename); + return 0; + } + /* Accept authentication. */ + return 1; + } + + /* Authentication using this file denied. */ + fclose(f); + return 0; +} + +/* + * Tries to authenticate the user using the .shosts or .rhosts file. Returns + * true if authentication succeeds. If ignore_rhosts is true, only + * /etc/hosts.equiv will be considered (.rhosts and .shosts are ignored). + */ + +int +auth_rhosts(struct passwd *pw, const char *client_user) +{ + const char *hostname, *ipaddr; + + hostname = get_canonical_hostname(options.use_dns); + ipaddr = get_remote_ipaddr(); + return auth_rhosts2(pw, client_user, hostname, ipaddr); +} + +static int +auth_rhosts2_raw(struct passwd *pw, const char *client_user, const char *hostname, + const char *ipaddr) +{ + char buf[1024]; + struct stat st; + static const char *rhosts_files[] = {".shosts", ".rhosts", NULL}; + u_int rhosts_file_index; + + debug2("auth_rhosts2: clientuser %s hostname %s ipaddr %s", + client_user, hostname, ipaddr); + + /* Switch to the user's uid. */ + temporarily_use_uid(pw); + /* + * Quick check: if the user has no .shosts or .rhosts files, return + * failure immediately without doing costly lookups from name + * servers. + */ + for (rhosts_file_index = 0; rhosts_files[rhosts_file_index]; + rhosts_file_index++) { + /* Check users .rhosts or .shosts. */ + snprintf(buf, sizeof buf, "%.500s/%.100s", + pw->pw_dir, rhosts_files[rhosts_file_index]); + if (stat(buf, &st) >= 0) + break; + } + /* Switch back to privileged uid. */ + restore_uid(); + + /* Deny if The user has no .shosts or .rhosts file and there are no system-wide files. */ + if (!rhosts_files[rhosts_file_index] && + stat(_PATH_RHOSTS_EQUIV, &st) < 0 && + stat(_PATH_SSH_HOSTS_EQUIV, &st) < 0) + return 0; + + /* If not logging in as superuser, try /etc/hosts.equiv and shosts.equiv. */ + if (pw->pw_uid != 0) { + if (check_rhosts_file(_PATH_RHOSTS_EQUIV, hostname, ipaddr, + client_user, pw->pw_name)) { + auth_debug_add("Accepted for %.100s [%.100s] by /etc/hosts.equiv.", + hostname, ipaddr); + return 1; + } + if (check_rhosts_file(_PATH_SSH_HOSTS_EQUIV, hostname, ipaddr, + client_user, pw->pw_name)) { + auth_debug_add("Accepted for %.100s [%.100s] by %.100s.", + hostname, ipaddr, _PATH_SSH_HOSTS_EQUIV); + return 1; + } + } + /* + * Check that the home directory is owned by root or the user, and is + * not group or world writable. + */ + if (stat(pw->pw_dir, &st) < 0) { + logit("Rhosts authentication refused for %.100s: " + "no home directory %.200s", pw->pw_name, pw->pw_dir); + auth_debug_add("Rhosts authentication refused for %.100s: " + "no home directory %.200s", pw->pw_name, pw->pw_dir); + return 0; + } + if (options.strict_modes && + ((st.st_uid != 0 && st.st_uid != pw->pw_uid) || + (st.st_mode & 022) != 0)) { + logit("Rhosts authentication refused for %.100s: " + "bad ownership or modes for home directory.", pw->pw_name); + auth_debug_add("Rhosts authentication refused for %.100s: " + "bad ownership or modes for home directory.", pw->pw_name); + return 0; + } + /* Temporarily use the user's uid. */ + temporarily_use_uid(pw); + + /* Check all .rhosts files (currently .shosts and .rhosts). */ + for (rhosts_file_index = 0; rhosts_files[rhosts_file_index]; + rhosts_file_index++) { + /* Check users .rhosts or .shosts. */ + snprintf(buf, sizeof buf, "%.500s/%.100s", + pw->pw_dir, rhosts_files[rhosts_file_index]); + if (stat(buf, &st) < 0) + continue; + + /* + * Make sure that the file is either owned by the user or by + * root, and make sure it is not writable by anyone but the + * owner. This is to help avoid novices accidentally + * allowing access to their account by anyone. + */ + if (options.strict_modes && + ((st.st_uid != 0 && st.st_uid != pw->pw_uid) || + (st.st_mode & 022) != 0)) { + logit("Rhosts authentication refused for %.100s: bad modes for %.200s", + pw->pw_name, buf); + auth_debug_add("Bad file modes for %.200s", buf); + continue; + } + /* Check if we have been configured to ignore .rhosts and .shosts files. */ + if (options.ignore_rhosts) { + auth_debug_add("Server has been configured to ignore %.100s.", + rhosts_files[rhosts_file_index]); + continue; + } + /* Check if authentication is permitted by the file. */ + if (check_rhosts_file(buf, hostname, ipaddr, client_user, pw->pw_name)) { + auth_debug_add("Accepted by %.100s.", + rhosts_files[rhosts_file_index]); + /* Restore the privileged uid. */ + restore_uid(); + auth_debug_add("Accepted host %s ip %s client_user %s server_user %s", + hostname, ipaddr, client_user, pw->pw_name); + return 1; + } + } + + /* Restore the privileged uid. */ + restore_uid(); + return 0; +} + +int +auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname, + const char *ipaddr) +{ + return auth_rhosts2_raw(pw, client_user, hostname, ipaddr); +}
diff --git a/openssh-6.0p1/auth-rsa.c b/openssh-6.0p1/auth-rsa.c new file mode 100644 index 0000000..4ab46cd --- /dev/null +++ b/openssh-6.0p1/auth-rsa.c
@@ -0,0 +1,337 @@ +/* $OpenBSD: auth-rsa.c,v 1.80 2011/05/23 03:30:07 djm Exp $ */ +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * RSA-based authentication. This code determines whether to admit a login + * based on RSA authentication. This file also contains functions to check + * validity of the host key. + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ + +#include "includes.h" + +#include <sys/types.h> +#include <sys/stat.h> + +#include <openssl/rsa.h> +#include <openssl/md5.h> + +#include <pwd.h> +#include <stdio.h> +#include <stdarg.h> +#include <string.h> + +#include "xmalloc.h" +#include "rsa.h" +#include "packet.h" +#include "ssh1.h" +#include "uidswap.h" +#include "match.h" +#include "buffer.h" +#include "pathnames.h" +#include "log.h" +#include "servconf.h" +#include "key.h" +#include "auth-options.h" +#include "hostfile.h" +#include "auth.h" +#ifdef GSSAPI +#include "ssh-gss.h" +#endif +#include "monitor_wrap.h" +#include "ssh.h" +#include "misc.h" + +/* import */ +extern ServerOptions options; + +/* + * Session identifier that is used to bind key exchange and authentication + * responses to a particular session. + */ +extern u_char session_id[16]; + +/* + * The .ssh/authorized_keys file contains public keys, one per line, in the + * following format: + * options bits e n comment + * where bits, e and n are decimal numbers, + * and comment is any string of characters up to newline. The maximum + * length of a line is SSH_MAX_PUBKEY_BYTES characters. See sshd(8) for a + * description of the options. + */ + +BIGNUM * +auth_rsa_generate_challenge(Key *key) +{ + BIGNUM *challenge; + BN_CTX *ctx; + + if ((challenge = BN_new()) == NULL) + fatal("auth_rsa_generate_challenge: BN_new() failed"); + /* Generate a random challenge. */ + if (BN_rand(challenge, 256, 0, 0) == 0) + fatal("auth_rsa_generate_challenge: BN_rand failed"); + if ((ctx = BN_CTX_new()) == NULL) + fatal("auth_rsa_generate_challenge: BN_CTX_new failed"); + if (BN_mod(challenge, challenge, key->rsa->n, ctx) == 0) + fatal("auth_rsa_generate_challenge: BN_mod failed"); + BN_CTX_free(ctx); + + return challenge; +} + +int +auth_rsa_verify_response(Key *key, BIGNUM *challenge, u_char response[16]) +{ + u_char buf[32], mdbuf[16]; + MD5_CTX md; + int len; + + /* don't allow short keys */ + if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) { + error("auth_rsa_verify_response: RSA modulus too small: %d < minimum %d bits", + BN_num_bits(key->rsa->n), SSH_RSA_MINIMUM_MODULUS_SIZE); + return (0); + } + + /* The response is MD5 of decrypted challenge plus session id. */ + len = BN_num_bytes(challenge); + if (len <= 0 || len > 32) + fatal("auth_rsa_verify_response: bad challenge length %d", len); + memset(buf, 0, 32); + BN_bn2bin(challenge, buf + 32 - len); + MD5_Init(&md); + MD5_Update(&md, buf, 32); + MD5_Update(&md, session_id, 16); + MD5_Final(mdbuf, &md); + + /* Verify that the response is the original challenge. */ + if (timingsafe_bcmp(response, mdbuf, 16) != 0) { + /* Wrong answer. */ + return (0); + } + /* Correct answer. */ + return (1); +} + +/* + * Performs the RSA authentication challenge-response dialog with the client, + * and returns true (non-zero) if the client gave the correct answer to + * our challenge; returns zero if the client gives a wrong answer. + */ + +int +auth_rsa_challenge_dialog(Key *key) +{ + BIGNUM *challenge, *encrypted_challenge; + u_char response[16]; + int i, success; + + if ((encrypted_challenge = BN_new()) == NULL) + fatal("auth_rsa_challenge_dialog: BN_new() failed"); + + challenge = PRIVSEP(auth_rsa_generate_challenge(key)); + + /* Encrypt the challenge with the public key. */ + rsa_public_encrypt(encrypted_challenge, challenge, key->rsa); + + /* Send the encrypted challenge to the client. */ + packet_start(SSH_SMSG_AUTH_RSA_CHALLENGE); + packet_put_bignum(encrypted_challenge); + packet_send(); + BN_clear_free(encrypted_challenge); + packet_write_wait(); + + /* Wait for a response. */ + packet_read_expect(SSH_CMSG_AUTH_RSA_RESPONSE); + for (i = 0; i < 16; i++) + response[i] = (u_char)packet_get_char(); + packet_check_eom(); + + success = PRIVSEP(auth_rsa_verify_response(key, challenge, response)); + BN_clear_free(challenge); + return (success); +} + +static int +rsa_key_allowed_in_file(struct passwd *pw, char *file, + const BIGNUM *client_n, Key **rkey) +{ + char line[SSH_MAX_PUBKEY_BYTES]; + int allowed = 0; + u_int bits; + FILE *f; + u_long linenum = 0; + Key *key; + + debug("trying public RSA key file %s", file); + if ((f = auth_openkeyfile(file, pw, options.strict_modes)) == NULL) + return 0; + + /* + * Go though the accepted keys, looking for the current key. If + * found, perform a challenge-response dialog to verify that the + * user really has the corresponding private key. + */ + key = key_new(KEY_RSA1); + while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) { + char *cp; + char *key_options; + int keybits; + + /* Skip leading whitespace, empty and comment lines. */ + for (cp = line; *cp == ' ' || *cp == '\t'; cp++) + ; + if (!*cp || *cp == '\n' || *cp == '#') + continue; + + /* + * Check if there are options for this key, and if so, + * save their starting address and skip the option part + * for now. If there are no options, set the starting + * address to NULL. + */ + if (*cp < '0' || *cp > '9') { + int quoted = 0; + key_options = cp; + for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) { + if (*cp == '\\' && cp[1] == '"') + cp++; /* Skip both */ + else if (*cp == '"') + quoted = !quoted; + } + } else + key_options = NULL; + + /* Parse the key from the line. */ + if (hostfile_read_key(&cp, &bits, key) == 0) { + debug("%.100s, line %lu: non ssh1 key syntax", + file, linenum); + continue; + } + /* cp now points to the comment part. */ + + /* + * Check if the we have found the desired key (identified + * by its modulus). + */ + if (BN_cmp(key->rsa->n, client_n) != 0) + continue; + + /* check the real bits */ + keybits = BN_num_bits(key->rsa->n); + if (keybits < 0 || bits != (u_int)keybits) + logit("Warning: %s, line %lu: keysize mismatch: " + "actual %d vs. announced %d.", + file, linenum, BN_num_bits(key->rsa->n), bits); + + /* Never accept a revoked key */ + if (auth_key_is_revoked(key)) + break; + + /* We have found the desired key. */ + /* + * If our options do not allow this key to be used, + * do not send challenge. + */ + if (!auth_parse_options(pw, key_options, file, linenum)) + continue; + if (key_is_cert_authority) + continue; + /* break out, this key is allowed */ + allowed = 1; + break; + } + + /* Close the file. */ + fclose(f); + + /* return key if allowed */ + if (allowed && rkey != NULL) + *rkey = key; + else + key_free(key); + + return allowed; +} + +/* + * check if there's user key matching client_n, + * return key if login is allowed, NULL otherwise + */ + +int +auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey) +{ + char *file; + u_int i, allowed = 0; + + temporarily_use_uid(pw); + + for (i = 0; !allowed && i < options.num_authkeys_files; i++) { + file = expand_authorized_keys( + options.authorized_keys_files[i], pw); + allowed = rsa_key_allowed_in_file(pw, file, client_n, rkey); + xfree(file); + } + + restore_uid(); + + return allowed; +} + +/* + * Performs the RSA authentication dialog with the client. This returns + * 0 if the client could not be authenticated, and 1 if authentication was + * successful. This may exit if there is a serious protocol violation. + */ +int +auth_rsa(Authctxt *authctxt, BIGNUM *client_n) +{ + Key *key; + char *fp; + struct passwd *pw = authctxt->pw; + + /* no user given */ + if (!authctxt->valid) + return 0; + + if (!PRIVSEP(auth_rsa_key_allowed(pw, client_n, &key))) { + auth_clear_options(); + return (0); + } + + /* Perform the challenge-response dialog for this key. */ + if (!auth_rsa_challenge_dialog(key)) { + /* Wrong response. */ + verbose("Wrong response to RSA authentication challenge."); + packet_send_debug("Wrong response to RSA authentication challenge."); + /* + * Break out of the loop. Otherwise we might send + * another challenge and break the protocol. + */ + key_free(key); + return (0); + } + /* + * Correct response. The client has been successfully + * authenticated. Note that we have not yet processed the + * options; this will be reset if the options cause the + * authentication to be rejected. + */ + fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); + verbose("Found matching %s key: %s", + key_type(key), fp); + xfree(fp); + key_free(key); + + packet_send_debug("RSA authentication accepted."); + return (1); +}
diff --git a/openssh-6.0p1/auth-shadow.c b/openssh-6.0p1/auth-shadow.c new file mode 100644 index 0000000..2190916 --- /dev/null +++ b/openssh-6.0p1/auth-shadow.c
@@ -0,0 +1,142 @@ +/* + * Copyright (c) 2004 Darren Tucker. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE) +#include <shadow.h> +#include <stdarg.h> +#include <string.h> +#include <time.h> + +#include "key.h" +#include "hostfile.h" +#include "auth.h" +#include "buffer.h" +#include "log.h" + +#ifdef DAY +# undef DAY +#endif +#define DAY (24L * 60 * 60) /* 1 day in seconds */ + +extern Buffer loginmsg; + +/* + * For the account and password expiration functions, we assume the expiry + * occurs the day after the day specified. + */ + +/* + * Check if specified account is expired. Returns 1 if account is expired, + * 0 otherwise. + */ +int +auth_shadow_acctexpired(struct spwd *spw) +{ + time_t today; + int daysleft; + char buf[256]; + + today = time(NULL) / DAY; + daysleft = spw->sp_expire - today; + debug3("%s: today %d sp_expire %d days left %d", __func__, (int)today, + (int)spw->sp_expire, daysleft); + + if (spw->sp_expire == -1) { + debug3("account expiration disabled"); + } else if (daysleft < 0) { + logit("Account %.100s has expired", spw->sp_namp); + return 1; + } else if (daysleft <= spw->sp_warn) { + debug3("account will expire in %d days", daysleft); + snprintf(buf, sizeof(buf), + "Your account will expire in %d day%s.\n", daysleft, + daysleft == 1 ? "" : "s"); + buffer_append(&loginmsg, buf, strlen(buf)); + } + + return 0; +} + +/* + * Checks password expiry for platforms that use shadow passwd files. + * Returns: 1 = password expired, 0 = password not expired + */ +int +auth_shadow_pwexpired(Authctxt *ctxt) +{ + struct spwd *spw = NULL; + const char *user = ctxt->pw->pw_name; + char buf[256]; + time_t today; + int daysleft, disabled = 0; + + if ((spw = getspnam((char *)user)) == NULL) { + error("Could not get shadow information for %.100s", user); + return 0; + } + + today = time(NULL) / DAY; + debug3("%s: today %d sp_lstchg %d sp_max %d", __func__, (int)today, + (int)spw->sp_lstchg, (int)spw->sp_max); + +#if defined(__hpux) && !defined(HAVE_SECUREWARE) + if (iscomsec()) { + struct pr_passwd *pr; + + pr = getprpwnam((char *)user); + + /* Test for Trusted Mode expiry disabled */ + if (pr != NULL && pr->ufld.fd_min == 0 && + pr->ufld.fd_lifetime == 0 && pr->ufld.fd_expire == 0 && + pr->ufld.fd_pw_expire_warning == 0 && + pr->ufld.fd_schange != 0) + disabled = 1; + } +#endif + + /* TODO: check sp_inact */ + daysleft = spw->sp_lstchg + spw->sp_max - today; + if (disabled) { + debug3("password expiration disabled"); + } else if (spw->sp_lstchg == 0) { + logit("User %.100s password has expired (root forced)", user); + return 1; + } else if (spw->sp_max == -1) { + debug3("password expiration disabled"); + } else if (daysleft < 0) { + logit("User %.100s password has expired (password aged)", user); + return 1; + } else if (daysleft <= spw->sp_warn) { + debug3("password will expire in %d days", daysleft); + snprintf(buf, sizeof(buf), + "Your password will expire in %d day%s.\n", daysleft, + daysleft == 1 ? "" : "s"); + buffer_append(&loginmsg, buf, strlen(buf)); + } + + return 0; +} +#endif /* USE_SHADOW && HAS_SHADOW_EXPIRE */
diff --git a/openssh-6.0p1/auth-sia.c b/openssh-6.0p1/auth-sia.c new file mode 100644 index 0000000..a9e1c25 --- /dev/null +++ b/openssh-6.0p1/auth-sia.c
@@ -0,0 +1,114 @@ +/* + * Copyright (c) 2002 Chris Adams. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#ifdef HAVE_OSF_SIA +#include <sia.h> +#include <siad.h> +#include <pwd.h> +#include <signal.h> +#include <setjmp.h> +#include <sys/resource.h> +#include <unistd.h> +#include <stdarg.h> +#include <string.h> + +#include "ssh.h" +#include "key.h" +#include "hostfile.h" +#include "auth.h" +#include "auth-sia.h" +#include "log.h" +#include "servconf.h" +#include "canohost.h" +#include "uidswap.h" + +extern ServerOptions options; +extern int saved_argc; +extern char **saved_argv; + +int +sys_auth_passwd(Authctxt *authctxt, const char *pass) +{ + int ret; + SIAENTITY *ent = NULL; + const char *host; + + host = get_canonical_hostname(options.use_dns); + + if (!authctxt->user || pass == NULL || pass[0] == '\0') + return (0); + + if (sia_ses_init(&ent, saved_argc, saved_argv, host, authctxt->user, + NULL, 0, NULL) != SIASUCCESS) + return (0); + + if ((ret = sia_ses_authent(NULL, pass, ent)) != SIASUCCESS) { + error("Couldn't authenticate %s from %s", + authctxt->user, host); + if (ret & SIASTOP) + sia_ses_release(&ent); + + return (0); + } + + sia_ses_release(&ent); + + return (1); +} + +void +session_setup_sia(struct passwd *pw, char *tty) +{ + SIAENTITY *ent = NULL; + const char *host; + + host = get_canonical_hostname(options.use_dns); + + if (sia_ses_init(&ent, saved_argc, saved_argv, host, pw->pw_name, + tty, 0, NULL) != SIASUCCESS) + fatal("sia_ses_init failed"); + + if (sia_make_entity_pwd(pw, ent) != SIASUCCESS) { + sia_ses_release(&ent); + fatal("sia_make_entity_pwd failed"); + } + + ent->authtype = SIA_A_NONE; + if (sia_ses_estab(sia_collect_trm, ent) != SIASUCCESS) + fatal("Couldn't establish session for %s from %s", + pw->pw_name, host); + + if (sia_ses_launch(sia_collect_trm, ent) != SIASUCCESS) + fatal("Couldn't launch session for %s from %s", + pw->pw_name, host); + + sia_ses_release(&ent); + + setuid(0); + permanently_set_uid(pw); +} + +#endif /* HAVE_OSF_SIA */
diff --git a/openssh-6.0p1/auth-sia.h b/openssh-6.0p1/auth-sia.h new file mode 100644 index 0000000..27cbb93 --- /dev/null +++ b/openssh-6.0p1/auth-sia.h
@@ -0,0 +1,31 @@ +/* + * 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 */
diff --git a/openssh-6.0p1/auth-skey.c b/openssh-6.0p1/auth-skey.c new file mode 100644 index 0000000..3536ec8 --- /dev/null +++ b/openssh-6.0p1/auth-skey.c
@@ -0,0 +1,108 @@ +/* $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 <sys/types.h> + +#include <pwd.h> +#include <stdio.h> + +#include <skey.h> + +#include "xmalloc.h" +#include "key.h" +#include "hostfile.h" +#include "auth.h" +#include "ssh-gss.h" +#include "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 */
diff --git a/openssh-6.0p1/auth.c b/openssh-6.0p1/auth.c new file mode 100644 index 0000000..cd95da9 --- /dev/null +++ b/openssh-6.0p1/auth.c
@@ -0,0 +1,695 @@ +/* $OpenBSD: auth.c,v 1.94 2011/05/23 03:33:38 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 <sys/types.h> +#include <sys/stat.h> +#include <sys/param.h> + +#include <netinet/in.h> + +#include <errno.h> +#include <fcntl.h> +#ifdef HAVE_PATHS_H +# include <paths.h> +#endif +#include <pwd.h> +#ifdef HAVE_LOGIN_H +#include <login.h> +#endif +#ifdef USE_SHADOW +#include <shadow.h> +#endif +#ifdef HAVE_LIBGEN_H +#include <libgen.h> +#endif +#include <stdarg.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +#include "xmalloc.h" +#include "match.h" +#include "groupaccess.h" +#include "log.h" +#include "buffer.h" +#include "servconf.h" +#include "key.h" +#include "hostfile.h" +#include "auth.h" +#include "auth-options.h" +#include "canohost.h" +#include "uidswap.h" +#include "misc.h" +#include "packet.h" +#include "loginrec.h" +#ifdef GSSAPI +#include "ssh-gss.h" +#endif +#include "authfile.h" +#include "monitor_wrap.h" + +/* import */ +extern ServerOptions options; +extern int use_privsep; +extern Buffer loginmsg; +extern struct passwd *privsep_pw; + +/* Debugging messages */ +Buffer auth_debug; +int auth_debug_init; + +/* + * Check if the user is allowed to log in via ssh. If user is listed + * in DenyUsers or one of user's groups is listed in DenyGroups, false + * will be returned. If AllowUsers isn't empty and user isn't listed + * there, or if AllowGroups isn't empty and one of user's groups isn't + * listed there, false will be returned. + * If the user's shell is not executable, false will be returned. + * Otherwise true is returned. + */ +int +allowed_user(struct passwd * pw) +{ + struct stat st; + const char *hostname = NULL, *ipaddr = NULL, *passwd = NULL; + u_int i; +#ifdef USE_SHADOW + struct spwd *spw = NULL; +#endif + + /* Shouldn't be called if pw is NULL, but better safe than sorry... */ + if (!pw || !pw->pw_name) + return 0; + +#ifdef USE_SHADOW + if (!options.use_pam) + spw = getspnam(pw->pw_name); +#ifdef HAS_SHADOW_EXPIRE + if (!options.use_pam && spw != NULL && auth_shadow_acctexpired(spw)) + return 0; +#endif /* HAS_SHADOW_EXPIRE */ +#endif /* USE_SHADOW */ + + /* grab passwd field for locked account check */ + passwd = pw->pw_passwd; +#ifdef USE_SHADOW + if (spw != NULL) +#ifdef USE_LIBIAF + passwd = get_iaf_password(pw); +#else + passwd = spw->sp_pwdp; +#endif /* USE_LIBIAF */ +#endif + + /* check for locked account */ + if (!options.use_pam && passwd && *passwd) { + int locked = 0; + +#ifdef LOCKED_PASSWD_STRING + if (strcmp(passwd, LOCKED_PASSWD_STRING) == 0) + locked = 1; +#endif +#ifdef LOCKED_PASSWD_PREFIX + if (strncmp(passwd, LOCKED_PASSWD_PREFIX, + strlen(LOCKED_PASSWD_PREFIX)) == 0) + locked = 1; +#endif +#ifdef LOCKED_PASSWD_SUBSTR + if (strstr(passwd, LOCKED_PASSWD_SUBSTR)) + locked = 1; +#endif +#ifdef USE_LIBIAF + free((void *) passwd); +#endif /* USE_LIBIAF */ + if (locked) { + logit("User %.100s not allowed because account is locked", + pw->pw_name); + return 0; + } + } + + /* + * Deny if shell does not exist or is not executable unless we + * are chrooting. + */ + if (options.chroot_directory == NULL || + strcasecmp(options.chroot_directory, "none") == 0) { + char *shell = xstrdup((pw->pw_shell[0] == '\0') ? + _PATH_BSHELL : pw->pw_shell); /* empty = /bin/sh */ + + if (stat(shell, &st) != 0) { + logit("User %.100s not allowed because shell %.100s " + "does not exist", pw->pw_name, shell); + xfree(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); + xfree(shell); + return 0; + } + xfree(shell); + } + + if (options.num_deny_users > 0 || options.num_allow_users > 0 || + options.num_deny_groups > 0 || options.num_allow_groups > 0) { + hostname = get_canonical_hostname(options.use_dns); + ipaddr = get_remote_ipaddr(); + } + + /* Return false if user is listed in DenyUsers */ + if (options.num_deny_users > 0) { + for (i = 0; i < options.num_deny_users; i++) + if (match_user(pw->pw_name, hostname, ipaddr, + options.deny_users[i])) { + logit("User %.100s from %.100s not allowed " + "because listed in DenyUsers", + pw->pw_name, hostname); + return 0; + } + } + /* Return false if AllowUsers isn't empty and user isn't listed there */ + if (options.num_allow_users > 0) { + for (i = 0; i < options.num_allow_users; i++) + if (match_user(pw->pw_name, hostname, ipaddr, + options.allow_users[i])) + break; + /* i < options.num_allow_users iff we break for loop */ + if (i >= options.num_allow_users) { + logit("User %.100s from %.100s not allowed because " + "not listed in AllowUsers", pw->pw_name, hostname); + return 0; + } + } + if (options.num_deny_groups > 0 || options.num_allow_groups > 0) { + /* Get the user's group access list (primary and supplementary) */ + if (ga_init(pw->pw_name, pw->pw_gid) == 0) { + logit("User %.100s from %.100s not allowed because " + "not in any group", pw->pw_name, hostname); + return 0; + } + + /* Return false if one of user's groups is listed in DenyGroups */ + if (options.num_deny_groups > 0) + if (ga_match(options.deny_groups, + options.num_deny_groups)) { + ga_free(); + logit("User %.100s from %.100s not allowed " + "because a group is listed in DenyGroups", + pw->pw_name, hostname); + return 0; + } + /* + * Return false if AllowGroups isn't empty and one of user's groups + * isn't listed there + */ + if (options.num_allow_groups > 0) + if (!ga_match(options.allow_groups, + options.num_allow_groups)) { + ga_free(); + logit("User %.100s from %.100s not allowed " + "because none of user's groups are listed " + "in AllowGroups", pw->pw_name, hostname); + return 0; + } + ga_free(); + } + +#ifdef CUSTOM_SYS_AUTH_ALLOWED_USER + if (!sys_auth_allowed_user(pw, &loginmsg)) + return 0; +#endif + + /* We found no reason not to let this user try to log on... */ + return 1; +} + +void +auth_log(Authctxt *authctxt, int authenticated, char *method, char *info) +{ + void (*authlog) (const char *fmt,...) = verbose; + char *authmsg; + + if (use_privsep && !mm_is_monitor() && !authctxt->postponed) + return; + + /* Raise logging level */ + if (authenticated == 1 || + !authctxt->valid || + authctxt->failures >= options.max_authtries / 2 || + strcmp(method, "password") == 0) + authlog = logit; + + if (authctxt->postponed) + authmsg = "Postponed"; + else + authmsg = authenticated ? "Accepted" : "Failed"; + + authlog("%s %s for %s%.100s from %.200s port %d%s", + authmsg, + method, + authctxt->valid ? "" : "invalid user ", + authctxt->user, + get_remote_ipaddr(), + get_remote_port(), + info); + +#ifdef CUSTOM_FAILED_LOGIN + if (authenticated == 0 && !authctxt->postponed && + (strcmp(method, "password") == 0 || + strncmp(method, "keyboard-interactive", 20) == 0 || + strcmp(method, "challenge-response") == 0)) + record_failed_login(authctxt->user, + get_canonical_hostname(options.use_dns), "ssh"); +# ifdef WITH_AIXAUTHENTICATE + if (authenticated) + sys_auth_record_login(authctxt->user, + get_canonical_hostname(options.use_dns), "ssh", &loginmsg); +# endif +#endif +#ifdef SSH_AUDIT_EVENTS + if (authenticated == 0 && !authctxt->postponed) + audit_event(audit_classify_auth(method)); +#endif +} + +/* + * Check whether root logins are disallowed. + */ +int +auth_root_allowed(char *method) +{ + switch (options.permit_root_login) { + case PERMIT_YES: + return 1; + case PERMIT_NO_PASSWD: + if (strcmp(method, "password") != 0) + return 1; + break; + case PERMIT_FORCED_ONLY: + if (forced_command) { + logit("Root login accepted for forced command."); + return 1; + } + break; + } + logit("ROOT LOGIN REFUSED FROM %.200s", get_remote_ipaddr()); + return 0; +} + + +/* + * Given a template and a passwd structure, build a filename + * by substituting % tokenised options. Currently, %% becomes '%', + * %h becomes the home directory and %u the username. + * + * This returns a buffer allocated by xmalloc. + */ +char * +expand_authorized_keys(const char *filename, struct passwd *pw) +{ + char *file, ret[MAXPATHLEN]; + int i; + + file = percent_expand(filename, "h", pw->pw_dir, + "u", pw->pw_name, (char *)NULL); + + /* + * Ensure that filename starts anchored. If not, be backward + * compatible and prepend the '%h/' + */ + if (*file == '/') + return (file); + + i = snprintf(ret, sizeof(ret), "%s/%s", pw->pw_dir, file); + if (i < 0 || (size_t)i >= sizeof(ret)) + fatal("expand_authorized_keys: path too long"); + xfree(file); + return (xstrdup(ret)); +} + +char * +authorized_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(); + } + xfree(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 file for security. This is defined as all components + * of the path to the file must be owned by either the owner of + * of the file or root and no directories must be group or world writable. + * + * XXX Should any specific check be done for sym links ? + * + * Takes an open file descriptor, the file name, a uid and and + * error buffer plus max size as arguments. + * + * Returns 0 on success and -1 on failure + */ +static int +secure_filename(FILE *f, const char *file, struct passwd *pw, + char *err, size_t errlen) +{ + uid_t uid = pw->pw_uid; + char buf[MAXPATHLEN], homedir[MAXPATHLEN]; + char *cp; + int comparehome = 0; + struct stat st; + + if (realpath(file, buf) == NULL) { + snprintf(err, errlen, "realpath %s failed: %s", file, + strerror(errno)); + return -1; + } + if (realpath(pw->pw_dir, homedir) != NULL) + comparehome = 1; + + /* check the open file to avoid races */ + if (fstat(fileno(f), &st) < 0 || + (st.st_uid != 0 && st.st_uid != uid) || + (st.st_mode & 022) != 0) { + snprintf(err, errlen, "bad ownership or modes for file %s", + buf); + return -1; + } + + /* for each component of the canonical path, walking upwards */ + for (;;) { + if ((cp = dirname(buf)) == NULL) { + snprintf(err, errlen, "dirname() failed"); + return -1; + } + strlcpy(buf, cp, sizeof(buf)); + + if (stat(buf, &st) < 0 || + (st.st_uid != 0 && st.st_uid != uid) || + (st.st_mode & 022) != 0) { + snprintf(err, errlen, + "bad ownership or modes for directory %s", buf); + return -1; + } + + /* If are 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 FILE * +auth_openfile(const char *file, struct passwd *pw, int strict_modes, + int log_missing, char *file_type) +{ + char line[1024]; + struct stat st; + int fd; + FILE *f; + + if ((fd = open(file, O_RDONLY|O_NONBLOCK)) == -1) { + if (log_missing || errno != ENOENT) + debug("Could not open %s '%s': %s", file_type, file, + strerror(errno)); + return NULL; + } + + if (fstat(fd, &st) < 0) { + close(fd); + return NULL; + } + if (!S_ISREG(st.st_mode)) { + logit("User %s %s %s is not a regular file", + pw->pw_name, file_type, file); + close(fd); + return NULL; + } + unset_nonblock(fd); + if ((f = fdopen(fd, "r")) == NULL) { + close(fd); + return NULL; + } + if (strict_modes && + secure_filename(f, file, pw, line, sizeof(line)) != 0) { + fclose(f); + logit("Authentication refused: %s", line); + auth_debug_add("Ignored %s: %s", file_type, line); + return NULL; + } + + return f; +} + + +FILE * +auth_openkeyfile(const char *file, struct passwd *pw, int strict_modes) +{ + return auth_openfile(file, pw, strict_modes, 1, "authorized keys"); +} + +FILE * +auth_openprincipals(const char *file, struct passwd *pw, int strict_modes) +{ + return auth_openfile(file, pw, strict_modes, 0, + "authorized principals"); +} + +struct passwd * +getpwnamallow(const char *user) +{ +#ifdef HAVE_LOGIN_CAP + extern login_cap_t *lc; +#ifdef BSD_AUTH + auth_session_t *as; +#endif +#endif + struct passwd *pw; + + parse_server_match_config(&options, user, + get_canonical_hostname(options.use_dns), get_remote_ipaddr()); + +#if defined(_AIX) && defined(HAVE_SETAUTHDB) + aix_setauthdb(user); +#endif + + pw = getpwnam(user); + +#if defined(_AIX) && defined(HAVE_SETAUTHDB) + aix_restoreauthdb(); +#endif +#ifdef HAVE_CYGWIN + /* + * Windows usernames are case-insensitive. To avoid later problems + * when trying to match the username, the user is only allowed to + * login if the username is given in the same case as stored in the + * user database. + */ + if (pw != NULL && strcmp(user, pw->pw_name) != 0) { + logit("Login name %.100s does not match stored username %.100s", + user, pw->pw_name); + pw = NULL; + } +#endif + if (pw == NULL) { + logit("Invalid user %.100s from %.100s", + user, get_remote_ipaddr()); +#ifdef CUSTOM_FAILED_LOGIN + record_failed_login(user, + get_canonical_hostname(options.use_dns), "ssh"); +#endif +#ifdef SSH_AUDIT_EVENTS + audit_event(SSH_INVALID_USER); +#endif /* SSH_AUDIT_EVENTS */ + return (NULL); + } + if (!allowed_user(pw)) + return (NULL); +#ifdef HAVE_LOGIN_CAP + if ((lc = login_getclass(pw->pw_class)) == NULL) { + debug("unable to get login class: %s", user); + return (NULL); + } +#ifdef BSD_AUTH + if ((as = auth_open()) == NULL || auth_setpwd(as, pw) != 0 || + auth_approval(as, lc, pw->pw_name, "ssh") <= 0) { + debug("Approval failure for %s", user); + pw = NULL; + } + if (as != NULL) + auth_close(as); +#endif +#endif + if (pw != NULL) + return (pwcopy(pw)); + return (NULL); +} + +/* Returns 1 if key is revoked by revoked_keys_file, 0 otherwise */ +int +auth_key_is_revoked(Key *key) +{ + char *key_fp; + + if (options.revoked_keys_file == NULL) + return 0; + + switch (key_in_file(key, options.revoked_keys_file, 0)) { + case 0: + /* key not revoked */ + return 0; + case -1: + /* Error opening revoked_keys_file: refuse all keys */ + error("Revoked keys file is unreadable: refusing public key " + "authentication"); + return 1; + case 1: + /* Key revoked */ + key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); + error("WARNING: authentication attempt with a revoked " + "%s key %s ", key_type(key), key_fp); + xfree(key_fp); + return 1; + } + fatal("key_in_file returned junk"); +} + +void +auth_debug_add(const char *fmt,...) +{ + char buf[1024]; + va_list args; + + if (!auth_debug_init) + return; + + va_start(args, fmt); + vsnprintf(buf, sizeof(buf), fmt, args); + va_end(args); + buffer_put_cstring(&auth_debug, buf); +} + +void +auth_debug_send(void) +{ + char *msg; + + if (!auth_debug_init) + return; + while (buffer_len(&auth_debug)) { + msg = buffer_get_string(&auth_debug, NULL); + packet_send_debug("%s", msg); + xfree(msg); + } +} + +void +auth_debug_reset(void) +{ + if (auth_debug_init) + buffer_clear(&auth_debug); + else { + buffer_init(&auth_debug); + auth_debug_init = 1; + } +} + +struct passwd * +fakepw(void) +{ + static struct passwd fake; + + memset(&fake, 0, sizeof(fake)); + fake.pw_name = "NOUSER"; + fake.pw_passwd = + "$2a$06$r3.juUaHZDlIbQaO2dS9FuYxL1W9M81R1Tc92PoSNmzvpEqLkLGrK"; + fake.pw_gecos = "NOUSER"; + fake.pw_uid = privsep_pw == NULL ? (uid_t)-1 : privsep_pw->pw_uid; + fake.pw_gid = privsep_pw == NULL ? (gid_t)-1 : privsep_pw->pw_gid; +#ifdef HAVE_PW_CLASS_IN_PASSWD + fake.pw_class = ""; +#endif + fake.pw_dir = "/nonexist"; + fake.pw_shell = "/nonexist"; + + return (&fake); +}
diff --git a/openssh-6.0p1/auth.h b/openssh-6.0p1/auth.h new file mode 100644 index 0000000..0d786c4 --- /dev/null +++ b/openssh-6.0p1/auth.h
@@ -0,0 +1,206 @@ +/* $OpenBSD: auth.h,v 1.69 2011/05/23 03:30: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. + * + */ + +#ifndef AUTH_H +#define AUTH_H + +#include <signal.h> + +#include <openssl/rsa.h> + +#ifdef HAVE_LOGIN_CAP +#include <login_cap.h> +#endif +#ifdef BSD_AUTH +#include <bsd_auth.h> +#endif +#ifdef KRB5 +#include <krb5.h> +#endif + +typedef struct Authctxt Authctxt; +typedef struct Authmethod Authmethod; +typedef struct KbdintDevice KbdintDevice; + +struct Authctxt { + sig_atomic_t success; + int authenticated; /* authenticated and alarms cancelled */ + int postponed; /* authentication needs another step */ + int valid; /* user exists and is allowed to login */ + int attempt; + int failures; + int 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; + void *jpake_ctx; +#ifdef BSD_AUTH + auth_session_t *as; +#endif +#ifdef KRB5 + krb5_context krb5_ctx; + krb5_ccache krb5_fwd_ccache; + krb5_principal krb5_user; + char *krb5_ticket_file; + char *krb5_ccname; +#endif + Buffer *loginmsg; + void *methoddata; +}; +/* + * Every authentication method has to handle authentication requests for + * non-existing users, or for users that are not allowed to login. In this + * case 'valid' is set to 0, but 'user' points to the username requested by + * the client. + */ + +struct Authmethod { + char *name; + int (*userauth)(Authctxt *authctxt); + int *enabled; +}; + +/* + * Keyboard interactive device: + * init_ctx returns: non NULL upon success + * query returns: 0 - success, otherwise failure + * respond returns: 0 - success, 1 - need further interaction, + * otherwise - failure + */ +struct KbdintDevice +{ + const char *name; + void* (*init_ctx)(Authctxt*); + int (*query)(void *ctx, char **name, char **infotxt, + u_int *numprompts, char ***prompts, u_int **echo_on); + int (*respond)(void *ctx, u_int numresp, char **responses); + void (*free_ctx)(void *ctx); +}; + +int auth_rhosts(struct passwd *, const char *); +int +auth_rhosts2(struct passwd *, const char *, const char *, const char *); + +int auth_rhosts_rsa(Authctxt *, char *, Key *); +int auth_password(Authctxt *, const char *); +int auth_rsa(Authctxt *, BIGNUM *); +int auth_rsa_challenge_dialog(Key *); +BIGNUM *auth_rsa_generate_challenge(Key *); +int auth_rsa_verify_response(Key *, BIGNUM *, u_char[]); +int auth_rsa_key_allowed(struct passwd *, BIGNUM *, Key **); + +int auth_rhosts_rsa_key_allowed(struct passwd *, char *, char *, Key *); +int hostbased_key_allowed(struct passwd *, const char *, char *, Key *); +int user_key_allowed(struct passwd *, Key *); + +#ifdef KRB5 +int auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *); +int auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt); +int auth_krb5_password(Authctxt *authctxt, const char *password); +void krb5_cleanup_proc(Authctxt *authctxt); +#endif /* KRB5 */ + +#if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE) +#include <shadow.h> +int auth_shadow_acctexpired(struct spwd *); +int auth_shadow_pwexpired(Authctxt *); +#endif + +#include "auth-pam.h" +#include "audit.h" +void remove_kbdint_device(const char *); + +void disable_forwarding(void); + +void do_authentication(Authctxt *); +void do_authentication2(Authctxt *); + +void auth_log(Authctxt *, int, char *, char *); +void userauth_finish(Authctxt *, int, char *); +void userauth_send_banner(const char *); +int auth_root_allowed(char *); + +char *auth2_read_banner(void); + +void privsep_challenge_enable(void); + +int auth2_challenge(Authctxt *, char *); +void auth2_challenge_stop(Authctxt *); +int bsdauth_query(void *, char **, char **, u_int *, char ***, u_int **); +int bsdauth_respond(void *, u_int, char **); +int skey_query(void *, char **, char **, u_int *, char ***, u_int **); +int skey_respond(void *, u_int, char **); + +void auth2_jpake_get_pwdata(Authctxt *, BIGNUM **, char **, char **); +void auth2_jpake_stop(Authctxt *); + +int allowed_user(struct passwd *); +struct passwd * getpwnamallow(const char *user); + +char *get_challenge(Authctxt *); +int verify_response(Authctxt *, const char *); +void abandon_challenge_response(Authctxt *); + +char *expand_authorized_keys(const char *, struct passwd *pw); +char *authorized_principals_file(struct passwd *); + +FILE *auth_openkeyfile(const char *, struct passwd *, int); +FILE *auth_openprincipals(const char *, struct passwd *, int); +int auth_key_is_revoked(Key *); + +HostStatus +check_key_in_hostfiles(struct passwd *, Key *, const char *, + const char *, const char *); + +/* hostkey handling */ +Key *get_hostkey_by_index(int); +Key *get_hostkey_public_by_type(int); +Key *get_hostkey_private_by_type(int); +int get_hostkey_index(Key *); +int ssh1_session_key(BIGNUM *); + +/* debug messages during authentication */ +void auth_debug_add(const char *fmt,...) __attribute__((format(printf, 1, 2))); +void auth_debug_send(void); +void auth_debug_reset(void); + +struct passwd *fakepw(void); + +int sys_auth_passwd(Authctxt *, const char *); + +#define AUTH_FAIL_MSG "Too many authentication failures for %.100s" + +#define SKEY_PROMPT "\nS/Key Password: " + +#if defined(KRB5) && !defined(HEIMDAL) +#include <krb5.h> +krb5_error_code ssh_krb5_cc_gen(krb5_context, krb5_ccache *); +#endif +#endif
diff --git a/openssh-6.0p1/auth1.c b/openssh-6.0p1/auth1.c new file mode 100644 index 0000000..cc85aec --- /dev/null +++ b/openssh-6.0p1/auth1.c
@@ -0,0 +1,437 @@ +/* $OpenBSD: auth1.c,v 1.75 2010/08/31 09:58:37 djm Exp $ */ +/* + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ + +#include "includes.h" + +#include <sys/types.h> + +#include <stdarg.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <pwd.h> + +#include "openbsd-compat/sys-queue.h" +#include "xmalloc.h" +#include "rsa.h" +#include "ssh1.h" +#include "packet.h" +#include "buffer.h" +#include "log.h" +#include "servconf.h" +#include "compat.h" +#include "key.h" +#include "hostfile.h" +#include "auth.h" +#include "channels.h" +#include "session.h" +#include "uidswap.h" +#ifdef GSSAPI +#include "ssh-gss.h" +#endif +#include "monitor_wrap.h" +#include "buffer.h" + +/* import */ +extern ServerOptions options; +extern Buffer loginmsg; + +static int auth1_process_password(Authctxt *, char *, size_t); +static int auth1_process_rsa(Authctxt *, char *, size_t); +static int auth1_process_rhosts_rsa(Authctxt *, char *, size_t); +static int auth1_process_tis_challenge(Authctxt *, char *, size_t); +static int auth1_process_tis_response(Authctxt *, char *, size_t); + +static char *client_user = NULL; /* Used to fill in remote user for PAM */ + +struct AuthMethod1 { + int type; + char *name; + int *enabled; + int (*method)(Authctxt *, char *, size_t); +}; + +const struct AuthMethod1 auth1_methods[] = { + { + SSH_CMSG_AUTH_PASSWORD, "password", + &options.password_authentication, auth1_process_password + }, + { + SSH_CMSG_AUTH_RSA, "rsa", + &options.rsa_authentication, auth1_process_rsa + }, + { + SSH_CMSG_AUTH_RHOSTS_RSA, "rhosts-rsa", + &options.rhosts_rsa_authentication, auth1_process_rhosts_rsa + }, + { + SSH_CMSG_AUTH_TIS, "challenge-response", + &options.challenge_response_authentication, + auth1_process_tis_challenge + }, + { + SSH_CMSG_AUTH_TIS_RESPONSE, "challenge-response", + &options.challenge_response_authentication, + auth1_process_tis_response + }, + { -1, NULL, NULL, NULL} +}; + +static const struct AuthMethod1 +*lookup_authmethod1(int type) +{ + int i; + + for (i = 0; auth1_methods[i].name != NULL; i++) + if (auth1_methods[i].type == type) + return (&(auth1_methods[i])); + + return (NULL); +} + +static char * +get_authname(int type) +{ + const struct AuthMethod1 *a; + static char buf[64]; + + if ((a = lookup_authmethod1(type)) != NULL) + return (a->name); + snprintf(buf, sizeof(buf), "bad-auth-msg-%d", type); + return (buf); +} + +/*ARGSUSED*/ +static int +auth1_process_password(Authctxt *authctxt, char *info, size_t infolen) +{ + int authenticated = 0; + char *password; + u_int dlen; + + /* + * Read user password. It is in plain text, but was + * transmitted over the encrypted channel so it is + * not visible to an outside observer. + */ + password = packet_get_string(&dlen); + packet_check_eom(); + + /* Try authentication with the password. */ + authenticated = PRIVSEP(auth_password(authctxt, password)); + + memset(password, 0, dlen); + xfree(password); + + return (authenticated); +} + +/*ARGSUSED*/ +static int +auth1_process_rsa(Authctxt *authctxt, char *info, size_t infolen) +{ + int authenticated = 0; + BIGNUM *n; + + /* RSA authentication requested. */ + if ((n = BN_new()) == NULL) + fatal("do_authloop: BN_new failed"); + packet_get_bignum(n); + packet_check_eom(); + authenticated = auth_rsa(authctxt, n); + BN_clear_free(n); + + return (authenticated); +} + +/*ARGSUSED*/ +static int +auth1_process_rhosts_rsa(Authctxt *authctxt, char *info, size_t infolen) +{ + int keybits, authenticated = 0; + u_int bits; + Key *client_host_key; + u_int ulen; + + /* + * Get client user name. Note that we just have to + * trust the client; root on the client machine can + * claim to be any user. + */ + client_user = packet_get_cstring(&ulen); + + /* Get the client host key. */ + client_host_key = key_new(KEY_RSA1); + bits = packet_get_int(); + packet_get_bignum(client_host_key->rsa->e); + packet_get_bignum(client_host_key->rsa->n); + + keybits = BN_num_bits(client_host_key->rsa->n); + if (keybits < 0 || bits != (u_int)keybits) { + verbose("Warning: keysize mismatch for client_host_key: " + "actual %d, announced %d", + BN_num_bits(client_host_key->rsa->n), bits); + } + packet_check_eom(); + + authenticated = auth_rhosts_rsa(authctxt, client_user, + client_host_key); + key_free(client_host_key); + + snprintf(info, infolen, " ruser %.100s", client_user); + + return (authenticated); +} + +/*ARGSUSED*/ +static int +auth1_process_tis_challenge(Authctxt *authctxt, char *info, size_t infolen) +{ + char *challenge; + + if ((challenge = get_challenge(authctxt)) == NULL) + return (0); + + debug("sending challenge '%s'", challenge); + packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE); + packet_put_cstring(challenge); + xfree(challenge); + packet_send(); + packet_write_wait(); + + return (-1); +} + +/*ARGSUSED*/ +static int +auth1_process_tis_response(Authctxt *authctxt, char *info, size_t infolen) +{ + int authenticated = 0; + char *response; + u_int dlen; + + response = packet_get_string(&dlen); + packet_check_eom(); + authenticated = verify_response(authctxt, response); + memset(response, 'r', dlen); + xfree(response); + + return (authenticated); +} + +/* + * read packets, try to authenticate the user and + * return only if authentication is successful + */ +static void +do_authloop(Authctxt *authctxt) +{ + int authenticated = 0; + char info[1024]; + int prev = 0, type = 0; + const struct AuthMethod1 *meth; + + debug("Attempting authentication for %s%.100s.", + authctxt->valid ? "" : "invalid user ", authctxt->user); + + /* If the user has no password, accept authentication immediately. */ + if (options.permit_empty_passwd && options.password_authentication && +#ifdef KRB5 + (!options.kerberos_authentication || options.kerberos_or_local_passwd) && +#endif + PRIVSEP(auth_password(authctxt, ""))) { +#ifdef USE_PAM + if (options.use_pam && (PRIVSEP(do_pam_account()))) +#endif + { + auth_log(authctxt, 1, "without authentication", ""); + return; + } + } + + /* Indicate that authentication is needed. */ + packet_start(SSH_SMSG_FAILURE); + packet_send(); + packet_write_wait(); + + for (;;) { + /* default to fail */ + authenticated = 0; + + info[0] = '\0'; + + /* Get a packet from the client. */ + prev = type; + type = packet_read(); + + /* + * If we started challenge-response authentication but the + * next packet is not a response to our challenge, release + * the resources allocated by get_challenge() (which would + * normally have been released by verify_response() had we + * received such a response) + */ + if (prev == SSH_CMSG_AUTH_TIS && + type != SSH_CMSG_AUTH_TIS_RESPONSE) + abandon_challenge_response(authctxt); + + if (authctxt->failures >= options.max_authtries) + goto skip; + if ((meth = lookup_authmethod1(type)) == NULL) { + logit("Unknown message during authentication: " + "type %d", type); + goto skip; + } + + if (!*(meth->enabled)) { + verbose("%s authentication disabled.", meth->name); + goto skip; + } + + authenticated = meth->method(authctxt, info, sizeof(info)); + if (authenticated == -1) + continue; /* "postponed" */ + +#ifdef BSD_AUTH + if (authctxt->as) { + auth_close(authctxt->as); + authctxt->as = NULL; + } +#endif + if (!authctxt->valid && authenticated) + fatal("INTERNAL ERROR: authenticated invalid user %s", + authctxt->user); + +#ifdef _UNICOS + if (authenticated && cray_access_denied(authctxt->user)) { + authenticated = 0; + fatal("Access denied for user %s.",authctxt->user); + } +#endif /* _UNICOS */ + +#ifndef HAVE_CYGWIN + /* Special handling for root */ + if (authenticated && authctxt->pw->pw_uid == 0 && + !auth_root_allowed(meth->name)) { + authenticated = 0; +# ifdef SSH_AUDIT_EVENTS + PRIVSEP(audit_event(SSH_LOGIN_ROOT_DENIED)); +# endif + } +#endif + +#ifdef USE_PAM + if (options.use_pam && authenticated && + !PRIVSEP(do_pam_account())) { + char *msg; + size_t len; + + error("Access denied for user %s by PAM account " + "configuration", authctxt->user); + len = buffer_len(&loginmsg); + buffer_append(&loginmsg, "\0", 1); + msg = buffer_ptr(&loginmsg); + /* strip trailing newlines */ + if (len > 0) + while (len > 0 && msg[--len] == '\n') + msg[len] = '\0'; + else + msg = "Access denied."; + packet_disconnect("%s", msg); + } +#endif + + skip: + /* Log before sending the reply */ + auth_log(authctxt, authenticated, get_authname(type), info); + + if (client_user != NULL) { + xfree(client_user); + client_user = NULL; + } + + if (authenticated) + return; + + if (++authctxt->failures >= options.max_authtries) { +#ifdef SSH_AUDIT_EVENTS + PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES)); +#endif + packet_disconnect(AUTH_FAIL_MSG, authctxt->user); + } + + packet_start(SSH_SMSG_FAILURE); + packet_send(); + packet_write_wait(); + } +} + +/* + * Performs authentication of an incoming connection. Session key has already + * been exchanged and encryption is enabled. + */ +void +do_authentication(Authctxt *authctxt) +{ + u_int ulen; + char *user, *style = NULL; + + /* Get the name of the user that we wish to log in as. */ + packet_read_expect(SSH_CMSG_USER); + + /* Get the user name. */ + user = packet_get_cstring(&ulen); + packet_check_eom(); + + if ((style = strchr(user, ':')) != NULL) + *style++ = '\0'; + + authctxt->user = user; + authctxt->style = style; + + /* Verify that the user is a valid user. */ + if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL) + authctxt->valid = 1; + else { + debug("do_authentication: invalid user %s", user); + authctxt->pw = fakepw(); + } + + setproctitle("%s%s", authctxt->valid ? user : "unknown", + use_privsep ? " [net]" : ""); + +#ifdef USE_PAM + if (options.use_pam) + PRIVSEP(start_pam(authctxt)); +#endif + + /* + * If we are not running as root, the user must have the same uid as + * the server. + */ +#ifndef HAVE_CYGWIN + if (!use_privsep && getuid() != 0 && authctxt->pw && + authctxt->pw->pw_uid != getuid()) + packet_disconnect("Cannot change user when server not running as root."); +#endif + + /* + * Loop until the user has been authenticated or the connection is + * closed, do_authloop() returns only if authentication is successful + */ + do_authloop(authctxt); + + /* The user has been authenticated and accepted. */ + packet_start(SSH_SMSG_SUCCESS); + packet_send(); + packet_write_wait(); +}
diff --git a/openssh-6.0p1/auth2-chall.c b/openssh-6.0p1/auth2-chall.c new file mode 100644 index 0000000..e6dbffe --- /dev/null +++ b/openssh-6.0p1/auth2-chall.c
@@ -0,0 +1,374 @@ +/* $OpenBSD: auth2-chall.c,v 1.34 2008/12/09 04:32:22 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 <sys/types.h> + +#include <stdarg.h> +#include <stdio.h> +#include <string.h> + +#include "xmalloc.h" +#include "ssh2.h" +#include "key.h" +#include "hostfile.h" +#include "auth.h" +#include "buffer.h" +#include "packet.h" +#include "dispatch.h" +#include "log.h" +#include "servconf.h" + +/* import */ +extern ServerOptions options; + +static int auth2_challenge_start(Authctxt *); +static int send_userauth_info_request(Authctxt *); +static void input_userauth_info_response(int, u_int32_t, void *); + +#ifdef BSD_AUTH +extern KbdintDevice bsdauth_device; +#else +#ifdef USE_PAM +extern KbdintDevice sshpam_device; +#endif +#ifdef SKEY +extern KbdintDevice skey_device; +#endif +#endif + +KbdintDevice *devices[] = { +#ifdef BSD_AUTH + &bsdauth_device, +#else +#ifdef USE_PAM + &sshpam_device, +#endif +#ifdef SKEY + &skey_device, +#endif +#endif + NULL +}; + +typedef struct KbdintAuthctxt KbdintAuthctxt; +struct KbdintAuthctxt +{ + char *devices; + void *ctxt; + KbdintDevice *device; + u_int nreq; +}; + +#ifdef USE_PAM +void +remove_kbdint_device(const char *devname) +{ + int i, j; + + for (i = 0; devices[i] != NULL; i++) + if (strcmp(devices[i]->name, devname) == 0) { + for (j = i; devices[j] != NULL; j++) + devices[j] = devices[j+1]; + i--; + } +} +#endif + +static KbdintAuthctxt * +kbdint_alloc(const char *devs) +{ + KbdintAuthctxt *kbdintctxt; + Buffer b; + int i; + +#ifdef USE_PAM + if (!options.use_pam) + remove_kbdint_device("pam"); +#endif + + kbdintctxt = xmalloc(sizeof(KbdintAuthctxt)); + if (strcmp(devs, "") == 0) { + buffer_init(&b); + for (i = 0; devices[i]; i++) { + if (buffer_len(&b) > 0) + buffer_append(&b, ",", 1); + buffer_append(&b, devices[i]->name, + strlen(devices[i]->name)); + } + buffer_append(&b, "\0", 1); + kbdintctxt->devices = xstrdup(buffer_ptr(&b)); + buffer_free(&b); + } else { + kbdintctxt->devices = xstrdup(devs); + } + debug("kbdint_alloc: devices '%s'", kbdintctxt->devices); + kbdintctxt->ctxt = NULL; + kbdintctxt->device = NULL; + kbdintctxt->nreq = 0; + + return kbdintctxt; +} +static void +kbdint_reset_device(KbdintAuthctxt *kbdintctxt) +{ + if (kbdintctxt->ctxt) { + kbdintctxt->device->free_ctx(kbdintctxt->ctxt); + kbdintctxt->ctxt = NULL; + } + kbdintctxt->device = NULL; +} +static void +kbdint_free(KbdintAuthctxt *kbdintctxt) +{ + if (kbdintctxt->device) + kbdint_reset_device(kbdintctxt); + if (kbdintctxt->devices) { + xfree(kbdintctxt->devices); + kbdintctxt->devices = NULL; + } + xfree(kbdintctxt); +} +/* get next device */ +static int +kbdint_next_device(KbdintAuthctxt *kbdintctxt) +{ + size_t len; + char *t; + int i; + + if (kbdintctxt->device) + kbdint_reset_device(kbdintctxt); + do { + len = kbdintctxt->devices ? + strcspn(kbdintctxt->devices, ",") : 0; + + if (len == 0) + break; + for (i = 0; devices[i]; i++) + if (strncmp(kbdintctxt->devices, devices[i]->name, len) == 0) + kbdintctxt->device = devices[i]; + t = kbdintctxt->devices; + kbdintctxt->devices = t[len] ? xstrdup(t+len+1) : NULL; + xfree(t); + debug2("kbdint_next_device: devices %s", kbdintctxt->devices ? + kbdintctxt->devices : "<empty>"); + } while (kbdintctxt->devices && !kbdintctxt->device); + + return kbdintctxt->device ? 1 : 0; +} + +/* + * try challenge-response, set authctxt->postponed if we have to + * wait for the response. + */ +int +auth2_challenge(Authctxt *authctxt, char *devs) +{ + debug("auth2_challenge: user=%s devs=%s", + authctxt->user ? authctxt->user : "<nouser>", + devs ? devs : "<no devs>"); + + if (authctxt->user == NULL || !devs) + return 0; + if (authctxt->kbdintctxt == NULL) + authctxt->kbdintctxt = kbdint_alloc(devs); + return auth2_challenge_start(authctxt); +} + +/* unregister kbd-int callbacks and context */ +void +auth2_challenge_stop(Authctxt *authctxt) +{ + /* unregister callback */ + dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL); + if (authctxt->kbdintctxt != NULL) { + kbdint_free(authctxt->kbdintctxt); + authctxt->kbdintctxt = NULL; + } +} + +/* side effect: sets authctxt->postponed if a reply was sent*/ +static int +auth2_challenge_start(Authctxt *authctxt) +{ + KbdintAuthctxt *kbdintctxt = authctxt->kbdintctxt; + + debug2("auth2_challenge_start: devices %s", + kbdintctxt->devices ? kbdintctxt->devices : "<empty>"); + + if (kbdint_next_device(kbdintctxt) == 0) { + auth2_challenge_stop(authctxt); + return 0; + } + debug("auth2_challenge_start: trying authentication method '%s'", + kbdintctxt->device->name); + + if ((kbdintctxt->ctxt = kbdintctxt->device->init_ctx(authctxt)) == NULL) { + auth2_challenge_stop(authctxt); + return 0; + } + if (send_userauth_info_request(authctxt) == 0) { + auth2_challenge_stop(authctxt); + return 0; + } + dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, + &input_userauth_info_response); + + authctxt->postponed = 1; + return 0; +} + +static int +send_userauth_info_request(Authctxt *authctxt) +{ + KbdintAuthctxt *kbdintctxt; + char *name, *instr, **prompts; + u_int i, *echo_on; + + kbdintctxt = authctxt->kbdintctxt; + if (kbdintctxt->device->query(kbdintctxt->ctxt, + &name, &instr, &kbdintctxt->nreq, &prompts, &echo_on)) + return 0; + + packet_start(SSH2_MSG_USERAUTH_INFO_REQUEST); + packet_put_cstring(name); + packet_put_cstring(instr); + packet_put_cstring(""); /* language not used */ + packet_put_int(kbdintctxt->nreq); + for (i = 0; i < kbdintctxt->nreq; i++) { + packet_put_cstring(prompts[i]); + packet_put_char(echo_on[i]); + } + packet_send(); + packet_write_wait(); + + for (i = 0; i < kbdintctxt->nreq; i++) + xfree(prompts[i]); + xfree(prompts); + xfree(echo_on); + xfree(name); + xfree(instr); + return 1; +} + +static void +input_userauth_info_response(int type, u_int32_t seq, void *ctxt) +{ + Authctxt *authctxt = ctxt; + KbdintAuthctxt *kbdintctxt; + int authenticated = 0, res; + u_int i, nresp; + char **response = NULL, *method; + + if (authctxt == NULL) + fatal("input_userauth_info_response: no authctxt"); + kbdintctxt = authctxt->kbdintctxt; + if (kbdintctxt == NULL || kbdintctxt->ctxt == NULL) + fatal("input_userauth_info_response: no kbdintctxt"); + if (kbdintctxt->device == NULL) + fatal("input_userauth_info_response: no device"); + + authctxt->postponed = 0; /* reset */ + nresp = packet_get_int(); + if (nresp != kbdintctxt->nreq) + fatal("input_userauth_info_response: wrong number of replies"); + if (nresp > 100) + fatal("input_userauth_info_response: too many replies"); + if (nresp > 0) { + response = xcalloc(nresp, sizeof(char *)); + for (i = 0; i < nresp; i++) + response[i] = packet_get_string(NULL); + } + packet_check_eom(); + + res = kbdintctxt->device->respond(kbdintctxt->ctxt, nresp, response); + + for (i = 0; i < nresp; i++) { + memset(response[i], 'r', strlen(response[i])); + xfree(response[i]); + } + if (response) + xfree(response); + + switch (res) { + case 0: + /* Success! */ + authenticated = authctxt->valid ? 1 : 0; + break; + case 1: + /* Authentication needs further interaction */ + if (send_userauth_info_request(authctxt) == 1) + authctxt->postponed = 1; + break; + default: + /* Failure! */ + break; + } + + xasprintf(&method, "keyboard-interactive/%s", kbdintctxt->device->name); + + if (!authctxt->postponed) { + if (authenticated) { + auth2_challenge_stop(authctxt); + } else { + /* start next device */ + /* may set authctxt->postponed */ + auth2_challenge_start(authctxt); + } + } + userauth_finish(authctxt, authenticated, method); + xfree(method); +} + +void +privsep_challenge_enable(void) +{ +#if defined(BSD_AUTH) || defined(USE_PAM) || defined(SKEY) + int n = 0; +#endif +#ifdef BSD_AUTH + extern KbdintDevice mm_bsdauth_device; +#endif +#ifdef USE_PAM + extern KbdintDevice mm_sshpam_device; +#endif +#ifdef SKEY + extern KbdintDevice mm_skey_device; +#endif + +#ifdef BSD_AUTH + devices[n++] = &mm_bsdauth_device; +#else +#ifdef USE_PAM + devices[n++] = &mm_sshpam_device; +#endif +#ifdef SKEY + devices[n++] = &mm_skey_device; +#endif +#endif +}
diff --git a/openssh-6.0p1/auth2-gss.c b/openssh-6.0p1/auth2-gss.c new file mode 100644 index 0000000..0d59b21 --- /dev/null +++ b/openssh-6.0p1/auth2-gss.c
@@ -0,0 +1,303 @@ +/* $OpenBSD: auth2-gss.c,v 1.17 2011/03/10 02:52:57 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 <sys/types.h> + +#include <stdarg.h> + +#include "xmalloc.h" +#include "key.h" +#include "hostfile.h" +#include "auth.h" +#include "ssh2.h" +#include "log.h" +#include "dispatch.h" +#include "buffer.h" +#include "servconf.h" +#include "packet.h" +#include "ssh-gss.h" +#include "monitor_wrap.h" + +extern ServerOptions options; + +static void input_gssapi_token(int type, u_int32_t plen, void *ctxt); +static void input_gssapi_mic(int type, u_int32_t plen, void *ctxt); +static void input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt); +static void input_gssapi_errtok(int, u_int32_t, void *); + +/* + * We only support those mechanisms that we know about (ie ones that we know + * how to check local user kuserok and the like) + */ +static int +userauth_gssapi(Authctxt *authctxt) +{ + gss_OID_desc goid = {0, NULL}; + Gssctxt *ctxt = NULL; + int mechs; + gss_OID_set supported; + int present; + OM_uint32 ms; + u_int len; + u_char *doid = NULL; + + if (!authctxt->valid || authctxt->user == NULL) + return (0); + + mechs = packet_get_int(); + if (mechs == 0) { + debug("Mechanism negotiation is not supported"); + return (0); + } + + ssh_gssapi_supported_oids(&supported); + do { + mechs--; + + if (doid) + xfree(doid); + + present = 0; + doid = packet_get_string(&len); + + if (len > 2 && doid[0] == SSH_GSS_OIDTYPE && + doid[1] == len - 2) { + goid.elements = doid + 2; + goid.length = len - 2; + gss_test_oid_set_member(&ms, &goid, supported, + &present); + } else { + logit("Badly formed OID received"); + } + } while (mechs > 0 && !present); + + gss_release_oid_set(&ms, &supported); + + if (!present) { + xfree(doid); + 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); + xfree(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(); + xfree(doid); + + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token); + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok); + authctxt->postponed = 1; + + return (0); +} + +static void +input_gssapi_token(int type, u_int32_t plen, void *ctxt) +{ + Authctxt *authctxt = ctxt; + Gssctxt *gssctxt; + gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; + gss_buffer_desc recv_tok; + OM_uint32 maj_status, min_status, flags; + u_int len; + + if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) + fatal("No authentication or GSSAPI context"); + + gssctxt = authctxt->methoddata; + recv_tok.value = packet_get_string(&len); + recv_tok.length = len; /* u_int vs. size_t */ + + packet_check_eom(); + + maj_status = PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok, + &send_tok, &flags)); + + xfree(recv_tok.value); + + if (GSS_ERROR(maj_status)) { + if (send_tok.length != 0) { + packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK); + packet_put_string(send_tok.value, send_tok.length); + packet_send(); + } + authctxt->postponed = 0; + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); + userauth_finish(authctxt, 0, "gssapi-with-mic"); + } else { + if (send_tok.length != 0) { + packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN); + packet_put_string(send_tok.value, send_tok.length); + packet_send(); + } + if (maj_status == GSS_S_COMPLETE) { + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); + if (flags & GSS_C_INTEG_FLAG) + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, + &input_gssapi_mic); + else + dispatch_set( + SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, + &input_gssapi_exchange_complete); + } + } + + gss_release_buffer(&min_status, &send_tok); +} + +static void +input_gssapi_errtok(int type, u_int32_t plen, void *ctxt) +{ + Authctxt *authctxt = ctxt; + Gssctxt *gssctxt; + gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; + gss_buffer_desc recv_tok; + OM_uint32 maj_status; + u_int len; + + if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) + fatal("No authentication or GSSAPI context"); + + gssctxt = authctxt->methoddata; + recv_tok.value = packet_get_string(&len); + recv_tok.length = len; + + packet_check_eom(); + + /* Push the error token into GSSAPI to see what it says */ + maj_status = PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok, + &send_tok, NULL)); + + xfree(recv_tok.value); + + /* We can't return anything to the client, even if we wanted to */ + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL); + + /* The client will have already moved on to the next auth */ + + gss_release_buffer(&maj_status, &send_tok); +} + +/* + * This is called when the client thinks we've completed authentication. + * It should only be enabled in the dispatch handler by the function above, + * which only enables it once the GSSAPI exchange is complete. + */ + +static void +input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt) +{ + Authctxt *authctxt = ctxt; + Gssctxt *gssctxt; + int authenticated; + + if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) + fatal("No authentication or GSSAPI context"); + + gssctxt = authctxt->methoddata; + + /* + * We don't need to check the status, because we're only enabled in + * the dispatcher once the exchange is complete + */ + + packet_check_eom(); + + authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); + + authctxt->postponed = 0; + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL); + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL); + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL); + userauth_finish(authctxt, authenticated, "gssapi-with-mic"); +} + +static void +input_gssapi_mic(int type, u_int32_t plen, void *ctxt) +{ + Authctxt *authctxt = ctxt; + Gssctxt *gssctxt; + int authenticated = 0; + Buffer b; + gss_buffer_desc mic, gssbuf; + u_int len; + + if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) + fatal("No authentication or GSSAPI context"); + + gssctxt = authctxt->methoddata; + + mic.value = packet_get_string(&len); + mic.length = len; + + ssh_gssapi_buildmic(&b, authctxt->user, authctxt->service, + "gssapi-with-mic"); + + gssbuf.value = buffer_ptr(&b); + gssbuf.length = buffer_len(&b); + + if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))) + authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); + else + logit("GSSAPI MIC check failed"); + + buffer_free(&b); + xfree(mic.value); + + authctxt->postponed = 0; + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL); + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL); + dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL); + userauth_finish(authctxt, authenticated, "gssapi-with-mic"); +} + +Authmethod method_gssapi = { + "gssapi-with-mic", + userauth_gssapi, + &options.gss_authentication +}; + +#endif /* GSSAPI */
diff --git a/openssh-6.0p1/auth2-hostbased.c b/openssh-6.0p1/auth2-hostbased.c new file mode 100644 index 0000000..cdf442f --- /dev/null +++ b/openssh-6.0p1/auth2-hostbased.c
@@ -0,0 +1,220 @@ +/* $OpenBSD: auth2-hostbased.c,v 1.14 2010/08/04 05:42:47 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 <sys/types.h> + +#include <pwd.h> +#include <string.h> +#include <stdarg.h> + +#include "xmalloc.h" +#include "ssh2.h" +#include "packet.h" +#include "buffer.h" +#include "log.h" +#include "servconf.h" +#include "compat.h" +#include "key.h" +#include "hostfile.h" +#include "auth.h" +#include "canohost.h" +#ifdef GSSAPI +#include "ssh-gss.h" +#endif +#include "monitor_wrap.h" +#include "pathnames.h" + +/* import */ +extern ServerOptions options; +extern u_char *session_id2; +extern u_int session_id2_len; + +static int +userauth_hostbased(Authctxt *authctxt) +{ + Buffer b; + Key *key = NULL; + char *pkalg, *cuser, *chost, *service; + u_char *pkblob, *sig; + u_int alen, blen, slen; + int pktype; + int authenticated = 0; + + if (!authctxt->valid) { + debug2("userauth_hostbased: disabled because of invalid user"); + return 0; + } + pkalg = packet_get_string(&alen); + pkblob = packet_get_string(&blen); + chost = packet_get_string(NULL); + cuser = packet_get_string(NULL); + sig = packet_get_string(&slen); + + debug("userauth_hostbased: cuser %s chost %s pkalg %s slen %d", + cuser, chost, pkalg, slen); +#ifdef DEBUG_PK + debug("signature:"); + buffer_init(&b); + buffer_append(&b, sig, slen); + buffer_dump(&b); + buffer_free(&b); +#endif + pktype = key_type_from_name(pkalg); + if (pktype == KEY_UNSPEC) { + /* this is perfectly legal */ + logit("userauth_hostbased: unsupported " + "public key algorithm: %s", pkalg); + goto done; + } + key = key_from_blob(pkblob, blen); + if (key == NULL) { + error("userauth_hostbased: cannot decode key: %s", pkalg); + goto done; + } + if (key->type != pktype) { + error("userauth_hostbased: type mismatch for decoded key " + "(received %d, expected %d)", key->type, pktype); + goto done; + } + service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" : + authctxt->service; + buffer_init(&b); + buffer_put_string(&b, session_id2, session_id2_len); + /* reconstruct packet */ + buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); + buffer_put_cstring(&b, authctxt->user); + buffer_put_cstring(&b, service); + buffer_put_cstring(&b, "hostbased"); + buffer_put_string(&b, pkalg, alen); + buffer_put_string(&b, pkblob, blen); + buffer_put_cstring(&b, chost); + buffer_put_cstring(&b, cuser); +#ifdef DEBUG_PK + buffer_dump(&b); +#endif + /* test for allowed key and correct signature */ + authenticated = 0; + if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) && + PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), + buffer_len(&b))) == 1) + authenticated = 1; + + buffer_free(&b); +done: + debug2("userauth_hostbased: authenticated %d", authenticated); + if (key != NULL) + key_free(key); + xfree(pkalg); + xfree(pkblob); + xfree(cuser); + xfree(chost); + xfree(sig); + return authenticated; +} + +/* return 1 if given hostkey is allowed */ +int +hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, + Key *key) +{ + const char *resolvedname, *ipaddr, *lookup, *reason; + HostStatus host_status; + int len; + char *fp; + + if (auth_key_is_revoked(key)) + return 0; + + resolvedname = get_canonical_hostname(options.use_dns); + ipaddr = get_remote_ipaddr(); + + debug2("userauth_hostbased: chost %s resolvedname %s ipaddr %s", + 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) + 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) + return 0; + lookup = resolvedname; + } + debug2("userauth_hostbased: access allowed by auth_rhosts2"); + + 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)) { + fp = key_fingerprint(key->cert->signature_key, + SSH_FP_MD5, SSH_FP_HEX); + 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 { + fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); + verbose("Accepted %s public key %s from %s@%s", + key_type(key), fp, cuser, lookup); + } + xfree(fp); + } + + return (host_status == HOST_OK); +} + +Authmethod method_hostbased = { + "hostbased", + userauth_hostbased, + &options.hostbased_authentication +};
diff --git a/openssh-6.0p1/auth2-jpake.c b/openssh-6.0p1/auth2-jpake.c new file mode 100644 index 0000000..a460e82 --- /dev/null +++ b/openssh-6.0p1/auth2-jpake.c
@@ -0,0 +1,563 @@ +/* $OpenBSD: auth2-jpake.c,v 1.4 2010/08/31 11:54:45 djm Exp $ */ +/* + * Copyright (c) 2008 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. + */ + +/* + * Server side of zero-knowledge password auth using J-PAKE protocol + * as described in: + * + * F. Hao, P. Ryan, "Password Authenticated Key Exchange by Juggling", + * 16th Workshop on Security Protocols, Cambridge, April 2008 + * + * http://grouper.ieee.org/groups/1363/Research/contributions/hao-ryan-2008.pdf + */ + +#ifdef JPAKE + +#include <sys/types.h> +#include <sys/param.h> + +#include <pwd.h> +#include <stdio.h> +#include <string.h> +#include <login_cap.h> + +#include <openssl/bn.h> +#include <openssl/evp.h> + +#include "xmalloc.h" +#include "ssh2.h" +#include "key.h" +#include "hostfile.h" +#include "auth.h" +#include "buffer.h" +#include "packet.h" +#include "dispatch.h" +#include "log.h" +#include "servconf.h" +#include "auth-options.h" +#include "canohost.h" +#ifdef GSSAPI +#include "ssh-gss.h" +#endif +#include "monitor_wrap.h" + +#include "schnorr.h" +#include "jpake.h" + +/* + * XXX options->permit_empty_passwd (at the moment, they will be refused + * anyway because they will mismatch on fake salt. + */ + +/* Dispatch handlers */ +static void input_userauth_jpake_client_step1(int, u_int32_t, void *); +static void input_userauth_jpake_client_step2(int, u_int32_t, void *); +static void input_userauth_jpake_client_confirm(int, u_int32_t, void *); + +static int auth2_jpake_start(Authctxt *); + +/* import */ +extern ServerOptions options; +extern u_char *session_id2; +extern u_int session_id2_len; + +/* + * Attempt J-PAKE authentication. + */ +static int +userauth_jpake(Authctxt *authctxt) +{ + int authenticated = 0; + + packet_check_eom(); + + debug("jpake-01@openssh.com requested"); + + if (authctxt->user != NULL) { + if (authctxt->jpake_ctx == NULL) + authctxt->jpake_ctx = jpake_new(); + if (options.zero_knowledge_password_authentication) + authenticated = auth2_jpake_start(authctxt); + } + + return authenticated; +} + +Authmethod method_jpake = { + "jpake-01@openssh.com", + userauth_jpake, + &options.zero_knowledge_password_authentication +}; + +/* Clear context and callbacks */ +void +auth2_jpake_stop(Authctxt *authctxt) +{ + /* unregister callbacks */ + dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP1, NULL); + dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP2, NULL); + dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_CONFIRM, NULL); + if (authctxt->jpake_ctx != NULL) { + jpake_free(authctxt->jpake_ctx); + authctxt->jpake_ctx = NULL; + } +} + +/* Returns 1 if 'c' is a valid crypt(3) salt character, 0 otherwise */ +static int +valid_crypt_salt(int c) +{ + if (c >= 'A' && c <= 'Z') + return 1; + if (c >= 'a' && c <= 'z') + return 1; + if (c >= '.' && c <= '9') + return 1; + return 0; +} + +/* + * Derive fake salt as H(username || first_private_host_key) + * This provides relatively stable fake salts for non-existent + * users and avoids the jpake method becoming an account validity + * oracle. + */ +static void +derive_rawsalt(const char *username, u_char *rawsalt, u_int len) +{ + u_char *digest; + u_int digest_len; + Buffer b; + Key *k; + + buffer_init(&b); + buffer_put_cstring(&b, username); + if ((k = get_hostkey_by_index(0)) == NULL || + (k->flags & KEY_FLAG_EXT)) + fatal("%s: no hostkeys", __func__); + switch (k->type) { + case KEY_RSA1: + case KEY_RSA: + if (k->rsa->p == NULL || k->rsa->q == NULL) + fatal("%s: RSA key missing p and/or q", __func__); + buffer_put_bignum2(&b, k->rsa->p); + buffer_put_bignum2(&b, k->rsa->q); + break; + case KEY_DSA: + if (k->dsa->priv_key == NULL) + fatal("%s: DSA key missing priv_key", __func__); + buffer_put_bignum2(&b, k->dsa->priv_key); + break; + case KEY_ECDSA: + if (EC_KEY_get0_private_key(k->ecdsa) == NULL) + fatal("%s: ECDSA key missing priv_key", __func__); + buffer_put_bignum2(&b, EC_KEY_get0_private_key(k->ecdsa)); + break; + default: + fatal("%s: unknown key type %d", __func__, k->type); + } + if (hash_buffer(buffer_ptr(&b), buffer_len(&b), EVP_sha256(), + &digest, &digest_len) != 0) + fatal("%s: hash_buffer", __func__); + buffer_free(&b); + if (len > digest_len) + fatal("%s: not enough bytes for rawsalt (want %u have %u)", + __func__, len, digest_len); + memcpy(rawsalt, digest, len); + bzero(digest, digest_len); + xfree(digest); +} + +/* ASCII an integer [0, 64) for inclusion in a password/salt */ +static char +pw_encode64(u_int i64) +{ + const u_char e64[] = + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + return e64[i64 % 64]; +} + +/* Generate ASCII salt bytes for user */ +static char * +makesalt(u_int want, const char *user) +{ + u_char rawsalt[32]; + static char ret[33]; + u_int i; + + if (want > sizeof(ret) - 1) + fatal("%s: want %u", __func__, want); + + derive_rawsalt(user, rawsalt, sizeof(rawsalt)); + bzero(ret, sizeof(ret)); + for (i = 0; i < want; i++) + ret[i] = pw_encode64(rawsalt[i]); + bzero(rawsalt, sizeof(rawsalt)); + + return ret; +} + +/* + * Select the system's default password hashing scheme and generate + * a stable fake salt under it for use by a non-existent account. + * Prevents jpake method being used to infer the validity of accounts. + */ +static void +fake_salt_and_scheme(Authctxt *authctxt, char **salt, char **scheme) +{ + char *rounds_s, *style; + long long rounds; + login_cap_t *lc; + + + if ((lc = login_getclass(authctxt->pw->pw_class)) == NULL && + (lc = login_getclass(NULL)) == NULL) + fatal("%s: login_getclass failed", __func__); + style = login_getcapstr(lc, "localcipher", NULL, NULL); + if (style == NULL) + style = xstrdup("blowfish,6"); + login_close(lc); + + if ((rounds_s = strchr(style, ',')) != NULL) + *rounds_s++ = '\0'; + rounds = strtonum(rounds_s, 1, 1<<31, NULL); + + if (strcmp(style, "md5") == 0) { + xasprintf(salt, "$1$%s$", makesalt(8, authctxt->user)); + *scheme = xstrdup("md5"); + } else if (strcmp(style, "old") == 0) { + *salt = xstrdup(makesalt(2, authctxt->user)); + *scheme = xstrdup("crypt"); + } else if (strcmp(style, "newsalt") == 0) { + rounds = MAX(rounds, 7250); + rounds = MIN(rounds, (1<<24) - 1); + xasprintf(salt, "_%c%c%c%c%s", + pw_encode64(rounds), pw_encode64(rounds >> 6), + pw_encode64(rounds >> 12), pw_encode64(rounds >> 18), + makesalt(4, authctxt->user)); + *scheme = xstrdup("crypt-extended"); + } else { + /* Default to blowfish */ + rounds = MAX(rounds, 3); + rounds = MIN(rounds, 31); + xasprintf(salt, "$2a$%02lld$%s", rounds, + makesalt(22, authctxt->user)); + *scheme = xstrdup("bcrypt"); + } + xfree(style); + debug3("%s: fake %s salt for user %s: %s", + __func__, *scheme, authctxt->user, *salt); +} + +/* + * Fetch password hashing scheme, password salt and derive shared secret + * for user. If user does not exist, a fake but stable and user-unique + * salt will be returned. + */ +void +auth2_jpake_get_pwdata(Authctxt *authctxt, BIGNUM **s, + char **hash_scheme, char **salt) +{ + char *cp; + u_char *secret; + u_int secret_len, salt_len; + +#ifdef JPAKE_DEBUG + debug3("%s: valid %d pw %.5s...", __func__, + authctxt->valid, authctxt->pw->pw_passwd); +#endif + + *salt = NULL; + *hash_scheme = NULL; + if (authctxt->valid) { + if (strncmp(authctxt->pw->pw_passwd, "$2$", 3) == 0 && + strlen(authctxt->pw->pw_passwd) > 28) { + /* + * old-variant bcrypt: + * "$2$", 2 digit rounds, "$", 22 bytes salt + */ + salt_len = 3 + 2 + 1 + 22 + 1; + *salt = xmalloc(salt_len); + strlcpy(*salt, authctxt->pw->pw_passwd, salt_len); + *hash_scheme = xstrdup("bcrypt"); + } else if (strncmp(authctxt->pw->pw_passwd, "$2a$", 4) == 0 && + strlen(authctxt->pw->pw_passwd) > 29) { + /* + * current-variant bcrypt: + * "$2a$", 2 digit rounds, "$", 22 bytes salt + */ + salt_len = 4 + 2 + 1 + 22 + 1; + *salt = xmalloc(salt_len); + strlcpy(*salt, authctxt->pw->pw_passwd, salt_len); + *hash_scheme = xstrdup("bcrypt"); + } else if (strncmp(authctxt->pw->pw_passwd, "$1$", 3) == 0 && + strlen(authctxt->pw->pw_passwd) > 5) { + /* + * md5crypt: + * "$1$", salt until "$" + */ + cp = strchr(authctxt->pw->pw_passwd + 3, '$'); + if (cp != NULL) { + salt_len = (cp - authctxt->pw->pw_passwd) + 1; + *salt = xmalloc(salt_len); + strlcpy(*salt, authctxt->pw->pw_passwd, + salt_len); + *hash_scheme = xstrdup("md5crypt"); + } + } else if (strncmp(authctxt->pw->pw_passwd, "_", 1) == 0 && + strlen(authctxt->pw->pw_passwd) > 9) { + /* + * BSDI extended crypt: + * "_", 4 digits count, 4 chars salt + */ + salt_len = 1 + 4 + 4 + 1; + *salt = xmalloc(salt_len); + strlcpy(*salt, authctxt->pw->pw_passwd, salt_len); + *hash_scheme = xstrdup("crypt-extended"); + } else if (strlen(authctxt->pw->pw_passwd) == 13 && + valid_crypt_salt(authctxt->pw->pw_passwd[0]) && + valid_crypt_salt(authctxt->pw->pw_passwd[1])) { + /* + * traditional crypt: + * 2 chars salt + */ + salt_len = 2 + 1; + *salt = xmalloc(salt_len); + strlcpy(*salt, authctxt->pw->pw_passwd, salt_len); + *hash_scheme = xstrdup("crypt"); + } + if (*salt == NULL) { + debug("%s: unrecognised crypt scheme for user %s", + __func__, authctxt->pw->pw_name); + } + } + if (*salt == NULL) + fake_salt_and_scheme(authctxt, salt, hash_scheme); + + if (hash_buffer(authctxt->pw->pw_passwd, + strlen(authctxt->pw->pw_passwd), EVP_sha256(), + &secret, &secret_len) != 0) + fatal("%s: hash_buffer", __func__); + if ((*s = BN_bin2bn(secret, secret_len, NULL)) == NULL) + fatal("%s: BN_bin2bn (secret)", __func__); +#ifdef JPAKE_DEBUG + debug3("%s: salt = %s (len %u)", __func__, + *salt, (u_int)strlen(*salt)); + debug3("%s: scheme = %s", __func__, *hash_scheme); + JPAKE_DEBUG_BN((*s, "%s: s = ", __func__)); +#endif + bzero(secret, secret_len); + xfree(secret); +} + +/* + * Begin authentication attempt. + * Note, sets authctxt->postponed while in subprotocol + */ +static int +auth2_jpake_start(Authctxt *authctxt) +{ + struct jpake_ctx *pctx = authctxt->jpake_ctx; + u_char *x3_proof, *x4_proof; + u_int x3_proof_len, x4_proof_len; + char *salt, *hash_scheme; + + debug("%s: start", __func__); + + PRIVSEP(jpake_step1(pctx->grp, + &pctx->server_id, &pctx->server_id_len, + &pctx->x3, &pctx->x4, &pctx->g_x3, &pctx->g_x4, + &x3_proof, &x3_proof_len, + &x4_proof, &x4_proof_len)); + + PRIVSEP(auth2_jpake_get_pwdata(authctxt, &pctx->s, + &hash_scheme, &salt)); + + if (!use_privsep) + JPAKE_DEBUG_CTX((pctx, "step 1 sending in %s", __func__)); + + packet_start(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP1); + packet_put_cstring(hash_scheme); + packet_put_cstring(salt); + packet_put_string(pctx->server_id, pctx->server_id_len); + packet_put_bignum2(pctx->g_x3); + packet_put_bignum2(pctx->g_x4); + packet_put_string(x3_proof, x3_proof_len); + packet_put_string(x4_proof, x4_proof_len); + packet_send(); + packet_write_wait(); + + bzero(hash_scheme, strlen(hash_scheme)); + bzero(salt, strlen(salt)); + xfree(hash_scheme); + xfree(salt); + bzero(x3_proof, x3_proof_len); + bzero(x4_proof, x4_proof_len); + xfree(x3_proof); + xfree(x4_proof); + + /* Expect step 1 packet from peer */ + dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP1, + input_userauth_jpake_client_step1); + + authctxt->postponed = 1; + return 0; +} + +/* ARGSUSED */ +static void +input_userauth_jpake_client_step1(int type, u_int32_t seq, void *ctxt) +{ + Authctxt *authctxt = ctxt; + struct jpake_ctx *pctx = authctxt->jpake_ctx; + u_char *x1_proof, *x2_proof, *x4_s_proof; + u_int x1_proof_len, x2_proof_len, x4_s_proof_len; + + /* Disable this message */ + dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP1, NULL); + + /* Fetch step 1 values */ + if ((pctx->g_x1 = BN_new()) == NULL || + (pctx->g_x2 = BN_new()) == NULL) + fatal("%s: BN_new", __func__); + pctx->client_id = packet_get_string(&pctx->client_id_len); + packet_get_bignum2(pctx->g_x1); + packet_get_bignum2(pctx->g_x2); + x1_proof = packet_get_string(&x1_proof_len); + x2_proof = packet_get_string(&x2_proof_len); + packet_check_eom(); + + if (!use_privsep) + JPAKE_DEBUG_CTX((pctx, "step 1 received in %s", __func__)); + + PRIVSEP(jpake_step2(pctx->grp, pctx->s, pctx->g_x3, + pctx->g_x1, pctx->g_x2, pctx->x4, + pctx->client_id, pctx->client_id_len, + pctx->server_id, pctx->server_id_len, + x1_proof, x1_proof_len, + x2_proof, x2_proof_len, + &pctx->b, + &x4_s_proof, &x4_s_proof_len)); + + bzero(x1_proof, x1_proof_len); + bzero(x2_proof, x2_proof_len); + xfree(x1_proof); + xfree(x2_proof); + + if (!use_privsep) + JPAKE_DEBUG_CTX((pctx, "step 2 sending in %s", __func__)); + + /* Send values for step 2 */ + packet_start(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP2); + packet_put_bignum2(pctx->b); + packet_put_string(x4_s_proof, x4_s_proof_len); + packet_send(); + packet_write_wait(); + + bzero(x4_s_proof, x4_s_proof_len); + xfree(x4_s_proof); + + /* Expect step 2 packet from peer */ + dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP2, + input_userauth_jpake_client_step2); +} + +/* ARGSUSED */ +static void +input_userauth_jpake_client_step2(int type, u_int32_t seq, void *ctxt) +{ + Authctxt *authctxt = ctxt; + struct jpake_ctx *pctx = authctxt->jpake_ctx; + u_char *x2_s_proof; + u_int x2_s_proof_len; + + /* Disable this message */ + dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP2, NULL); + + if ((pctx->a = BN_new()) == NULL) + fatal("%s: BN_new", __func__); + + /* Fetch step 2 values */ + packet_get_bignum2(pctx->a); + x2_s_proof = packet_get_string(&x2_s_proof_len); + packet_check_eom(); + + if (!use_privsep) + JPAKE_DEBUG_CTX((pctx, "step 2 received in %s", __func__)); + + /* Derive shared key and calculate confirmation hash */ + PRIVSEP(jpake_key_confirm(pctx->grp, pctx->s, pctx->a, + pctx->x4, pctx->g_x3, pctx->g_x4, pctx->g_x1, pctx->g_x2, + pctx->server_id, pctx->server_id_len, + pctx->client_id, pctx->client_id_len, + session_id2, session_id2_len, + x2_s_proof, x2_s_proof_len, + &pctx->k, + &pctx->h_k_sid_sessid, &pctx->h_k_sid_sessid_len)); + + bzero(x2_s_proof, x2_s_proof_len); + xfree(x2_s_proof); + + if (!use_privsep) + JPAKE_DEBUG_CTX((pctx, "confirm sending in %s", __func__)); + + /* Send key confirmation proof */ + packet_start(SSH2_MSG_USERAUTH_JPAKE_SERVER_CONFIRM); + packet_put_string(pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len); + packet_send(); + packet_write_wait(); + + /* Expect confirmation from peer */ + dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_CONFIRM, + input_userauth_jpake_client_confirm); +} + +/* ARGSUSED */ +static void +input_userauth_jpake_client_confirm(int type, u_int32_t seq, void *ctxt) +{ + Authctxt *authctxt = ctxt; + struct jpake_ctx *pctx = authctxt->jpake_ctx; + int authenticated = 0; + + /* Disable this message */ + dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_CONFIRM, NULL); + + pctx->h_k_cid_sessid = packet_get_string(&pctx->h_k_cid_sessid_len); + packet_check_eom(); + + if (!use_privsep) + JPAKE_DEBUG_CTX((pctx, "confirm received in %s", __func__)); + + /* Verify expected confirmation hash */ + if (PRIVSEP(jpake_check_confirm(pctx->k, + pctx->client_id, pctx->client_id_len, + session_id2, session_id2_len, + pctx->h_k_cid_sessid, pctx->h_k_cid_sessid_len)) == 1) + authenticated = authctxt->valid ? 1 : 0; + else + debug("%s: confirmation mismatch", __func__); + + /* done */ + authctxt->postponed = 0; + jpake_free(authctxt->jpake_ctx); + authctxt->jpake_ctx = NULL; + userauth_finish(authctxt, authenticated, method_jpake.name); +} + +#endif /* JPAKE */ +
diff --git a/openssh-6.0p1/auth2-kbdint.c b/openssh-6.0p1/auth2-kbdint.c new file mode 100644 index 0000000..fae67da --- /dev/null +++ b/openssh-6.0p1/auth2-kbdint.c
@@ -0,0 +1,68 @@ +/* $OpenBSD: auth2-kbdint.c,v 1.5 2006/08/03 03:34:41 deraadt Exp $ */ +/* + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#include <sys/types.h> + +#include <stdarg.h> + +#include "xmalloc.h" +#include "packet.h" +#include "key.h" +#include "hostfile.h" +#include "auth.h" +#include "log.h" +#include "buffer.h" +#include "servconf.h" + +/* import */ +extern ServerOptions options; + +static int +userauth_kbdint(Authctxt *authctxt) +{ + int authenticated = 0; + char *lang, *devs; + + lang = packet_get_string(NULL); + devs = packet_get_string(NULL); + packet_check_eom(); + + debug("keyboard-interactive devs %s", devs); + + if (options.challenge_response_authentication) + authenticated = auth2_challenge(authctxt, devs); + + xfree(devs); + xfree(lang); + return authenticated; +} + +Authmethod method_kbdint = { + "keyboard-interactive", + userauth_kbdint, + &options.kbd_interactive_authentication +};
diff --git a/openssh-6.0p1/auth2-none.c b/openssh-6.0p1/auth2-none.c new file mode 100644 index 0000000..c8c6c74 --- /dev/null +++ b/openssh-6.0p1/auth2-none.c
@@ -0,0 +1,73 @@ +/* $OpenBSD: auth2-none.c,v 1.16 2010/06/25 08:46:17 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 <sys/types.h> +#include <sys/stat.h> +#include <sys/uio.h> + +#include <fcntl.h> +#include <stdarg.h> +#include <string.h> +#include <unistd.h> + +#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 "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 +};
diff --git a/openssh-6.0p1/auth2-passwd.c b/openssh-6.0p1/auth2-passwd.c new file mode 100644 index 0000000..5f1f363 --- /dev/null +++ b/openssh-6.0p1/auth2-passwd.c
@@ -0,0 +1,80 @@ +/* $OpenBSD: auth2-passwd.c,v 1.9 2006/08/03 03:34:41 deraadt Exp $ */ +/* + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#include <sys/types.h> + +#include <string.h> +#include <stdarg.h> + +#include "xmalloc.h" +#include "packet.h" +#include "log.h" +#include "key.h" +#include "hostfile.h" +#include "auth.h" +#include "buffer.h" +#ifdef GSSAPI +#include "ssh-gss.h" +#endif +#include "monitor_wrap.h" +#include "servconf.h" + +/* import */ +extern ServerOptions options; + +static int +userauth_passwd(Authctxt *authctxt) +{ + char *password, *newpass; + int authenticated = 0; + int change; + u_int len, newlen; + + change = packet_get_char(); + password = packet_get_string(&len); + if (change) { + /* discard new password from packet */ + newpass = packet_get_string(&newlen); + memset(newpass, 0, newlen); + xfree(newpass); + } + packet_check_eom(); + + if (change) + logit("password change not supported"); + else if (PRIVSEP(auth_password(authctxt, password)) == 1) + authenticated = 1; + memset(password, 0, len); + xfree(password); + return authenticated; +} + +Authmethod method_passwd = { + "password", + userauth_passwd, + &options.password_authentication +};
diff --git a/openssh-6.0p1/auth2-pubkey.c b/openssh-6.0p1/auth2-pubkey.c new file mode 100644 index 0000000..5bccb5d --- /dev/null +++ b/openssh-6.0p1/auth2-pubkey.c
@@ -0,0 +1,466 @@ +/* $OpenBSD: auth2-pubkey.c,v 1.30 2011/09/25 05:44:47 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 <sys/types.h> +#include <sys/stat.h> + +#include <fcntl.h> +#include <pwd.h> +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include <time.h> +#include <unistd.h> + +#include "xmalloc.h" +#include "ssh.h" +#include "ssh2.h" +#include "packet.h" +#include "buffer.h" +#include "log.h" +#include "servconf.h" +#include "compat.h" +#include "key.h" +#include "hostfile.h" +#include "auth.h" +#include "pathnames.h" +#include "uidswap.h" +#include "auth-options.h" +#include "canohost.h" +#ifdef GSSAPI +#include "ssh-gss.h" +#endif +#include "monitor_wrap.h" +#include "misc.h" +#include "authfile.h" +#include "match.h" + +/* import */ +extern ServerOptions options; +extern u_char *session_id2; +extern u_int session_id2_len; + +static int +userauth_pubkey(Authctxt *authctxt) +{ + Buffer b; + Key *key = NULL; + char *pkalg; + u_char *pkblob, *sig; + u_int alen, blen, slen; + int have_sig, pktype; + int authenticated = 0; + + if (!authctxt->valid) { + debug2("userauth_pubkey: disabled because of invalid user"); + return 0; + } + have_sig = packet_get_char(); + if (datafellows & SSH_BUG_PKAUTH) { + debug2("userauth_pubkey: SSH_BUG_PKAUTH"); + /* no explicit pkalg given */ + pkblob = packet_get_string(&blen); + buffer_init(&b); + buffer_append(&b, pkblob, blen); + /* so we have to extract the pkalg from the pkblob */ + pkalg = buffer_get_string(&b, &alen); + buffer_free(&b); + } else { + pkalg = packet_get_string(&alen); + pkblob = packet_get_string(&blen); + } + pktype = key_type_from_name(pkalg); + if (pktype == KEY_UNSPEC) { + /* this is perfectly legal */ + logit("userauth_pubkey: unsupported public key algorithm: %s", + pkalg); + goto done; + } + key = key_from_blob(pkblob, blen); + if (key == NULL) { + error("userauth_pubkey: cannot decode key: %s", pkalg); + goto done; + } + if (key->type != pktype) { + error("userauth_pubkey: type mismatch for decoded key " + "(received %d, expected %d)", key->type, pktype); + goto done; + } + if (have_sig) { + sig = packet_get_string(&slen); + packet_check_eom(); + buffer_init(&b); + if (datafellows & SSH_OLD_SESSIONID) { + buffer_append(&b, session_id2, session_id2_len); + } else { + buffer_put_string(&b, session_id2, session_id2_len); + } + /* reconstruct packet */ + buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); + buffer_put_cstring(&b, authctxt->user); + buffer_put_cstring(&b, + datafellows & SSH_BUG_PKSERVICE ? + "ssh-userauth" : + authctxt->service); + if (datafellows & SSH_BUG_PKAUTH) { + buffer_put_char(&b, have_sig); + } else { + buffer_put_cstring(&b, "publickey"); + buffer_put_char(&b, have_sig); + buffer_put_cstring(&b, pkalg); + } + buffer_put_string(&b, pkblob, blen); +#ifdef DEBUG_PK + buffer_dump(&b); +#endif + /* test for correct signature */ + authenticated = 0; + if (PRIVSEP(user_key_allowed(authctxt->pw, key)) && + PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), + buffer_len(&b))) == 1) + authenticated = 1; + buffer_free(&b); + xfree(sig); + } else { + debug("test whether pkalg/pkblob are acceptable"); + packet_check_eom(); + + /* XXX fake reply and always send PK_OK ? */ + /* + * XXX this allows testing whether a user is allowed + * to login: if you happen to have a valid pubkey this + * message is sent. the message is NEVER sent at all + * if a user is not allowed to login. is this an + * issue? -markus + */ + if (PRIVSEP(user_key_allowed(authctxt->pw, key))) { + packet_start(SSH2_MSG_USERAUTH_PK_OK); + packet_put_string(pkalg, alen); + packet_put_string(pkblob, blen); + packet_send(); + packet_write_wait(); + authctxt->postponed = 1; + } + } + if (authenticated != 1) + auth_clear_options(); +done: + debug2("userauth_pubkey: authenticated %d pkalg %s", authenticated, pkalg); + if (key != NULL) + key_free(key); + xfree(pkalg); + xfree(pkblob); + return authenticated; +} + +static int +match_principals_option(const char *principal_list, struct KeyCert *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); + xfree(result); + return 1; + } + } + return 0; +} + +static int +match_principals_file(char *file, struct passwd *pw, struct KeyCert *cert) +{ + FILE *f; + char line[SSH_MAX_PUBKEY_BYTES], *cp, *ep, *line_opts; + u_long linenum = 0; + u_int i; + + 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; + } + while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) { + /* Skip leading whitespace. */ + for (cp = line; *cp == ' ' || *cp == '\t'; cp++) + ; + /* Skip blank and comment lines. */ + if ((ep = strchr(cp, '#')) != NULL) + *ep = '\0'; + if (!*cp || *cp == '\n') + continue; + /* Trim trailing whitespace. */ + ep = cp + strlen(cp) - 1; + while (ep > cp && (*ep == '\n' || *ep == ' ' || *ep == '\t')) + *ep-- = '\0'; + /* + * If the line has internal whitespace then assume it has + * key options. + */ + line_opts = NULL; + if ((ep = strrchr(cp, ' ')) != NULL || + (ep = strrchr(cp, '\t')) != NULL) { + for (; *ep == ' ' || *ep == '\t'; ep++) + ; + line_opts = cp; + cp = ep; + } + for (i = 0; i < cert->nprincipals; i++) { + if (strcmp(cp, cert->principals[i]) == 0) { + debug3("matched principal \"%.100s\" " + "from file \"%s\" on line %lu", + cert->principals[i], file, linenum); + if (auth_parse_options(pw, line_opts, + file, linenum) != 1) + continue; + fclose(f); + restore_uid(); + return 1; + } + } + } + fclose(f); + restore_uid(); + return 0; +} + +/* return 1 if user allows given key */ +static int +user_key_allowed2(struct passwd *pw, Key *key, char *file) +{ + char line[SSH_MAX_PUBKEY_BYTES]; + const char *reason; + int found_key = 0; + FILE *f; + u_long linenum = 0; + Key *found; + char *fp; + + /* Temporarily use the user's uid. */ + temporarily_use_uid(pw); + + debug("trying public key file %s", file); + f = auth_openkeyfile(file, pw, options.strict_modes); + + if (!f) { + restore_uid(); + return 0; + } + + found_key = 0; + found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type); + + while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) { + char *cp, *key_options = NULL; + + 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; + fp = key_fingerprint(found, SSH_FP_MD5, + SSH_FP_HEX); + 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: + xfree(fp); + error("%s", reason); + auth_debug_add("%s", reason); + continue; + } + if (key_cert_check_authority(key, 0, 0, + authorized_principals == NULL ? pw->pw_name : NULL, + &reason) != 0) + goto fail_reason; + if (auth_cert_options(key, pw) != 0) { + xfree(fp); + continue; + } + verbose("Accepted certificate ID \"%s\" " + "signed by %s CA %s via %s", key->cert->key_id, + key_type(found), fp, file); + xfree(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; + found_key = 1; + debug("matching key found: file %s, line %lu", + file, linenum); + fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX); + verbose("Found matching %s key: %s", + key_type(found), fp); + xfree(fp); + break; + } + } + restore_uid(); + fclose(f); + key_free(found); + if (!found_key) + debug2("key not found"); + return found_key; +} + +/* 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; + + if (!key_is_cert(key) || options.trusted_user_ca_keys == NULL) + return 0; + + ca_fp = key_fingerprint(key->cert->signature_key, + SSH_FP_MD5, SSH_FP_HEX); + + if (key_in_file(key->cert->signature_key, + options.trusted_user_ca_keys, 1) != 1) { + 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)) { + 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, + principals_file == NULL ? pw->pw_name : NULL, &reason) != 0) + goto fail_reason; + if (auth_cert_options(key, pw) != 0) + goto out; + + verbose("Accepted certificate ID \"%s\" signed by %s CA %s via %s", + key->cert->key_id, key_type(key->cert->signature_key), ca_fp, + options.trusted_user_ca_keys); + ret = 1; + + out: + if (principals_file != NULL) + xfree(principals_file); + if (ca_fp != NULL) + xfree(ca_fp); + return ret; +} + +/* check whether given key is in .ssh/authorized_keys* */ +int +user_key_allowed(struct passwd *pw, Key *key) +{ + 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; + + for (i = 0; !success && i < options.num_authkeys_files; i++) { + file = expand_authorized_keys( + options.authorized_keys_files[i], pw); + success = user_key_allowed2(pw, key, file); + xfree(file); + } + + return success; +} + +Authmethod method_pubkey = { + "publickey", + userauth_pubkey, + &options.pubkey_authentication +};
diff --git a/openssh-6.0p1/auth2.c b/openssh-6.0p1/auth2.c new file mode 100644 index 0000000..b66bef6 --- /dev/null +++ b/openssh-6.0p1/auth2.c
@@ -0,0 +1,409 @@ +/* $OpenBSD: auth2.c,v 1.124 2011/12/07 05:44:38 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 <sys/types.h> +#include <sys/stat.h> +#include <sys/uio.h> + +#include <fcntl.h> +#include <pwd.h> +#include <stdarg.h> +#include <string.h> +#include <unistd.h> + +#include "atomicio.h" +#include "xmalloc.h" +#include "ssh2.h" +#include "packet.h" +#include "log.h" +#include "buffer.h" +#include "servconf.h" +#include "compat.h" +#include "key.h" +#include "hostfile.h" +#include "auth.h" +#include "dispatch.h" +#include "pathnames.h" +#include "buffer.h" + +#ifdef GSSAPI +#include "ssh-gss.h" +#endif +#include "monitor_wrap.h" + +/* import */ +extern ServerOptions options; +extern u_char *session_id2; +extern u_int session_id2_len; +extern Buffer loginmsg; + +/* methods */ + +extern Authmethod method_none; +extern Authmethod method_pubkey; +extern Authmethod method_passwd; +extern Authmethod method_kbdint; +extern Authmethod method_hostbased; +#ifdef GSSAPI +extern Authmethod method_gssapi; +#endif +#ifdef JPAKE +extern Authmethod method_jpake; +#endif + +Authmethod *authmethods[] = { + &method_none, + &method_pubkey, +#ifdef GSSAPI + &method_gssapi, +#endif +#ifdef JPAKE + &method_jpake, +#endif + &method_passwd, + &method_kbdint, + &method_hostbased, + NULL +}; + +/* protocol */ + +static void input_service_request(int, u_int32_t, void *); +static void input_userauth_request(int, u_int32_t, void *); + +/* helper */ +static Authmethod *authmethod_lookup(const char *); +static char *authmethods_get(void); + +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) { + xfree(banner); + return (NULL); + } + banner[n] = '\0'; + + return (banner); +} + +void +userauth_send_banner(const char *msg) +{ + if (datafellows & SSH_BUG_BANNER) + return; + + packet_start(SSH2_MSG_USERAUTH_BANNER); + packet_put_cstring(msg); + packet_put_cstring(""); /* language, unused */ + packet_send(); + debug("%s: sent", __func__); +} + +static void +userauth_banner(void) +{ + char *banner = NULL; + + if (options.banner == NULL || + strcasecmp(options.banner, "none") == 0 || + (datafellows & SSH_BUG_BANNER) != 0) + return; + + if ((banner = PRIVSEP(auth2_read_banner())) == NULL) + goto done; + userauth_send_banner(banner); + +done: + if (banner) + xfree(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 void +input_service_request(int type, u_int32_t seq, void *ctxt) +{ + Authctxt *authctxt = ctxt; + u_int len; + int acceptit = 0; + char *service = packet_get_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); + } + xfree(service); +} + +/*ARGSUSED*/ +static void +input_userauth_request(int type, u_int32_t seq, void *ctxt) +{ + Authctxt *authctxt = ctxt; + Authmethod *m = NULL; + char *user, *service, *method, *style = NULL; + int authenticated = 0; + + if (authctxt == NULL) + fatal("input_userauth_request: no authctxt"); + + user = packet_get_cstring(NULL); + service = packet_get_cstring(NULL); + method = packet_get_cstring(NULL); + debug("userauth-request for user %s service %s method %s", user, service, method); + debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); + + if ((style = strchr(user, ':')) != NULL) + *style++ = 0; + + if (authctxt->attempt++ == 0) { + /* setup auth context */ + authctxt->pw = PRIVSEP(getpwnamallow(user)); + authctxt->user = xstrdup(user); + if (authctxt->pw && strcmp(service, "ssh-connection")==0) { + authctxt->valid = 1; + debug2("input_userauth_request: setting up authctxt for %s", user); + } else { + logit("input_userauth_request: invalid user %s", user); + authctxt->pw = fakepw(); +#ifdef SSH_AUDIT_EVENTS + PRIVSEP(audit_event(SSH_INVALID_USER)); +#endif + } +#ifdef USE_PAM + if (options.use_pam) + PRIVSEP(start_pam(authctxt)); +#endif + setproctitle("%s%s", authctxt->valid ? user : "unknown", + use_privsep ? " [net]" : ""); + authctxt->service = xstrdup(service); + authctxt->style = style ? xstrdup(style) : NULL; + if (use_privsep) + mm_inform_authserv(service, style); + userauth_banner(); + } 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 JPAKE + auth2_jpake_stop(authctxt); +#endif + +#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(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); + + xfree(service); + xfree(user); + xfree(method); +} + +void +userauth_finish(Authctxt *authctxt, int authenticated, char *method) +{ + char *methods; + + if (!authctxt->valid && authenticated) + fatal("INTERNAL ERROR: authenticated invalid user %s", + authctxt->user); + + /* Special handling for root */ + if (authenticated && authctxt->pw->pw_uid == 0 && + !auth_root_allowed(method)) { + authenticated = 0; +#ifdef SSH_AUDIT_EVENTS + PRIVSEP(audit_event(SSH_LOGIN_ROOT_DENIED)); +#endif + } + +#ifdef USE_PAM + if (options.use_pam && authenticated) { + if (!PRIVSEP(do_pam_account())) { + /* if PAM returned a message, send it to the user */ + if (buffer_len(&loginmsg) > 0) { + buffer_append(&loginmsg, "\0", 1); + userauth_send_banner(buffer_ptr(&loginmsg)); + packet_write_wait(); + } + fatal("Access denied for user %s by PAM account " + "configuration", authctxt->user); + } + } +#endif + +#ifdef _UNICOS + if (authenticated && cray_access_denied(authctxt->user)) { + authenticated = 0; + fatal("Access denied for user %s.",authctxt->user); + } +#endif /* _UNICOS */ + + /* Log before sending the reply */ + auth_log(authctxt, authenticated, method, " ssh2"); + + if (authctxt->postponed) + return; + + /* XXX todo: check if multiple auth methods are needed */ + if (authenticated == 1) { + /* turn off userauth */ + dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore); + packet_start(SSH2_MSG_USERAUTH_SUCCESS); + packet_send(); + packet_write_wait(); + /* now we can break out */ + authctxt->success = 1; + } else { + + /* Allow initial try of "none" auth without failure penalty */ + if (!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 + packet_disconnect(AUTH_FAIL_MSG, authctxt->user); + } + methods = authmethods_get(); + packet_start(SSH2_MSG_USERAUTH_FAILURE); + packet_put_cstring(methods); + packet_put_char(0); /* XXX partial success, unused */ + packet_send(); + packet_write_wait(); + xfree(methods); + } +} + +static char * +authmethods_get(void) +{ + Buffer b; + char *list; + int i; + + buffer_init(&b); + for (i = 0; authmethods[i] != NULL; i++) { + if (strcmp(authmethods[i]->name, "none") == 0) + continue; + if (authmethods[i]->enabled != NULL && + *(authmethods[i]->enabled) != 0) { + if (buffer_len(&b) > 0) + buffer_append(&b, ",", 1); + buffer_append(&b, authmethods[i]->name, + strlen(authmethods[i]->name)); + } + } + buffer_append(&b, "\0", 1); + list = xstrdup(buffer_ptr(&b)); + buffer_free(&b); + return list; +} + +static Authmethod * +authmethod_lookup(const char *name) +{ + int i; + + if (name != NULL) + for (i = 0; authmethods[i] != NULL; i++) + if (authmethods[i]->enabled != NULL && + *(authmethods[i]->enabled) != 0 && + strcmp(name, authmethods[i]->name) == 0) + return authmethods[i]; + debug2("Unrecognized authentication method name: %s", + name ? name : "NULL"); + return NULL; +} +
diff --git a/openssh-6.0p1/authfd.c b/openssh-6.0p1/authfd.c new file mode 100644 index 0000000..f037e83 --- /dev/null +++ b/openssh-6.0p1/authfd.c
@@ -0,0 +1,708 @@ +/* $OpenBSD: authfd.c,v 1.86 2011/07/06 18:09:21 tedu Exp $ */ +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * Functions for connecting the local authentication agent. + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + * + * SSH2 implementation, + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#include <sys/types.h> +#include <sys/un.h> +#include <sys/socket.h> + +#include <openssl/evp.h> + +#include <openssl/crypto.h> +#include <fcntl.h> +#include <stdlib.h> +#include <signal.h> +#include <stdarg.h> +#include <string.h> +#include <unistd.h> + +#include "xmalloc.h" +#include "ssh.h" +#include "rsa.h" +#include "buffer.h" +#include "key.h" +#include "authfd.h" +#include "cipher.h" +#include "kex.h" +#include "compat.h" +#include "log.h" +#include "atomicio.h" +#include "misc.h" + +static int agent_present = 0; + +/* helper */ +int decode_reply(int type); + +/* macro to check for "agent failure" message */ +#define agent_failed(x) \ + ((x == SSH_AGENT_FAILURE) || (x == SSH_COM_AGENT2_FAILURE) || \ + (x == SSH2_AGENT_FAILURE)) + +int +ssh_agent_present(void) +{ + int authfd; + + if (agent_present) + return 1; + if ((authfd = ssh_get_authentication_socket()) == -1) + return 0; + else { + ssh_close_authentication_socket(authfd); + return 1; + } +} + +/* Returns the number of the authentication fd, or -1 if there is none. */ + +int +ssh_get_authentication_socket(void) +{ + const char *authsocket; + int sock; + struct sockaddr_un sunaddr; + + authsocket = getenv(SSH_AUTHSOCKET_ENV_NAME); + if (!authsocket) + return -1; + + bzero(&sunaddr, sizeof(sunaddr)); + sunaddr.sun_family = AF_UNIX; + strlcpy(sunaddr.sun_path, authsocket, sizeof(sunaddr.sun_path)); + + sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (sock < 0) + return -1; + + /* close on exec */ + if (fcntl(sock, F_SETFD, FD_CLOEXEC) == -1) { + close(sock); + return -1; + } + if (connect(sock, (struct sockaddr *)&sunaddr, sizeof sunaddr) < 0) { + close(sock); + return -1; + } + agent_present = 1; + return sock; +} + +static int +ssh_request_reply(AuthenticationConnection *auth, Buffer *request, Buffer *reply) +{ + u_int l, len; + char buf[1024]; + + /* Get the length of the message, and format it in the buffer. */ + len = buffer_len(request); + put_u32(buf, len); + + /* Send the length and then the packet to the agent. */ + if (atomicio(vwrite, auth->fd, buf, 4) != 4 || + atomicio(vwrite, auth->fd, buffer_ptr(request), + buffer_len(request)) != buffer_len(request)) { + error("Error writing to authentication socket."); + return 0; + } + /* + * Wait for response from the agent. First read the length of the + * response packet. + */ + if (atomicio(read, auth->fd, buf, 4) != 4) { + error("Error reading response length from authentication socket."); + return 0; + } + + /* Extract the length, and check it for sanity. */ + len = get_u32(buf); + if (len > 256 * 1024) + fatal("Authentication response too long: %u", len); + + /* Read the rest of the response in to the buffer. */ + buffer_clear(reply); + while (len > 0) { + l = len; + if (l > sizeof(buf)) + l = sizeof(buf); + if (atomicio(read, auth->fd, buf, l) != l) { + error("Error reading response from authentication socket."); + return 0; + } + buffer_append(reply, buf, l); + len -= l; + } + return 1; +} + +/* + * Closes the agent socket if it should be closed (depends on how it was + * obtained). The argument must have been returned by + * ssh_get_authentication_socket(). + */ + +void +ssh_close_authentication_socket(int sock) +{ + if (getenv(SSH_AUTHSOCKET_ENV_NAME)) + close(sock); +} + +/* + * Opens and connects a private socket for communication with the + * authentication agent. Returns the file descriptor (which must be + * shut down and closed by the caller when no longer needed). + * Returns NULL if an error occurred and the connection could not be + * opened. + */ + +AuthenticationConnection * +ssh_get_authentication_connection(void) +{ + AuthenticationConnection *auth; + int sock; + + sock = ssh_get_authentication_socket(); + + /* + * Fail if we couldn't obtain a connection. This happens if we + * exited due to a timeout. + */ + if (sock < 0) + return NULL; + + auth = xmalloc(sizeof(*auth)); + auth->fd = sock; + buffer_init(&auth->identities); + auth->howmany = 0; + + return auth; +} + +/* + * Closes the connection to the authentication agent and frees any associated + * memory. + */ + +void +ssh_close_authentication_connection(AuthenticationConnection *auth) +{ + buffer_free(&auth->identities); + close(auth->fd); + xfree(auth); +} + +/* Lock/unlock agent */ +int +ssh_lock_agent(AuthenticationConnection *auth, int lock, const char *password) +{ + int type; + Buffer msg; + + buffer_init(&msg); + buffer_put_char(&msg, lock ? SSH_AGENTC_LOCK : SSH_AGENTC_UNLOCK); + buffer_put_cstring(&msg, password); + + if (ssh_request_reply(auth, &msg, &msg) == 0) { + buffer_free(&msg); + return 0; + } + type = buffer_get_char(&msg); + buffer_free(&msg); + return decode_reply(type); +} + +/* + * Returns the first authentication identity held by the agent. + */ + +int +ssh_get_num_identities(AuthenticationConnection *auth, int version) +{ + int type, code1 = 0, code2 = 0; + Buffer request; + + switch (version) { + case 1: + code1 = SSH_AGENTC_REQUEST_RSA_IDENTITIES; + code2 = SSH_AGENT_RSA_IDENTITIES_ANSWER; + break; + case 2: + code1 = SSH2_AGENTC_REQUEST_IDENTITIES; + code2 = SSH2_AGENT_IDENTITIES_ANSWER; + break; + default: + return 0; + } + + /* + * Send a message to the agent requesting for a list of the + * identities it can represent. + */ + buffer_init(&request); + buffer_put_char(&request, code1); + + buffer_clear(&auth->identities); + if (ssh_request_reply(auth, &request, &auth->identities) == 0) { + buffer_free(&request); + return 0; + } + buffer_free(&request); + + /* Get message type, and verify that we got a proper answer. */ + type = buffer_get_char(&auth->identities); + if (agent_failed(type)) { + return 0; + } else if (type != code2) { + fatal("Bad authentication reply message type: %d", type); + } + + /* Get the number of entries in the response and check it for sanity. */ + auth->howmany = buffer_get_int(&auth->identities); + if ((u_int)auth->howmany > 1024) + fatal("Too many identities in authentication reply: %d", + auth->howmany); + + return auth->howmany; +} + +Key * +ssh_get_first_identity(AuthenticationConnection *auth, char **comment, int version) +{ + /* get number of identities and return the first entry (if any). */ + if (ssh_get_num_identities(auth, version) > 0) + return ssh_get_next_identity(auth, comment, version); + return NULL; +} + +Key * +ssh_get_next_identity(AuthenticationConnection *auth, char **comment, int version) +{ + int keybits; + u_int bits; + u_char *blob; + u_int blen; + Key *key = NULL; + + /* Return failure if no more entries. */ + if (auth->howmany <= 0) + return NULL; + + /* + * Get the next entry from the packet. These will abort with a fatal + * error if the packet is too short or contains corrupt data. + */ + switch (version) { + case 1: + key = key_new(KEY_RSA1); + bits = buffer_get_int(&auth->identities); + buffer_get_bignum(&auth->identities, key->rsa->e); + buffer_get_bignum(&auth->identities, key->rsa->n); + *comment = buffer_get_string(&auth->identities, NULL); + keybits = BN_num_bits(key->rsa->n); + if (keybits < 0 || bits != (u_int)keybits) + logit("Warning: identity keysize mismatch: actual %d, announced %u", + BN_num_bits(key->rsa->n), bits); + break; + case 2: + blob = buffer_get_string(&auth->identities, &blen); + *comment = buffer_get_string(&auth->identities, NULL); + key = key_from_blob(blob, blen); + xfree(blob); + break; + default: + return NULL; + } + /* Decrement the number of remaining entries. */ + auth->howmany--; + return key; +} + +/* + * Generates a random challenge, sends it to the agent, and waits for + * response from the agent. Returns true (non-zero) if the agent gave the + * correct answer, zero otherwise. Response type selects the style of + * response desired, with 0 corresponding to protocol version 1.0 (no longer + * supported) and 1 corresponding to protocol version 1.1. + */ + +int +ssh_decrypt_challenge(AuthenticationConnection *auth, + Key* key, BIGNUM *challenge, + u_char session_id[16], + u_int response_type, + u_char response[16]) +{ + Buffer buffer; + int success = 0; + int i; + int type; + + if (key->type != KEY_RSA1) + return 0; + if (response_type == 0) { + logit("Compatibility with ssh protocol version 1.0 no longer supported."); + return 0; + } + buffer_init(&buffer); + buffer_put_char(&buffer, SSH_AGENTC_RSA_CHALLENGE); + buffer_put_int(&buffer, BN_num_bits(key->rsa->n)); + buffer_put_bignum(&buffer, key->rsa->e); + buffer_put_bignum(&buffer, key->rsa->n); + buffer_put_bignum(&buffer, challenge); + buffer_append(&buffer, session_id, 16); + buffer_put_int(&buffer, response_type); + + if (ssh_request_reply(auth, &buffer, &buffer) == 0) { + buffer_free(&buffer); + return 0; + } + type = buffer_get_char(&buffer); + + if (agent_failed(type)) { + logit("Agent admitted failure to authenticate using the key."); + } else if (type != SSH_AGENT_RSA_RESPONSE) { + fatal("Bad authentication response: %d", type); + } else { + success = 1; + /* + * Get the response from the packet. This will abort with a + * fatal error if the packet is corrupt. + */ + for (i = 0; i < 16; i++) + response[i] = (u_char)buffer_get_char(&buffer); + } + buffer_free(&buffer); + return success; +} + +/* ask agent to sign data, returns -1 on error, 0 on success */ +int +ssh_agent_sign(AuthenticationConnection *auth, + Key *key, + u_char **sigp, u_int *lenp, + u_char *data, u_int datalen) +{ + extern int datafellows; + Buffer msg; + u_char *blob; + u_int blen; + int type, flags = 0; + int ret = -1; + + if (key_to_blob(key, &blob, &blen) == 0) + return -1; + + if (datafellows & SSH_BUG_SIGBLOB) + flags = SSH_AGENT_OLD_SIGNATURE; + + buffer_init(&msg); + buffer_put_char(&msg, SSH2_AGENTC_SIGN_REQUEST); + buffer_put_string(&msg, blob, blen); + buffer_put_string(&msg, data, datalen); + buffer_put_int(&msg, flags); + xfree(blob); + + if (ssh_request_reply(auth, &msg, &msg) == 0) { + buffer_free(&msg); + return -1; + } + type = buffer_get_char(&msg); + if (agent_failed(type)) { + logit("Agent admitted failure to sign using the key."); + } else if (type != SSH2_AGENT_SIGN_RESPONSE) { + fatal("Bad authentication response: %d", type); + } else { + ret = 0; + *sigp = buffer_get_string(&msg, lenp); + } + buffer_free(&msg); + return ret; +} + +/* Encode key for a message to the agent. */ + +static void +ssh_encode_identity_rsa1(Buffer *b, RSA *key, const char *comment) +{ + buffer_put_int(b, BN_num_bits(key->n)); + buffer_put_bignum(b, key->n); + buffer_put_bignum(b, key->e); + buffer_put_bignum(b, key->d); + /* To keep within the protocol: p < q for ssh. in SSL p > q */ + buffer_put_bignum(b, key->iqmp); /* ssh key->u */ + buffer_put_bignum(b, key->q); /* ssh key->p, SSL key->q */ + buffer_put_bignum(b, key->p); /* ssh key->q, SSL key->p */ + buffer_put_cstring(b, comment); +} + +static void +ssh_encode_identity_ssh2(Buffer *b, Key *key, const char *comment) +{ + buffer_put_cstring(b, key_ssh_name(key)); + switch (key->type) { + case KEY_RSA: + buffer_put_bignum2(b, key->rsa->n); + buffer_put_bignum2(b, key->rsa->e); + buffer_put_bignum2(b, key->rsa->d); + buffer_put_bignum2(b, key->rsa->iqmp); + buffer_put_bignum2(b, key->rsa->p); + buffer_put_bignum2(b, key->rsa->q); + break; + case KEY_RSA_CERT_V00: + case KEY_RSA_CERT: + if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0) + fatal("%s: no cert/certblob", __func__); + buffer_put_string(b, buffer_ptr(&key->cert->certblob), + buffer_len(&key->cert->certblob)); + buffer_put_bignum2(b, key->rsa->d); + buffer_put_bignum2(b, key->rsa->iqmp); + buffer_put_bignum2(b, key->rsa->p); + buffer_put_bignum2(b, key->rsa->q); + break; + case KEY_DSA: + buffer_put_bignum2(b, key->dsa->p); + buffer_put_bignum2(b, key->dsa->q); + buffer_put_bignum2(b, key->dsa->g); + buffer_put_bignum2(b, key->dsa->pub_key); + buffer_put_bignum2(b, key->dsa->priv_key); + break; + case KEY_DSA_CERT_V00: + case KEY_DSA_CERT: + if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0) + fatal("%s: no cert/certblob", __func__); + buffer_put_string(b, buffer_ptr(&key->cert->certblob), + buffer_len(&key->cert->certblob)); + buffer_put_bignum2(b, key->dsa->priv_key); + break; +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA: + buffer_put_cstring(b, key_curve_nid_to_name(key->ecdsa_nid)); + buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa), + EC_KEY_get0_public_key(key->ecdsa)); + buffer_put_bignum2(b, EC_KEY_get0_private_key(key->ecdsa)); + break; + case KEY_ECDSA_CERT: + if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0) + fatal("%s: no cert/certblob", __func__); + buffer_put_string(b, buffer_ptr(&key->cert->certblob), + buffer_len(&key->cert->certblob)); + buffer_put_bignum2(b, EC_KEY_get0_private_key(key->ecdsa)); + break; +#endif + } + buffer_put_cstring(b, comment); +} + +/* + * Adds an identity to the authentication server. This call is not meant to + * be used by normal applications. + */ + +int +ssh_add_identity_constrained(AuthenticationConnection *auth, Key *key, + const char *comment, u_int life, u_int confirm) +{ + Buffer msg; + int type, constrained = (life || confirm); + + buffer_init(&msg); + + switch (key->type) { + case KEY_RSA1: + type = constrained ? + SSH_AGENTC_ADD_RSA_ID_CONSTRAINED : + SSH_AGENTC_ADD_RSA_IDENTITY; + buffer_put_char(&msg, type); + ssh_encode_identity_rsa1(&msg, key->rsa, comment); + break; + case KEY_RSA: + case KEY_RSA_CERT: + case KEY_RSA_CERT_V00: + case KEY_DSA: + case KEY_DSA_CERT: + case KEY_DSA_CERT_V00: + case KEY_ECDSA: + case KEY_ECDSA_CERT: + type = constrained ? + SSH2_AGENTC_ADD_ID_CONSTRAINED : + SSH2_AGENTC_ADD_IDENTITY; + buffer_put_char(&msg, type); + ssh_encode_identity_ssh2(&msg, key, comment); + break; + default: + buffer_free(&msg); + return 0; + } + if (constrained) { + if (life != 0) { + buffer_put_char(&msg, SSH_AGENT_CONSTRAIN_LIFETIME); + buffer_put_int(&msg, life); + } + if (confirm != 0) + buffer_put_char(&msg, SSH_AGENT_CONSTRAIN_CONFIRM); + } + if (ssh_request_reply(auth, &msg, &msg) == 0) { + buffer_free(&msg); + return 0; + } + type = buffer_get_char(&msg); + buffer_free(&msg); + return decode_reply(type); +} + +/* + * Removes an identity from the authentication server. This call is not + * meant to be used by normal applications. + */ + +int +ssh_remove_identity(AuthenticationConnection *auth, Key *key) +{ + Buffer msg; + int type; + u_char *blob; + u_int blen; + + buffer_init(&msg); + + if (key->type == KEY_RSA1) { + buffer_put_char(&msg, SSH_AGENTC_REMOVE_RSA_IDENTITY); + buffer_put_int(&msg, BN_num_bits(key->rsa->n)); + buffer_put_bignum(&msg, key->rsa->e); + buffer_put_bignum(&msg, key->rsa->n); + } else if (key_type_plain(key->type) == KEY_DSA || + key_type_plain(key->type) == KEY_RSA || + key_type_plain(key->type) == KEY_ECDSA) { + key_to_blob(key, &blob, &blen); + buffer_put_char(&msg, SSH2_AGENTC_REMOVE_IDENTITY); + buffer_put_string(&msg, blob, blen); + xfree(blob); + } else { + buffer_free(&msg); + return 0; + } + if (ssh_request_reply(auth, &msg, &msg) == 0) { + buffer_free(&msg); + return 0; + } + type = buffer_get_char(&msg); + buffer_free(&msg); + return decode_reply(type); +} + +int +ssh_update_card(AuthenticationConnection *auth, int add, + const char *reader_id, const char *pin, u_int life, u_int confirm) +{ + Buffer msg; + int type, constrained = (life || confirm); + + if (add) { + type = constrained ? + SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED : + SSH_AGENTC_ADD_SMARTCARD_KEY; + } else + type = SSH_AGENTC_REMOVE_SMARTCARD_KEY; + + buffer_init(&msg); + buffer_put_char(&msg, type); + buffer_put_cstring(&msg, reader_id); + buffer_put_cstring(&msg, pin); + + if (constrained) { + if (life != 0) { + buffer_put_char(&msg, SSH_AGENT_CONSTRAIN_LIFETIME); + buffer_put_int(&msg, life); + } + if (confirm != 0) + buffer_put_char(&msg, SSH_AGENT_CONSTRAIN_CONFIRM); + } + + if (ssh_request_reply(auth, &msg, &msg) == 0) { + buffer_free(&msg); + return 0; + } + type = buffer_get_char(&msg); + buffer_free(&msg); + return decode_reply(type); +} + +/* + * Removes all identities from the agent. This call is not meant to be used + * by normal applications. + */ + +int +ssh_remove_all_identities(AuthenticationConnection *auth, int version) +{ + Buffer msg; + int type; + int code = (version==1) ? + SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES : + SSH2_AGENTC_REMOVE_ALL_IDENTITIES; + + buffer_init(&msg); + buffer_put_char(&msg, code); + + if (ssh_request_reply(auth, &msg, &msg) == 0) { + buffer_free(&msg); + return 0; + } + type = buffer_get_char(&msg); + buffer_free(&msg); + return decode_reply(type); +} + +int +decode_reply(int type) +{ + switch (type) { + case SSH_AGENT_FAILURE: + case SSH_COM_AGENT2_FAILURE: + case SSH2_AGENT_FAILURE: + logit("SSH_AGENT_FAILURE"); + return 0; + case SSH_AGENT_SUCCESS: + return 1; + default: + fatal("Bad response from authentication agent: %d", type); + } + /* NOTREACHED */ + return 0; +}
diff --git a/openssh-6.0p1/authfd.h b/openssh-6.0p1/authfd.h new file mode 100644 index 0000000..2582a27 --- /dev/null +++ b/openssh-6.0p1/authfd.h
@@ -0,0 +1,94 @@ +/* $OpenBSD: authfd.h,v 1.37 2009/08/27 17:44:52 djm Exp $ */ + +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * Functions to interface with the SSH_AUTHENTICATION_FD socket. + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ + +#ifndef AUTHFD_H +#define AUTHFD_H + +/* Messages for the authentication agent connection. */ +#define SSH_AGENTC_REQUEST_RSA_IDENTITIES 1 +#define SSH_AGENT_RSA_IDENTITIES_ANSWER 2 +#define SSH_AGENTC_RSA_CHALLENGE 3 +#define SSH_AGENT_RSA_RESPONSE 4 +#define SSH_AGENT_FAILURE 5 +#define SSH_AGENT_SUCCESS 6 +#define SSH_AGENTC_ADD_RSA_IDENTITY 7 +#define SSH_AGENTC_REMOVE_RSA_IDENTITY 8 +#define SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES 9 + +/* private OpenSSH extensions for SSH2 */ +#define SSH2_AGENTC_REQUEST_IDENTITIES 11 +#define SSH2_AGENT_IDENTITIES_ANSWER 12 +#define SSH2_AGENTC_SIGN_REQUEST 13 +#define SSH2_AGENT_SIGN_RESPONSE 14 +#define SSH2_AGENTC_ADD_IDENTITY 17 +#define SSH2_AGENTC_REMOVE_IDENTITY 18 +#define SSH2_AGENTC_REMOVE_ALL_IDENTITIES 19 + +/* smartcard */ +#define SSH_AGENTC_ADD_SMARTCARD_KEY 20 +#define SSH_AGENTC_REMOVE_SMARTCARD_KEY 21 + +/* lock/unlock the agent */ +#define SSH_AGENTC_LOCK 22 +#define SSH_AGENTC_UNLOCK 23 + +/* add key with constraints */ +#define SSH_AGENTC_ADD_RSA_ID_CONSTRAINED 24 +#define SSH2_AGENTC_ADD_ID_CONSTRAINED 25 +#define SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED 26 + +#define SSH_AGENT_CONSTRAIN_LIFETIME 1 +#define SSH_AGENT_CONSTRAIN_CONFIRM 2 + +/* extended failure messages */ +#define SSH2_AGENT_FAILURE 30 + +/* additional error code for ssh.com's ssh-agent2 */ +#define SSH_COM_AGENT2_FAILURE 102 + +#define SSH_AGENT_OLD_SIGNATURE 0x01 + +typedef struct { + int fd; + Buffer identities; + int howmany; +} AuthenticationConnection; + +int ssh_agent_present(void); +int ssh_get_authentication_socket(void); +void ssh_close_authentication_socket(int); + +AuthenticationConnection *ssh_get_authentication_connection(void); +void ssh_close_authentication_connection(AuthenticationConnection *); +int ssh_get_num_identities(AuthenticationConnection *, int); +Key *ssh_get_first_identity(AuthenticationConnection *, char **, int); +Key *ssh_get_next_identity(AuthenticationConnection *, char **, int); +int ssh_add_identity_constrained(AuthenticationConnection *, Key *, + const char *, u_int, u_int); +int ssh_remove_identity(AuthenticationConnection *, Key *); +int ssh_remove_all_identities(AuthenticationConnection *, int); +int ssh_lock_agent(AuthenticationConnection *, int, const char *); +int ssh_update_card(AuthenticationConnection *, int, const char *, + const char *, u_int, u_int); + +int +ssh_decrypt_challenge(AuthenticationConnection *, Key *, BIGNUM *, u_char[16], + u_int, u_char[16]); + +int +ssh_agent_sign(AuthenticationConnection *, Key *, u_char **, u_int *, u_char *, + u_int); + +#endif /* AUTHFD_H */
diff --git a/openssh-6.0p1/authfile.c b/openssh-6.0p1/authfile.c new file mode 100644 index 0000000..7dd4496 --- /dev/null +++ b/openssh-6.0p1/authfile.c
@@ -0,0 +1,946 @@ +/* $OpenBSD: authfile.c,v 1.93 2012/01/25 19:36:31 markus Exp $ */ +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * This file contains functions for reading and writing identity files, and + * for reading the passphrase from the user. + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + * + * + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/param.h> +#include <sys/uio.h> + +#include <openssl/err.h> +#include <openssl/evp.h> +#include <openssl/pem.h> + +/* compatibility with old or broken OpenSSL versions */ +#include "openbsd-compat/openssl-compat.h" + +#include <errno.h> +#include <fcntl.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "xmalloc.h" +#include "cipher.h" +#include "buffer.h" +#include "key.h" +#include "ssh.h" +#include "log.h" +#include "authfile.h" +#include "rsa.h" +#include "misc.h" +#include "atomicio.h" + +#define MAX_KEY_FILE_SIZE (1024 * 1024) + +/* Version identification string for SSH v1 identity files. */ +static const char authfile_id_string[] = + "SSH PRIVATE KEY FILE FORMAT 1.1\n"; + +/* + * 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 +key_private_rsa1_to_blob(Key *key, Buffer *blob, const char *passphrase, + const char *comment) +{ + Buffer buffer, encrypted; + u_char buf[100], *cp; + int i, cipher_num; + CipherContext ciphercontext; + Cipher *cipher; + u_int32_t rnd; + + /* + * If the passphrase is empty, use SSH_CIPHER_NONE to ease converting + * to another cipher; otherwise use SSH_AUTHFILE_CIPHER. + */ + cipher_num = (strcmp(passphrase, "") == 0) ? + SSH_CIPHER_NONE : SSH_AUTHFILE_CIPHER; + if ((cipher = cipher_by_number(cipher_num)) == NULL) + fatal("save_private_key_rsa: bad cipher"); + + /* This buffer is used to built the secret part of the private key. */ + buffer_init(&buffer); + + /* Put checkbytes for checking passphrase validity. */ + rnd = arc4random(); + buf[0] = rnd & 0xff; + buf[1] = (rnd >> 8) & 0xff; + buf[2] = buf[0]; + buf[3] = buf[1]; + buffer_append(&buffer, buf, 4); + + /* + * Store the private key (n and e will not be stored because they + * will be stored in plain text, and storing them also in encrypted + * format would just give known plaintext). + */ + buffer_put_bignum(&buffer, key->rsa->d); + buffer_put_bignum(&buffer, key->rsa->iqmp); + buffer_put_bignum(&buffer, key->rsa->q); /* reverse from SSL p */ + buffer_put_bignum(&buffer, key->rsa->p); /* reverse from SSL q */ + + /* Pad the part to be encrypted until its size is a multiple of 8. */ + while (buffer_len(&buffer) % 8 != 0) + buffer_put_char(&buffer, 0); + + /* This buffer will be used to contain the data in the file. */ + buffer_init(&encrypted); + + /* First store keyfile id string. */ + for (i = 0; authfile_id_string[i]; i++) + buffer_put_char(&encrypted, authfile_id_string[i]); + buffer_put_char(&encrypted, 0); + + /* Store cipher type. */ + buffer_put_char(&encrypted, cipher_num); + buffer_put_int(&encrypted, 0); /* For future extension */ + + /* Store public key. This will be in plain text. */ + buffer_put_int(&encrypted, BN_num_bits(key->rsa->n)); + buffer_put_bignum(&encrypted, key->rsa->n); + buffer_put_bignum(&encrypted, key->rsa->e); + buffer_put_cstring(&encrypted, comment); + + /* Allocate space for the private part of the key in the buffer. */ + cp = buffer_append_space(&encrypted, buffer_len(&buffer)); + + cipher_set_key_string(&ciphercontext, cipher, passphrase, + CIPHER_ENCRYPT); + cipher_crypt(&ciphercontext, cp, + buffer_ptr(&buffer), buffer_len(&buffer)); + cipher_cleanup(&ciphercontext); + memset(&ciphercontext, 0, sizeof(ciphercontext)); + + /* Destroy temporary data. */ + memset(buf, 0, sizeof(buf)); + buffer_free(&buffer); + + buffer_append(blob, buffer_ptr(&encrypted), buffer_len(&encrypted)); + buffer_free(&encrypted); + + return 1; +} + +/* convert SSH v2 key in OpenSSL PEM format */ +static int +key_private_pem_to_blob(Key *key, Buffer *blob, const char *_passphrase, + const char *comment) +{ + int success = 0; + 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; + + if (len > 0 && len <= 4) { + error("passphrase too short: have %d bytes, need > 4", len); + return 0; + } + if ((bio = BIO_new(BIO_s_mem())) == NULL) { + error("%s: BIO_new failed", __func__); + return 0; + } + 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; + } + if (success) { + if ((blen = BIO_get_mem_data(bio, &bptr)) <= 0) + success = 0; + else + buffer_append(blob, bptr, blen); + } + BIO_free(bio); + return success; +} + +/* Save a key blob to a file */ +static int +key_save_private_blob(Buffer *keybuf, const char *filename) +{ + int fd; + + if ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0) { + error("open %s failed: %s.", filename, strerror(errno)); + return 0; + } + if (atomicio(vwrite, fd, buffer_ptr(keybuf), + buffer_len(keybuf)) != buffer_len(keybuf)) { + error("write to key file %s failed: %s", filename, + strerror(errno)); + close(fd); + unlink(filename); + return 0; + } + close(fd); + return 1; +} + +/* Serialise "key" to buffer "blob" */ +static int +key_private_to_blob(Key *key, Buffer *blob, const char *passphrase, + const char *comment) +{ + switch (key->type) { + case KEY_RSA1: + return key_private_rsa1_to_blob(key, blob, passphrase, comment); + case KEY_DSA: + case KEY_ECDSA: + case KEY_RSA: + return key_private_pem_to_blob(key, blob, passphrase, comment); + default: + error("%s: cannot save key type %d", __func__, key->type); + return 0; + } +} + +int +key_save_private(Key *key, const char *filename, const char *passphrase, + const char *comment) +{ + Buffer keyblob; + int success = 0; + + buffer_init(&keyblob); + if (!key_private_to_blob(key, &keyblob, passphrase, comment)) + goto out; + if (!key_save_private_blob(&keyblob, filename)) + goto out; + success = 1; + out: + buffer_free(&keyblob); + return success; +} + +/* + * Parse the public, unencrypted portion of a RSA1 key. + */ +static Key * +key_parse_public_rsa1(Buffer *blob, char **commentp) +{ + Key *pub; + Buffer copy; + + /* Check that it is at least big enough to contain the ID string. */ + if (buffer_len(blob) < sizeof(authfile_id_string)) { + debug3("Truncated RSA1 identifier"); + return NULL; + } + + /* + * Make sure it begins with the id string. Consume the id string + * from the buffer. + */ + if (memcmp(buffer_ptr(blob), authfile_id_string, + sizeof(authfile_id_string)) != 0) { + debug3("Incorrect RSA1 identifier"); + return NULL; + } + buffer_init(©); + buffer_append(©, buffer_ptr(blob), buffer_len(blob)); + buffer_consume(©, sizeof(authfile_id_string)); + + /* Skip cipher type and reserved data. */ + (void) buffer_get_char(©); /* cipher type */ + (void) buffer_get_int(©); /* reserved */ + + /* Read the public key from the buffer. */ + (void) buffer_get_int(©); + pub = key_new(KEY_RSA1); + buffer_get_bignum(©, pub->rsa->n); + buffer_get_bignum(©, pub->rsa->e); + if (commentp) + *commentp = buffer_get_string(©, NULL); + /* The encrypted private part is not parsed by this function. */ + buffer_free(©); + + return pub; +} + +/* Load a key from a fd into a buffer */ +int +key_load_file(int fd, const char *filename, Buffer *blob) +{ + u_char buf[1024]; + size_t len; + struct stat st; + + if (fstat(fd, &st) < 0) { + error("%s: fstat of key file %.200s%sfailed: %.100s", __func__, + filename == NULL ? "" : filename, + filename == NULL ? "" : " ", + strerror(errno)); + return 0; + } + if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 && + st.st_size > MAX_KEY_FILE_SIZE) { + toobig: + error("%s: key file %.200s%stoo large", __func__, + filename == NULL ? "" : filename, + filename == NULL ? "" : " "); + return 0; + } + buffer_clear(blob); + for (;;) { + if ((len = atomicio(read, fd, buf, sizeof(buf))) == 0) { + if (errno == EPIPE) + break; + debug("%s: read from key file %.200s%sfailed: %.100s", + __func__, filename == NULL ? "" : filename, + filename == NULL ? "" : " ", strerror(errno)); + buffer_clear(blob); + bzero(buf, sizeof(buf)); + return 0; + } + buffer_append(blob, buf, len); + if (buffer_len(blob) > MAX_KEY_FILE_SIZE) { + buffer_clear(blob); + bzero(buf, sizeof(buf)); + goto toobig; + } + } + bzero(buf, sizeof(buf)); + if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 && + st.st_size != buffer_len(blob)) { + debug("%s: key file %.200s%schanged size while reading", + __func__, filename == NULL ? "" : filename, + filename == NULL ? "" : " "); + buffer_clear(blob); + return 0; + } + + return 1; +} + +/* + * Loads the public part of the ssh v1 key file. Returns NULL if an error was + * encountered (the file does not exist or is not readable), and the key + * otherwise. + */ +static Key * +key_load_public_rsa1(int fd, const char *filename, char **commentp) +{ + Buffer buffer; + Key *pub; + + buffer_init(&buffer); + if (!key_load_file(fd, filename, &buffer)) { + buffer_free(&buffer); + return NULL; + } + + pub = key_parse_public_rsa1(&buffer, commentp); + if (pub == NULL) + debug3("Could not load \"%s\" as a RSA1 public key", filename); + buffer_free(&buffer); + return pub; +} + +/* load public key from private-key file, works only for SSH v1 */ +Key * +key_load_public_type(int type, const char *filename, char **commentp) +{ + Key *pub; + int fd; + + if (type == KEY_RSA1) { + fd = open(filename, O_RDONLY); + if (fd < 0) + return NULL; + pub = key_load_public_rsa1(fd, filename, commentp); + close(fd); + return pub; + } + return NULL; +} + +static Key * +key_parse_private_rsa1(Buffer *blob, const char *passphrase, char **commentp) +{ + int check1, check2, cipher_type; + Buffer decrypted; + u_char *cp; + CipherContext ciphercontext; + Cipher *cipher; + Key *prv = NULL; + Buffer copy; + + /* Check that it is at least big enough to contain the ID string. */ + if (buffer_len(blob) < sizeof(authfile_id_string)) { + debug3("Truncated RSA1 identifier"); + return NULL; + } + + /* + * Make sure it begins with the id string. Consume the id string + * from the buffer. + */ + if (memcmp(buffer_ptr(blob), authfile_id_string, + sizeof(authfile_id_string)) != 0) { + debug3("Incorrect RSA1 identifier"); + return NULL; + } + buffer_init(©); + buffer_append(©, buffer_ptr(blob), buffer_len(blob)); + buffer_consume(©, sizeof(authfile_id_string)); + + /* Read cipher type. */ + cipher_type = buffer_get_char(©); + (void) buffer_get_int(©); /* Reserved data. */ + + /* Read the public key from the buffer. */ + (void) buffer_get_int(©); + prv = key_new_private(KEY_RSA1); + + buffer_get_bignum(©, prv->rsa->n); + buffer_get_bignum(©, prv->rsa->e); + if (commentp) + *commentp = buffer_get_string(©, NULL); + else + (void)buffer_get_string_ptr(©, NULL); + + /* Check that it is a supported cipher. */ + cipher = cipher_by_number(cipher_type); + if (cipher == NULL) { + debug("Unsupported RSA1 cipher %d", cipher_type); + buffer_free(©); + goto fail; + } + /* Initialize space for decrypted data. */ + buffer_init(&decrypted); + cp = buffer_append_space(&decrypted, buffer_len(©)); + + /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */ + cipher_set_key_string(&ciphercontext, cipher, passphrase, + CIPHER_DECRYPT); + cipher_crypt(&ciphercontext, cp, + buffer_ptr(©), buffer_len(©)); + cipher_cleanup(&ciphercontext); + memset(&ciphercontext, 0, sizeof(ciphercontext)); + buffer_free(©); + + check1 = buffer_get_char(&decrypted); + check2 = buffer_get_char(&decrypted); + if (check1 != buffer_get_char(&decrypted) || + check2 != buffer_get_char(&decrypted)) { + if (strcmp(passphrase, "") != 0) + debug("Bad passphrase supplied for RSA1 key"); + /* Bad passphrase. */ + buffer_free(&decrypted); + goto fail; + } + /* Read the rest of the private key. */ + buffer_get_bignum(&decrypted, prv->rsa->d); + buffer_get_bignum(&decrypted, prv->rsa->iqmp); /* u */ + /* in SSL and SSH v1 p and q are exchanged */ + buffer_get_bignum(&decrypted, prv->rsa->q); /* p */ + buffer_get_bignum(&decrypted, prv->rsa->p); /* q */ + + /* calculate p-1 and q-1 */ + rsa_generate_additional_parameters(prv->rsa); + + buffer_free(&decrypted); + + /* enable blinding */ + if (RSA_blinding_on(prv->rsa, NULL) != 1) { + error("%s: RSA_blinding_on failed", __func__); + goto fail; + } + return prv; + +fail: + if (commentp) + xfree(*commentp); + key_free(prv); + return NULL; +} + +static Key * +key_parse_private_pem(Buffer *blob, int type, const char *passphrase, + char **commentp) +{ + EVP_PKEY *pk = NULL; + Key *prv = NULL; + char *name = "<no key>"; + BIO *bio; + + if ((bio = BIO_new_mem_buf(buffer_ptr(blob), + buffer_len(blob))) == NULL) { + error("%s: BIO_new_mem_buf failed", __func__); + return NULL; + } + + pk = PEM_read_bio_PrivateKey(bio, NULL, NULL, (char *)passphrase); + BIO_free(bio); + if (pk == NULL) { + debug("%s: PEM_read_PrivateKey failed", __func__); + (void)ERR_get_error(); + } else if (pk->type == EVP_PKEY_RSA && + (type == KEY_UNSPEC||type==KEY_RSA)) { + prv = key_new(KEY_UNSPEC); + prv->rsa = EVP_PKEY_get1_RSA(pk); + prv->type = KEY_RSA; + name = "rsa w/o comment"; +#ifdef DEBUG_PK + RSA_print_fp(stderr, prv->rsa, 8); +#endif + if (RSA_blinding_on(prv->rsa, NULL) != 1) { + error("%s: RSA_blinding_on failed", __func__); + key_free(prv); + prv = NULL; + } + } else if (pk->type == EVP_PKEY_DSA && + (type == KEY_UNSPEC||type==KEY_DSA)) { + prv = key_new(KEY_UNSPEC); + prv->dsa = EVP_PKEY_get1_DSA(pk); + prv->type = KEY_DSA; + name = "dsa w/o comment"; +#ifdef DEBUG_PK + DSA_print_fp(stderr, prv->dsa, 8); +#endif +#ifdef OPENSSL_HAS_ECC + } else if (pk->type == EVP_PKEY_EC && + (type == KEY_UNSPEC||type==KEY_ECDSA)) { + prv = key_new(KEY_UNSPEC); + prv->ecdsa = EVP_PKEY_get1_EC_KEY(pk); + prv->type = KEY_ECDSA; + if ((prv->ecdsa_nid = key_ecdsa_key_to_nid(prv->ecdsa)) == -1 || + key_curve_nid_to_name(prv->ecdsa_nid) == NULL || + key_ec_validate_public(EC_KEY_get0_group(prv->ecdsa), + EC_KEY_get0_public_key(prv->ecdsa)) != 0 || + key_ec_validate_private(prv->ecdsa) != 0) { + error("%s: bad ECDSA key", __func__); + key_free(prv); + prv = NULL; + } + name = "ecdsa w/o comment"; +#ifdef DEBUG_PK + if (prv != NULL && prv->ecdsa != NULL) + key_dump_ec_key(prv->ecdsa); +#endif +#endif /* OPENSSL_HAS_ECC */ + } else { + error("%s: PEM_read_PrivateKey: mismatch or " + "unknown EVP_PKEY save_type %d", __func__, pk->save_type); + } + if (pk != NULL) + EVP_PKEY_free(pk); + if (prv != NULL && commentp) + *commentp = xstrdup(name); + debug("read PEM private key done: type %s", + prv ? key_type(prv) : "<unknown>"); + return prv; +} + +Key * +key_load_private_pem(int fd, int type, const char *passphrase, + char **commentp) +{ + Buffer buffer; + Key *prv; + + buffer_init(&buffer); + if (!key_load_file(fd, NULL, &buffer)) { + buffer_free(&buffer); + return NULL; + } + prv = key_parse_private_pem(&buffer, type, passphrase, commentp); + buffer_free(&buffer); + return prv; +} + +int +key_perm_ok(int fd, const char *filename) +{ + struct stat st; + + if (fstat(fd, &st) < 0) + return 0; + /* + * if a key owned by the user is accessed, then we check the + * permissions of the file. if the key owned by a different user, + * then we don't care. + */ +#ifdef HAVE_CYGWIN + if (check_ntsec(filename)) +#endif + if ((st.st_uid == getuid()) && (st.st_mode & 077) != 0) { + error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); + error("@ WARNING: UNPROTECTED PRIVATE KEY FILE! @"); + error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); + error("Permissions 0%3.3o for '%s' are too open.", + (u_int)st.st_mode & 0777, filename); + error("It is required that your private key files are NOT accessible by others."); + error("This private key will be ignored."); + return 0; + } + return 1; +} + +static Key * +key_parse_private_type(Buffer *blob, int type, const char *passphrase, + char **commentp) +{ + switch (type) { + case KEY_RSA1: + return key_parse_private_rsa1(blob, passphrase, commentp); + case KEY_DSA: + case KEY_ECDSA: + case KEY_RSA: + case KEY_UNSPEC: + return key_parse_private_pem(blob, type, passphrase, commentp); + default: + error("%s: cannot parse key type %d", __func__, type); + break; + } + return NULL; +} + +Key * +key_load_private_type(int type, const char *filename, const char *passphrase, + char **commentp, int *perm_ok) +{ + int fd; + Key *ret; + Buffer buffer; + + fd = open(filename, O_RDONLY); + if (fd < 0) { + debug("could not open key file '%s': %s", filename, + strerror(errno)); + if (perm_ok != NULL) + *perm_ok = 0; + return NULL; + } + if (!key_perm_ok(fd, filename)) { + if (perm_ok != NULL) + *perm_ok = 0; + error("bad permissions: ignore key: %s", filename); + close(fd); + return NULL; + } + if (perm_ok != NULL) + *perm_ok = 1; + + buffer_init(&buffer); + if (!key_load_file(fd, filename, &buffer)) { + buffer_free(&buffer); + close(fd); + return NULL; + } + close(fd); + ret = key_parse_private_type(&buffer, type, passphrase, commentp); + buffer_free(&buffer); + return ret; +} + +Key * +key_parse_private(Buffer *buffer, const char *filename, + const char *passphrase, char **commentp) +{ + Key *pub, *prv; + + /* it's a SSH v1 key if the public key part is readable */ + pub = key_parse_public_rsa1(buffer, commentp); + if (pub == NULL) { + prv = key_parse_private_type(buffer, KEY_UNSPEC, + passphrase, NULL); + /* use the filename as a comment for PEM */ + if (commentp && prv) + *commentp = xstrdup(filename); + } else { + key_free(pub); + /* key_parse_public_rsa1() has already loaded the comment */ + prv = key_parse_private_type(buffer, KEY_RSA1, passphrase, + NULL); + } + return prv; +} + +Key * +key_load_private(const char *filename, const char *passphrase, + char **commentp) +{ + Key *prv; + Buffer buffer; + int fd; + + fd = open(filename, O_RDONLY); + if (fd < 0) { + debug("could not open key file '%s': %s", filename, + strerror(errno)); + return NULL; + } + if (!key_perm_ok(fd, filename)) { + error("bad permissions: ignore key: %s", filename); + close(fd); + return NULL; + } + + buffer_init(&buffer); + if (!key_load_file(fd, filename, &buffer)) { + buffer_free(&buffer); + close(fd); + return NULL; + } + close(fd); + + prv = key_parse_private(&buffer, filename, passphrase, commentp); + buffer_free(&buffer); + return prv; +} + +static int +key_try_load_public(Key *k, const char *filename, char **commentp) +{ + FILE *f; + char line[SSH_MAX_PUBKEY_BYTES]; + char *cp; + u_long linenum = 0; + + f = fopen(filename, "r"); + if (f != NULL) { + while (read_keyfile_line(f, filename, line, sizeof(line), + &linenum) != -1) { + cp = line; + switch (*cp) { + case '#': + case '\n': + case '\0': + continue; + } + /* Abort loading if this looks like a private key */ + if (strncmp(cp, "-----BEGIN", 10) == 0) + break; + /* Skip leading whitespace. */ + for (; *cp && (*cp == ' ' || *cp == '\t'); cp++) + ; + if (*cp) { + if (key_read(k, &cp) == 1) { + cp[strcspn(cp, "\r\n")] = '\0'; + if (commentp) { + *commentp = xstrdup(*cp ? + cp : filename); + } + fclose(f); + return 1; + } + } + } + fclose(f); + } + return 0; +} + +/* load public key from ssh v1 private or any pubkey file */ +Key * +key_load_public(const char *filename, char **commentp) +{ + Key *pub; + char file[MAXPATHLEN]; + + /* try rsa1 private key */ + pub = key_load_public_type(KEY_RSA1, filename, commentp); + if (pub != NULL) + return pub; + + /* try rsa1 public key */ + pub = key_new(KEY_RSA1); + if (key_try_load_public(pub, filename, commentp) == 1) + return pub; + key_free(pub); + + /* try ssh2 public key */ + pub = key_new(KEY_UNSPEC); + if (key_try_load_public(pub, filename, commentp) == 1) + return pub; + if ((strlcpy(file, filename, sizeof file) < sizeof(file)) && + (strlcat(file, ".pub", sizeof file) < sizeof(file)) && + (key_try_load_public(pub, file, commentp) == 1)) + return pub; + key_free(pub); + return NULL; +} + +/* Load the certificate associated with the named private key */ +Key * +key_load_cert(const char *filename) +{ + Key *pub; + char *file; + + pub = key_new(KEY_UNSPEC); + xasprintf(&file, "%s-cert.pub", filename); + if (key_try_load_public(pub, file, NULL) == 1) { + xfree(file); + return pub; + } + xfree(file); + key_free(pub); + return NULL; +} + +/* Load private key and certificate */ +Key * +key_load_private_cert(int type, const char *filename, const char *passphrase, + int *perm_ok) +{ + Key *key, *pub; + + switch (type) { + case KEY_RSA: + case KEY_DSA: + case KEY_ECDSA: + break; + default: + error("%s: unsupported key type", __func__); + return NULL; + } + + if ((key = key_load_private_type(type, filename, + passphrase, NULL, perm_ok)) == NULL) + return NULL; + + if ((pub = key_load_cert(filename)) == NULL) { + key_free(key); + return NULL; + } + + /* Make sure the private key matches the certificate */ + if (key_equal_public(key, pub) == 0) { + error("%s: certificate does not match private key %s", + __func__, filename); + } else if (key_to_certified(key, key_cert_is_legacy(pub)) != 0) { + error("%s: key_to_certified failed", __func__); + } else { + key_cert_copy(pub, key); + key_free(pub); + return key; + } + + key_free(key); + key_free(pub); + return NULL; +} + +/* + * Returns 1 if the specified "key" is listed in the file "filename", + * 0 if the key is not listed or -1 on error. + * If strict_type is set then the key type must match exactly, + * otherwise a comparison that ignores certficiate data is performed. + */ +int +key_in_file(Key *key, const char *filename, int strict_type) +{ + FILE *f; + char line[SSH_MAX_PUBKEY_BYTES]; + char *cp; + u_long linenum = 0; + int ret = 0; + Key *pub; + int (*key_compare)(const Key *, const Key *) = strict_type ? + key_equal : key_equal_public; + + if ((f = fopen(filename, "r")) == NULL) { + if (errno == ENOENT) { + debug("%s: keyfile \"%s\" missing", __func__, filename); + return 0; + } else { + error("%s: could not open keyfile \"%s\": %s", __func__, + filename, strerror(errno)); + return -1; + } + } + + 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; + } + + pub = key_new(KEY_UNSPEC); + if (key_read(pub, &cp) != 1) { + key_free(pub); + continue; + } + if (key_compare(key, pub)) { + ret = 1; + key_free(pub); + break; + } + key_free(pub); + } + fclose(f); + return ret; +} +
diff --git a/openssh-6.0p1/authfile.h b/openssh-6.0p1/authfile.h new file mode 100644 index 0000000..78349be --- /dev/null +++ b/openssh-6.0p1/authfile.h
@@ -0,0 +1,31 @@ +/* $OpenBSD: authfile.h,v 1.16 2011/05/04 21:15:29 djm Exp $ */ + +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ + +#ifndef AUTHFILE_H +#define AUTHFILE_H + +int key_save_private(Key *, const char *, const char *, const char *); +int key_load_file(int, const char *, Buffer *); +Key *key_load_cert(const char *); +Key *key_load_public(const char *, char **); +Key *key_load_public_type(int, const char *, char **); +Key *key_parse_private(Buffer *, const char *, 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 *); +Key *key_load_private_pem(int, int, const char *, char **); +int key_perm_ok(int, const char *); +int key_in_file(Key *, const char *, int); + +#endif
diff --git a/openssh-6.0p1/bufaux.c b/openssh-6.0p1/bufaux.c new file mode 100644 index 0000000..00208ca --- /dev/null +++ b/openssh-6.0p1/bufaux.c
@@ -0,0 +1,316 @@ +/* $OpenBSD: bufaux.c,v 1.50 2010/08/31 09:58:37 djm Exp $ */ +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * Auxiliary functions for storing and retrieving various data types to/from + * Buffers. + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + * + * + * SSH2 packet format added by Markus Friedl + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#include <sys/types.h> + +#include <openssl/bn.h> + +#include <string.h> +#include <stdarg.h> + +#include "xmalloc.h" +#include "buffer.h" +#include "log.h" +#include "misc.h" + +/* + * Returns integers from the buffer (msb first). + */ + +int +buffer_get_short_ret(u_short *ret, Buffer *buffer) +{ + u_char buf[2]; + + if (buffer_get_ret(buffer, (char *) buf, 2) == -1) + return (-1); + *ret = get_u16(buf); + return (0); +} + +u_short +buffer_get_short(Buffer *buffer) +{ + u_short ret; + + if (buffer_get_short_ret(&ret, buffer) == -1) + fatal("buffer_get_short: buffer error"); + + return (ret); +} + +int +buffer_get_int_ret(u_int *ret, Buffer *buffer) +{ + u_char buf[4]; + + if (buffer_get_ret(buffer, (char *) buf, 4) == -1) + return (-1); + if (ret != NULL) + *ret = get_u32(buf); + return (0); +} + +u_int +buffer_get_int(Buffer *buffer) +{ + u_int ret; + + if (buffer_get_int_ret(&ret, buffer) == -1) + fatal("buffer_get_int: buffer error"); + + return (ret); +} + +int +buffer_get_int64_ret(u_int64_t *ret, Buffer *buffer) +{ + u_char buf[8]; + + if (buffer_get_ret(buffer, (char *) buf, 8) == -1) + return (-1); + if (ret != NULL) + *ret = get_u64(buf); + return (0); +} + +u_int64_t +buffer_get_int64(Buffer *buffer) +{ + u_int64_t ret; + + if (buffer_get_int64_ret(&ret, buffer) == -1) + fatal("buffer_get_int: buffer error"); + + return (ret); +} + +/* + * Stores integers in the buffer, msb first. + */ +void +buffer_put_short(Buffer *buffer, u_short value) +{ + char buf[2]; + + put_u16(buf, value); + buffer_append(buffer, buf, 2); +} + +void +buffer_put_int(Buffer *buffer, u_int value) +{ + char buf[4]; + + put_u32(buf, value); + buffer_append(buffer, buf, 4); +} + +void +buffer_put_int64(Buffer *buffer, u_int64_t value) +{ + char buf[8]; + + put_u64(buf, value); + buffer_append(buffer, buf, 8); +} + +/* + * Returns an arbitrary binary string from the buffer. The string cannot + * be longer than 256k. The returned value points to memory allocated + * with xmalloc; it is the responsibility of the calling function to free + * the data. If length_ptr is non-NULL, the length of the returned data + * will be stored there. A null character will be automatically appended + * to the returned string, and is not counted in length. + */ +void * +buffer_get_string_ret(Buffer *buffer, u_int *length_ptr) +{ + u_char *value; + u_int len; + + /* Get the length. */ + if (buffer_get_int_ret(&len, buffer) != 0) { + error("buffer_get_string_ret: cannot extract length"); + return (NULL); + } + if (len > 256 * 1024) { + error("buffer_get_string_ret: bad string length %u", len); + return (NULL); + } + /* Allocate space for the string. Add one byte for a null character. */ + value = xmalloc(len + 1); + /* Get the string. */ + if (buffer_get_ret(buffer, value, len) == -1) { + error("buffer_get_string_ret: buffer_get failed"); + xfree(value); + return (NULL); + } + /* Append a null character to make processing easier. */ + value[len] = '\0'; + /* Optionally return the length of the string. */ + if (length_ptr) + *length_ptr = len; + return (value); +} + +void * +buffer_get_string(Buffer *buffer, u_int *length_ptr) +{ + void *ret; + + if ((ret = buffer_get_string_ret(buffer, length_ptr)) == NULL) + fatal("buffer_get_string: buffer error"); + return (ret); +} + +char * +buffer_get_cstring_ret(Buffer *buffer, u_int *length_ptr) +{ + u_int length; + char *cp, *ret = buffer_get_string_ret(buffer, &length); + + if (ret == NULL) + return NULL; + if ((cp = memchr(ret, '\0', length)) != NULL) { + /* XXX allow \0 at end-of-string for a while, remove later */ + if (cp == ret + length - 1) + error("buffer_get_cstring_ret: string contains \\0"); + else { + bzero(ret, length); + xfree(ret); + return NULL; + } + } + if (length_ptr != NULL) + *length_ptr = length; + return ret; +} + +char * +buffer_get_cstring(Buffer *buffer, u_int *length_ptr) +{ + char *ret; + + if ((ret = buffer_get_cstring_ret(buffer, length_ptr)) == NULL) + fatal("buffer_get_cstring: buffer error"); + return ret; +} + +void * +buffer_get_string_ptr_ret(Buffer *buffer, u_int *length_ptr) +{ + void *ptr; + u_int len; + + if (buffer_get_int_ret(&len, buffer) != 0) + return NULL; + if (len > 256 * 1024) { + error("buffer_get_string_ptr: bad string length %u", len); + return NULL; + } + ptr = buffer_ptr(buffer); + buffer_consume(buffer, len); + if (length_ptr) + *length_ptr = len; + return (ptr); +} + +void * +buffer_get_string_ptr(Buffer *buffer, u_int *length_ptr) +{ + void *ret; + + if ((ret = buffer_get_string_ptr_ret(buffer, length_ptr)) == NULL) + fatal("buffer_get_string_ptr: buffer error"); + return (ret); +} + +/* + * Stores and arbitrary binary string in the buffer. + */ +void +buffer_put_string(Buffer *buffer, const void *buf, u_int len) +{ + buffer_put_int(buffer, len); + buffer_append(buffer, buf, len); +} +void +buffer_put_cstring(Buffer *buffer, const char *s) +{ + if (s == NULL) + fatal("buffer_put_cstring: s == NULL"); + buffer_put_string(buffer, s, strlen(s)); +} + +/* + * Returns a character from the buffer (0 - 255). + */ +int +buffer_get_char_ret(char *ret, Buffer *buffer) +{ + if (buffer_get_ret(buffer, ret, 1) == -1) { + error("buffer_get_char_ret: buffer_get_ret failed"); + return (-1); + } + return (0); +} + +int +buffer_get_char(Buffer *buffer) +{ + char ch; + + if (buffer_get_char_ret(&ch, buffer) == -1) + fatal("buffer_get_char: buffer error"); + return (u_char) ch; +} + +/* + * Stores a character in the buffer. + */ +void +buffer_put_char(Buffer *buffer, int value) +{ + char ch = value; + + buffer_append(buffer, &ch, 1); +}
diff --git a/openssh-6.0p1/bufbn.c b/openssh-6.0p1/bufbn.c new file mode 100644 index 0000000..251cd09 --- /dev/null +++ b/openssh-6.0p1/bufbn.c
@@ -0,0 +1,223 @@ +/* $OpenBSD: bufbn.c,v 1.6 2007/06/02 09:04:58 djm Exp $*/ +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * Auxiliary functions for storing and retrieving various data types to/from + * Buffers. + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + * + * + * SSH2 packet format added by Markus Friedl + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#include <sys/types.h> + +#include <openssl/bn.h> + +#include <string.h> +#include <stdarg.h> + +#include "xmalloc.h" +#include "buffer.h" +#include "log.h" +#include "misc.h" + +/* + * Stores an BIGNUM in the buffer with a 2-byte msb first bit count, followed + * by (bits+7)/8 bytes of binary data, msb first. + */ +int +buffer_put_bignum_ret(Buffer *buffer, const BIGNUM *value) +{ + int bits = BN_num_bits(value); + int bin_size = (bits + 7) / 8; + u_char *buf = xmalloc(bin_size); + int oi; + char msg[2]; + + /* Get the value of in binary */ + oi = BN_bn2bin(value, buf); + if (oi != bin_size) { + error("buffer_put_bignum_ret: BN_bn2bin() failed: oi %d != bin_size %d", + oi, bin_size); + xfree(buf); + return (-1); + } + + /* Store the number of bits in the buffer in two bytes, msb first. */ + put_u16(msg, bits); + buffer_append(buffer, msg, 2); + /* Store the binary data. */ + buffer_append(buffer, buf, oi); + + memset(buf, 0, bin_size); + xfree(buf); + + return (0); +} + +void +buffer_put_bignum(Buffer *buffer, const BIGNUM *value) +{ + if (buffer_put_bignum_ret(buffer, value) == -1) + fatal("buffer_put_bignum: buffer error"); +} + +/* + * Retrieves a BIGNUM from the buffer. + */ +int +buffer_get_bignum_ret(Buffer *buffer, BIGNUM *value) +{ + u_int bits, bytes; + u_char buf[2], *bin; + + /* Get the number of bits. */ + if (buffer_get_ret(buffer, (char *) buf, 2) == -1) { + error("buffer_get_bignum_ret: invalid length"); + return (-1); + } + bits = get_u16(buf); + /* Compute the number of binary bytes that follow. */ + bytes = (bits + 7) / 8; + if (bytes > 8 * 1024) { + error("buffer_get_bignum_ret: cannot handle BN of size %d", bytes); + return (-1); + } + if (buffer_len(buffer) < bytes) { + error("buffer_get_bignum_ret: input buffer too small"); + return (-1); + } + bin = buffer_ptr(buffer); + if (BN_bin2bn(bin, bytes, value) == NULL) { + error("buffer_get_bignum_ret: BN_bin2bn failed"); + return (-1); + } + if (buffer_consume_ret(buffer, bytes) == -1) { + error("buffer_get_bignum_ret: buffer_consume failed"); + return (-1); + } + return (0); +} + +void +buffer_get_bignum(Buffer *buffer, BIGNUM *value) +{ + if (buffer_get_bignum_ret(buffer, value) == -1) + fatal("buffer_get_bignum: buffer error"); +} + +/* + * Stores a BIGNUM in the buffer in SSH2 format. + */ +int +buffer_put_bignum2_ret(Buffer *buffer, const BIGNUM *value) +{ + u_int bytes; + u_char *buf; + int oi; + u_int hasnohigh = 0; + + if (BN_is_zero(value)) { + buffer_put_int(buffer, 0); + return 0; + } + if (value->neg) { + error("buffer_put_bignum2_ret: negative numbers not supported"); + return (-1); + } + bytes = BN_num_bytes(value) + 1; /* extra padding byte */ + if (bytes < 2) { + error("buffer_put_bignum2_ret: BN too small"); + return (-1); + } + buf = xmalloc(bytes); + buf[0] = 0x00; + /* Get the value of in binary */ + oi = BN_bn2bin(value, buf+1); + if (oi < 0 || (u_int)oi != bytes - 1) { + error("buffer_put_bignum2_ret: BN_bn2bin() failed: " + "oi %d != bin_size %d", oi, bytes); + xfree(buf); + return (-1); + } + hasnohigh = (buf[1] & 0x80) ? 0 : 1; + buffer_put_string(buffer, buf+hasnohigh, bytes-hasnohigh); + memset(buf, 0, bytes); + xfree(buf); + return (0); +} + +void +buffer_put_bignum2(Buffer *buffer, const BIGNUM *value) +{ + if (buffer_put_bignum2_ret(buffer, value) == -1) + fatal("buffer_put_bignum2: buffer error"); +} + +int +buffer_get_bignum2_ret(Buffer *buffer, BIGNUM *value) +{ + u_int len; + u_char *bin; + + if ((bin = buffer_get_string_ret(buffer, &len)) == NULL) { + error("buffer_get_bignum2_ret: invalid bignum"); + return (-1); + } + + if (len > 0 && (bin[0] & 0x80)) { + error("buffer_get_bignum2_ret: negative numbers not supported"); + xfree(bin); + return (-1); + } + if (len > 8 * 1024) { + error("buffer_get_bignum2_ret: cannot handle BN of size %d", + len); + xfree(bin); + return (-1); + } + if (BN_bin2bn(bin, len, value) == NULL) { + error("buffer_get_bignum2_ret: BN_bin2bn failed"); + xfree(bin); + return (-1); + } + xfree(bin); + return (0); +} + +void +buffer_get_bignum2(Buffer *buffer, BIGNUM *value) +{ + if (buffer_get_bignum2_ret(buffer, value) == -1) + fatal("buffer_get_bignum2: buffer error"); +}
diff --git a/openssh-6.0p1/bufec.c b/openssh-6.0p1/bufec.c new file mode 100644 index 0000000..3dcb494 --- /dev/null +++ b/openssh-6.0p1/bufec.c
@@ -0,0 +1,146 @@ +/* $OpenBSD: bufec.c,v 1.1 2010/08/31 11:54:45 djm Exp $ */ +/* + * Copyright (c) 2010 Damien Miller <djm@mindrot.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#ifdef OPENSSL_HAS_ECC + +#include <sys/types.h> + +#include <openssl/bn.h> +#include <openssl/ec.h> + +#include <string.h> +#include <stdarg.h> + +#include "xmalloc.h" +#include "buffer.h" +#include "log.h" +#include "misc.h" + +/* + * Maximum supported EC GFp field length is 528 bits. SEC1 uncompressed + * encoding represents this as two bitstring points that should each + * be no longer than the field length, SEC1 specifies a 1 byte + * point type header. + * Being paranoid here may insulate us to parsing problems in + * EC_POINT_oct2point. + */ +#define BUFFER_MAX_ECPOINT_LEN ((528*2 / 8) + 1) + +/* + * Append an EC_POINT to the buffer as a string containing a SEC1 encoded + * uncompressed point. Fortunately OpenSSL handles the gory details for us. + */ +int +buffer_put_ecpoint_ret(Buffer *buffer, const EC_GROUP *curve, + const EC_POINT *point) +{ + u_char *buf = NULL; + size_t len; + BN_CTX *bnctx; + int ret = -1; + + /* Determine length */ + if ((bnctx = BN_CTX_new()) == NULL) + fatal("%s: BN_CTX_new failed", __func__); + len = EC_POINT_point2oct(curve, point, POINT_CONVERSION_UNCOMPRESSED, + NULL, 0, bnctx); + if (len > BUFFER_MAX_ECPOINT_LEN) { + error("%s: giant EC point: len = %lu (max %u)", + __func__, (u_long)len, BUFFER_MAX_ECPOINT_LEN); + goto out; + } + /* Convert */ + buf = xmalloc(len); + if (EC_POINT_point2oct(curve, point, POINT_CONVERSION_UNCOMPRESSED, + buf, len, bnctx) != len) { + error("%s: EC_POINT_point2oct length mismatch", __func__); + goto out; + } + /* Append */ + buffer_put_string(buffer, buf, len); + ret = 0; + out: + if (buf != NULL) { + bzero(buf, len); + xfree(buf); + } + BN_CTX_free(bnctx); + return ret; +} + +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) +{ + u_char *buf; + u_int len; + BN_CTX *bnctx; + int ret = -1; + + if ((buf = buffer_get_string_ret(buffer, &len)) == NULL) { + error("%s: invalid point", __func__); + return -1; + } + if ((bnctx = BN_CTX_new()) == NULL) + fatal("%s: BN_CTX_new failed", __func__); + if (len > BUFFER_MAX_ECPOINT_LEN) { + error("%s: EC_POINT too long: %u > max %u", __func__, + len, BUFFER_MAX_ECPOINT_LEN); + goto out; + } + if (len == 0) { + error("%s: EC_POINT buffer is empty", __func__); + goto out; + } + if (buf[0] != POINT_CONVERSION_UNCOMPRESSED) { + error("%s: EC_POINT is in an incorrect form: " + "0x%02x (want 0x%02x)", __func__, buf[0], + POINT_CONVERSION_UNCOMPRESSED); + goto out; + } + if (EC_POINT_oct2point(curve, point, buf, len, bnctx) != 1) { + error("buffer_get_bignum2_ret: BN_bin2bn failed"); + goto out; + } + /* EC_POINT_oct2point verifies that the point is on the curve for us */ + ret = 0; + out: + BN_CTX_free(bnctx); + bzero(buf, len); + xfree(buf); + return ret; +} + +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 */
diff --git a/openssh-6.0p1/buffer.c b/openssh-6.0p1/buffer.c new file mode 100644 index 0000000..ae97003 --- /dev/null +++ b/openssh-6.0p1/buffer.c
@@ -0,0 +1,252 @@ +/* $OpenBSD: buffer.c,v 1.32 2010/02/09 03:56:28 djm Exp $ */ +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * Functions for manipulating fifo buffers (that can grow if needed). + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ + +#include "includes.h" + +#include <sys/param.h> + +#include <stdio.h> +#include <string.h> +#include <stdarg.h> + +#include "xmalloc.h" +#include "buffer.h" +#include "log.h" + +#define BUFFER_MAX_CHUNK 0x100000 +#define BUFFER_MAX_LEN 0xa00000 +#define BUFFER_ALLOCSZ 0x008000 + +/* Initializes the buffer structure. */ + +void +buffer_init(Buffer *buffer) +{ + const u_int len = 4096; + + buffer->alloc = 0; + buffer->buf = xmalloc(len); + buffer->alloc = len; + buffer->offset = 0; + buffer->end = 0; +} + +/* Frees any memory used for the buffer. */ + +void +buffer_free(Buffer *buffer) +{ + if (buffer->alloc > 0) { + memset(buffer->buf, 0, buffer->alloc); + buffer->alloc = 0; + xfree(buffer->buf); + } +} + +/* + * Clears any data from the buffer, making it empty. This does not actually + * zero the memory. + */ + +void +buffer_clear(Buffer *buffer) +{ + buffer->offset = 0; + buffer->end = 0; +} + +/* Appends data to the buffer, expanding it if necessary. */ + +void +buffer_append(Buffer *buffer, const void *data, u_int len) +{ + void *p; + p = buffer_append_space(buffer, len); + memcpy(p, data, len); +} + +static int +buffer_compact(Buffer *buffer) +{ + /* + * If the buffer is quite empty, but all data is at the end, move the + * data to the beginning. + */ + if (buffer->offset > MIN(buffer->alloc, BUFFER_MAX_CHUNK)) { + memmove(buffer->buf, buffer->buf + buffer->offset, + buffer->end - buffer->offset); + buffer->end -= buffer->offset; + buffer->offset = 0; + return (1); + } + return (0); +} + +/* + * Appends space to the buffer, expanding the buffer if necessary. This does + * not actually copy the data into the buffer, but instead returns a pointer + * to the allocated region. + */ + +void * +buffer_append_space(Buffer *buffer, u_int len) +{ + u_int newlen; + void *p; + + if (len > BUFFER_MAX_CHUNK) + fatal("buffer_append_space: len %u not supported", len); + + /* If the buffer is empty, start using it from the beginning. */ + if (buffer->offset == buffer->end) { + buffer->offset = 0; + buffer->end = 0; + } +restart: + /* If there is enough space to store all data, store it now. */ + if (buffer->end + len < buffer->alloc) { + p = buffer->buf + buffer->end; + buffer->end += len; + return p; + } + + /* Compact data back to the start of the buffer if necessary */ + if (buffer_compact(buffer)) + goto restart; + + /* Increase the size of the buffer and retry. */ + newlen = roundup(buffer->alloc + len, BUFFER_ALLOCSZ); + if (newlen > BUFFER_MAX_LEN) + fatal("buffer_append_space: alloc %u not supported", + newlen); + buffer->buf = xrealloc(buffer->buf, 1, newlen); + buffer->alloc = newlen; + goto restart; + /* NOTREACHED */ +} + +/* + * Check whether an allocation of 'len' will fit in the buffer + * This must follow the same math as buffer_append_space + */ +int +buffer_check_alloc(Buffer *buffer, u_int len) +{ + if (buffer->offset == buffer->end) { + buffer->offset = 0; + buffer->end = 0; + } + restart: + if (buffer->end + len < buffer->alloc) + return (1); + if (buffer_compact(buffer)) + goto restart; + if (roundup(buffer->alloc + len, BUFFER_ALLOCSZ) <= BUFFER_MAX_LEN) + return (1); + return (0); +} + +/* Returns the number of bytes of data in the buffer. */ + +u_int +buffer_len(const Buffer *buffer) +{ + return buffer->end - buffer->offset; +} + +/* Gets data from the beginning of the buffer. */ + +int +buffer_get_ret(Buffer *buffer, void *buf, u_int len) +{ + if (len > buffer->end - buffer->offset) { + error("buffer_get_ret: trying to get more bytes %d than in buffer %d", + len, buffer->end - buffer->offset); + return (-1); + } + memcpy(buf, buffer->buf + buffer->offset, len); + buffer->offset += len; + return (0); +} + +void +buffer_get(Buffer *buffer, void *buf, u_int len) +{ + if (buffer_get_ret(buffer, buf, len) == -1) + fatal("buffer_get: buffer error"); +} + +/* Consumes the given number of bytes from the beginning of the buffer. */ + +int +buffer_consume_ret(Buffer *buffer, u_int bytes) +{ + if (bytes > buffer->end - buffer->offset) { + error("buffer_consume_ret: trying to get more bytes than in buffer"); + return (-1); + } + buffer->offset += bytes; + return (0); +} + +void +buffer_consume(Buffer *buffer, u_int bytes) +{ + if (buffer_consume_ret(buffer, bytes) == -1) + fatal("buffer_consume: buffer error"); +} + +/* Consumes the given number of bytes from the end of the buffer. */ + +int +buffer_consume_end_ret(Buffer *buffer, u_int bytes) +{ + if (bytes > buffer->end - buffer->offset) + return (-1); + buffer->end -= bytes; + return (0); +} + +void +buffer_consume_end(Buffer *buffer, u_int bytes) +{ + if (buffer_consume_end_ret(buffer, bytes) == -1) + fatal("buffer_consume_end: trying to get more bytes than in buffer"); +} + +/* Returns a pointer to the first used byte in the buffer. */ + +void * +buffer_ptr(const Buffer *buffer) +{ + return buffer->buf + buffer->offset; +} + +/* Dumps the contents of the buffer to stderr. */ + +void +buffer_dump(const Buffer *buffer) +{ + u_int i; + u_char *ucp = buffer->buf; + + for (i = buffer->offset; i < buffer->end; i++) { + fprintf(stderr, "%02x", ucp[i]); + if ((i-buffer->offset)%16==15) + fprintf(stderr, "\r\n"); + else if ((i-buffer->offset)%2==1) + fprintf(stderr, " "); + } + fprintf(stderr, "\r\n"); +}
diff --git a/openssh-6.0p1/buffer.h b/openssh-6.0p1/buffer.h new file mode 100644 index 0000000..e2a9dd1 --- /dev/null +++ b/openssh-6.0p1/buffer.h
@@ -0,0 +1,98 @@ +/* $OpenBSD: buffer.h,v 1.21 2010/08/31 11:54:45 djm Exp $ */ + +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * Code for manipulating FIFO buffers. + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ + +#ifndef BUFFER_H +#define BUFFER_H + +typedef struct { + u_char *buf; /* Buffer for data. */ + u_int alloc; /* Number of bytes allocated for data. */ + u_int offset; /* Offset of first byte containing data. */ + u_int end; /* Offset of last byte containing data. */ +} Buffer; + +void buffer_init(Buffer *); +void buffer_clear(Buffer *); +void buffer_free(Buffer *); + +u_int buffer_len(const Buffer *); +void *buffer_ptr(const Buffer *); + +void buffer_append(Buffer *, const void *, u_int); +void *buffer_append_space(Buffer *, u_int); + +int buffer_check_alloc(Buffer *, u_int); + +void buffer_get(Buffer *, void *, u_int); + +void buffer_consume(Buffer *, u_int); +void buffer_consume_end(Buffer *, u_int); + +void buffer_dump(const Buffer *); + +int buffer_get_ret(Buffer *, void *, u_int); +int buffer_consume_ret(Buffer *, u_int); +int buffer_consume_end_ret(Buffer *, u_int); + +#include <openssl/bn.h> + +void buffer_put_bignum(Buffer *, const BIGNUM *); +void buffer_put_bignum2(Buffer *, const BIGNUM *); +void buffer_get_bignum(Buffer *, BIGNUM *); +void buffer_get_bignum2(Buffer *, BIGNUM *); + +u_short buffer_get_short(Buffer *); +void buffer_put_short(Buffer *, u_short); + +u_int buffer_get_int(Buffer *); +void buffer_put_int(Buffer *, u_int); + +u_int64_t buffer_get_int64(Buffer *); +void buffer_put_int64(Buffer *, u_int64_t); + +int buffer_get_char(Buffer *); +void buffer_put_char(Buffer *, int); + +void *buffer_get_string(Buffer *, u_int *); +void *buffer_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) \ + do { u_int l = buffer_get_int(b); buffer_consume(b, l); } while (0) + +int buffer_put_bignum_ret(Buffer *, const BIGNUM *); +int buffer_get_bignum_ret(Buffer *, BIGNUM *); +int buffer_put_bignum2_ret(Buffer *, const BIGNUM *); +int buffer_get_bignum2_ret(Buffer *, BIGNUM *); +int buffer_get_short_ret(u_short *, Buffer *); +int buffer_get_int_ret(u_int *, Buffer *); +int buffer_get_int64_ret(u_int64_t *, Buffer *); +void *buffer_get_string_ret(Buffer *, u_int *); +char *buffer_get_cstring_ret(Buffer *, u_int *); +void *buffer_get_string_ptr_ret(Buffer *, u_int *); +int buffer_get_char_ret(char *, Buffer *); + +#ifdef OPENSSL_HAS_ECC +#include <openssl/ec.h> + +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 */
diff --git a/openssh-6.0p1/buildpkg.sh.in b/openssh-6.0p1/buildpkg.sh.in new file mode 100644 index 0000000..4de9d42 --- /dev/null +++ b/openssh-6.0p1/buildpkg.sh.in
@@ -0,0 +1,677 @@ +#!/bin/sh +# +# Fake Root Solaris/SVR4/SVR5 Build System - Prototype +# +# The following code has been provide under Public Domain License. I really +# don't care what you use it for. Just as long as you don't complain to me +# nor my employer if you break it. - Ben Lindstrom (mouring@eviladmin.org) +# +umask 022 +# +# Options for building the package +# You can create a openssh-config.local with your customized options +# +REMOVE_FAKE_ROOT_WHEN_DONE=yes +# +# uncommenting TEST_DIR and using +# configure --prefix=/var/tmp --with-privsep-path=/var/tmp/empty +# and +# PKGNAME=tOpenSSH should allow testing a package without interfering +# with a real OpenSSH package on a system. This is not needed on systems +# that support the -R option to pkgadd. +#TEST_DIR=/var/tmp # leave commented out for production build +PKGNAME=OpenSSH +# revisions within the same version (REV=a) +#REV= +SYSVINIT_NAME=opensshd +AWK=${AWK:="nawk"} +MAKE=${MAKE:="make"} +SSHDUID=67 # Default privsep uid +SSHDGID=67 # Default privsep gid +# uncomment these next three as needed +#PERMIT_ROOT_LOGIN=no +#X11_FORWARDING=yes +#USR_LOCAL_IS_SYMLINK=yes +# System V init run levels +SYSVINITSTART=S98 +SYSVINITSTOPT=K30 +# We will source these if they exist +POST_MAKE_INSTALL_FIXES=./pkg-post-make-install-fixes.sh +POST_PROTOTYPE_EDITS=./pkg-post-prototype-edit.sh +# We'll be one level deeper looking for these +PKG_PREINSTALL_LOCAL=../pkg-preinstall.local +PKG_POSTINSTALL_LOCAL=../pkg-postinstall.local +PKG_PREREMOVE_LOCAL=../pkg-preremove.local +PKG_POSTREMOVE_LOCAL=../pkg-postremove.local +PKG_REQUEST_LOCAL=../pkg-request.local +# end of sourced files +# +OPENSSHD=opensshd.init +OPENSSH_MANIFEST=openssh.xml +OPENSSH_FMRI=svc:/site/${SYSVINIT_NAME}:default +SMF_METHOD_DIR=/lib/svc/method/site +SMF_MANIFEST_DIR=/var/svc/manifest/site + +PATH_GROUPADD_PROG=@PATH_GROUPADD_PROG@ +PATH_USERADD_PROG=@PATH_USERADD_PROG@ +PATH_PASSWD_PROG=@PATH_PASSWD_PROG@ +# +# list of system directories we do NOT want to change owner/group/perms +# when installing our package +SYSTEM_DIR="/etc \ +/etc/init.d \ +/etc/rcS.d \ +/etc/rc0.d \ +/etc/rc1.d \ +/etc/rc2.d \ +/etc/opt \ +/lib \ +/lib/svc \ +/lib/svc/method \ +/lib/svc/method/site \ +/opt \ +/opt/bin \ +/usr \ +/usr/bin \ +/usr/lib \ +/usr/sbin \ +/usr/share \ +/usr/share/man \ +/usr/share/man/man1 \ +/usr/share/man/man8 \ +/usr/local \ +/usr/local/bin \ +/usr/local/etc \ +/usr/local/libexec \ +/usr/local/man \ +/usr/local/man/man1 \ +/usr/local/man/man8 \ +/usr/local/sbin \ +/usr/local/share \ +/var \ +/var/opt \ +/var/run \ +/var/svc \ +/var/svc/manifest \ +/var/svc/manifest/site \ +/var/tmp \ +/tmp" + +# We may need to build as root so we make sure PATH is set up +# only set the path if it's not set already +[ -d /opt/bin ] && { + echo $PATH | grep ":/opt/bin" > /dev/null 2>&1 + [ $? -ne 0 ] && PATH=$PATH:/opt/bin +} +[ -d /usr/local/bin ] && { + echo $PATH | grep ":/usr/local/bin" > /dev/null 2>&1 + [ $? -ne 0 ] && PATH=$PATH:/usr/local/bin +} +[ -d /usr/ccs/bin ] && { + echo $PATH | grep ":/usr/ccs/bin" > /dev/null 2>&1 + [ $? -ne 0 ] && PATH=$PATH:/usr/ccs/bin +} +export PATH +# + +[ -f Makefile ] || { + echo "Please run this script from your build directory" + exit 1 +} + +# we will look for openssh-config.local to override the above options +[ -s ./openssh-config.local ] && . ./openssh-config.local + +START=`pwd` +FAKE_ROOT=$START/pkg + +## Fill in some details, like prefix and sysconfdir +for confvar in prefix exec_prefix bindir sbindir libexecdir datadir mandir sysconfdir piddir srcdir +do + eval $confvar=`grep "^$confvar=" Makefile | cut -d = -f 2` +done + +## Are we using Solaris' SMF? +DO_SMF=0 +if egrep "^#define USE_SOLARIS_PROCESS_CONTRACTS" config.h > /dev/null 2>&1 +then + DO_SMF=1 +fi + +## Collect value of privsep user +for confvar in SSH_PRIVSEP_USER +do + eval $confvar=`awk '/#define[ \t]'$confvar'/{print $3}' config.h` +done + +## Set privsep defaults if not defined +if [ -z "$SSH_PRIVSEP_USER" ] +then + SSH_PRIVSEP_USER=sshd +fi + +## Extract common info requires for the 'info' part of the package. +VERSION=`./ssh -V 2>&1 | sed -e 's/,.*//'` + +ARCH=`uname -m` +DEF_MSG="\n" +OS_VER=`uname -v` +SCRIPT_SHELL=/sbin/sh +UNAME_R=`uname -r` +UNAME_S=`uname -s` +case ${UNAME_S} in + SunOS) UNAME_S=Solaris + OS_VER=${UNAME_R} + ARCH=`uname -p` + RCS_D=yes + DEF_MSG="(default: n)" + ;; + SCO_SV) case ${UNAME_R} in + 3.2) UNAME_S=OpenServer5 + OS_VER=`uname -X | grep Release | sed -e 's/^Rel.*3.2v//'` + ;; + 5) UNAME_S=OpenServer6 + ;; + esac + SCRIPT_SHELL=/bin/sh + RC1_D=no + DEF_MSG="(default: n)" + ;; +esac + +case `basename $0` in + buildpkg.sh) +## Start by faking root install +echo "Faking root install..." +[ -d $FAKE_ROOT ] && rm -fr $FAKE_ROOT +mkdir $FAKE_ROOT +${MAKE} install-nokeys DESTDIR=$FAKE_ROOT +if [ $? -gt 0 ] +then + echo "Fake root install failed, stopping." + exit 1 +fi + +## Setup our run level stuff while we are at it. +if [ $DO_SMF -eq 1 ] +then + # For Solaris' SMF, /lib/svc/method/site is the preferred place + # for start/stop scripts that aren't supplied with the OS, and + # similarly /var/svc/manifest/site for manifests. + mkdir -p $FAKE_ROOT${TEST_DIR}${SMF_METHOD_DIR} + mkdir -p $FAKE_ROOT${TEST_DIR}${SMF_MANIFEST_DIR} + + cp ${OPENSSHD} $FAKE_ROOT${TEST_DIR}${SMF_METHOD_DIR}/${SYSVINIT_NAME} + chmod 744 $FAKE_ROOT${TEST_DIR}${SMF_METHOD_DIR}/${SYSVINIT_NAME} + + cat ${OPENSSH_MANIFEST} | \ + sed -e "s|__SYSVINIT_NAME__|${SYSVINIT_NAME}|" \ + -e "s|__SMF_METHOD_DIR__|${SMF_METHOD_DIR}|" \ + > $FAKE_ROOT${TEST_DIR}${SMF_MANIFEST_DIR}/${SYSVINIT_NAME}.xml + chmod 644 $FAKE_ROOT${TEST_DIR}${SMF_MANIFEST_DIR}/${SYSVINIT_NAME}.xml +else + mkdir -p $FAKE_ROOT${TEST_DIR}/etc/init.d + + cp ${OPENSSHD} $FAKE_ROOT${TEST_DIR}/etc/init.d/${SYSVINIT_NAME} + chmod 744 $FAKE_ROOT${TEST_DIR}/etc/init.d/${SYSVINIT_NAME} +fi + +[ "${PERMIT_ROOT_LOGIN}" = no ] && \ + perl -p -i -e "s/#PermitRootLogin yes/PermitRootLogin no/" \ + $FAKE_ROOT${sysconfdir}/sshd_config +[ "${X11_FORWARDING}" = yes ] && \ + perl -p -i -e "s/#X11Forwarding no/X11Forwarding yes/" \ + $FAKE_ROOT${sysconfdir}/sshd_config +# fix PrintMotd +perl -p -i -e "s/#PrintMotd yes/PrintMotd no/" \ + $FAKE_ROOT${sysconfdir}/sshd_config + +# We don't want to overwrite config files on multiple installs +mv $FAKE_ROOT${sysconfdir}/ssh_config $FAKE_ROOT${sysconfdir}/ssh_config.default +mv $FAKE_ROOT${sysconfdir}/sshd_config $FAKE_ROOT${sysconfdir}/sshd_config.default + +# local tweeks here +[ -s "${POST_MAKE_INSTALL_FIXES}" ] && . ${POST_MAKE_INSTALL_FIXES} + +cd $FAKE_ROOT + +## Ok, this is outright wrong, but it will work. I'm tired of pkgmk +## whining. +for i in *; do + PROTO_ARGS="$PROTO_ARGS $i=/$i"; +done + +## Build info file +echo "Building pkginfo file..." +cat > pkginfo << _EOF +PKG=$PKGNAME +NAME="OpenSSH Portable for ${UNAME_S}" +DESC="Secure Shell remote access utility; replaces telnet and rlogin/rsh." +VENDOR="OpenSSH Portable Team - http://www.openssh.com/portable.html" +ARCH=$ARCH +VERSION=$VERSION$REV +CATEGORY="Security,application" +BASEDIR=/ +CLASSES="none" +PSTAMP="${UNAME_S} ${OS_VER} ${ARCH} `date '+%d%b%Y %H:%M'`" +_EOF + +## Build empty depend file that may get updated by $POST_PROTOTYPE_EDITS +echo "Building depend file..." +touch depend + +## Build space file +echo "Building space file..." +if [ $DO_SMF -eq 1 ] +then + # XXX Is this necessary? If not, remove space line from mk-proto.awk. + touch space +else + cat > space << _EOF +# extra space required by start/stop links added by installf +# in postinstall +$TEST_DIR/etc/rc0.d/${SYSVINITSTOPT}${SYSVINIT_NAME} 0 1 +$TEST_DIR/etc/rc2.d/${SYSVINITSTART}${SYSVINIT_NAME} 0 1 +_EOF + [ "$RC1_D" = no ] || \ + echo "$TEST_DIR/etc/rc1.d/${SYSVINITSTOPT}${SYSVINIT_NAME} 0 1" >> space + [ "$RCS_D" = yes ] && \ + echo "$TEST_DIR/etc/rcS.d/${SYSVINITSTOPT}${SYSVINIT_NAME} 0 1" >> space +fi + +## Build preinstall file +echo "Building preinstall file..." +cat > preinstall << _EOF +#! ${SCRIPT_SHELL} +# +_EOF + +# local preinstall changes here +[ -s "${PKG_PREINSTALL_LOCAL}" ] && . ${PKG_PREINSTALL_LOCAL} + +cat >> preinstall << _EOF +# +if [ "\${PRE_INS_STOP}" = "yes" ] +then + if [ $DO_SMF -eq 1 ] + then + svcadm disable $OPENSSH_FMRI + else + ${TEST_DIR}/etc/init.d/${SYSVINIT_NAME} stop + fi +fi + +exit 0 +_EOF + +## Build postinstall file +echo "Building postinstall file..." +cat > postinstall << _EOF +#! ${SCRIPT_SHELL} +# +[ -f \${PKG_INSTALL_ROOT}${sysconfdir}/ssh_config ] || \\ + cp -p \${PKG_INSTALL_ROOT}${sysconfdir}/ssh_config.default \\ + \${PKG_INSTALL_ROOT}${sysconfdir}/ssh_config +[ -f \${PKG_INSTALL_ROOT}${sysconfdir}/sshd_config ] || \\ + cp -p \${PKG_INSTALL_ROOT}${sysconfdir}/sshd_config.default \\ + \${PKG_INSTALL_ROOT}${sysconfdir}/sshd_config + +# make rc?.d dirs only if we are doing a test install +[ -n "${TEST_DIR}" ] && [ $DO_SMF -ne 1 ] && { + [ "$RCS_D" = yes ] && mkdir -p ${TEST_DIR}/etc/rcS.d + mkdir -p ${TEST_DIR}/etc/rc0.d + [ "$RC1_D" = no ] || mkdir -p ${TEST_DIR}/etc/rc1.d + mkdir -p ${TEST_DIR}/etc/rc2.d +} + +if [ $DO_SMF -eq 1 ] +then + # Delete the existing service, if it exists, then import the + # new one. + if svcs $OPENSSH_FMRI > /dev/null 2>&1 + then + svccfg delete -f $OPENSSH_FMRI + fi + # NOTE, The manifest disables sshd by default. + svccfg import ${TEST_DIR}${SMF_MANIFEST_DIR}/${SYSVINIT_NAME}.xml +else + if [ "\${USE_SYM_LINKS}" = yes ] + then + [ "$RCS_D" = yes ] && \ + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rcS.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc0.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s + [ "$RC1_D" = no ] || \ + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc1.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc2.d/${SYSVINITSTART}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s + else + [ "$RCS_D" = yes ] && \ + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rcS.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=\${PKG_INSTALL_ROOT}$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc0.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=\${PKG_INSTALL_ROOT}$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l + [ "$RC1_D" = no ] || \ + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc1.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=\${PKG_INSTALL_ROOT}$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc2.d/${SYSVINITSTART}${SYSVINIT_NAME}=\${PKG_INSTALL_ROOT}$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l + fi +fi + +# If piddir doesn't exist we add it. (Ie. --with-pid-dir=/var/opt/ssh) +[ -d $piddir ] || installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR$piddir d 0755 root sys + +_EOF + +# local postinstall changes here +[ -s "${PKG_POSTINSTALL_LOCAL}" ] && . ${PKG_POSTINSTALL_LOCAL} + +cat >> postinstall << _EOF +installf -f ${PKGNAME} + +# Use chroot to handle PKG_INSTALL_ROOT +if [ ! -z "\${PKG_INSTALL_ROOT}" ] +then + chroot="chroot \${PKG_INSTALL_ROOT}" +fi +# If this is a test build, we will skip the groupadd/useradd/passwd commands +if [ ! -z "${TEST_DIR}" ] +then + chroot=echo +fi + + echo "PrivilegeSeparation user always required." + if cut -f1 -d: \${PKG_INSTALL_ROOT}/etc/passwd | egrep '^'$SSH_PRIVSEP_USER'\$' >/dev/null + then + echo "PrivSep user $SSH_PRIVSEP_USER already exists." + SSH_PRIVSEP_GROUP=\`grep "^$SSH_PRIVSEP_USER:" \${PKG_INSTALL_ROOT}/etc/passwd | awk -F: '{print \$4}'\` + SSH_PRIVSEP_GROUP=\`grep ":\$SSH_PRIVSEP_GROUP:" \${PKG_INSTALL_ROOT}/etc/group | awk -F: '{print \$1}'\` + else + DO_PASSWD=yes + fi + [ -z "\$SSH_PRIVSEP_GROUP" ] && SSH_PRIVSEP_GROUP=$SSH_PRIVSEP_USER + + # group required? + if cut -f1 -d: \${PKG_INSTALL_ROOT}/etc/group | egrep '^'\$SSH_PRIVSEP_GROUP'\$' >/dev/null + then + echo "PrivSep group \$SSH_PRIVSEP_GROUP already exists." + else + DO_GROUP=yes + fi + + # create group if required + [ "\$DO_GROUP" = yes ] && { + # Use gid of 67 if possible + if cut -f3 -d: \${PKG_INSTALL_ROOT}/etc/group | egrep '^'$SSHDGID'\$' >/dev/null + then + : + else + sshdgid="-g $SSHDGID" + fi + echo "Creating PrivSep group \$SSH_PRIVSEP_GROUP." + \$chroot ${PATH_GROUPADD_PROG} \$sshdgid \$SSH_PRIVSEP_GROUP + } + + # Create user if required + [ "\$DO_PASSWD" = yes ] && { + # Use uid of 67 if possible + if cut -f3 -d: \${PKG_INSTALL_ROOT}/etc/passwd | egrep '^'$SSHDUID'\$' >/dev/null + then + : + else + sshduid="-u $SSHDUID" + fi + echo "Creating PrivSep user $SSH_PRIVSEP_USER." + \$chroot ${PATH_USERADD_PROG} -c 'SSHD PrivSep User' -s /bin/false -g $SSH_PRIVSEP_USER \$sshduid $SSH_PRIVSEP_USER + \$chroot ${PATH_PASSWD_PROG} -l $SSH_PRIVSEP_USER + } + +if [ "\${POST_INS_START}" = "yes" ] +then + if [ $DO_SMF -eq 1 ] + then + svcadm enable $OPENSSH_FMRI + else + ${TEST_DIR}/etc/init.d/${SYSVINIT_NAME} start + fi +fi +exit 0 +_EOF + +## Build preremove file +echo "Building preremove file..." +cat > preremove << _EOF +#! ${SCRIPT_SHELL} +# +if [ $DO_SMF -eq 1 ] +then + svcadm disable $OPENSSH_FMRI +else + ${TEST_DIR}/etc/init.d/${SYSVINIT_NAME} stop +fi +_EOF + +# local preremove changes here +[ -s "${PKG_PREREMOVE_LOCAL}" ] && . ${PKG_PREREMOVE_LOCAL} + +cat >> preremove << _EOF +exit 0 +_EOF + +## Build postremove file +echo "Building postremove file..." +cat > postremove << _EOF +#! ${SCRIPT_SHELL} +# +if [ $DO_SMF -eq 1 ] +then + if svcs $OPENSSH_FMRI > /dev/null 2>&1 + then + svccfg delete -f $OPENSSH_FMRI + fi +fi +_EOF + +# local postremove changes here +[ -s "${PKG_POSTREMOVE_LOCAL}" ] && . ${PKG_POSTREMOVE_LOCAL} + +cat >> postremove << _EOF +exit 0 +_EOF + +## Build request file +echo "Building request file..." +cat > request << _EOF +trap 'exit 3' 15 + +_EOF + +[ -x /usr/bin/ckyorn ] || cat >> request << _EOF + +ckyorn() { +# for some strange reason OpenServer5 has no ckyorn +# We build a striped down version here + +DEFAULT=n +PROMPT="Yes or No [yes,no,?,quit]" +HELP_PROMPT=" Enter y or yes if your answer is yes; n or no if your answer is no." +USAGE="usage: ckyorn [options] +where options may include: + -d default + -h help + -p prompt +" + +if [ \$# != 0 ] +then + while getopts d:p:h: c + do + case \$c in + h) HELP_PROMPT="\$OPTARG" ;; + d) DEFAULT=\$OPTARG ;; + p) PROMPT=\$OPTARG ;; + \\?) echo "\$USAGE" 1>&2 + exit 1 ;; + esac + done + shift \`expr \$OPTIND - 1\` +fi + +while true +do + echo "\${PROMPT}\\c " 1>&2 + read key + [ -z "\$key" ] && key=\$DEFAULT + case \$key in + [n,N]|[n,N][o,O]|[y,Y]|[y,Y][e,E][s,S]) echo "\${key}\\c" + exit 0 ;; + \\?) echo \$HELP_PROMPT 1>&2 ;; + q|quit) echo "q\\c" 1>&2 + exit 3 ;; + esac +done + +} + +_EOF + +if [ $DO_SMF -eq 1 ] +then + # This could get hairy, as the running sshd may not be under SMF. + # We'll assume an earlier version of OpenSSH started via SMF. + cat >> request << _EOF +PRE_INS_STOP=no +POST_INS_START=no +# determine if should restart the daemon +if [ -s ${piddir}/sshd.pid ] && \ + /usr/bin/svcs -H $OPENSSH_FMRI 2>&1 | egrep "^online" > /dev/null 2>&1 +then + ans=\`ckyorn -d n \ +-p "Should the running sshd daemon be restarted? ${DEF_MSG}"\` || exit \$? + case \$ans in + [y,Y]*) PRE_INS_STOP=yes + POST_INS_START=yes + ;; + esac + +else + +# determine if we should start sshd + ans=\`ckyorn -d n \ +-p "Start the sshd daemon after installing this package? ${DEF_MSG}"\` || exit \$? + case \$ans in + [y,Y]*) POST_INS_START=yes ;; + esac +fi + +# make parameters available to installation service, +# and so to any other packaging scripts +cat >\$1 <<! +PRE_INS_STOP='\$PRE_INS_STOP' +POST_INS_START='\$POST_INS_START' +! + +_EOF +else + cat >> request << _EOF +USE_SYM_LINKS=no +PRE_INS_STOP=no +POST_INS_START=no +# Use symbolic links? +ans=\`ckyorn -d n \ +-p "Do you want symbolic links for the start/stop scripts? ${DEF_MSG}"\` || exit \$? +case \$ans in + [y,Y]*) USE_SYM_LINKS=yes ;; +esac + +# determine if should restart the daemon +if [ -s ${piddir}/sshd.pid -a -f ${TEST_DIR}/etc/init.d/${SYSVINIT_NAME} ] +then + ans=\`ckyorn -d n \ +-p "Should the running sshd daemon be restarted? ${DEF_MSG}"\` || exit \$? + case \$ans in + [y,Y]*) PRE_INS_STOP=yes + POST_INS_START=yes + ;; + esac + +else + +# determine if we should start sshd + ans=\`ckyorn -d n \ +-p "Start the sshd daemon after installing this package? ${DEF_MSG}"\` || exit \$? + case \$ans in + [y,Y]*) POST_INS_START=yes ;; + esac +fi + +# make parameters available to installation service, +# and so to any other packaging scripts +cat >\$1 <<! +USE_SYM_LINKS='\$USE_SYM_LINKS' +PRE_INS_STOP='\$PRE_INS_STOP' +POST_INS_START='\$POST_INS_START' +! + +_EOF +fi + +# local request changes here +[ -s "${PKG_REQUEST_LOCAL}" ] && . ${PKG_REQUEST_LOCAL} + +cat >> request << _EOF +exit 0 + +_EOF + +## Next Build our prototype +echo "Building prototype file..." +cat >mk-proto.awk << _EOF + BEGIN { print "i pkginfo"; print "i depend"; \\ + print "i preinstall"; print "i postinstall"; \\ + print "i preremove"; print "i postremove"; \\ + print "i request"; print "i space"; \\ + split("$SYSTEM_DIR",sys_files); } + { + for (dir in sys_files) { if ( \$3 != sys_files[dir] ) + { if ( \$1 == "s" ) + { \$5=""; \$6=""; } + else + { \$5="root"; \$6="sys"; } + } + else + { \$4="?"; \$5="?"; \$6="?"; break;} + } } + { print; } +_EOF + +find . | egrep -v "prototype|pkginfo|mk-proto.awk" | sort | \ + pkgproto $PROTO_ARGS | ${AWK} -f mk-proto.awk > prototype + +# /usr/local is a symlink on some systems +[ "${USR_LOCAL_IS_SYMLINK}" = yes ] && { + grep -v "^d none /usr/local ? ? ?$" prototype > prototype.new + mv prototype.new prototype +} + +## Step back a directory and now build the package. +cd .. +# local prototype tweeks here +[ -s "${POST_PROTOTYPE_EDITS}" ] && . ${POST_PROTOTYPE_EDITS} + +echo "Building package.." +pkgmk -d ${FAKE_ROOT} -f $FAKE_ROOT/prototype -o +echo | pkgtrans -os ${FAKE_ROOT} ${START}/$PKGNAME-$VERSION$REV-$UNAME_S-$ARCH.pkg + ;; + + justpkg.sh) +rm -fr ${FAKE_ROOT}/${PKGNAME} +grep -v "^PSTAMP=" $FAKE_ROOT/pkginfo > $$tmp +mv $$tmp $FAKE_ROOT/pkginfo +cat >> $FAKE_ROOT/pkginfo << _EOF +PSTAMP="${UNAME_S} ${OS_VER} ${ARCH} `date '+%d%b%Y %H:%M'`" +_EOF +pkgmk -d ${FAKE_ROOT} -f $FAKE_ROOT/prototype -o +echo | pkgtrans -os ${FAKE_ROOT} ${START}/$PKGNAME-$VERSION$REV-$UNAME_S-$ARCH.pkg + ;; + +esac + +[ "${REMOVE_FAKE_ROOT_WHEN_DONE}" = yes ] && rm -rf $FAKE_ROOT +exit 0 +
diff --git a/openssh-6.0p1/canohost.c b/openssh-6.0p1/canohost.c new file mode 100644 index 0000000..dabd8a3 --- /dev/null +++ b/openssh-6.0p1/canohost.c
@@ -0,0 +1,440 @@ +/* $OpenBSD: canohost.c,v 1.66 2010/01/13 01:20:20 dtucker Exp $ */ +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * Functions for returning the canonical host name of the remote site. + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ + +#include "includes.h" + +#include <sys/types.h> +#include <sys/socket.h> + +#include <netinet/in.h> +#include <arpa/inet.h> + +#include <ctype.h> +#include <errno.h> +#include <netdb.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> +#include <unistd.h> + +#include "xmalloc.h" +#include "packet.h" +#include "log.h" +#include "canohost.h" +#include "misc.h" + +static void check_ip_options(int, char *); +static char *canonical_host_ip = NULL; +static int cached_port = -1; + +/* + * Return the canonical name of the host at the other end of the socket. The + * caller should free the returned string with xfree. + */ + +static char * +get_remote_hostname(int sock, int use_dns) +{ + struct sockaddr_storage from; + int i; + socklen_t fromlen; + struct addrinfo hints, *ai, *aitop; + char name[NI_MAXHOST], ntop[NI_MAXHOST], ntop2[NI_MAXHOST]; + + /* Get IP address of client. */ + fromlen = sizeof(from); + memset(&from, 0, sizeof(from)); + if (getpeername(sock, (struct sockaddr *)&from, &fromlen) < 0) { + debug("getpeername failed: %.100s", strerror(errno)); + cleanup_exit(255); + } + + if (from.ss_family == AF_INET) + check_ip_options(sock, ntop); + + ipv64_normalise_mapped(&from, &fromlen); + + if (from.ss_family == AF_INET6) + fromlen = sizeof(struct sockaddr_in6); + + if (getnameinfo((struct sockaddr *)&from, fromlen, ntop, sizeof(ntop), + NULL, 0, NI_NUMERICHOST) != 0) + fatal("get_remote_hostname: getnameinfo NI_NUMERICHOST failed"); + + if (!use_dns) + return xstrdup(ntop); + + debug3("Trying to reverse map address %.100s.", ntop); + /* Map the IP address to a host name. */ + if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name), + NULL, 0, NI_NAMEREQD) != 0) { + /* Host name not found. Use ip address. */ + return xstrdup(ntop); + } + + /* + * if reverse lookup result looks like a numeric hostname, + * someone is trying to trick us by PTR record like following: + * 1.1.1.10.in-addr.arpa. IN PTR 2.3.4.5 + */ + memset(&hints, 0, sizeof(hints)); + hints.ai_socktype = SOCK_DGRAM; /*dummy*/ + hints.ai_flags = AI_NUMERICHOST; + if (getaddrinfo(name, NULL, &hints, &ai) == 0) { + logit("Nasty PTR record \"%s\" is set up for %s, ignoring", + name, ntop); + freeaddrinfo(ai); + return xstrdup(ntop); + } + + /* + * Convert it to all lowercase (which is expected by the rest + * of this software). + */ + for (i = 0; name[i]; i++) + if (isupper(name[i])) + name[i] = (char)tolower(name[i]); + /* + * Map it back to an IP address and check that the given + * address actually is an address of this host. This is + * necessary because anyone with access to a name server can + * define arbitrary names for an IP address. Mapping from + * name to IP address can be trusted better (but can still be + * fooled if the intruder has access to the name server of + * the domain). + */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = from.ss_family; + hints.ai_socktype = SOCK_STREAM; + if (getaddrinfo(name, NULL, &hints, &aitop) != 0) { + logit("reverse mapping checking getaddrinfo for %.700s " + "[%s] failed - POSSIBLE BREAK-IN ATTEMPT!", name, ntop); + return xstrdup(ntop); + } + /* Look for the address from the list of addresses. */ + for (ai = aitop; ai; ai = ai->ai_next) { + if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop2, + sizeof(ntop2), NULL, 0, NI_NUMERICHOST) == 0 && + (strcmp(ntop, ntop2) == 0)) + break; + } + freeaddrinfo(aitop); + /* If we reached the end of the list, the address was not there. */ + if (!ai) { + /* Address not found for the host name. */ + logit("Address %.100s maps to %.600s, but this does not " + "map back to the address - POSSIBLE BREAK-IN ATTEMPT!", + ntop, name); + return xstrdup(ntop); + } + return xstrdup(name); +} + +/* + * If IP options are supported, make sure there are none (log and + * disconnect them if any are found). Basically we are worried about + * source routing; it can be used to pretend you are somebody + * (ip-address) you are not. That itself may be "almost acceptable" + * under certain circumstances, but rhosts autentication is useless + * if source routing is accepted. Notice also that if we just dropped + * source routing here, the other side could use IP spoofing to do + * rest of the interaction and could still bypass security. So we + * exit here if we detect any IP options. + */ +/* IPv4 only */ +static void +check_ip_options(int sock, char *ipaddr) +{ +#ifdef IP_OPTIONS + u_char options[200]; + char text[sizeof(options) * 3 + 1]; + socklen_t option_size; + u_int i; + int ipproto; + struct protoent *ip; + + if ((ip = getprotobyname("ip")) != NULL) + ipproto = ip->p_proto; + else + ipproto = IPPROTO_IP; + option_size = sizeof(options); + if (getsockopt(sock, ipproto, IP_OPTIONS, options, + &option_size) >= 0 && option_size != 0) { + text[0] = '\0'; + for (i = 0; i < option_size; i++) + snprintf(text + i*3, sizeof(text) - i*3, + " %2.2x", options[i]); + fatal("Connection from %.100s with IP options:%.800s", + ipaddr, text); + } +#endif /* IP_OPTIONS */ +} + +void +ipv64_normalise_mapped(struct sockaddr_storage *addr, socklen_t *len) +{ + struct sockaddr_in6 *a6 = (struct sockaddr_in6 *)addr; + struct sockaddr_in *a4 = (struct sockaddr_in *)addr; + struct in_addr inaddr; + u_int16_t port; + + if (addr->ss_family != AF_INET6 || + !IN6_IS_ADDR_V4MAPPED(&a6->sin6_addr)) + return; + + debug3("Normalising mapped IPv4 in IPv6 address"); + + memcpy(&inaddr, ((char *)&a6->sin6_addr) + 12, sizeof(inaddr)); + port = a6->sin6_port; + + bzero(a4, sizeof(*a4)); + + a4->sin_family = AF_INET; + *len = sizeof(*a4); + memcpy(&a4->sin_addr, &inaddr, sizeof(inaddr)); + a4->sin_port = port; +} + +/* + * Return the canonical name of the host in the other side of the current + * connection. The host name is cached, so it is efficient to call this + * several times. + */ + +const char * +get_canonical_hostname(int use_dns) +{ + char *host; + static char *canonical_host_name = NULL; + static char *remote_ip = NULL; + + /* Check if we have previously retrieved name with same option. */ + if (use_dns && canonical_host_name != NULL) + return canonical_host_name; + if (!use_dns && remote_ip != NULL) + return remote_ip; + + /* Get the real hostname if socket; otherwise return UNKNOWN. */ + if (packet_connection_is_on_socket()) + host = get_remote_hostname(packet_get_connection_in(), use_dns); + else + host = "UNKNOWN"; + + if (use_dns) + canonical_host_name = host; + else + remote_ip = host; + return host; +} + +/* + * Returns the local/remote IP-address/hostname of socket as a string. + * The returned string must be freed. + */ +static char * +get_socket_address(int sock, int remote, int flags) +{ + struct sockaddr_storage addr; + socklen_t addrlen; + char ntop[NI_MAXHOST]; + int r; + + /* Get IP address of client. */ + addrlen = sizeof(addr); + memset(&addr, 0, sizeof(addr)); + + if (remote) { + if (getpeername(sock, (struct sockaddr *)&addr, &addrlen) + < 0) + return NULL; + } else { + if (getsockname(sock, (struct sockaddr *)&addr, &addrlen) + < 0) + return NULL; + } + + /* Work around Linux IPv6 weirdness */ + if (addr.ss_family == AF_INET6) + addrlen = sizeof(struct sockaddr_in6); + + ipv64_normalise_mapped(&addr, &addrlen); + + /* Get the address in ascii. */ + if ((r = getnameinfo((struct sockaddr *)&addr, addrlen, ntop, + sizeof(ntop), NULL, 0, flags)) != 0) { + error("get_socket_address: getnameinfo %d failed: %s", flags, + ssh_gai_strerror(r)); + return NULL; + } + return xstrdup(ntop); +} + +char * +get_peer_ipaddr(int sock) +{ + char *p; + + if ((p = get_socket_address(sock, 1, NI_NUMERICHOST)) != NULL) + return p; + return xstrdup("UNKNOWN"); +} + +char * +get_local_ipaddr(int sock) +{ + char *p; + + if ((p = get_socket_address(sock, 0, NI_NUMERICHOST)) != NULL) + return p; + return xstrdup("UNKNOWN"); +} + +char * +get_local_name(int fd) +{ + char *host, myname[NI_MAXHOST]; + + /* Assume we were passed a socket */ + if ((host = get_socket_address(fd, 0, NI_NAMEREQD)) != NULL) + return host; + + /* Handle the case where we were passed a pipe */ + if (gethostname(myname, sizeof(myname)) == -1) { + verbose("get_local_name: gethostname: %s", strerror(errno)); + } else { + host = xstrdup(myname); + } + + return host; +} + +void +clear_cached_addr(void) +{ + if (canonical_host_ip != NULL) { + xfree(canonical_host_ip); + canonical_host_ip = NULL; + } + cached_port = -1; +} + +/* + * Returns the IP-address of the remote host as a string. The returned + * string must not be freed. + */ + +const char * +get_remote_ipaddr(void) +{ + /* Check whether we have cached the ipaddr. */ + if (canonical_host_ip == NULL) { + if (packet_connection_is_on_socket()) { + canonical_host_ip = + get_peer_ipaddr(packet_get_connection_in()); + if (canonical_host_ip == NULL) + cleanup_exit(255); + } else { + /* If not on socket, return UNKNOWN. */ + canonical_host_ip = xstrdup("UNKNOWN"); + } + } + return canonical_host_ip; +} + +const char * +get_remote_name_or_ip(u_int utmp_len, int use_dns) +{ + static const char *remote = ""; + if (utmp_len > 0) + remote = get_canonical_hostname(use_dns); + if (utmp_len == 0 || strlen(remote) > utmp_len) + remote = get_remote_ipaddr(); + return remote; +} + +/* Returns the local/remote port for the socket. */ + +int +get_sock_port(int sock, int local) +{ + struct sockaddr_storage from; + socklen_t fromlen; + char strport[NI_MAXSERV]; + int r; + + /* Get IP address of client. */ + fromlen = sizeof(from); + memset(&from, 0, sizeof(from)); + if (local) { + if (getsockname(sock, (struct sockaddr *)&from, &fromlen) < 0) { + error("getsockname failed: %.100s", strerror(errno)); + return 0; + } + } else { + if (getpeername(sock, (struct sockaddr *)&from, &fromlen) < 0) { + debug("getpeername failed: %.100s", strerror(errno)); + return -1; + } + } + + /* Work around Linux IPv6 weirdness */ + if (from.ss_family == AF_INET6) + fromlen = sizeof(struct sockaddr_in6); + + /* Return port number. */ + if ((r = getnameinfo((struct sockaddr *)&from, fromlen, NULL, 0, + strport, sizeof(strport), NI_NUMERICSERV)) != 0) + fatal("get_sock_port: getnameinfo NI_NUMERICSERV failed: %s", + ssh_gai_strerror(r)); + return atoi(strport); +} + +/* Returns remote/local port number for the current connection. */ + +static int +get_port(int local) +{ + /* + * If the connection is not a socket, return 65535. This is + * intentionally chosen to be an unprivileged port number. + */ + if (!packet_connection_is_on_socket()) + return 65535; + + /* Get socket and return the port number. */ + return get_sock_port(packet_get_connection_in(), local); +} + +int +get_peer_port(int sock) +{ + return get_sock_port(sock, 0); +} + +int +get_remote_port(void) +{ + /* Cache to avoid getpeername() on a dead connection */ + if (cached_port == -1) + cached_port = get_port(0); + + return cached_port; +} + +int +get_local_port(void) +{ + return get_port(1); +}
diff --git a/openssh-6.0p1/canohost.h b/openssh-6.0p1/canohost.h new file mode 100644 index 0000000..4c8636f --- /dev/null +++ b/openssh-6.0p1/canohost.h
@@ -0,0 +1,29 @@ +/* $OpenBSD: canohost.h,v 1.11 2009/05/27 06:31:25 andreas Exp $ */ + +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ + +const char *get_canonical_hostname(int); +const char *get_remote_ipaddr(void); +const char *get_remote_name_or_ip(u_int, int); + +char *get_peer_ipaddr(int); +int get_peer_port(int); +char *get_local_ipaddr(int); +char *get_local_name(int); + +int get_remote_port(void); +int get_local_port(void); +int get_sock_port(int, int); +void clear_cached_addr(void); + +void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *);
diff --git a/openssh-6.0p1/channels.c b/openssh-6.0p1/channels.c new file mode 100644 index 0000000..f6e9b4d --- /dev/null +++ b/openssh-6.0p1/channels.c
@@ -0,0 +1,3764 @@ +/* $OpenBSD: channels.c,v 1.315 2011/09/23 07:45:05 markus Exp $ */ +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * This file contains functions for 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 <sys/types.h> +#include <sys/ioctl.h> +#include <sys/un.h> +#include <sys/socket.h> +#ifdef HAVE_SYS_TIME_H +# include <sys/time.h> +#endif + +#include <netinet/in.h> +#include <arpa/inet.h> + +#include <errno.h> +#include <fcntl.h> +#include <netdb.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <termios.h> +#include <unistd.h> +#include <stdarg.h> + +#include "openbsd-compat/sys-queue.h" +#include "xmalloc.h" +#include "ssh.h" +#include "ssh1.h" +#include "ssh2.h" +#include "packet.h" +#include "log.h" +#include "misc.h" +#include "buffer.h" +#include "channels.h" +#include "compat.h" +#include "canohost.h" +#include "key.h" +#include "authfd.h" +#include "pathnames.h" + +/* -- channel core */ + +/* + * Pointer to an array containing all allocated channels. The array is + * dynamically extended as needed. + */ +static Channel **channels = NULL; + +/* + * Size of the channel array. All slots of the array must always be + * initialized (at least the type field); unused slots set to NULL + */ +static u_int channels_alloc = 0; + +/* + * Maximum file descriptor value used in any of the channels. This is + * updated in channel_new. + */ +static int channel_max_fd = 0; + + +/* -- tcp forwarding */ + +/* + * Data structure for storing which hosts are permitted for forward requests. + * The local sides of any remote forwards are stored in this array to prevent + * a corrupt remote server from accessing arbitrary TCP/IP ports on our local + * network (which might be behind a firewall). + */ +typedef struct { + char *host_to_connect; /* Connect to 'host'. */ + u_short port_to_connect; /* Connect to 'port'. */ + u_short listen_port; /* Remote side should listen port number. */ +} ForwardPermission; + +/* List of all permitted host/port pairs to connect by the user. */ +static ForwardPermission *permitted_opens = NULL; + +/* List of all permitted host/port pairs to connect by the admin. */ +static ForwardPermission *permitted_adm_opens = NULL; + +/* Number of permitted host/port pairs in the array permitted by the user. */ +static int num_permitted_opens = 0; + +/* Number of permitted host/port pair in the array permitted by the admin. */ +static int num_adm_permitted_opens = 0; + +/* special-case port number meaning allow any port */ +#define FWD_PERMIT_ANY_PORT 0 + +/* + * If this is true, all opens are permitted. This is the case on the server + * on which we have to trust the client anyway, and the user could do + * anything after logging in anyway. + */ +static int all_opens_permitted = 0; + + +/* -- X11 forwarding */ + +/* Maximum number of fake X11 displays to try. */ +#define MAX_DISPLAYS 1000 + +/* Saved X11 local (client) display. */ +static char *x11_saved_display = NULL; + +/* Saved X11 authentication protocol name. */ +static char *x11_saved_proto = NULL; + +/* Saved X11 authentication data. This is the real data. */ +static char *x11_saved_data = NULL; +static u_int x11_saved_data_len = 0; + +/* + * Fake X11 authentication data. This is what the server will be sending us; + * we should replace any occurrences of this by the real data. + */ +static u_char *x11_fake_data = NULL; +static u_int x11_fake_data_len; + + +/* -- agent forwarding */ + +#define NUM_SOCKS 10 + +/* AF_UNSPEC or AF_INET or AF_INET6 */ +static int IPv4or6 = AF_UNSPEC; + +/* helper */ +static void port_open_helper(Channel *c, char *rtype); + +/* non-blocking connect helpers */ +static int connect_next(struct channel_connect *); +static void channel_connect_ctx_free(struct channel_connect *); + +/* -- channel core */ + +Channel * +channel_by_id(int id) +{ + Channel *c; + + if (id < 0 || (u_int)id >= channels_alloc) { + logit("channel_by_id: %d: bad id", id); + return NULL; + } + c = channels[id]; + if (c == NULL) { + logit("channel_by_id: %d: bad id: channel free", id); + return NULL; + } + return c; +} + +/* + * Returns the channel if it is allowed to receive protocol messages. + * Private channels, like listening sockets, may not receive messages. + */ +Channel * +channel_lookup(int id) +{ + Channel *c; + + if ((c = channel_by_id(id)) == NULL) + return (NULL); + + switch (c->type) { + case SSH_CHANNEL_X11_OPEN: + case SSH_CHANNEL_LARVAL: + case SSH_CHANNEL_CONNECTING: + case SSH_CHANNEL_DYNAMIC: + case SSH_CHANNEL_OPENING: + case SSH_CHANNEL_OPEN: + case SSH_CHANNEL_INPUT_DRAINING: + case SSH_CHANNEL_OUTPUT_DRAINING: + return (c); + } + logit("Non-public channel %d, type %d.", id, c->type); + return (NULL); +} + +/* + * Register filedescriptors for a channel, used when allocating a channel or + * when the channel consumer/producer is ready, e.g. shell exec'd + */ +static void +channel_register_fds(Channel *c, int rfd, int wfd, int efd, + int extusage, int nonblock, int is_tty) +{ + /* Update the maximum file descriptor value. */ + channel_max_fd = MAX(channel_max_fd, rfd); + channel_max_fd = MAX(channel_max_fd, wfd); + channel_max_fd = MAX(channel_max_fd, efd); + + if (rfd != -1) + fcntl(rfd, F_SETFD, FD_CLOEXEC); + if (wfd != -1 && wfd != rfd) + fcntl(wfd, F_SETFD, FD_CLOEXEC); + if (efd != -1 && efd != rfd && efd != wfd) + fcntl(efd, F_SETFD, FD_CLOEXEC); + + c->rfd = rfd; + c->wfd = wfd; + c->sock = (rfd == wfd) ? rfd : -1; + c->efd = efd; + c->extended_usage = extusage; + + if ((c->isatty = is_tty) != 0) + debug2("channel %d: rfd %d isatty", c->self, c->rfd); + c->wfd_isatty = is_tty || isatty(c->wfd); + + /* 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 = xrealloc(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->self = found; + c->type = type; + c->ctype = ctype; + c->local_window = window; + c->local_window_max = window; + c->local_consumed = 0; + c->local_maxpacket = maxpack; + c->remote_id = -1; + c->remote_name = xstrdup(remote_name); + c->remote_window = 0; + c->remote_maxpacket = 0; + c->force_drain = 0; + c->single_connection = 0; + c->detach_user = NULL; + c->detach_close = 0; + c->open_confirm = NULL; + c->open_confirm_ctx = NULL; + c->input_filter = NULL; + c->output_filter = NULL; + c->filter_ctx = NULL; + c->filter_cleanup = NULL; + c->ctl_chan = -1; + c->mux_rcb = NULL; + c->mux_ctx = NULL; + c->mux_pause = 0; + c->delayed = 1; /* prevent call to channel_post handler */ + TAILQ_INIT(&c->status_confirms); + debug("channel %d: new [%s]", found, remote_name); + return c; +} + +static int +channel_find_maxfd(void) +{ + u_int i; + int max = 0; + Channel *c; + + for (i = 0; i < channels_alloc; i++) { + c = channels[i]; + if (c != NULL) { + max = MAX(max, c->rfd); + max = MAX(max, c->wfd); + max = MAX(max, c->efd); + } + } + return max; +} + +int +channel_close_fd(int *fdp) +{ + int ret = 0, fd = *fdp; + + if (fd != -1) { + ret = close(fd); + *fdp = -1; + if (fd == channel_max_fd) + channel_max_fd = channel_find_maxfd(); + } + return ret; +} + +/* Close all channel fd/socket. */ +static void +channel_close_fds(Channel *c) +{ + channel_close_fd(&c->sock); + channel_close_fd(&c->rfd); + channel_close_fd(&c->wfd); + channel_close_fd(&c->efd); +} + +/* Free the channel and close its fd/socket. */ +void +channel_free(Channel *c) +{ + char *s; + u_int i, n; + struct channel_confirm *cc; + + for (n = 0, i = 0; i < channels_alloc; i++) + if (channels[i]) + n++; + debug("channel %d: free: %s, nchannels %u", c->self, + c->remote_name ? c->remote_name : "???", n); + + s = channel_open_message(); + debug3("channel %d: status: %s", c->self, s); + xfree(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); + if (c->remote_name) { + xfree(c->remote_name); + c->remote_name = NULL; + } + if (c->path) { + xfree(c->path); + c->path = NULL; + } + if (c->listening_addr) { + xfree(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); + bzero(cc, sizeof(*cc)); + xfree(cc); + } + if (c->filter_cleanup != NULL && c->filter_ctx != NULL) + c->filter_cleanup(c->self, c->filter_ctx); + channels[c->self] = NULL; + xfree(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: + 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: + continue; + case SSH_CHANNEL_LARVAL: + if (!compat20) + fatal("cannot happen: SSH_CHANNEL_LARVAL"); + continue; + case SSH_CHANNEL_OPENING: + case SSH_CHANNEL_OPEN: + case SSH_CHANNEL_X11_OPEN: + case SSH_CHANNEL_MUX_CLIENT: + return 1; + case SSH_CHANNEL_INPUT_DRAINING: + case SSH_CHANNEL_OUTPUT_DRAINING: + if (!compat13) + fatal("cannot happen: OUT_DRAIN"); + return 1; + default: + fatal("channel_still_open: bad channel type %d", c->type); + /* NOTREACHED */ + } + } + return 0; +} + +/* Returns the id of an open channel suitable for keepaliving */ +int +channel_find_open(void) +{ + u_int i; + Channel *c; + + for (i = 0; i < channels_alloc; i++) { + c = channels[i]; + if (c == NULL || c->remote_id < 0) + continue; + switch (c->type) { + case SSH_CHANNEL_CLOSED: + case SSH_CHANNEL_DYNAMIC: + case SSH_CHANNEL_X11_LISTENER: + case SSH_CHANNEL_PORT_LISTENER: + case SSH_CHANNEL_RPORT_LISTENER: + case SSH_CHANNEL_MUX_LISTENER: + case SSH_CHANNEL_MUX_CLIENT: + case SSH_CHANNEL_OPENING: + case SSH_CHANNEL_CONNECTING: + case SSH_CHANNEL_ZOMBIE: + 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_MUX_CLIENT: + case SSH_CHANNEL_MUX_LISTENER: + continue; + case SSH_CHANNEL_LARVAL: + case SSH_CHANNEL_OPENING: + case SSH_CHANNEL_CONNECTING: + case SSH_CHANNEL_DYNAMIC: + case SSH_CHANNEL_OPEN: + case SSH_CHANNEL_X11_OPEN: + case SSH_CHANNEL_INPUT_DRAINING: + case SSH_CHANNEL_OUTPUT_DRAINING: + snprintf(buf, sizeof buf, + " #%d %.300s (t%d r%d i%d/%d o%d/%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(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 = xmalloc(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; + + /* 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 = 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 = buffer_ptr(&c->input); + 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); + + if (c->path != NULL) { + xfree(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 = 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; + u_char *p, dest_addr[255+1], ntop[INET6_ADDRSTRLEN]; + 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, (char *)&dest_addr, addrlen); + buffer_get(&c->input, (char *)&dest_port, 2); + dest_addr[addrlen] = '\0'; + if (c->path != NULL) { + xfree(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; + ((struct in_addr *)&dest_addr)->s_addr = INADDR_ANY; + dest_port = 0; /* ignored */ + + buffer_append(&c->output, &s5_rsp, sizeof(s5_rsp)); + buffer_append(&c->output, &dest_addr, sizeof(struct in_addr)); + 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; + 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) { + debug2("single_connection: closing X11 listener."); + channel_close_fd(&c->sock); + chan_mark_dead(c); + } + if (newsock < 0) { + error("accept: %.100s", strerror(errno)); + 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(); + } + xfree(remote_ipaddr); + } +} + +static void +port_open_helper(Channel *c, char *rtype) +{ + int direct; + char buf[1024]; + 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) */ + xfree(remote_ipaddr); + remote_ipaddr = xstrdup("127.0.0.1"); + remote_port = 65535; + } + + direct = (strcmp(rtype, "direct-tcpip") == 0); + + snprintf(buf, sizeof buf, + "%s: listening port %d for %.100s port %d, " + "connect from %.200s port %d", + rtype, c->listening_port, c->path, c->host_port, + remote_ipaddr, remote_port); + + xfree(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 (direct) { + /* target host, port */ + packet_put_cstring(c->path); + packet_put_int(c->host_port); + } else { + /* listen address, port */ + packet_put_cstring(c->path); + packet_put_int(c->listening_port); + } + /* 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(); + } + xfree(remote_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)); +} + +/* + * 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->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) { + error("accept: %.100s", strerror(errno)); + return; + } + 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)); + 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); + xfree(data); + if (len < 0 && (errno == EINTR || errno == EAGAIN || + errno == EWOULDBLOCK)) + return 1; + if (len <= 0) { + if (c->type != SSH_CHANNEL_OPEN) + chan_mark_dead(c); + else + chan_write_failed(c); + return -1; + } + goto out; + } +#ifdef _AIX + /* XXX: Later AIX versions can't push as much data to tty */ + if (compat20 && c->wfd_isatty) + dlen = MIN(dlen, 8*1024); +#endif + + len = write(c->wfd, buf, dlen); + if (len < 0 && + (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)) + return 1; + if (len <= 0) { + if (c->type != SSH_CHANNEL_OPEN) { + debug2("channel %d: not open", c->self); + chan_mark_dead(c); + return -1; + } else if (compat13) { + buffer_clear(&c->output); + debug2("channel %d: input draining.", c->self); + c->type = SSH_CHANNEL_INPUT_DRAINING; + } else { + chan_write_failed(c); + } + return -1; + } +#ifndef BROKEN_TCGETATTR_ICANON + if (compat20 && c->isatty && dlen >= 1 && buf[0] != '\r') { + if (tcgetattr(c->wfd, &tio) == 0 && + !(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) { + /* + * Simulate echo to reduce the impact of + * traffic analysis. We need to match the + * size of a SSH2_MSG_CHANNEL_DATA message + * (4 byte channel id + buf) + */ + packet_send_ignore(4 + len); + packet_send(); + } + } +#endif + buffer_consume(&c->output, len); + } + out: + if (compat20 && olen > 0) + c->local_consumed += olen - buffer_len(&c->output); + return 1; +} + +static int +channel_handle_efd(Channel *c, fd_set *readset, fd_set *writeset) +{ + char buf[CHAN_RBUF]; + int len; + +/** XXX handle drain efd, too */ + if (c->efd != -1) { + if (c->extended_usage == CHAN_EXTENDED_WRITE && + FD_ISSET(c->efd, writeset) && + buffer_len(&c->extended) > 0) { + len = write(c->efd, buffer_ptr(&c->extended), + buffer_len(&c->extended)); + debug2("channel %d: written %d to efd %d", + c->self, len, c->efd); + if (len < 0 && (errno == EINTR || errno == EAGAIN || + errno == EWOULDBLOCK)) + return 1; + if (len <= 0) { + debug2("channel %d: closing write-efd %d", + c->self, c->efd); + channel_close_fd(&c->efd); + } else { + buffer_consume(&c->extended, len); + c->local_consumed += len; + } + } else if (c->efd != -1 && + (c->extended_usage == CHAN_EXTENDED_READ || + c->extended_usage == CHAN_EXTENDED_IGNORE) && + (c->detach_close || FD_ISSET(c->efd, readset))) { + len = read(c->efd, buf, sizeof(buf)); + debug2("channel %d: read %d from efd %d", + c->self, len, c->efd); + if (len < 0 && (errno == EINTR || ((errno == EAGAIN || + errno == EWOULDBLOCK) && !c->detach_close))) + return 1; + if (len <= 0) { + debug2("channel %d: closing read-efd %d", + c->self, c->efd); + channel_close_fd(&c->efd); + } else { + if (c->extended_usage == CHAN_EXTENDED_IGNORE) { + debug3("channel %d: discard efd", + c->self); + } else + buffer_append(&c->extended, buf, len); + } + } + } + return 1; +} + +static int +channel_check_window(Channel *c) +{ + if (c->type == SSH_CHANNEL_OPEN && + !(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) && + ((c->local_window_max - c->local_window > + c->local_maxpacket*3) || + c->local_window < c->local_window_max/2) && + c->local_consumed > 0) { + packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST); + packet_put_int(c->remote_id); + packet_put_int(c->local_consumed); + packet_send(); + debug2("channel %d: window %d sent adjust %d", + c->self, c->local_window, + c->local_consumed); + c->local_window += c->local_consumed; + c->local_consumed = 0; + } + return 1; +} + +static void +channel_post_open(Channel *c, fd_set *readset, fd_set *writeset) +{ + channel_handle_rfd(c, readset, writeset); + channel_handle_wfd(c, readset, writeset); + if (!compat20) + return; + channel_handle_efd(c, readset, writeset); + channel_check_window(c); +} + +static u_int +read_mux(Channel *c, u_int need) +{ + char buf[CHAN_RBUF]; + int len; + u_int rlen; + + if (buffer_len(&c->input) < need) { + rlen = need - buffer_len(&c->input); + len = read(c->rfd, buf, MIN(rlen, CHAN_RBUF)); + if (len <= 0) { + if (errno != EINTR && errno != EAGAIN) { + 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)); + 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_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_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) +{ + static int did_init = 0; + u_int i, oalloc; + Channel *c; + + if (!did_init) { + channel_handler_init(); + did_init = 1; + } + 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) + (*ftab[c->type])(c, readset, writeset); + channel_garbage_collect(c); + } +} + +/* + * 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, int rekeying) +{ + u_int n, sz, nfdset; + + n = MAX(*maxfdp, channel_max_fd); + + nfdset = howmany(n+1, NFDBITS); + /* Explicitly test here, because xrealloc isn't always called */ + if (nfdset && SIZE_T_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 = xrealloc(*readsetp, nfdset, sizeof(fd_mask)); + *writesetp = xrealloc(*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); +} + +/* + * 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); +} + + +/* 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); + xfree(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 + 4; + xfree(data); + } + continue; + } + /* + * Send some data for the other side over the secure + * connection. + */ + if (compat20) { + if (len > c->remote_window) + len = c->remote_window; + if (len > c->remote_maxpacket) + len = c->remote_maxpacket; + } else { + if (packet_is_interactive()) { + if (len > 1024) + len = 512; + } else { + /* Keep the packets at reasonable size. */ + if (len > packet_get_maxsize()/2) + len = packet_get_maxsize()/2; + } + } + if (len > 0) { + packet_start(compat20 ? + SSH2_MSG_CHANNEL_DATA : SSH_MSG_CHANNEL_DATA); + packet_put_int(c->remote_id); + packet_put_string(buffer_ptr(&c->input), len); + packet_send(); + buffer_consume(&c->input, len); + c->remote_window -= len; + } + } else if (c->istate == CHAN_INPUT_WAIT_DRAIN) { + if (compat13) + fatal("cannot happen: istate == INPUT_WAIT_DRAIN for proto 1.3"); + /* + * input-buffer is empty and read-socket shutdown: + * tell peer, that we will not send more data: send IEOF. + * hack for extended data: delay EOF if EFD still in use. + */ + if (CHANNEL_EFD_INPUT_ACTIVE(c)) + debug2("channel %d: ibuf_empty delayed efd %d/(%d)", + c->self, c->efd, buffer_len(&c->extended)); + else + chan_ibuf_empty(c); + } + /* Send extended data, i.e. stderr */ + if (compat20 && + !(c->flags & CHAN_EOF_SENT) && + c->remote_window > 0 && + (len = buffer_len(&c->extended)) > 0 && + c->extended_usage == CHAN_EXTENDED_READ) { + debug2("channel %d: rwin %u elen %u euse %d", + c->self, c->remote_window, buffer_len(&c->extended), + c->extended_usage); + if (len > c->remote_window) + len = c->remote_window; + if (len > c->remote_maxpacket) + len = c->remote_maxpacket; + packet_start(SSH2_MSG_CHANNEL_EXTENDED_DATA); + packet_put_int(c->remote_id); + packet_put_int(SSH2_EXTENDED_DATA_STDERR); + packet_put_string(buffer_ptr(&c->extended), len); + packet_send(); + buffer_consume(&c->extended, len); + c->remote_window -= len; + debug2("channel %d: sent ext data %d", c->self, len); + } + } +} + + +/* -- protocol input */ + +/* ARGSUSED */ +void +channel_input_data(int type, u_int32_t seq, void *ctxt) +{ + int id; + char *data; + u_int data_len, win_len; + Channel *c; + + /* Get the channel number and verify it. */ + id = packet_get_int(); + c = channel_lookup(id); + if (c == NULL) + packet_disconnect("Received data for nonexistent channel %d.", id); + + /* Ignore any data for non-open channels (might happen on close) */ + if (c->type != SSH_CHANNEL_OPEN && + c->type != SSH_CHANNEL_X11_OPEN) + return; + + /* 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; + } + + 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; + } + 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(); +} + +/* ARGSUSED */ +void +channel_input_extended_data(int type, u_int32_t seq, void *ctxt) +{ + int id; + char *data; + u_int data_len, tcode; + Channel *c; + + /* Get the channel number and verify it. */ + id = packet_get_int(); + c = channel_lookup(id); + + if (c == NULL) + packet_disconnect("Received extended_data for bad channel %d.", id); + if (c->type != SSH_CHANNEL_OPEN) { + logit("channel %d: ext data for non open", id); + return; + } + 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; + } + 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); + xfree(data); + return; + } + debug2("channel %d: rcvd ext data %d", c->self, data_len); + c->local_window -= data_len; + buffer_append(&c->extended, data, data_len); + xfree(data); +} + +/* ARGSUSED */ +void +channel_input_ieof(int type, u_int32_t seq, void *ctxt) +{ + int id; + Channel *c; + + id = packet_get_int(); + packet_check_eom(); + c = channel_lookup(id); + if (c == NULL) + packet_disconnect("Received ieof for nonexistent channel %d.", id); + chan_rcvd_ieof(c); + + /* XXX force input close */ + if (c->force_drain && c->istate == CHAN_INPUT_OPEN) { + debug("channel %d: FORCE input drain", c->self); + c->istate = CHAN_INPUT_WAIT_DRAIN; + if (buffer_len(&c->input) == 0) + chan_ibuf_empty(c); + } + +} + +/* ARGSUSED */ +void +channel_input_close(int type, u_int32_t seq, void *ctxt) +{ + int id; + Channel *c; + + id = packet_get_int(); + packet_check_eom(); + c = channel_lookup(id); + if (c == NULL) + packet_disconnect("Received close for nonexistent channel %d.", id); + + /* + * Send a confirmation that we have closed the channel and no more + * data is coming for it. + */ + packet_start(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION); + packet_put_int(c->remote_id); + packet_send(); + + /* + * If the channel is in closed state, we have sent a close request, + * and the other side will eventually respond with a confirmation. + * Thus, we cannot free the channel here, because then there would be + * no-one to receive the confirmation. The channel gets freed when + * the confirmation arrives. + */ + if (c->type != SSH_CHANNEL_CLOSED) { + /* + * Not a closed channel - mark it as draining, which will + * cause it to be freed later. + */ + buffer_clear(&c->input); + c->type = SSH_CHANNEL_OUTPUT_DRAINING; + } +} + +/* proto version 1.5 overloads CLOSE_CONFIRMATION with OCLOSE */ +/* ARGSUSED */ +void +channel_input_oclose(int type, u_int32_t seq, void *ctxt) +{ + int id = packet_get_int(); + Channel *c = channel_lookup(id); + + packet_check_eom(); + if (c == NULL) + packet_disconnect("Received oclose for nonexistent channel %d.", id); + chan_rcvd_oclose(c); +} + +/* ARGSUSED */ +void +channel_input_close_confirmation(int type, u_int32_t seq, void *ctxt) +{ + int id = packet_get_int(); + Channel *c = channel_lookup(id); + + packet_check_eom(); + if (c == NULL) + packet_disconnect("Received close confirmation for " + "out-of-range channel %d.", id); + if (c->type != SSH_CHANNEL_CLOSED) + packet_disconnect("Received close confirmation for " + "non-closed channel %d (type %d).", id, c->type); + channel_free(c); +} + +/* ARGSUSED */ +void +channel_input_open_confirmation(int type, u_int32_t seq, void *ctxt) +{ + int id, remote_id; + Channel *c; + + id = packet_get_int(); + c = channel_lookup(id); + + if (c==NULL || c->type != SSH_CHANNEL_OPENING) + packet_disconnect("Received open confirmation for " + "non-opening channel %d.", id); + remote_id = packet_get_int(); + /* Record the remote channel number and mark that the channel is now open. */ + c->remote_id = remote_id; + c->type = SSH_CHANNEL_OPEN; + + if (compat20) { + c->remote_window = packet_get_int(); + c->remote_maxpacket = packet_get_int(); + if (c->open_confirm) { + debug2("callback start"); + c->open_confirm(c->self, 1, c->open_confirm_ctx); + debug2("callback done"); + } + debug2("channel %d: open confirm rwindow %u rmax %u", c->self, + c->remote_window, c->remote_maxpacket); + } + packet_check_eom(); +} + +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 */ +void +channel_input_open_failure(int type, u_int32_t seq, void *ctxt) +{ + int id, reason; + char *msg = NULL, *lang = NULL; + Channel *c; + + id = packet_get_int(); + c = channel_lookup(id); + + if (c==NULL || c->type != SSH_CHANNEL_OPENING) + packet_disconnect("Received open failure for " + "non-opening channel %d.", id); + if (compat20) { + reason = packet_get_int(); + if (!(datafellows & SSH_BUG_OPENFAILURE)) { + msg = packet_get_string(NULL); + lang = packet_get_string(NULL); + } + logit("channel %d: open failed: %s%s%s", id, + reason2txt(reason), msg ? ": ": "", msg ? msg : ""); + if (msg != NULL) + xfree(msg); + if (lang != NULL) + xfree(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); +} + +/* ARGSUSED */ +void +channel_input_window_adjust(int type, u_int32_t seq, void *ctxt) +{ + Channel *c; + int id; + u_int adjust; + + if (!compat20) + return; + + /* 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; + } + adjust = packet_get_int(); + packet_check_eom(); + debug2("channel %d: rcvd adjust %u", id, adjust); + c->remote_window += adjust; +} + +/* ARGSUSED */ +void +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(host, host_port, + "connected socket", originator_string); + xfree(originator_string); + xfree(host); + if (c == NULL) { + packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); + packet_put_int(remote_id); + packet_send(); + } else + c->remote_id = remote_id; +} + +/* ARGSUSED */ +void +channel_input_status_confirm(int type, u_int32_t seq, void *ctxt) +{ + Channel *c; + struct channel_confirm *cc; + int id; + + /* Reset keepalive timeout */ + packet_set_alive_timeouts(0); + + id = packet_get_int(); + packet_check_eom(); + + debug2("channel_input_status_confirm: type %d id %d", type, id); + + if ((c = channel_lookup(id)) == NULL) { + logit("channel_input_status_confirm: %d: unknown", id); + return; + } + ; + if ((cc = TAILQ_FIRST(&c->status_confirms)) == NULL) + return; + cc->cb(type, c, cc->ctx); + TAILQ_REMOVE(&c->status_confirms, cc, entry); + bzero(cc, sizeof(*cc)); + xfree(cc); +} + +/* -- 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 + */ +static const char * +channel_fwd_bind_addr(const char *listen_addr, int *wildcardp, + int is_client, int gateway_ports) +{ + const char *addr = NULL; + int wildcard = 0; + + if (listen_addr == NULL) { + /* No address specified: default to gateway_ports setting */ + if (gateway_ports) + wildcard = 1; + } else if (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 && gateway_ports == 1)) + wildcard = 1; + else if (strcmp(listen_addr, "localhost") != 0) + addr = listen_addr; + } + if (wildcardp != NULL) + *wildcardp = wildcard; + return addr; +} + +static int +channel_setup_fwd_listener(int type, const char *listen_addr, + u_short listen_port, int *allocated_listen_port, + const char *host_to_connect, u_short port_to_connect, int gateway_ports) +{ + 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; + + host = (type == SSH_CHANNEL_RPORT_LISTENER) ? + listen_addr : host_to_connect; + is_client = (type == SSH_CHANNEL_PORT_LISTENER); + + 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(listen_addr, &wildcard, + is_client, gateway_ports); + debug3("channel_setup_fwd_listener: type %d wildcard %d addr %s", + 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", 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("channel_setup_fwd_listener: " + "getaddrinfo(%.64s): %s", 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 && 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("channel_setup_fwd_listener: getnameinfo failed"); + 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; + } + + /* + * listen_port == 0 requests a dynamically allocated port - + * record what we got. + */ + if (type == SSH_CHANNEL_RPORT_LISTENER && listen_port == 0 && + allocated_listen_port != NULL && + *allocated_listen_port == 0) { + *allocated_listen_port = get_sock_port(sock, 1); + debug("Allocated listen port %d", + *allocated_listen_port); + } + + /* Allocate a channel number for the socket. */ + c = channel_new("port listener", type, sock, sock, -1, + CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, + 0, "port listener", 1); + c->path = xstrdup(host); + c->host_port = port_to_connect; + c->listening_addr = addr == NULL ? NULL : xstrdup(addr); + if (listen_port == 0 && allocated_listen_port != NULL && + !(datafellows & SSH_BUG_DYNAMIC_RPORT)) + c->listening_port = *allocated_listen_port; + else + c->listening_port = listen_port; + success = 1; + } + if (success == 0) + error("channel_setup_fwd_listener: cannot listen to port: %d", + listen_port); + freeaddrinfo(aitop); + return success; +} + +int +channel_cancel_rport_listener(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); +} + +int +channel_cancel_lport_listener(const char *lhost, u_short lport, + int cport, int gateway_ports) +{ + u_int i; + int found = 0; + const char *addr = channel_fwd_bind_addr(lhost, NULL, 1, gateway_ports); + + 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); +} + +/* protocol local port fwd, used by ssh (and sshd in v1) */ +int +channel_setup_local_fwd_listener(const char *listen_host, u_short listen_port, + const char *host_to_connect, u_short port_to_connect, int gateway_ports) +{ + return channel_setup_fwd_listener(SSH_CHANNEL_PORT_LISTENER, + listen_host, listen_port, NULL, host_to_connect, port_to_connect, + gateway_ports); +} + +/* protocol v2 remote port fwd, used by sshd */ +int +channel_setup_remote_fwd_listener(const char *listen_address, + u_short listen_port, int *allocated_listen_port, int gateway_ports) +{ + return channel_setup_fwd_listener(SSH_CHANNEL_RPORT_LISTENER, + listen_address, listen_port, allocated_listen_port, + NULL, 0, gateway_ports); +} + +/* + * 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(const char *listen_host, u_short listen_port, + const char *host_to_connect, u_short port_to_connect) +{ + int type, success = 0, idx = -1; + + /* Send the forward request to the remote side. */ + if (compat20) { + packet_start(SSH2_MSG_GLOBAL_REQUEST); + packet_put_cstring("tcpip-forward"); + packet_put_char(1); /* boolean: want reply */ + packet_put_cstring(channel_rfwd_bind_host(listen_host)); + packet_put_int(listen_port); + packet_send(); + packet_write_wait(); + /* Assume that server accepts the request */ + success = 1; + } else { + packet_start(SSH_CMSG_PORT_FORWARD_REQUEST); + packet_put_int(listen_port); + packet_put_cstring(host_to_connect); + packet_put_int(port_to_connect); + 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); + } + } + if (success) { + /* Record that connection to this host/port is permitted. */ + permitted_opens = xrealloc(permitted_opens, + num_permitted_opens + 1, sizeof(*permitted_opens)); + idx = num_permitted_opens++; + permitted_opens[idx].host_to_connect = xstrdup(host_to_connect); + permitted_opens[idx].port_to_connect = port_to_connect; + permitted_opens[idx].listen_port = listen_port; + } + return (idx); +} + +/* + * Request cancellation of remote forwarding of connection host:port from + * local side. + */ +int +channel_request_rforward_cancel(const char *host, u_short port) +{ + int i; + + if (!compat20) + return -1; + + for (i = 0; i < num_permitted_opens; i++) { + if (permitted_opens[i].host_to_connect != NULL && + permitted_opens[i].listen_port == port) + 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; + xfree(permitted_opens[i].host_to_connect); + permitted_opens[i].host_to_connect = NULL; + + return 0; +} + +/* + * This is called after receiving CHANNEL_FORWARDING_REQUEST. This initates + * listening for the port, and sends back a success reply (or disconnect + * message if there was an error). + */ +int +channel_input_port_forward_request(int is_root, int gateway_ports) +{ + u_short port, host_port; + int success = 0; + char *hostname; + + /* Get arguments from the packet. */ + port = packet_get_int(); + hostname = packet_get_string(NULL); + host_port = packet_get_int(); + +#ifndef HAVE_CYGWIN + /* + * Check that an unprivileged user is not trying to forward a + * privileged port. + */ + if (port < IPPORT_RESERVED && !is_root) + packet_disconnect( + "Requested forwarding of port %d but user is not root.", + port); + if (host_port == 0) + packet_disconnect("Dynamic forwarding denied."); +#endif + + /* Initiate forwarding */ + success = channel_setup_local_fwd_listener(NULL, port, hostname, + host_port, gateway_ports); + + /* Free the argument string. */ + xfree(hostname); + + return (success ? 0 : -1); +} + +/* + * Permits opening to any host/port if permitted_opens[] is empty. This is + * usually called by the server, because the user could connect to any port + * anyway, and the server has no way to know but to trust the client anyway. + */ +void +channel_permit_all_opens(void) +{ + if (num_permitted_opens == 0) + all_opens_permitted = 1; +} + +void +channel_add_permitted_opens(char *host, int port) +{ + debug("allow port forwarding to host %s port %d", host, port); + + permitted_opens = xrealloc(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; + 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; + xfree(permitted_opens[idx].host_to_connect); + permitted_opens[idx].host_to_connect = 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 = xrealloc(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; + return ++num_adm_permitted_opens; +} + +void +channel_clear_permitted_opens(void) +{ + int i; + + for (i = 0; i < num_permitted_opens; i++) + if (permitted_opens[i].host_to_connect != NULL) + xfree(permitted_opens[i].host_to_connect); + if (num_permitted_opens > 0) { + xfree(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++) + if (permitted_adm_opens[i].host_to_connect != NULL) + xfree(permitted_adm_opens[i].host_to_connect); + if (num_adm_permitted_opens > 0) { + xfree(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(" %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; +} + +static int +port_match(u_short allowedport, u_short requestedport) +{ + if (allowedport == FWD_PERMIT_ANY_PORT || + allowedport == requestedport) + return 1; + return 0; +} + +/* Try to start non-blocking connect to next host in cctx list */ +static int +connect_next(struct channel_connect *cctx) +{ + int sock, saved_errno; + char ntop[NI_MAXHOST], strport[NI_MAXSERV]; + + for (; cctx->ai; cctx->ai = cctx->ai->ai_next) { + if (cctx->ai->ai_family != AF_INET && + cctx->ai->ai_family != AF_INET6) + continue; + 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; + } + 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 */ + } + debug("connect_next: host %.100s ([%.100s]:%s) " + "in progress, fd=%d", cctx->host, ntop, strport, sock); + cctx->ai = cctx->ai->ai_next; + set_nodelay(sock); + return sock; + } + return -1; +} + +static void +channel_connect_ctx_free(struct channel_connect *cctx) +{ + xfree(cctx->host); + if (cctx->aitop) + freeaddrinfo(cctx->aitop); + bzero(cctx, sizeof(*cctx)); + cctx->host = NULL; + cctx->ai = cctx->aitop = NULL; +} + +/* Return CONNECTING channel to remote host, port */ +static Channel * +connect_to(const char *host, u_short port, char *ctype, char *rname) +{ + struct addrinfo hints; + int gaierr; + int sock = -1; + char strport[NI_MAXSERV]; + struct channel_connect cctx; + Channel *c; + + memset(&cctx, 0, sizeof(cctx)); + memset(&hints, 0, sizeof(hints)); + hints.ai_family = IPv4or6; + hints.ai_socktype = SOCK_STREAM; + snprintf(strport, sizeof strport, "%d", port); + if ((gaierr = getaddrinfo(host, strport, &hints, &cctx.aitop)) != 0) { + error("connect_to %.100s: unknown host (%s)", host, + ssh_gai_strerror(gaierr)); + return NULL; + } + + cctx.host = xstrdup(host); + cctx.port = port; + cctx.ai = cctx.aitop; + + if ((sock = connect_next(&cctx)) == -1) { + error("connect to %.100s port %d failed: %s", + host, port, strerror(errno)); + channel_connect_ctx_free(&cctx); + return NULL; + } + c = channel_new(ctype, SSH_CHANNEL_CONNECTING, sock, sock, -1, + CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, rname, 1); + c->connect_ctx = cctx; + return c; +} + +Channel * +channel_connect_by_listen_address(u_short listen_port, char *ctype, char *rname) +{ + int i; + + for (i = 0; i < num_permitted_opens; i++) { + if (permitted_opens[i].host_to_connect != NULL && + port_match(permitted_opens[i].listen_port, listen_port)) { + 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; +} + +/* Check if connecting to that port is permitted and connect. */ +Channel * +channel_connect_to(const char *host, u_short port, char *ctype, char *rname) +{ + int i, permit, permit_adm = 1; + + permit = all_opens_permitted; + if (!permit) { + for (i = 0; i < num_permitted_opens; i++) + if (permitted_opens[i].host_to_connect != NULL && + port_match(permitted_opens[i].port_to_connect, port) && + strcmp(permitted_opens[i].host_to_connect, host) == 0) + permit = 1; + } + + if (num_adm_permitted_opens > 0) { + permit_adm = 0; + for (i = 0; i < num_adm_permitted_opens; i++) + if (permitted_adm_opens[i].host_to_connect != NULL && + port_match(permitted_adm_opens[i].port_to_connect, port) && + strcmp(permitted_adm_opens[i].host_to_connect, host) + == 0) + permit_adm = 1; + } + + if (!permit || !permit_adm) { + logit("Received request to connect to host %.100s port %d, " + "but the request was denied.", host, port); + return NULL; + } + return connect_to(host, port, ctype, rname); +} + +void +channel_send_window_changes(void) +{ + u_int i; + struct winsize ws; + + for (i = 0; i < channels_alloc; i++) { + if (channels[i] == NULL || !channels[i]->client_tty || + channels[i]->type != SSH_CHANNEL_OPEN) + continue; + if (ioctl(channels[i]->rfd, TIOCGWINSZ, &ws) < 0) + continue; + channel_request_start(i, "window-change", 0); + packet_put_int((u_int)ws.ws_col); + packet_put_int((u_int)ws.ws_row); + packet_put_int((u_int)ws.ws_xpixel); + packet_put_int((u_int)ws.ws_ypixel); + packet_send(); + } +} + +/* -- X11 forwarding */ + +/* + * Creates an internet domain socket for listening for X11 connections. + * Returns 0 and a suitable display number for the DISPLAY variable + * stored in display_numberp , or -1 if an error occurs. + */ +int +x11_create_display_inet(int x11_display_offset, int x11_use_localhost, + int single_connection, u_int *display_numberp, int **chanids) +{ + Channel *nc = NULL; + int display_number, sock; + u_short port; + struct addrinfo hints, *ai, *aitop; + char strport[NI_MAXSERV]; + int gaierr, n, num_socks = 0, socks[NUM_SOCKS]; + + if (chanids == NULL) + return -1; + + for (display_number = x11_display_offset; + display_number < MAX_DISPLAYS; + display_number++) { + port = 6000 + display_number; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = IPv4or6; + hints.ai_flags = x11_use_localhost ? 0: AI_PASSIVE; + hints.ai_socktype = SOCK_STREAM; + snprintf(strport, sizeof strport, "%d", port); + if ((gaierr = getaddrinfo(NULL, strport, &hints, &aitop)) != 0) { + error("getaddrinfo: %.100s", ssh_gai_strerror(gaierr)); + return -1; + } + for (ai = aitop; ai; ai = ai->ai_next) { + if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) + continue; + sock = socket(ai->ai_family, ai->ai_socktype, + ai->ai_protocol); + if (sock < 0) { + if ((errno != EINVAL) && (errno != EAFNOSUPPORT) +#ifdef EPFNOSUPPORT + && (errno != EPFNOSUPPORT) +#endif + ) { + error("socket: %.100s", strerror(errno)); + freeaddrinfo(aitop); + return -1; + } else { + debug("x11_create_display_inet: Socket family %d not supported", + ai->ai_family); + continue; + } + } + if (ai->ai_family == AF_INET6) + sock_set_v6only(sock); + if (x11_use_localhost) + channel_set_reuseaddr(sock); + if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) { + debug2("bind port %d: %.100s", port, strerror(errno)); + close(sock); + + for (n = 0; n < num_socks; n++) { + close(socks[n]); + } + num_socks = 0; + break; + } + socks[num_socks++] = sock; + if (num_socks == NUM_SOCKS) + break; + } + freeaddrinfo(aitop); + if (num_socks > 0) + break; + } + if (display_number >= MAX_DISPLAYS) { + error("Failed to allocate internet-domain X11 display socket."); + return -1; + } + /* Start listening for connections on the socket. */ + for (n = 0; n < num_socks; n++) { + sock = socks[n]; + if (listen(sock, SSH_LISTEN_BACKLOG) < 0) { + error("listen: %.100s", strerror(errno)); + close(sock); + return -1; + } + } + + /* Allocate a channel for each socket. */ + *chanids = xcalloc(num_socks + 1, sizeof(**chanids)); + for (n = 0; n < num_socks; n++) { + sock = socks[n]; + nc = channel_new("x11 listener", + SSH_CHANNEL_X11_LISTENER, sock, sock, -1, + CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, + 0, "X11 inet listener", 1); + nc->single_connection = single_connection; + (*chanids)[n] = nc->self; + } + (*chanids)[n] = -1; + + /* Return the display number for the DISPLAY environment variable. */ + *display_numberp = display_number; + return (0); +} + +static int +connect_local_xsocket_path(const char *pathname) +{ + int sock; + struct sockaddr_un addr; + + sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (sock < 0) + error("socket: %.100s", strerror(errno)); + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + strlcpy(addr.sun_path, pathname, sizeof addr.sun_path); + if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) + return sock; + close(sock); + error("connect %.100s: %.100s", addr.sun_path, strerror(errno)); + return -1; +} + +static int +connect_local_xsocket(u_int dnr) +{ + char buf[1024]; + snprintf(buf, sizeof buf, _PATH_UNIX_X, dnr); + return connect_local_xsocket_path(buf); +} + +int +x11_connect_display(void) +{ + u_int display_number; + const char *display; + char buf[1024], *cp; + struct addrinfo hints, *ai, *aitop; + char strport[NI_MAXSERV]; + int gaierr, sock = 0; + + /* Try to open a socket for the local X server. */ + display = getenv("DISPLAY"); + if (!display) { + error("DISPLAY not set."); + return -1; + } + /* + * Now we decode the value of the DISPLAY variable and make a + * connection to the real X server. + */ + + /* Check if the display is from launchd. */ +#ifdef __APPLE__ + if (strncmp(display, "/tmp/launch", 11) == 0) { + sock = connect_local_xsocket_path(display); + if (sock < 0) + return -1; + + /* OK, we now have a connection to the display. */ + return sock; + } +#endif + /* + * Check if it is a unix domain socket. Unix domain displays are in + * one of the following formats: unix:d[.s], :d[.s], ::d[.s] + */ + if (strncmp(display, "unix:", 5) == 0 || + display[0] == ':') { + /* Connect to the unix domain socket. */ + if (sscanf(strrchr(display, ':') + 1, "%u", &display_number) != 1) { + error("Could not parse display number from DISPLAY: %.100s", + display); + return -1; + } + /* Create a socket. */ + sock = connect_local_xsocket(display_number); + if (sock < 0) + return -1; + + /* OK, we now have a connection to the display. */ + return sock; + } + /* + * Connect to an inet socket. The DISPLAY value is supposedly + * hostname:d[.s], where hostname may also be numeric IP address. + */ + strlcpy(buf, display, sizeof(buf)); + cp = strchr(buf, ':'); + if (!cp) { + error("Could not find ':' in DISPLAY: %.100s", display); + return -1; + } + *cp = 0; + /* buf now contains the host name. But first we parse the display number. */ + if (sscanf(cp + 1, "%u", &display_number) != 1) { + error("Could not parse display number from DISPLAY: %.100s", + display); + return -1; + } + + /* Look up the host address */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = IPv4or6; + hints.ai_socktype = SOCK_STREAM; + snprintf(strport, sizeof strport, "%u", 6000 + display_number); + if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) { + error("%.100s: unknown host. (%s)", buf, + ssh_gai_strerror(gaierr)); + return -1; + } + for (ai = aitop; ai; ai = ai->ai_next) { + /* Create a socket. */ + sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if (sock < 0) { + debug2("socket: %.100s", strerror(errno)); + continue; + } + /* Connect it to the display. */ + if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) { + debug2("connect %.100s port %u: %.100s", buf, + 6000 + display_number, strerror(errno)); + close(sock); + continue; + } + /* Success */ + break; + } + freeaddrinfo(aitop); + if (!ai) { + error("connect %.100s port %u: %.100s", buf, 6000 + display_number, + strerror(errno)); + return -1; + } + set_nodelay(sock); + return sock; +} + +/* + * This is called when SSH_SMSG_X11_OPEN is received. The packet contains + * the remote channel number. We should do whatever we want, and respond + * with either SSH_MSG_OPEN_CONFIRMATION or SSH_MSG_OPEN_FAILURE. + */ + +/* ARGSUSED */ +void +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; + } + xfree(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(); +} + +/* dummy protocol handler that denies SSH-1 requests (agent/x11) */ +/* ARGSUSED */ +void +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(); +} + +/* + * Requests forwarding of X11 connections, generates fake authentication + * data, and enables authentication spoofing. + * This should be called in the client only. + */ +void +x11_request_forwarding_with_spoofing(int client_session_id, const char *disp, + const char *proto, const char *data, int want_reply) +{ + u_int data_len = (u_int) strlen(data) / 2; + u_int i, value; + char *new_data; + int screen_number; + const char *cp; + u_int32_t rnd = 0; + + if (x11_saved_display == NULL) + x11_saved_display = xstrdup(disp); + else if (strcmp(disp, x11_saved_display) != 0) { + error("x11_request_forwarding_with_spoofing: different " + "$DISPLAY already forwarded"); + return; + } + + cp = strchr(disp, ':'); + if (cp) + cp = strchr(cp, '.'); + if (cp) + screen_number = (u_int)strtonum(cp + 1, 0, 400, NULL); + else + screen_number = 0; + + if (x11_saved_proto == NULL) { + /* Save protocol name. */ + x11_saved_proto = xstrdup(proto); + /* + * Extract real authentication data and generate fake data + * of the same length. + */ + x11_saved_data = xmalloc(data_len); + x11_fake_data = xmalloc(data_len); + for (i = 0; i < data_len; i++) { + if (sscanf(data + 2 * i, "%2x", &value) != 1) + fatal("x11_request_forwarding: bad " + "authentication data: %.100s", data); + if (i % 4 == 0) + rnd = arc4random(); + x11_saved_data[i] = value; + x11_fake_data[i] = rnd & 0xff; + rnd >>= 8; + } + x11_saved_data_len = data_len; + x11_fake_data_len = data_len; + } + + /* Convert the fake data into hex. */ + new_data = tohex(x11_fake_data, data_len); + + /* Send the request packet. */ + if (compat20) { + channel_request_start(client_session_id, "x11-req", want_reply); + packet_put_char(0); /* XXX bool single connection */ + } else { + packet_start(SSH_CMSG_X11_REQUEST_FORWARDING); + } + packet_put_cstring(proto); + packet_put_cstring(new_data); + packet_put_int(screen_number); + packet_send(); + packet_write_wait(); + xfree(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(); +}
diff --git a/openssh-6.0p1/channels.h b/openssh-6.0p1/channels.h new file mode 100644 index 0000000..c1f01c4 --- /dev/null +++ b/openssh-6.0p1/channels.h
@@ -0,0 +1,303 @@ +/* $OpenBSD: channels.h,v 1.109 2011/09/23 07:45:05 markus Exp $ */ + +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ +/* + * 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_MAX_TYPE 17 + +#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 */ + int wfd_isatty; /* wfd is a tty */ + int client_tty; /* (client) TTY has been requested */ + int force_drain; /* force close on iEOF */ + 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 + * accidenly called if a FD gets reused */ + Buffer input; /* data read from socket, to be sent over + * encrypted connection */ + Buffer output; /* data received over encrypted connection for + * send on socket */ + Buffer extended; + char *path; + /* path for unix domain sockets, or host name for forwards */ + int listening_port; /* port being listened for forwards */ + char *listening_addr; /* addr being listened for forwards */ + int host_port; /* remote port to connect for forwards */ + char *remote_name; /* remote hostname */ + + u_int remote_window; + u_int remote_maxpacket; + u_int local_window; + u_int local_window_max; + u_int local_consumed; + u_int local_maxpacket; + int extended_usage; + int single_connection; + + char *ctype; /* type */ + + /* callback */ + channel_open_fn *open_confirm; + void *open_confirm_ctx; + channel_callback_fn *detach_user; + int detach_close; + struct channel_confirms status_confirms; + + /* filter */ + channel_infilter_fn *input_filter; + channel_outfilter_fn *output_filter; + void *filter_ctx; + channel_filter_cleanup_fn *filter_cleanup; + + /* keep boundaries */ + int datagram; + + /* non-blocking connect */ + struct channel_connect connect_ctx; + + /* multiplexing protocol hook, called for each packet received */ + mux_callback_fn *mux_rcb; + void *mux_ctx; + int mux_pause; +}; + +#define CHAN_EXTENDED_IGNORE 0 +#define CHAN_EXTENDED_READ 1 +#define CHAN_EXTENDED_WRITE 2 + +/* default window/packet sizes for tcp/x11-fwd-channel */ +#define CHAN_SES_PACKET_DEFAULT (32*1024) +#define CHAN_SES_WINDOW_DEFAULT (64*CHAN_SES_PACKET_DEFAULT) +#define CHAN_TCP_PACKET_DEFAULT (32*1024) +#define CHAN_TCP_WINDOW_DEFAULT (64*CHAN_TCP_PACKET_DEFAULT) +#define CHAN_X11_PACKET_DEFAULT (16*1024) +#define CHAN_X11_WINDOW_DEFAULT (4*CHAN_X11_PACKET_DEFAULT) + +/* possible input states */ +#define CHAN_INPUT_OPEN 0 +#define CHAN_INPUT_WAIT_DRAIN 1 +#define CHAN_INPUT_WAIT_OCLOSE 2 +#define CHAN_INPUT_CLOSED 3 + +/* possible output states */ +#define CHAN_OUTPUT_OPEN 0 +#define CHAN_OUTPUT_WAIT_DRAIN 1 +#define CHAN_OUTPUT_WAIT_IEOF 2 +#define CHAN_OUTPUT_CLOSED 3 + +#define CHAN_CLOSE_SENT 0x01 +#define CHAN_CLOSE_RCVD 0x02 +#define CHAN_EOF_SENT 0x04 +#define CHAN_EOF_RCVD 0x08 +#define CHAN_LOCAL 0x10 + +#define CHAN_RBUF 16*1024 + +/* check whether 'efd' is still in use */ +#define CHANNEL_EFD_INPUT_ACTIVE(c) \ + (compat20 && c->extended_usage == CHAN_EXTENDED_READ && \ + (c->efd != -1 || \ + buffer_len(&c->extended) > 0)) +#define CHANNEL_EFD_OUTPUT_ACTIVE(c) \ + (compat20 && c->extended_usage == CHAN_EXTENDED_WRITE && \ + c->efd != -1 && (!(c->flags & (CHAN_EOF_RCVD|CHAN_CLOSE_RCVD)) || \ + buffer_len(&c->extended) > 0)) + +/* channel management */ + +Channel *channel_by_id(int); +Channel *channel_lookup(int); +Channel *channel_new(char *, int, int, int, int, u_int, u_int, int, char *, int); +void channel_set_fds(int, int, int, int, int, int, int, u_int); +void channel_free(Channel *); +void channel_free_all(void); +void channel_stop_listening(void); + +void channel_send_open(int); +void channel_request_start(int, char *, int); +void channel_register_cleanup(int, channel_callback_fn *, int); +void channel_register_open_confirm(int, channel_open_fn *, void *); +void channel_register_filter(int, channel_infilter_fn *, + channel_outfilter_fn *, channel_filter_cleanup_fn *, void *); +void channel_register_status_confirm(int, channel_confirm_cb *, + channel_confirm_abandon_cb *, void *); +void channel_cancel_cleanup(int); +int channel_close_fd(int *); +void channel_send_window_changes(void); + +/* protocol handler */ + +void channel_input_close(int, u_int32_t, void *); +void channel_input_close_confirmation(int, u_int32_t, void *); +void channel_input_data(int, u_int32_t, void *); +void channel_input_extended_data(int, u_int32_t, void *); +void channel_input_ieof(int, u_int32_t, void *); +void channel_input_oclose(int, u_int32_t, void *); +void channel_input_open_confirmation(int, u_int32_t, void *); +void channel_input_open_failure(int, u_int32_t, void *); +void channel_input_port_open(int, u_int32_t, void *); +void channel_input_window_adjust(int, u_int32_t, void *); +void 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*, int); +void channel_after_select(fd_set *, fd_set *); +void channel_output_poll(void); + +int channel_not_very_much_buffered_data(void); +void channel_close_all(void); +int channel_still_open(void); +char *channel_open_message(void); +int channel_find_open(void); + +/* tcp forwarding */ +void channel_set_af(int af); +void channel_permit_all_opens(void); +void channel_add_permitted_opens(char *, int); +int channel_add_adm_permitted_opens(char *, int); +void channel_update_permitted_opens(int, int); +void channel_clear_permitted_opens(void); +void channel_clear_adm_permitted_opens(void); +void channel_print_adm_permitted_opens(void); +int channel_input_port_forward_request(int, int); +Channel *channel_connect_to(const char *, u_short, char *, char *); +Channel *channel_connect_stdio_fwd(const char*, u_short, int, int); +Channel *channel_connect_by_listen_address(u_short, char *, char *); +int channel_request_remote_forwarding(const char *, u_short, + const char *, u_short); +int channel_setup_local_fwd_listener(const char *, u_short, + const char *, u_short, int); +int channel_request_rforward_cancel(const char *host, u_short port); +int channel_setup_remote_fwd_listener(const char *, u_short, int *, int); +int channel_cancel_rport_listener(const char *, u_short); +int channel_cancel_lport_listener(const char *, u_short, int, int); +int permitopen_port(const char *); + +/* x11 forwarding */ + +int x11_connect_display(void); +int x11_create_display_inet(int, int, int, u_int *, int **); +void x11_input_open(int, u_int32_t, void *); +void x11_request_forwarding_with_spoofing(int, const char *, const char *, + const char *, int); +void deny_input_open(int, u_int32_t, void *); + +/* agent forwarding */ + +void auth_request_forwarding(void); + +/* channel close */ + +int chan_is_dead(Channel *, int); +void chan_mark_dead(Channel *); + +/* channel events */ + +void chan_rcvd_oclose(Channel *); +void chan_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
diff --git a/openssh-6.0p1/cipher-3des1.c b/openssh-6.0p1/cipher-3des1.c new file mode 100644 index 0000000..b7aa588 --- /dev/null +++ b/openssh-6.0p1/cipher-3des1.c
@@ -0,0 +1,183 @@ +/* $OpenBSD: cipher-3des1.c,v 1.7 2010/10/01 23:05:32 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. + */ + +#include "includes.h" + +#include <sys/types.h> + +#include <openssl/evp.h> + +#include <stdarg.h> +#include <string.h> + +#include "xmalloc.h" +#include "log.h" + +#include "openbsd-compat/openssl-compat.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); +void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); + +static int +ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv, + int enc) +{ + struct ssh1_3des_ctx *c; + u_char *k1, *k2, *k3; + + if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) { + c = xmalloc(sizeof(*c)); + EVP_CIPHER_CTX_set_app_data(ctx, c); + } + if (key == NULL) + return (1); + if (enc == -1) + enc = ctx->encrypt; + k1 = k2 = k3 = (u_char *) key; + k2 += 8; + if (EVP_CIPHER_CTX_key_length(ctx) >= 16+8) { + if (enc) + k3 += 16; + else + k1 += 16; + } + EVP_CIPHER_CTX_init(&c->k1); + EVP_CIPHER_CTX_init(&c->k2); + EVP_CIPHER_CTX_init(&c->k3); +#ifdef SSH_OLD_EVP + EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc); + EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc); + EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc); +#else + if (EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 || + EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 || + EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) { + memset(c, 0, sizeof(*c)); + xfree(c); + EVP_CIPHER_CTX_set_app_data(ctx, NULL); + return (0); + } +#endif + return (1); +} + +static int +ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, + LIBCRYPTO_EVP_INL_TYPE len) +{ + struct ssh1_3des_ctx *c; + + if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) { + error("ssh1_3des_cbc: no context"); + return (0); + } +#ifdef SSH_OLD_EVP + EVP_Cipher(&c->k1, dest, (u_char *)src, len); + EVP_Cipher(&c->k2, dest, dest, len); + EVP_Cipher(&c->k3, dest, dest, len); +#else + if (EVP_Cipher(&c->k1, dest, (u_char *)src, len) == 0 || + EVP_Cipher(&c->k2, dest, dest, len) == 0 || + EVP_Cipher(&c->k3, dest, dest, len) == 0) + return (0); +#endif + return (1); +} + +static int +ssh1_3des_cleanup(EVP_CIPHER_CTX *ctx) +{ + struct ssh1_3des_ctx *c; + + if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) { + EVP_CIPHER_CTX_cleanup(&c->k1); + EVP_CIPHER_CTX_cleanup(&c->k2); + EVP_CIPHER_CTX_cleanup(&c->k3); + memset(c, 0, sizeof(*c)); + xfree(c); + EVP_CIPHER_CTX_set_app_data(ctx, NULL); + } + return (1); +} + +void +ssh1_3des_iv(EVP_CIPHER_CTX *evp, int doset, u_char *iv, int len) +{ + struct ssh1_3des_ctx *c; + + if (len != 24) + fatal("%s: bad 3des iv length: %d", __func__, len); + if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL) + fatal("%s: no 3des context", __func__); + if (doset) { + debug3("%s: Installed 3DES IV", __func__); + memcpy(c->k1.iv, iv, 8); + memcpy(c->k2.iv, iv + 8, 8); + memcpy(c->k3.iv, iv + 16, 8); + } else { + debug3("%s: Copying 3DES IV", __func__); + memcpy(iv, c->k1.iv, 8); + memcpy(iv + 8, c->k2.iv, 8); + memcpy(iv + 16, c->k3.iv, 8); + } +} + +const EVP_CIPHER * +evp_ssh1_3des(void) +{ + static EVP_CIPHER ssh1_3des; + + memset(&ssh1_3des, 0, sizeof(EVP_CIPHER)); + ssh1_3des.nid = NID_undef; + ssh1_3des.block_size = 8; + ssh1_3des.iv_len = 0; + ssh1_3des.key_len = 16; + ssh1_3des.init = ssh1_3des_init; + ssh1_3des.cleanup = ssh1_3des_cleanup; + ssh1_3des.do_cipher = ssh1_3des_cbc; +#ifndef SSH_OLD_EVP + ssh1_3des.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH; +#endif + return (&ssh1_3des); +}
diff --git a/openssh-6.0p1/cipher-acss.c b/openssh-6.0p1/cipher-acss.c new file mode 100644 index 0000000..e755f92 --- /dev/null +++ b/openssh-6.0p1/cipher-acss.c
@@ -0,0 +1,86 @@ +/* + * Copyright (c) 2004 The OpenBSD project + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#include <openssl/evp.h> + +#include <string.h> + +#if !defined(EVP_CTRL_SET_ACSS_MODE) && (OPENSSL_VERSION_NUMBER >= 0x00907000L) + +#include "acss.h" +#include "openbsd-compat/openssl-compat.h" + +#define data(ctx) ((EVP_ACSS_KEY *)(ctx)->cipher_data) + +typedef struct { + ACSS_KEY ks; +} EVP_ACSS_KEY; + +#define EVP_CTRL_SET_ACSS_MODE 0xff06 +#define EVP_CTRL_SET_ACSS_SUBKEY 0xff07 + +static int +acss_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + acss_setkey(&data(ctx)->ks,key,enc,ACSS_DATA); + return 1; +} + +static int +acss_ciph(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, + LIBCRYPTO_EVP_INL_TYPE inl) +{ + acss(&data(ctx)->ks,inl,in,out); + return 1; +} + +static int +acss_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) +{ + switch(type) { + case EVP_CTRL_SET_ACSS_MODE: + data(ctx)->ks.mode = arg; + return 1; + case EVP_CTRL_SET_ACSS_SUBKEY: + acss_setsubkey(&data(ctx)->ks,(unsigned char *)ptr); + return 1; + default: + return -1; + } +} + +const EVP_CIPHER * +evp_acss(void) +{ + static EVP_CIPHER acss_cipher; + + memset(&acss_cipher, 0, sizeof(EVP_CIPHER)); + + acss_cipher.nid = NID_undef; + acss_cipher.block_size = 1; + acss_cipher.key_len = 5; + acss_cipher.init = acss_init_key; + acss_cipher.do_cipher = acss_ciph; + acss_cipher.ctx_size = sizeof(EVP_ACSS_KEY); + acss_cipher.ctrl = acss_ctrl; + + return (&acss_cipher); +} +#endif +
diff --git a/openssh-6.0p1/cipher-aes.c b/openssh-6.0p1/cipher-aes.c new file mode 100644 index 0000000..bfda6d2 --- /dev/null +++ b/openssh-6.0p1/cipher-aes.c
@@ -0,0 +1,164 @@ +/* + * Copyright (c) 2003 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +/* compatibility with old or broken OpenSSL versions */ +#include "openbsd-compat/openssl-compat.h" + +#ifdef USE_BUILTIN_RIJNDAEL +#include <sys/types.h> + +#include <openssl/evp.h> + +#include <stdarg.h> +#include <string.h> + +#include "rijndael.h" +#include "xmalloc.h" +#include "log.h" + +#define RIJNDAEL_BLOCKSIZE 16 +struct ssh_rijndael_ctx +{ + rijndael_ctx r_ctx; + u_char r_iv[RIJNDAEL_BLOCKSIZE]; +}; + +const EVP_CIPHER * evp_rijndael(void); +void ssh_rijndael_iv(EVP_CIPHER_CTX *, int, u_char *, u_int); + +static int +ssh_rijndael_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv, + int enc) +{ + struct ssh_rijndael_ctx *c; + + if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) { + c = xmalloc(sizeof(*c)); + EVP_CIPHER_CTX_set_app_data(ctx, c); + } + if (key != NULL) { + if (enc == -1) + enc = ctx->encrypt; + rijndael_set_key(&c->r_ctx, (u_char *)key, + 8*EVP_CIPHER_CTX_key_length(ctx), enc); + } + if (iv != NULL) + memcpy(c->r_iv, iv, RIJNDAEL_BLOCKSIZE); + return (1); +} + +static int +ssh_rijndael_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, + 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)); + xfree(c); + EVP_CIPHER_CTX_set_app_data(ctx, NULL); + } + return (1); +} + +void +ssh_rijndael_iv(EVP_CIPHER_CTX *evp, int doset, u_char * iv, u_int len) +{ + struct ssh_rijndael_ctx *c; + + if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL) + fatal("ssh_rijndael_iv: no context"); + if (doset) + memcpy(c->r_iv, iv, len); + else + memcpy(iv, c->r_iv, len); +} + +const EVP_CIPHER * +evp_rijndael(void) +{ + static EVP_CIPHER rijndal_cbc; + + memset(&rijndal_cbc, 0, sizeof(EVP_CIPHER)); + rijndal_cbc.nid = NID_undef; + rijndal_cbc.block_size = RIJNDAEL_BLOCKSIZE; + rijndal_cbc.iv_len = RIJNDAEL_BLOCKSIZE; + rijndal_cbc.key_len = 16; + rijndal_cbc.init = ssh_rijndael_init; + rijndal_cbc.cleanup = ssh_rijndael_cleanup; + rijndal_cbc.do_cipher = ssh_rijndael_cbc; +#ifndef SSH_OLD_EVP + rijndal_cbc.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | + EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV; +#endif + return (&rijndal_cbc); +} +#endif /* USE_BUILTIN_RIJNDAEL */
diff --git a/openssh-6.0p1/cipher-bf1.c b/openssh-6.0p1/cipher-bf1.c new file mode 100644 index 0000000..309509d --- /dev/null +++ b/openssh-6.0p1/cipher-bf1.c
@@ -0,0 +1,108 @@ +/* $OpenBSD: cipher-bf1.c,v 1.6 2010/10/01 23:05:32 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. + */ + +#include "includes.h" + +#include <sys/types.h> + +#include <openssl/evp.h> + +#include <stdarg.h> +#include <string.h> + +#include "xmalloc.h" +#include "log.h" + +#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); +}
diff --git a/openssh-6.0p1/cipher-ctr.c b/openssh-6.0p1/cipher-ctr.c new file mode 100644 index 0000000..04975b4 --- /dev/null +++ b/openssh-6.0p1/cipher-ctr.c
@@ -0,0 +1,146 @@ +/* $OpenBSD: cipher-ctr.c,v 1.11 2010/10/01 23:05:32 djm Exp $ */ +/* + * Copyright (c) 2003 Markus Friedl <markus@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include "includes.h" + +#include <sys/types.h> + +#include <stdarg.h> +#include <string.h> + +#include <openssl/evp.h> + +#include "xmalloc.h" +#include "log.h" + +/* compatibility with old or broken OpenSSL versions */ +#include "openbsd-compat/openssl-compat.h" + +#ifndef USE_BUILTIN_RIJNDAEL +#include <openssl/aes.h> +#endif + +const EVP_CIPHER *evp_aes_128_ctr(void); +void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, size_t); + +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)); + xfree(c); + EVP_CIPHER_CTX_set_app_data(ctx, NULL); + } + return (1); +} + +void +ssh_aes_ctr_iv(EVP_CIPHER_CTX *evp, int doset, u_char * iv, 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); +}
diff --git a/openssh-6.0p1/cipher.c b/openssh-6.0p1/cipher.c new file mode 100644 index 0000000..bb5c0ac --- /dev/null +++ b/openssh-6.0p1/cipher.c
@@ -0,0 +1,431 @@ +/* $OpenBSD: cipher.c,v 1.82 2009/01/26 09:58:15 markus Exp $ */ +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + * + * + * Copyright (c) 1999 Niels Provos. All rights reserved. + * Copyright (c) 1999, 2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#include <sys/types.h> + +#include <openssl/md5.h> + +#include <string.h> +#include <stdarg.h> + +#include "xmalloc.h" +#include "log.h" +#include "cipher.h" + +/* compatibility with old or broken OpenSSL versions */ +#include "openbsd-compat/openssl-compat.h" + +extern const EVP_CIPHER *evp_ssh1_bf(void); +extern const EVP_CIPHER *evp_ssh1_3des(void); +extern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); +extern const EVP_CIPHER *evp_aes_128_ctr(void); +extern void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, u_int); + +struct Cipher { + char *name; + int number; /* for ssh1 only */ + u_int block_size; + u_int key_len; + u_int discard_len; + u_int cbc_mode; + const EVP_CIPHER *(*evptype)(void); +} ciphers[] = { + { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, EVP_enc_null }, + { "des", SSH_CIPHER_DES, 8, 8, 0, 1, EVP_des_cbc }, + { "3des", SSH_CIPHER_3DES, 8, 16, 0, 1, evp_ssh1_3des }, + { "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, 0, 1, evp_ssh1_bf }, + + { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 1, EVP_des_ede3_cbc }, + { "blowfish-cbc", SSH_CIPHER_SSH2, 8, 16, 0, 1, EVP_bf_cbc }, + { "cast128-cbc", SSH_CIPHER_SSH2, 8, 16, 0, 1, EVP_cast5_cbc }, + { "arcfour", SSH_CIPHER_SSH2, 8, 16, 0, 0, EVP_rc4 }, + { "arcfour128", SSH_CIPHER_SSH2, 8, 16, 1536, 0, EVP_rc4 }, + { "arcfour256", SSH_CIPHER_SSH2, 8, 32, 1536, 0, EVP_rc4 }, + { "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, 0, 1, EVP_aes_128_cbc }, + { "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, 0, 1, EVP_aes_192_cbc }, + { "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, 0, 1, EVP_aes_256_cbc }, + { "rijndael-cbc@lysator.liu.se", + SSH_CIPHER_SSH2, 16, 32, 0, 1, EVP_aes_256_cbc }, + { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, evp_aes_128_ctr }, + { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, evp_aes_128_ctr }, + { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, evp_aes_128_ctr }, +#ifdef USE_CIPHER_ACSS + { "acss@openssh.org", SSH_CIPHER_SSH2, 16, 5, 0, 0, EVP_acss }, +#endif + { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, NULL } +}; + +/*--*/ + +u_int +cipher_blocksize(const Cipher *c) +{ + return (c->block_size); +} + +u_int +cipher_keylen(const Cipher *c) +{ + return (c->key_len); +} + +u_int +cipher_get_number(const Cipher *c) +{ + return (c->number); +} + +u_int +cipher_is_cbc(const Cipher *c) +{ + return (c->cbc_mode); +} + +u_int +cipher_mask_ssh1(int client) +{ + u_int mask = 0; + mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */ + mask |= 1 << SSH_CIPHER_BLOWFISH; + if (client) { + mask |= 1 << SSH_CIPHER_DES; + } + return mask; +} + +Cipher * +cipher_by_name(const char *name) +{ + Cipher *c; + for (c = ciphers; c->name != NULL; c++) + if (strcmp(c->name, name) == 0) + return c; + return NULL; +} + +Cipher * +cipher_by_number(int id) +{ + Cipher *c; + for (c = ciphers; c->name != NULL; c++) + if (c->number == id) + return c; + return NULL; +} + +#define CIPHER_SEP "," +int +ciphers_valid(const char *names) +{ + Cipher *c; + char *cipher_list, *cp; + char *p; + + if (names == NULL || strcmp(names, "") == 0) + return 0; + cipher_list = cp = xstrdup(names); + for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0'; + (p = strsep(&cp, CIPHER_SEP))) { + c = cipher_by_name(p); + if (c == NULL || c->number != SSH_CIPHER_SSH2) { + debug("bad cipher %s [%s]", p, names); + xfree(cipher_list); + return 0; + } else { + debug3("cipher ok: %s [%s]", p, names); + } + } + debug3("ciphers ok: [%s]", names); + xfree(cipher_list); + return 1; +} + +/* + * Parses the name of the cipher. Returns the number of the corresponding + * cipher, or -1 on error. + */ + +int +cipher_number(const char *name) +{ + Cipher *c; + if (name == NULL) + return -1; + for (c = ciphers; c->name != NULL; c++) + if (strcasecmp(c->name, name) == 0) + return c->number; + return -1; +} + +char * +cipher_name(int id) +{ + Cipher *c = cipher_by_number(id); + return (c==NULL) ? "<unknown>" : c->name; +} + +void +cipher_init(CipherContext *cc, Cipher *cipher, + const u_char *key, u_int keylen, const u_char *iv, u_int ivlen, + int do_encrypt) +{ + static int dowarn = 1; +#ifdef SSH_OLD_EVP + EVP_CIPHER *type; +#else + const EVP_CIPHER *type; + int klen; +#endif + u_char *junk, *discard; + + if (cipher->number == SSH_CIPHER_DES) { + if (dowarn) { + error("Warning: use of DES is strongly discouraged " + "due to cryptographic weaknesses"); + dowarn = 0; + } + if (keylen > 8) + keylen = 8; + } + cc->plaintext = (cipher->number == SSH_CIPHER_NONE); + + if (keylen < cipher->key_len) + fatal("cipher_init: key length %d is insufficient for %s.", + keylen, cipher->name); + if (iv != NULL && ivlen < cipher->block_size) + fatal("cipher_init: iv length %d is insufficient for %s.", + ivlen, cipher->name); + cc->cipher = cipher; + + type = (*cipher->evptype)(); + + EVP_CIPHER_CTX_init(&cc->evp); +#ifdef SSH_OLD_EVP + if (type->key_len > 0 && type->key_len != keylen) { + debug("cipher_init: set keylen (%d -> %d)", + type->key_len, keylen); + type->key_len = keylen; + } + EVP_CipherInit(&cc->evp, type, (u_char *)key, (u_char *)iv, + (do_encrypt == CIPHER_ENCRYPT)); +#else + if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv, + (do_encrypt == CIPHER_ENCRYPT)) == 0) + fatal("cipher_init: EVP_CipherInit failed for %s", + cipher->name); + klen = EVP_CIPHER_CTX_key_length(&cc->evp); + if (klen > 0 && keylen != (u_int)klen) { + debug2("cipher_init: set keylen (%d -> %d)", klen, keylen); + if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0) + fatal("cipher_init: set keylen failed (%d -> %d)", + klen, keylen); + } + if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0) + fatal("cipher_init: EVP_CipherInit: set key failed for %s", + cipher->name); +#endif + + if (cipher->discard_len > 0) { + junk = xmalloc(cipher->discard_len); + discard = xmalloc(cipher->discard_len); + if (EVP_Cipher(&cc->evp, discard, junk, + cipher->discard_len) == 0) + fatal("evp_crypt: EVP_Cipher failed during discard"); + memset(discard, 0, cipher->discard_len); + xfree(junk); + xfree(discard); + } +} + +void +cipher_crypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) +{ + if (len % cc->cipher->block_size) + fatal("cipher_encrypt: bad plaintext length %d", len); + if (EVP_Cipher(&cc->evp, dest, (u_char *)src, len) == 0) + fatal("evp_crypt: EVP_Cipher failed"); +} + +void +cipher_cleanup(CipherContext *cc) +{ + if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0) + error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed"); +} + +/* + * Selects the cipher, and keys if by computing the MD5 checksum of the + * passphrase and using the resulting 16 bytes as the key. + */ + +void +cipher_set_key_string(CipherContext *cc, Cipher *cipher, + const char *passphrase, int do_encrypt) +{ + MD5_CTX md; + u_char digest[16]; + + MD5_Init(&md); + MD5_Update(&md, (const u_char *)passphrase, strlen(passphrase)); + MD5_Final(digest, &md); + + cipher_init(cc, cipher, digest, 16, NULL, 0, do_encrypt); + + memset(digest, 0, sizeof(digest)); + memset(&md, 0, sizeof(md)); +} + +/* + * Exports an IV from the CipherContext required to export the key + * state back from the unprivileged child to the privileged parent + * process. + */ + +int +cipher_get_keyiv_len(const CipherContext *cc) +{ + Cipher *c = cc->cipher; + int ivlen; + + if (c->number == SSH_CIPHER_3DES) + ivlen = 24; + else + ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp); + return (ivlen); +} + +void +cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len) +{ + Cipher *c = cc->cipher; + int evplen; + + switch (c->number) { + case SSH_CIPHER_SSH2: + case SSH_CIPHER_DES: + case SSH_CIPHER_BLOWFISH: + evplen = EVP_CIPHER_CTX_iv_length(&cc->evp); + if (evplen <= 0) + return; + if ((u_int)evplen != len) + fatal("%s: wrong iv length %d != %d", __func__, + evplen, len); +#ifdef USE_BUILTIN_RIJNDAEL + if (c->evptype == evp_rijndael) + ssh_rijndael_iv(&cc->evp, 0, iv, len); + else +#endif + if (c->evptype == evp_aes_128_ctr) + ssh_aes_ctr_iv(&cc->evp, 0, iv, len); + else + memcpy(iv, cc->evp.iv, len); + break; + case SSH_CIPHER_3DES: + ssh1_3des_iv(&cc->evp, 0, iv, 24); + break; + default: + fatal("%s: bad cipher %d", __func__, c->number); + } +} + +void +cipher_set_keyiv(CipherContext *cc, u_char *iv) +{ + Cipher *c = cc->cipher; + int evplen = 0; + + switch (c->number) { + case SSH_CIPHER_SSH2: + case SSH_CIPHER_DES: + case SSH_CIPHER_BLOWFISH: + evplen = EVP_CIPHER_CTX_iv_length(&cc->evp); + if (evplen == 0) + return; +#ifdef USE_BUILTIN_RIJNDAEL + if (c->evptype == evp_rijndael) + ssh_rijndael_iv(&cc->evp, 1, iv, evplen); + else +#endif + if (c->evptype == evp_aes_128_ctr) + ssh_aes_ctr_iv(&cc->evp, 1, iv, evplen); + else + memcpy(cc->evp.iv, iv, evplen); + break; + case SSH_CIPHER_3DES: + ssh1_3des_iv(&cc->evp, 1, iv, 24); + break; + default: + fatal("%s: bad cipher %d", __func__, c->number); + } +} + +#if OPENSSL_VERSION_NUMBER < 0x00907000L +#define EVP_X_STATE(evp) &(evp).c +#define EVP_X_STATE_LEN(evp) sizeof((evp).c) +#else +#define EVP_X_STATE(evp) (evp).cipher_data +#define EVP_X_STATE_LEN(evp) (evp).cipher->ctx_size +#endif + +int +cipher_get_keycontext(const CipherContext *cc, u_char *dat) +{ + Cipher *c = cc->cipher; + int plen = 0; + + if (c->evptype == EVP_rc4 || c->evptype == EVP_acss) { + plen = EVP_X_STATE_LEN(cc->evp); + if (dat == NULL) + return (plen); + memcpy(dat, EVP_X_STATE(cc->evp), plen); + } + return (plen); +} + +void +cipher_set_keycontext(CipherContext *cc, u_char *dat) +{ + Cipher *c = cc->cipher; + int plen; + + if (c->evptype == EVP_rc4 || c->evptype == EVP_acss) { + plen = EVP_X_STATE_LEN(cc->evp); + memcpy(EVP_X_STATE(cc->evp), dat, plen); + } +}
diff --git a/openssh-6.0p1/cipher.h b/openssh-6.0p1/cipher.h new file mode 100644 index 0000000..3dd2270 --- /dev/null +++ b/openssh-6.0p1/cipher.h
@@ -0,0 +1,92 @@ +/* $OpenBSD: cipher.h,v 1.37 2009/01/26 09:58:15 markus Exp $ */ + +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + * + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef CIPHER_H +#define CIPHER_H + +#include <openssl/evp.h> +/* + * Cipher types for SSH-1. New types can be added, but old types should not + * be removed for compatibility. The maximum allowed value is 31. + */ +#define SSH_CIPHER_SSH2 -3 +#define SSH_CIPHER_INVALID -2 /* No valid cipher selected. */ +#define SSH_CIPHER_NOT_SET -1 /* None selected (invalid number). */ +#define SSH_CIPHER_NONE 0 /* no encryption */ +#define SSH_CIPHER_IDEA 1 /* IDEA CFB */ +#define SSH_CIPHER_DES 2 /* DES CBC */ +#define SSH_CIPHER_3DES 3 /* 3DES CBC */ +#define SSH_CIPHER_BROKEN_TSS 4 /* TRI's Simple Stream encryption CBC */ +#define SSH_CIPHER_BROKEN_RC4 5 /* Alleged RC4 */ +#define SSH_CIPHER_BLOWFISH 6 +#define SSH_CIPHER_RESERVED 7 +#define SSH_CIPHER_MAX 31 + +#define CIPHER_ENCRYPT 1 +#define CIPHER_DECRYPT 0 + +typedef struct Cipher Cipher; +typedef struct CipherContext CipherContext; + +struct Cipher; +struct CipherContext { + int plaintext; + EVP_CIPHER_CTX evp; + Cipher *cipher; +}; + +u_int cipher_mask_ssh1(int); +Cipher *cipher_by_name(const char *); +Cipher *cipher_by_number(int); +int cipher_number(const char *); +char *cipher_name(int); +int ciphers_valid(const char *); +void cipher_init(CipherContext *, Cipher *, const u_char *, u_int, + const u_char *, u_int, int); +void cipher_crypt(CipherContext *, u_char *, const u_char *, u_int); +void cipher_cleanup(CipherContext *); +void cipher_set_key_string(CipherContext *, Cipher *, const char *, int); +u_int cipher_blocksize(const Cipher *); +u_int cipher_keylen(const Cipher *); +u_int cipher_is_cbc(const Cipher *); + +u_int cipher_get_number(const Cipher *); +void cipher_get_keyiv(CipherContext *, u_char *, u_int); +void cipher_set_keyiv(CipherContext *, u_char *); +int cipher_get_keyiv_len(const CipherContext *); +int cipher_get_keycontext(const CipherContext *, u_char *); +void cipher_set_keycontext(CipherContext *, u_char *); +#endif /* CIPHER_H */
diff --git a/openssh-6.0p1/cleanup.c b/openssh-6.0p1/cleanup.c new file mode 100644 index 0000000..238f965 --- /dev/null +++ b/openssh-6.0p1/cleanup.c
@@ -0,0 +1,32 @@ +/* $OpenBSD: cleanup.c,v 1.5 2006/08/03 03:34:42 deraadt Exp $ */ +/* + * Copyright (c) 2003 Markus Friedl <markus@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#include <sys/types.h> + +#include <unistd.h> +#include <stdarg.h> + +#include "log.h" + +/* default implementation */ +void +cleanup_exit(int i) +{ + _exit(i); +}
diff --git a/openssh-6.0p1/clientloop.c b/openssh-6.0p1/clientloop.c new file mode 100644 index 0000000..f69a9b0 --- /dev/null +++ b/openssh-6.0p1/clientloop.c
@@ -0,0 +1,2207 @@ +/* $OpenBSD: clientloop.c,v 1.238 2012/01/18 21:46:43 dtucker Exp $ */ +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, 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 <sys/types.h> +#include <sys/ioctl.h> +#include <sys/param.h> +#ifdef HAVE_SYS_STAT_H +# include <sys/stat.h> +#endif +#ifdef HAVE_SYS_TIME_H +# include <sys/time.h> +#endif +#include <sys/socket.h> + +#include <ctype.h> +#include <errno.h> +#ifdef HAVE_PATHS_H +#include <paths.h> +#endif +#include <signal.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <termios.h> +#include <pwd.h> +#include <unistd.h> + +#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 "log.h" +#include "readconf.h" +#include "clientloop.h" +#include "sshconnect.h" +#include "authfd.h" +#include "atomicio.h" +#include "sshpty.h" +#include "misc.h" +#include "match.h" +#include "msg.h" +#include "roaming.h" + +/* import options */ +extern Options options; + +/* Flag indicating that stdin should be redirected from /dev/null. */ +extern int stdin_null_flag; + +/* Flag indicating that no shell has been requested */ +extern int no_shell_flag; + +/* Control socket */ +extern int muxserver_sock; /* XXX use mux_client_cleanup() instead */ + +/* + * Name of the host we are connecting to. This is the name given on the + * command line, or the HostName specified for the user-supplied name in a + * configuration file. + */ +extern char *host; + +/* + * Flag to indicate that we have received a window change signal which has + * not yet been processed. This will cause a message indicating the new + * window size to be sent to the server a little later. This is volatile + * because this is updated in a signal handler. + */ +static volatile sig_atomic_t received_window_change_signal = 0; +static volatile sig_atomic_t received_signal = 0; + +/* Flag indicating whether the user's terminal is in non-blocking mode. */ +static int in_non_blocking_mode = 0; + +/* Time when backgrounded control master using ControlPersist should exit */ +static time_t control_persist_exit_time = 0; + +/* Common data for the client loop code. */ +volatile sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */ +static int escape_char1; /* Escape character. (proto1 only) */ +static int escape_pending1; /* Last character was an escape (proto1 only) */ +static int last_was_cr; /* Last character was a newline. */ +static int exit_status; /* Used to store the command exit status. */ +static int stdin_eof; /* EOF has been encountered on stderr. */ +static Buffer stdin_buffer; /* Buffer for stdin data. */ +static Buffer stdout_buffer; /* Buffer for stdout data. */ +static Buffer stderr_buffer; /* Buffer for stderr data. */ +static u_int buffer_high; /* Soft max buffer size. */ +static int connection_in; /* Connection to server (input). */ +static int connection_out; /* Connection to server (output). */ +static int need_rekeying; /* Set to non-zero if rekeying is requested. */ +static int session_closed; /* In SSH2: login session closed. */ +static int x11_refuse_time; /* If >0, refuse x11 opens after this time. */ + +static void client_init_dispatch(void); +int session_ident = -1; + +int session_resumed = 0; + +/* 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); + +/*XXX*/ +extern Kex *xxx_kex; + +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 = time(NULL) + + (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; + + dlen = strlen(display); + for (i = 0; i < dlen; i++) { + if (!isalnum(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" +void +client_x11_get_proto(const char *display, const char *xauth_path, + u_int trusted, u_int timeout, char **_proto, char **_data) +{ + char cmd[1024]; + char line[512]; + char xdisplay[512]; + static char proto[512], data[512]; + FILE *f; + int got_data = 0, generated = 0, do_unlink = 0, i; + char *xauthdir, *xauthfile; + struct stat st; + u_int now; + + xauthdir = xauthfile = NULL; + *_proto = proto; + *_data = data; + proto[0] = data[0] = '\0'; + + if (xauth_path == NULL ||(stat(xauth_path, &st) == -1)) { + debug("No xauth program."); + } else if (!client_x11_display_valid(display)) { + logit("DISPLAY '%s' invalid, falling back to fake xauth data", + display); + } else { + if (display == NULL) { + debug("x11_get_proto: DISPLAY not set"); + return; + } + /* + * 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) { + snprintf(xdisplay, sizeof(xdisplay), "unix:%s", + display + 10); + display = xdisplay; + } + if (trusted == 0) { + xauthdir = xmalloc(MAXPATHLEN); + xauthfile = xmalloc(MAXPATHLEN); + mktemp_proto(xauthdir, MAXPATHLEN); + if (mkdtemp(xauthdir) != NULL) { + do_unlink = 1; + snprintf(xauthfile, MAXPATHLEN, "%s/xauthfile", + xauthdir); + snprintf(cmd, sizeof(cmd), + "%s -f %s generate %s " SSH_X11_PROTO + " untrusted timeout %u 2>" _PATH_DEVNULL, + xauth_path, xauthfile, display, timeout); + debug2("x11_get_proto: %s", cmd); + if (system(cmd) == 0) + generated = 1; + if (x11_refuse_time == 0) { + now = time(NULL) + 1; + if (UINT_MAX - timeout < now) + x11_refuse_time = UINT_MAX; + else + x11_refuse_time = now + timeout; + } + } + } + + /* + * 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); + } else + error("Warning: untrusted X11 forwarding setup failed: " + "xauth key data not generated"); + } + + if (do_unlink) { + unlink(xauthfile); + rmdir(xauthdir); + } + if (xauthdir) + xfree(xauthdir); + if (xauthfile) + xfree(xauthfile); + + /* + * If we didn't get authentication data, just make up some + * data. The forwarding code will check the validity of the + * response anyway, and substitute this data. The X11 + * server, however, will ignore this fake data and use + * whatever authentication mechanisms it was using otherwise + * for the local connection. + */ + if (!got_data) { + u_int32_t rnd = 0; + + logit("Warning: No xauth data; " + "using fake authentication data for X11 forwarding."); + strlcpy(proto, SSH_X11_PROTO, sizeof proto); + for (i = 0; i < 16; i++) { + if (i % 4 == 0) + rnd = arc4random(); + snprintf(data + 2 * i, sizeof data - 2 * i, "%02x", + rnd & 0xff); + rnd >>= 8; + } + } +} + +/* + * 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 void +client_global_request_reply(int type, u_int32_t seq, void *ctxt) +{ + struct global_confirm *gc; + + if ((gc = TAILQ_FIRST(&global_confirms)) == NULL) + return; + if (gc->cb != NULL) + gc->cb(type, seq, gc->ctx); + if (--gc->ref_count <= 0) { + TAILQ_REMOVE(&global_confirms, gc, entry); + bzero(gc, sizeof(*gc)); + xfree(gc); + } + + packet_set_alive_timeouts(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; + int ret; + + /* Add any selections by the channel mechanism. */ + channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, 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; + set_control_persist_exit_time(); + if (control_persist_exit_time > 0) { + timeout_secs = MIN(timeout_secs, + control_persist_exit_time - time(NULL)); + if (timeout_secs < 0) + timeout_secs = 0; + } + 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) + 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, cont = 0; + 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 = roaming_read(connection_in, buf, sizeof(buf), &cont); + if (len == 0 && cont == 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); + } + } + xfree(cr); +} + +static void +client_abandon_status_confirm(Channel *c, void *ctx) +{ + xfree(ctx); +} + +void +client_expect_confirm(int id, const char *request, + enum confirm_action action) +{ + struct channel_reply_ctx *cr = xmalloc(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 = xmalloc(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, *cancel_host; + int delete = 0, local = 0, remote = 0, dynamic = 0; + int cancel_port, ok; + Forward fwd; + + bzero(&fwd, sizeof(fwd)); + fwd.listen_host = fwd.connect_host = NULL; + + 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(*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(*++s)) + ; + + /* XXX update list of forwards in options */ + if (delete) { + cancel_port = 0; + cancel_host = hpdelim(&s); /* may be NULL */ + if (s != NULL) { + cancel_port = a2port(s); + cancel_host = cleanhostname(cancel_host); + } else { + cancel_port = a2port(cancel_host); + cancel_host = NULL; + } + if (cancel_port <= 0) { + logit("Bad forwarding close port"); + goto out; + } + if (remote) + ok = channel_request_rforward_cancel(cancel_host, + cancel_port) == 0; + else if (dynamic) + ok = channel_cancel_lport_listener(cancel_host, + cancel_port, 0, options.gateway_ports) > 0; + else + ok = channel_cancel_lport_listener(cancel_host, + cancel_port, CHANNEL_CANCEL_PORT_STATIC, + options.gateway_ports) > 0; + if (!ok) { + logit("Unkown port forwarding."); + goto out; + } + logit("Canceled forwarding."); + } else { + if (!parse_forward(&fwd, s, dynamic, remote)) { + logit("Bad forwarding specification."); + goto out; + } + if (local || dynamic) { + if (channel_setup_local_fwd_listener(fwd.listen_host, + fwd.listen_port, fwd.connect_host, + fwd.connect_port, options.gateway_ports) < 0) { + logit("Port forwarding failed."); + goto out; + } + } else { + if (channel_request_remote_forwarding(fwd.listen_host, + fwd.listen_port, fwd.connect_host, + fwd.connect_port) < 0) { + logit("Port forwarding failed."); + goto out; + } + } + logit("Forwarding port."); + } + +out: + signal(SIGINT, handler); + enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE); + if (cmd) + xfree(cmd); + if (fwd.listen_host != NULL) + xfree(fwd.listen_host); + if (fwd.connect_host != NULL) + xfree(fwd.connect_host); +} + +/* + * 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); + return 0; + } else + quit_pending = 1; + return -1; + + case 'Z' - 64: + /* XXX support this for mux clients */ + if (c && c->ctl_chan != -1) { + noescape: + snprintf(string, sizeof string, + "%c%c escape not available to " + "multiplexed sessions\r\n", + escape_char, ch); + 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(session_ident, + "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 '&': + 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 '?': + if (c && c->ctl_chan != -1) { + snprintf(string, sizeof string, +"%c?\r\n\ +Supported escape sequences:\r\n\ + %c. - terminate session\r\n\ + %cB - send a BREAK to the remote system\r\n\ + %cR - Request rekey (SSH protocol 2 only)\r\n\ + %c# - list forwarded connections\r\n\ + %c? - this message\r\n\ + %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, + escape_char, escape_char, + escape_char, escape_char, + escape_char, escape_char); + } else { + snprintf(string, sizeof string, +"%c?\r\n\ +Supported escape sequences:\r\n\ + %c. - terminate connection (and any multiplexed sessions)\r\n\ + %cB - send a BREAK to the remote system\r\n\ + %cC - open a command line\r\n\ + %cR - Request rekey (SSH protocol 2 only)\r\n\ + %c^Z - suspend ssh\r\n\ + %c# - list forwarded connections\r\n\ + %c& - background ssh (when waiting for connections to terminate)\r\n\ + %c? - this message\r\n\ + %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, + escape_char, escape_char, + escape_char, escape_char, + escape_char, escape_char, + escape_char, escape_char, + escape_char); + } + buffer_append(berr, string, strlen(string)); + continue; + + 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)); + xfree(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, + compat20 ? xxx_kex : NULL); +} + +/* 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 = xmalloc(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) +{ + xfree(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 max_fd = 0, max_fd2 = 0, len, rekeying = 0; + u_int64_t ibytes, obytes; + u_int nalloc = 0; + char buf[100]; + + debug("Entering interactive session."); + + start_time = get_current_time(); + + /* Initialize variables. */ + escape_pending1 = 0; + last_was_cr = 1; + exit_status = -1; + stdin_eof = 0; + buffer_high = 64 * 1024; + connection_in = packet_get_connection_in(); + connection_out = packet_get_connection_out(); + max_fd = MAX(connection_in, connection_out); + + if (!compat20) { + /* enable nonblocking unless tty */ + if (!isatty(fileno(stdin))) + set_nonblock(fileno(stdin)); + if (!isatty(fileno(stdout))) + set_nonblock(fileno(stdout)); + if (!isatty(fileno(stderr))) + set_nonblock(fileno(stderr)); + max_fd = MAX(max_fd, fileno(stdin)); + max_fd = MAX(max_fd, fileno(stdout)); + max_fd = MAX(max_fd, fileno(stderr)); + } + quit_pending = 0; + escape_char1 = escape_char_arg; + + /* Initialize buffers. */ + buffer_init(&stdin_buffer); + buffer_init(&stdout_buffer); + buffer_init(&stderr_buffer); + + client_init_dispatch(); + + /* + * Set signal handlers, (e.g. to restore non-blocking mode) + * but don't overwrite SIG_IGN, matches behaviour from rsh(1) + */ + if (signal(SIGHUP, SIG_IGN) != SIG_IGN) + signal(SIGHUP, signal_handler); + if (signal(SIGINT, SIG_IGN) != SIG_IGN) + signal(SIGINT, signal_handler); + if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) + signal(SIGQUIT, signal_handler); + if (signal(SIGTERM, SIG_IGN) != SIG_IGN) + signal(SIGTERM, signal_handler); + signal(SIGWINCH, window_change_handler); + + if (have_pty) + enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE); + + if (compat20) { + session_ident = ssh2_chan_id; + if (session_ident != -1) { + if (escape_char_arg != SSH_ESCAPECHAR_NONE) { + channel_register_filter(session_ident, + client_simple_escape_filter, NULL, + client_filter_cleanup, + client_new_escape_filter_ctx( + escape_char_arg)); + } + channel_register_cleanup(session_ident, + client_channel_closed, 0); + } + } else { + /* Check if we should immediately send eof on stdin. */ + client_check_initial_eof_on_stdin(); + } + + /* Main loop of the client for the interactive session mode. */ + while (!quit_pending) { + + /* Process buffered packets sent by the server. */ + client_process_buffered_input_packets(); + + if (compat20 && session_closed && !channel_still_open()) + break; + + rekeying = (xxx_kex != NULL && !xxx_kex->done); + + if (rekeying) { + debug("rekeying in progress"); + } 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, rekeying); + + if (quit_pending) + break; + + /* Do channel operations unless rekeying in progress. */ + if (!rekeying) { + channel_after_select(readset, writeset); + if (need_rekeying || packet_need_rekeying()) { + debug("need rekeying"); + xxx_kex->done = 0; + kex_send_kexinit(xxx_kex); + need_rekeying = 0; + } + } + + /* 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); + } + + if (session_resumed) { + connection_in = packet_get_connection_in(); + connection_out = packet_get_connection_out(); + max_fd = MAX(max_fd, connection_out); + max_fd = MAX(max_fd, connection_in); + session_resumed = 0; + } + + /* + * 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 (time(NULL) >= control_persist_exit_time) { + debug("ControlPersist timeout expired"); + break; + } + } + } + if (readset) + xfree(readset); + if (writeset) + xfree(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. */ + memset(buf, 0, 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_state(MODE_IN, NULL, NULL, NULL, &ibytes); + packet_get_state(MODE_OUT, NULL, NULL, NULL, &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 void +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); + memset(data, 0, data_len); + xfree(data); +} +static void +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); + memset(data, 0, data_len); + xfree(data); +} +static void +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; +} +static void +client_input_agent_open(int type, u_int32_t seq, void *ctxt) +{ + Channel *c = NULL; + int 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). + */ + sock = ssh_get_authentication_socket(); + + /* + * 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(); +} + +static Channel * +client_request_forwarded_tcpip(const char *request_type, int rchan) +{ + Channel *c = NULL; + char *listen_address, *originator_address; + u_short listen_port, originator_port; + + /* Get rest of the packet */ + listen_address = packet_get_string(NULL); + listen_port = packet_get_int(); + originator_address = packet_get_string(NULL); + originator_port = packet_get_int(); + packet_check_eom(); + + debug("client_request_forwarded_tcpip: listen %s port %d, " + "originator %s port %d", listen_address, listen_port, + originator_address, originator_port); + + c = channel_connect_by_listen_address(listen_port, + "forwarded-tcpip", originator_address); + + xfree(originator_address); + xfree(listen_address); + 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 && time(NULL) >= 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); + xfree(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 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; + } + sock = ssh_get_authentication_socket(); + if (sock < 0) + 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 void +client_input_channel_open(int type, u_int32_t seq, void *ctxt) +{ + Channel *c = NULL; + char *ctype; + int rchan; + u_int rmaxpack, rwindow, len; + + ctype = packet_get_string(&len); + rchan = packet_get_int(); + rwindow = packet_get_int(); + rmaxpack = packet_get_int(); + + debug("client_input_channel_open: ctype %s rchan %d win %d max %d", + ctype, rchan, rwindow, rmaxpack); + + if (strcmp(ctype, "forwarded-tcpip") == 0) { + c = client_request_forwarded_tcpip(ctype, rchan); + } else if (strcmp(ctype, "x11") == 0) { + c = client_request_x11(ctype, rchan); + } else if (strcmp(ctype, "auth-agent@openssh.com") == 0) { + c = client_request_agent(ctype, rchan); + } +/* XXX duplicate : */ + if (c != NULL) { + debug("confirm %s", ctype); + c->remote_id = rchan; + c->remote_window = rwindow; + c->remote_maxpacket = rmaxpack; + if (c->type != SSH_CHANNEL_CONNECTING) { + packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION); + packet_put_int(c->remote_id); + packet_put_int(c->self); + packet_put_int(c->local_window); + packet_put_int(c->local_maxpacket); + packet_send(); + } + } else { + debug("failure %s", ctype); + packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); + packet_put_int(rchan); + packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED); + if (!(datafellows & SSH_BUG_OPENFAILURE)) { + packet_put_cstring("open failed"); + packet_put_cstring(""); + } + packet_send(); + } + xfree(ctype); +} +static void +client_input_channel_req(int type, u_int32_t seq, void *ctxt) +{ + Channel *c = NULL; + int exitval, id, reply, success = 0; + char *rtype; + + id = packet_get_int(); + rtype = packet_get_string(NULL); + reply = packet_get_char(); + + debug("client_input_channel_req: channel %d rtype %s reply %d", + id, rtype, reply); + + if (id == -1) { + error("client_input_channel_req: request for channel -1"); + } else if ((c = channel_lookup(id)) == NULL) { + error("client_input_channel_req: channel %d: " + "unknown channel", id); + } else if (strcmp(rtype, "eow@openssh.com") == 0) { + packet_check_eom(); + chan_rcvd_eow(c); + } else if (strcmp(rtype, "exit-status") == 0) { + exitval = packet_get_int(); + if (c->ctl_chan != -1) { + mux_exit_message(c, exitval); + success = 1; + } else if (id == session_ident) { + /* Record exit value of local session */ + success = 1; + exit_status = exitval; + } else { + /* Probably for a mux channel that has already closed */ + debug("%s: no sink for exit-status on channel %d", + __func__, id); + } + packet_check_eom(); + } + if (reply && c != NULL) { + packet_start(success ? + SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); + packet_put_int(c->remote_id); + packet_send(); + } + xfree(rtype); +} +static void +client_input_global_request(int type, u_int32_t seq, void *ctxt) +{ + char *rtype; + int want_reply; + int success = 0; + + rtype = packet_get_string(NULL); + want_reply = packet_get_char(); + debug("client_input_global_request: rtype %s want_reply %d", + rtype, want_reply); + if (want_reply) { + packet_start(success ? + SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE); + packet_send(); + packet_write_wait(); + } + xfree(rtype); +} + +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) { + xfree(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); + xfree(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(); + xfree(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, signal that we should close when all + * active channels are closed. + */ + if (options.control_persist) { + 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); +}
diff --git a/openssh-6.0p1/clientloop.h b/openssh-6.0p1/clientloop.h new file mode 100644 index 0000000..3bb7948 --- /dev/null +++ b/openssh-6.0p1/clientloop.h
@@ -0,0 +1,79 @@ +/* $OpenBSD: clientloop.h,v 1.29 2011/09/09 22:46:44 djm Exp $ */ + +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ +/* + * Copyright (c) 2001 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <termios.h> + +/* Client side main loop for the interactive session. */ +int client_loop(int, int, int); +void client_x11_get_proto(const char *, const char *, u_int, u_int, + char **, char **); +void client_global_request_reply_fwd(int, u_int32_t, void *); +void client_session2_setup(int, int, int, const char *, struct termios *, + int, Buffer *, char **); +int client_request_tun_fwd(int, int, int); +void client_stop_mux(void); + +/* Escape filter for protocol 2 sessions */ +void *client_new_escape_filter_ctx(int); +void client_filter_cleanup(int, void *); +int client_simple_escape_filter(Channel *, char *, int); + +/* Global request confirmation callbacks */ +typedef void global_confirm_cb(int, u_int32_t seq, void *); +void client_register_global_confirm(global_confirm_cb *, void *); + +/* Channel request confirmation callbacks */ +enum confirm_action { CONFIRM_WARN = 0, CONFIRM_CLOSE, CONFIRM_TTY }; +void client_expect_confirm(int, const char *, enum confirm_action); + +/* Multiplexing protocol version */ +#define SSHMUX_VER 4 + +/* Multiplexing control protocol flags */ +#define SSHMUX_COMMAND_OPEN 1 /* Open new connection */ +#define SSHMUX_COMMAND_ALIVE_CHECK 2 /* Check master is alive */ +#define SSHMUX_COMMAND_TERMINATE 3 /* Ask master to exit */ +#define SSHMUX_COMMAND_STDIO_FWD 4 /* Open stdio fwd (ssh -W) */ +#define SSHMUX_COMMAND_FORWARD 5 /* Forward only, no command */ +#define SSHMUX_COMMAND_STOP 6 /* Disable mux but not conn */ +#define SSHMUX_COMMAND_CANCEL_FWD 7 /* Cancel forwarding(s) */ + +void muxserver_listen(void); +void muxclient(const char *); +void mux_exit_message(Channel *, int); +void mux_tty_alloc_failed(Channel *); +
diff --git a/openssh-6.0p1/compat.c b/openssh-6.0p1/compat.c new file mode 100644 index 0000000..0dc089f --- /dev/null +++ b/openssh-6.0p1/compat.c
@@ -0,0 +1,238 @@ +/* $OpenBSD: compat.c,v 1.79 2011/09/23 07:45:05 markus Exp $ */ +/* + * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#include <sys/types.h> + +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> + +#include "xmalloc.h" +#include "buffer.h" +#include "packet.h" +#include "compat.h" +#include "log.h" +#include "match.h" + +int compat13 = 0; +int compat20 = 0; +int datafellows = 0; + +void +enable_compat20(void) +{ + debug("Enabling compatibility mode for protocol 2.0"); + compat20 = 1; +} +void +enable_compat13(void) +{ + debug("Enabling compatibility mode for protocol 1.3"); + compat13 = 1; +} +/* datafellows bug compatibility */ +void +compat_datafellows(const char *version) +{ + int i; + static struct { + char *pat; + int bugs; + } check[] = { + { "OpenSSH-2.0*," + "OpenSSH-2.1*," + "OpenSSH_2.1*," + "OpenSSH_2.2*", SSH_OLD_SESSIONID|SSH_BUG_BANNER| + SSH_OLD_DHGEX|SSH_BUG_NOREKEY| + SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR}, + { "OpenSSH_2.3.0*", SSH_BUG_BANNER|SSH_BUG_BIGENDIANAES| + SSH_OLD_DHGEX|SSH_BUG_NOREKEY| + SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR}, + { "OpenSSH_2.3.*", SSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX| + SSH_BUG_NOREKEY|SSH_BUG_EXTEOF| + SSH_OLD_FORWARD_ADDR}, + { "OpenSSH_2.5.0p1*," + "OpenSSH_2.5.1p1*", + SSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX| + SSH_BUG_NOREKEY|SSH_BUG_EXTEOF| + SSH_OLD_FORWARD_ADDR}, + { "OpenSSH_2.5.0*," + "OpenSSH_2.5.1*," + "OpenSSH_2.5.2*", SSH_OLD_DHGEX|SSH_BUG_NOREKEY| + SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR}, + { "OpenSSH_2.5.3*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF| + SSH_OLD_FORWARD_ADDR}, + { "OpenSSH_2.*," + "OpenSSH_3.0*," + "OpenSSH_3.1*", SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR}, + { "OpenSSH_3.*", SSH_OLD_FORWARD_ADDR }, + { "Sun_SSH_1.0*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF}, + { "OpenSSH_4*", 0 }, + { "OpenSSH_5*", SSH_NEW_OPENSSH|SSH_BUG_DYNAMIC_RPORT}, + { "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 }, + { "*SSH Compatible Server*", /* Netscreen */ + SSH_BUG_PASSWORDPAD }, + { "*OSU_0*," + "OSU_1.0*," + "OSU_1.1*," + "OSU_1.2*," + "OSU_1.3*," + "OSU_1.4*," + "OSU_1.5alpha1*," + "OSU_1.5alpha2*," + "OSU_1.5alpha3*", SSH_BUG_PASSWORDPAD }, + { "*SSH_Version_Mapper*", + SSH_BUG_SCANNER }, + { "Probe-*", + SSH_BUG_PROBE }, + { NULL, 0 } + }; + + /* process table, return first match */ + for (i = 0; check[i].pat; i++) { + if (match_pattern_list(version, check[i].pat, + strlen(check[i].pat), 0) == 1) { + debug("match: %s pat %s", version, check[i].pat); + datafellows = check[i].bugs; + return; + } + } + debug("no match: %s", version); +} + +#define SEP "," +int +proto_spec(const char *spec) +{ + char *s, *p, *q; + int ret = SSH_PROTO_UNKNOWN; + + if (spec == NULL) + return ret; + q = s = xstrdup(spec); + for ((p = strsep(&q, SEP)); p && *p != '\0'; (p = strsep(&q, SEP))) { + switch (atoi(p)) { + case 1: + if (ret == SSH_PROTO_UNKNOWN) + ret |= SSH_PROTO_1_PREFERRED; + ret |= SSH_PROTO_1; + break; + case 2: + ret |= SSH_PROTO_2; + break; + default: + logit("ignoring bad proto spec: '%s'.", p); + break; + } + } + xfree(s); + return ret; +} + +char * +compat_cipher_proposal(char *cipher_prop) +{ + Buffer b; + char *orig_prop, *fix_ciphers; + char *cp, *tmp; + + if (!(datafellows & SSH_BUG_BIGENDIANAES)) + return(cipher_prop); + + buffer_init(&b); + tmp = orig_prop = xstrdup(cipher_prop); + while ((cp = strsep(&tmp, ",")) != NULL) { + if (strncmp(cp, "aes", 3) != 0) { + if (buffer_len(&b) > 0) + buffer_append(&b, ",", 1); + buffer_append(&b, cp, strlen(cp)); + } + } + buffer_append(&b, "\0", 1); + fix_ciphers = xstrdup(buffer_ptr(&b)); + buffer_free(&b); + xfree(orig_prop); + debug2("Original cipher proposal: %s", cipher_prop); + debug2("Compat cipher proposal: %s", fix_ciphers); + if (!*fix_ciphers) + fatal("No available ciphers found."); + + return(fix_ciphers); +}
diff --git a/openssh-6.0p1/compat.h b/openssh-6.0p1/compat.h new file mode 100644 index 0000000..3ae5d9c --- /dev/null +++ b/openssh-6.0p1/compat.h
@@ -0,0 +1,72 @@ +/* $OpenBSD: compat.h,v 1.43 2011/09/23 07:45:05 markus 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 + +void enable_compat13(void); +void enable_compat20(void); +void compat_datafellows(const char *); +int proto_spec(const char *); +char *compat_cipher_proposal(char *); + +extern int compat13; +extern int compat20; +extern int datafellows; +#endif
diff --git a/openssh-6.0p1/compress.c b/openssh-6.0p1/compress.c new file mode 100644 index 0000000..24778e5 --- /dev/null +++ b/openssh-6.0p1/compress.c
@@ -0,0 +1,167 @@ +/* $OpenBSD: compress.c,v 1.26 2010/09/08 04:13:31 deraadt Exp $ */ +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * Interface to packet compression for ssh. + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ + +#include "includes.h" + +#include <sys/types.h> + +#include <stdarg.h> + +#include "log.h" +#include "buffer.h" +#include "compress.h" + +#include <zlib.h> + +z_stream incoming_stream; +z_stream outgoing_stream; +static int compress_init_send_called = 0; +static int compress_init_recv_called = 0; +static int inflate_failed = 0; +static int deflate_failed = 0; + +/* + * Initializes compression; level is compression level from 1 to 9 + * (as in gzip). + */ + +void +buffer_compress_init_send(int level) +{ + if (compress_init_send_called == 1) + deflateEnd(&outgoing_stream); + compress_init_send_called = 1; + debug("Enabling compression at level %d.", level); + if (level < 1 || level > 9) + fatal("Bad compression level %d.", level); + deflateInit(&outgoing_stream, level); +} +void +buffer_compress_init_recv(void) +{ + if (compress_init_recv_called == 1) + inflateEnd(&incoming_stream); + compress_init_recv_called = 1; + inflateInit(&incoming_stream); +} + +/* Frees any data structures allocated for compression. */ + +void +buffer_compress_uninit(void) +{ + debug("compress outgoing: raw data %llu, compressed %llu, factor %.2f", + (unsigned long long)outgoing_stream.total_in, + (unsigned long long)outgoing_stream.total_out, + outgoing_stream.total_in == 0 ? 0.0 : + (double) outgoing_stream.total_out / outgoing_stream.total_in); + debug("compress incoming: raw data %llu, compressed %llu, factor %.2f", + (unsigned long long)incoming_stream.total_out, + (unsigned long long)incoming_stream.total_in, + incoming_stream.total_out == 0 ? 0.0 : + (double) incoming_stream.total_in / incoming_stream.total_out); + if (compress_init_recv_called == 1 && inflate_failed == 0) + inflateEnd(&incoming_stream); + if (compress_init_send_called == 1 && deflate_failed == 0) + deflateEnd(&outgoing_stream); +} + +/* + * Compresses the contents of input_buffer into output_buffer. All packets + * compressed using this function will form a single compressed data stream; + * however, data will be flushed at the end of every call so that each + * output_buffer can be decompressed independently (but in the appropriate + * order since they together form a single compression stream) by the + * receiver. This appends the compressed data to the output buffer. + */ + +void +buffer_compress(Buffer * input_buffer, Buffer * output_buffer) +{ + u_char buf[4096]; + int status; + + /* This case is not handled below. */ + if (buffer_len(input_buffer) == 0) + return; + + /* Input is the contents of the input buffer. */ + outgoing_stream.next_in = buffer_ptr(input_buffer); + outgoing_stream.avail_in = buffer_len(input_buffer); + + /* Loop compressing until deflate() returns with avail_out != 0. */ + do { + /* Set up fixed-size output buffer. */ + outgoing_stream.next_out = buf; + outgoing_stream.avail_out = sizeof(buf); + + /* Compress as much data into the buffer as possible. */ + status = deflate(&outgoing_stream, Z_PARTIAL_FLUSH); + switch (status) { + case Z_OK: + /* Append compressed data to output_buffer. */ + buffer_append(output_buffer, buf, + sizeof(buf) - outgoing_stream.avail_out); + break; + default: + deflate_failed = 1; + fatal("buffer_compress: deflate returned %d", status); + /* NOTREACHED */ + } + } while (outgoing_stream.avail_out == 0); +} + +/* + * Uncompresses the contents of input_buffer into output_buffer. All packets + * uncompressed using this function will form a single compressed data + * stream; however, data will be flushed at the end of every call so that + * each output_buffer. This must be called for the same size units that the + * buffer_compress was called, and in the same order that buffers compressed + * with that. This appends the uncompressed data to the output buffer. + */ + +void +buffer_uncompress(Buffer * input_buffer, Buffer * output_buffer) +{ + u_char buf[4096]; + int status; + + incoming_stream.next_in = buffer_ptr(input_buffer); + incoming_stream.avail_in = buffer_len(input_buffer); + + for (;;) { + /* Set up fixed-size output buffer. */ + incoming_stream.next_out = buf; + incoming_stream.avail_out = sizeof(buf); + + status = inflate(&incoming_stream, Z_PARTIAL_FLUSH); + switch (status) { + case Z_OK: + buffer_append(output_buffer, buf, + sizeof(buf) - incoming_stream.avail_out); + break; + case Z_BUF_ERROR: + /* + * Comments in zlib.h say that we should keep calling + * inflate() until we get an error. This appears to + * be the error that we get. + */ + return; + default: + inflate_failed = 1; + fatal("buffer_uncompress: inflate returned %d", status); + /* NOTREACHED */ + } + } +}
diff --git a/openssh-6.0p1/compress.h b/openssh-6.0p1/compress.h new file mode 100644 index 0000000..418d6fd --- /dev/null +++ b/openssh-6.0p1/compress.h
@@ -0,0 +1,25 @@ +/* $OpenBSD: compress.h,v 1.12 2006/03/25 22:22:43 djm Exp $ */ + +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * Interface to packet compression for ssh. + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ + +#ifndef COMPRESS_H +#define COMPRESS_H + +void buffer_compress_init_send(int); +void buffer_compress_init_recv(void); +void buffer_compress_uninit(void); +void buffer_compress(Buffer *, Buffer *); +void buffer_uncompress(Buffer *, Buffer *); + +#endif /* COMPRESS_H */
diff --git a/openssh-6.0p1/config.guess b/openssh-6.0p1/config.guess new file mode 100755 index 0000000..78553c4 --- /dev/null +++ b/openssh-6.0p1/config.guess
@@ -0,0 +1,1511 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011 Free Software Foundation, Inc. + +timestamp='2011-01-23' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner. Please send patches (context +# diff format) to <config-patches@gnu.org> and include a ChangeLog +# entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to <config-patches@gnu.org>." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free +Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include <stdio.h> /* 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 <sys/systemcfg.h> + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include <stdlib.h> + #include <unistd.h> + + 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 <unistd.h> + 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:*:*) + case ${UNAME_MACHINE} in + pc98) + echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-gnu + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + LIBC=gnu + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo or32-unknown-linux-gnu + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-gnu + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-tilera-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` + echo ${UNAME_MACHINE}-pc-isc$UNAME_REL + elif /bin/uname -X 2>/dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says <Richard.M.Bartel@ccMail.Census.GOV> + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes <hewes@openmarket.com>. + # 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 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + i386) + eval $set_cc_for_build + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + UNAME_PROCESSOR="x86_64" + fi + fi ;; + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c <<EOF +#ifdef _SEQUENT_ +# include <sys/types.h> +# include <sys/utsname.h> +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include <sys/param.h> + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include <sys/param.h> +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 <<EOF +$0: unable to guess system type + +This script, last modified $timestamp, has failed to recognize +the operating system you are using. It is advised that you +download the most up to date version of the config scripts from + + http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +and + http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +If the version you run ($0) is already up to date, please +send the following data and any information you think might be +pertinent to <config-patches@gnu.org> in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End:
diff --git a/openssh-6.0p1/config.h.in b/openssh-6.0p1/config.h.in new file mode 100644 index 0000000..60d0c65 --- /dev/null +++ b/openssh-6.0p1/config.h.in
@@ -0,0 +1,1551 @@ +/* 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 + +/* Ultrix mmap can't map files */ +#undef BROKEN_MMAP + +/* Define if your struct dirent expects you to allocate extra space for d_name + */ +#undef BROKEN_ONE_BYTE_DIRENT_D_NAME + +/* Can't do comparisons on readv */ +#undef BROKEN_READV_COMPARISON + +/* Define if you have a broken realpath. */ +#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 + +/* 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_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 `bindresvport_sa' function. */ +#undef HAVE_BINDRESVPORT_SA + +/* 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 <bsm/audit.h> header file. */ +#undef HAVE_BSM_AUDIT_H + +/* Define to 1 if you have the <bstring.h> header file. */ +#undef HAVE_BSTRING_H + +/* Define to 1 if you have the `clock' function. */ +#undef HAVE_CLOCK + +/* 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 <crypto/sha2.h> header file. */ +#undef HAVE_CRYPTO_SHA2_H + +/* Define to 1 if you have the <crypt.h> 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 `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 `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 `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 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 <dirent.h> 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 <endian.h> header file. */ +#undef HAVE_ENDIAN_H + +/* Define to 1 if you have the `endutent' function. */ +#undef HAVE_ENDUTENT + +/* Define to 1 if you have the `endutxent' function. */ +#undef HAVE_ENDUTXENT + +/* Define if your system has /etc/default/login */ +#undef HAVE_ETC_DEFAULT_LOGIN + +/* Define 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 `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 <fcntl.h> header file. */ +#undef HAVE_FCNTL_H + +/* Define to 1 if you have the <features.h> header file. */ +#undef HAVE_FEATURES_H + +/* Define to 1 if you have the <floatingpoint.h> 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 `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 <getopt.h> 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 `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 <glob.h> 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 <gssapi_generic.h> header file. */ +#undef HAVE_GSSAPI_GENERIC_H + +/* Define to 1 if you have the <gssapi/gssapi_generic.h> header file. */ +#undef HAVE_GSSAPI_GSSAPI_GENERIC_H + +/* Define to 1 if you have the <gssapi/gssapi.h> header file. */ +#undef HAVE_GSSAPI_GSSAPI_H + +/* Define to 1 if you have the <gssapi/gssapi_krb5.h> header file. */ +#undef HAVE_GSSAPI_GSSAPI_KRB5_H + +/* Define to 1 if you have the <gssapi.h> header file. */ +#undef HAVE_GSSAPI_H + +/* Define to 1 if you have the <gssapi_krb5.h> 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 <iaf.h> header file. */ +#undef HAVE_IAF_H + +/* Define to 1 if you have the <ia.h> 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 you have the <inttypes.h> 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 <lastlog.h> header file. */ +#undef HAVE_LASTLOG_H + +/* Define if you want ldns support */ +#undef HAVE_LDNS + +/* Define to 1 if you have the <libaudit.h> 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 <libgen.h> 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 `nsl' library (-lnsl). */ +#undef HAVE_LIBNSL + +/* 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 <libutil.h> 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 <limits.h> header file. */ +#undef HAVE_LIMITS_H + +/* Define to 1 if you have the <linux/audit.h> header file. */ +#undef HAVE_LINUX_AUDIT_H + +/* Define to 1 if you have the <linux/filter.h> header file. */ +#undef HAVE_LINUX_FILTER_H + +/* Define to 1 if you have the <linux/if_tun.h> header file. */ +#undef HAVE_LINUX_IF_TUN_H + +/* Define to 1 if you have the <linux/seccomp.h> header file. */ +#undef HAVE_LINUX_SECCOMP_H + +/* Define to 1 if you have the `login' function. */ +#undef HAVE_LOGIN + +/* Define to 1 if you have the <login_cap.h> 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 <login.h> 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 <maillock.h> header file. */ +#undef HAVE_MAILLOCK_H + +/* 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 <memory.h> header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `mkdtemp' function. */ +#undef HAVE_MKDTEMP + +/* Define to 1 if you have the `mmap' function. */ +#undef HAVE_MMAP + +/* define if you have mode_t data type */ +#undef HAVE_MODE_T + +/* Some systems put nanosleep outside of libc */ +#undef HAVE_NANOSLEEP + +/* Define to 1 if you have the <ndir.h> header file. */ +#undef HAVE_NDIR_H + +/* Define to 1 if you have the <netdb.h> header file. */ +#undef HAVE_NETDB_H + +/* Define to 1 if you have the <netgroup.h> header file. */ +#undef HAVE_NETGROUP_H + +/* Define to 1 if you have the <net/if_tun.h> header file. */ +#undef HAVE_NET_IF_TUN_H + +/* Define if you are on NeXT */ +#undef HAVE_NEXT + +/* Define to 1 if you have the `ngetaddrinfo' function. */ +#undef HAVE_NGETADDRINFO + +/* Define to 1 if you have the `nsleep' function. */ +#undef HAVE_NSLEEP + +/* Define to 1 if you have the `ogetaddrinfo' function. */ +#undef HAVE_OGETADDRINFO + +/* Define if you have an old version of PAM which takes only one argument to + pam_strerror */ +#undef HAVE_OLD_PAM + +/* Define to 1 if you have the `openlog_r' function. */ +#undef HAVE_OPENLOG_R + +/* Define to 1 if you have the `openpty' function. */ +#undef HAVE_OPENPTY + +/* Define if your ssl headers are included with #include <openssl/header.h> */ +#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 <pam/pam_appl.h> 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 <paths.h> 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 `poll' function. */ +#undef HAVE_POLL + +/* Define to 1 if you have the <poll.h> header file. */ +#undef HAVE_POLL_H + +/* Define to 1 if you have the `prctl' function. */ +#undef HAVE_PRCTL + +/* 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 <pty.h> 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 if your password has a pw_change field */ +#undef HAVE_PW_CHANGE_IN_PASSWD + +/* Define if your password has a pw_class field */ +#undef HAVE_PW_CLASS_IN_PASSWD + +/* Define if your password has a pw_expire field */ +#undef HAVE_PW_EXPIRE_IN_PASSWD + +/* Define to 1 if you have the `readpassphrase' function. */ +#undef HAVE_READPASSPHRASE + +/* Define to 1 if you have the <readpassphrase.h> header file. */ +#undef HAVE_READPASSPHRASE_H + +/* 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 <rpc/types.h> 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 <sandbox.h> 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 if you have SecureWare-based protected password database */ +#undef HAVE_SECUREWARE + +/* Define to 1 if you have the <security/pam_appl.h> 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 `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 `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 <sha2.h> header file. */ +#undef HAVE_SHA2_H + +/* Define to 1 if you have the <shadow.h> 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 <stddef.h> header file. */ +#undef HAVE_STDDEF_H + +/* Define to 1 if you have the <stdint.h> header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the <stdlib.h> header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strdup' function. */ +#undef HAVE_STRDUP + +/* Define to 1 if you have the `strerror' function. */ +#undef HAVE_STRERROR + +/* Define to 1 if you have the `strftime' function. */ +#undef HAVE_STRFTIME + +/* Silly mkstemp() */ +#undef HAVE_STRICT_MKSTEMP + +/* Define to 1 if you have the <strings.h> header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the <string.h> 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 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 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 <sys/audit.h> header file. */ +#undef HAVE_SYS_AUDIT_H + +/* Define to 1 if you have the <sys/bitypes.h> header file. */ +#undef HAVE_SYS_BITYPES_H + +/* Define to 1 if you have the <sys/bsdtty.h> header file. */ +#undef HAVE_SYS_BSDTTY_H + +/* Define to 1 if you have the <sys/cdefs.h> header file. */ +#undef HAVE_SYS_CDEFS_H + +/* Define to 1 if you have the <sys/dir.h> 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 <sys/mman.h> header file. */ +#undef HAVE_SYS_MMAN_H + +/* Define to 1 if you have the <sys/mount.h> header file. */ +#undef HAVE_SYS_MOUNT_H + +/* Define to 1 if you have the <sys/ndir.h> 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 <sys/poll.h> header file. */ +#undef HAVE_SYS_POLL_H + +/* Define to 1 if you have the <sys/prctl.h> header file. */ +#undef HAVE_SYS_PRCTL_H + +/* Define to 1 if you have the <sys/pstat.h> header file. */ +#undef HAVE_SYS_PSTAT_H + +/* Define to 1 if you have the <sys/ptms.h> header file. */ +#undef HAVE_SYS_PTMS_H + +/* Define to 1 if you have the <sys/select.h> header file. */ +#undef HAVE_SYS_SELECT_H + +/* Define to 1 if you have the <sys/statvfs.h> header file. */ +#undef HAVE_SYS_STATVFS_H + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the <sys/stream.h> header file. */ +#undef HAVE_SYS_STREAM_H + +/* Define to 1 if you have the <sys/stropts.h> header file. */ +#undef HAVE_SYS_STROPTS_H + +/* Define to 1 if you have the <sys/strtio.h> 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 <sys/sysmacros.h> header file. */ +#undef HAVE_SYS_SYSMACROS_H + +/* Define to 1 if you have the <sys/timers.h> header file. */ +#undef HAVE_SYS_TIMERS_H + +/* Define to 1 if you have the <sys/time.h> header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the <sys/types.h> header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the <sys/un.h> 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 <time.h> 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 <tmpdir.h> 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 <ttyent.h> 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 <ucred.h> header file. */ +#undef HAVE_UCRED_H + +/* define if you have uintxx_t data type */ +#undef HAVE_UINTXX_T + +/* Define to 1 if you have the <unistd.h> 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 <usersec.h> 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 <util.h> 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 <utime.h> 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 <utmpx.h> header file. */ +#undef HAVE_UTMPX_H + +/* Define to 1 if you have the <utmp.h> 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 `vhangup' function. */ +#undef HAVE_VHANGUP + +/* Define to 1 if you have the <vis.h> header file. */ +#undef HAVE_VIS_H + +/* Define to 1 if you have the `vsnprintf' function. */ +#undef HAVE_VSNPRINTF + +/* Define to 1 if you have the `waitpid' function. */ +#undef HAVE_WAITPID + +/* Define to 1 if you have the `_getlong' function. */ +#undef HAVE__GETLONG + +/* Define to 1 if you have the `_getpty' function. */ +#undef HAVE__GETPTY + +/* Define to 1 if you have the `_getshort' function. */ +#undef HAVE__GETSHORT + +/* Define if you have struct __res_state _res as an extern */ +#undef HAVE__RES_EXTERN + +/* Define to 1 if you have the `__b64_ntop' function. */ +#undef HAVE___B64_NTOP + +/* Define to 1 if you have the `__b64_pton' function. */ +#undef HAVE___B64_PTON + +/* Define if compiler implements __FUNCTION__ */ +#undef HAVE___FUNCTION__ + +/* Define if libc defines __progname */ +#undef HAVE___PROGNAME + +/* Fields in struct sockaddr_storage */ +#undef HAVE___SS_FAMILY_IN_SS + +/* Define if __va_copy exists */ +#undef HAVE___VA_COPY + +/* Define if compiler implements __func__ */ +#undef HAVE___func__ + +/* Define this if you are using the Heimdal version of Kerberos V5 */ +#undef HEIMDAL + +/* Define if you need to use IP address instead of hostname in $DISPLAY */ +#undef IPADDR_IN_DISPLAY + +/* Detect IPv4 in IPv6 mapped addresses and treat as IPv4 */ +#undef IPV4_IN_IPV6 + +/* Define if your system choked on IP TOS setting */ +#undef IP_TOS_IS_BROKEN + +/* Define if you want Kerberos 5 support */ +#undef KRB5 + +/* Define if pututxline updates lastlog too */ +#undef LASTLOG_WRITE_PUTUTXLINE + +/* Define if you want TCP Wrappers support */ +#undef LIBWRAP + +/* Define to whatever link() returns for "not supported" if it doesn't return + EOPNOTSUPP. */ +#undef LINK_OPNOTSUPP_ERRNO + +/* Adjust Linux out-of-memory killer */ +#undef LINUX_OOM_ADJUST + +/* max value of long long calculated by configure */ +#undef LLONG_MAX + +/* min value of long long calculated by configure */ +#undef LLONG_MIN + +/* Account locked with pw(1) */ +#undef LOCKED_PASSWD_PREFIX + +/* String used in /etc/passwd to denote locked account */ +#undef LOCKED_PASSWD_STRING + +/* String used in /etc/passwd to denote locked account */ +#undef LOCKED_PASSWD_SUBSTR + +/* Some versions of /bin/login need the TERM supplied on the commandline */ +#undef LOGIN_NEEDS_TERM + +/* Some systems need a utmpx entry for /bin/login to work */ +#undef LOGIN_NEEDS_UTMPX + +/* Define if your login program cannot handle end of options ("--") */ +#undef LOGIN_NO_ENDOPT + +/* If your header files don't define LOGIN_PROGRAM, then use this (detected) + from environment and PATH */ +#undef LOGIN_PROGRAM_FALLBACK + +/* Set this to your mail directory if you do not have _PATH_MAILDIR */ +#undef MAIL_DIRECTORY + +/* Define on *nto-qnx systems */ +#undef MISSING_FD_MASK + +/* Define on *nto-qnx systems */ +#undef MISSING_HOWMANY + +/* Define on *nto-qnx systems */ +#undef MISSING_NFDBITS + +/* Need setpgrp to acquire controlling tty */ +#undef NEED_SETPGRP + +/* Define if the concept of ports only accessible to superusers isn't known */ +#undef NO_IPPORT_RESERVED_CONCEPT + +/* Define if you don't want to use lastlog in session.c */ +#undef NO_SSH_LASTLOG + +/* Define 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 + +/* libcrypto includes complete ECC support */ +#undef OPENSSL_HAS_ECC + +/* libcrypto is missing AES 192 and 256 bit functions */ +#undef OPENSSL_LOBOTOMISED_AES + +/* Define if you want OpenSSL's 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 + +/* 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 Darwin sandbox_init(3) */ +#undef SANDBOX_DARWIN + +/* no privsep sandboxing */ +#undef SANDBOX_NULL + +/* Sandbox using setrlimit(2) */ +#undef SANDBOX_RLIMIT + +/* Sandbox using seccomp filter */ +#undef SANDBOX_SECCOMP_FILTER + +/* Sandbox using systrace(4) */ +#undef SANDBOX_SYSTRACE + +/* Specify the system call convention in use */ +#undef SECCOMP_AUDIT_ARCH + +/* Define if your platform breaks doing a seteuid before a setuid */ +#undef SETEUID_BREAKS_SETUID + +/* The size of `int', as computed by sizeof. */ +#undef SIZEOF_INT + +/* The size of `long int', as computed by sizeof. */ +#undef SIZEOF_LONG_INT + +/* The size of `long long int', as computed by sizeof. */ +#undef SIZEOF_LONG_LONG_INT + +/* The size of `short int', as computed by sizeof. */ +#undef SIZEOF_SHORT_INT + +/* Define if you want S/Key support */ +#undef SKEY + +/* Define if your skeychallenge() function takes 4 arguments (NetBSD) */ +#undef SKEYCHALLENGE_4ARG + +/* Define as const if snprintf() can declare const char *fmt */ +#undef SNPRINTF_CONST + +/* Define to a Set Process Title type if your system is supported by + bsd-setproctitle.c */ +#undef SPT_TYPE + +/* Define if sshd somehow reacquires a controlling TTY after setsid() */ +#undef SSHD_ACQUIRES_CTTY + +/* Define if pam_chauthtok wants real uid set to the unpriv'ed user */ +#undef SSHPAM_CHAUTHTOK_NEEDS_RUID + +/* Use audit debugging module */ +#undef SSH_AUDIT_EVENTS + +/* Windows is sensitive to read buffer size */ +#undef SSH_IOBUFSZ + +/* non-privileged user for privilege separation */ +#undef SSH_PRIVSEP_USER + +/* Use tunnel device compatibility to OpenBSD */ +#undef SSH_TUN_COMPAT_AF + +/* Open tunnel devices the FreeBSD way */ +#undef SSH_TUN_FREEBSD + +/* Open tunnel devices the Linux tun/tap way */ +#undef SSH_TUN_LINUX + +/* No layer 2 tunnel support */ +#undef SSH_TUN_NO_L2 + +/* Open tunnel devices the OpenBSD way */ +#undef SSH_TUN_OPENBSD + +/* Prepend the address family to IP tunnel traffic */ +#undef SSH_TUN_PREPEND_AF + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define if you want a different $PATH for the superuser */ +#undef SUPERUSER_PATH + +/* syslog_r function is safe to use in in a signal handler */ +#undef SYSLOG_R_SAFE_IN_SIGHAND + +/* Support passwords > 8 chars */ +#undef UNIXWARE_LONG_PASSWORDS + +/* Specify default $PATH */ +#undef USER_PATH + +/* Define this if you want to use libkafs' AFS support */ +#undef USE_AFS + +/* Use BSM audit module */ +#undef USE_BSM_AUDIT + +/* Use btmp to log bad logins */ +#undef USE_BTMP + +/* Use libedit for sftp */ +#undef USE_LIBEDIT + +/* Use Linux audit module */ +#undef USE_LINUX_AUDIT + +/* Enable OpenSSL engine support */ +#undef USE_OPENSSL_ENGINE + +/* Define if you want to enable PAM support */ +#undef USE_PAM + +/* Use PIPES instead of a socketpair() */ +#undef USE_PIPES + +/* Define if you have Solaris 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 + +/* Define if you want SELinux support. */ +#undef WITH_SELINUX + +/* 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 + +/* 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
diff --git a/openssh-6.0p1/config.sub b/openssh-6.0p1/config.sub new file mode 100755 index 0000000..2d81696 --- /dev/null +++ b/openssh-6.0p1/config.sub
@@ -0,0 +1,1739 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011 Free Software Foundation, Inc. + +timestamp='2011-01-01' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to <config-patches@gnu.org>. Submit a context +# diff and a properly formatted GNU ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to <config-patches@gnu.org>." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 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-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + 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*) + 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 \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 \ + | ns16k | ns32k \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu | strongarm \ + | tahoe | thumb | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e \ + | we32k \ + | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12 | picochip) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-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-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | 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-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile-* | tilegx-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze) + basic_machine=microblaze-xilinx + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + 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) basic_machine=powerpc-unknown + ;; + ppc-*) 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) + 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 + ;; + 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 + ;; + # This must be matched before tile*. + tilegx*) + basic_machine=tilegx-unknown + os=-linux-gnu + ;; + tile*) + basic_machine=tile-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 + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + 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 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + 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:
diff --git a/openssh-6.0p1/configure b/openssh-6.0p1/configure new file mode 100755 index 0000000..035b6f0 --- /dev/null +++ b/openssh-6.0p1/configure
@@ -0,0 +1,17982 @@ +#! /bin/sh +# From configure.ac Revision: 1.489 . +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.68 for OpenSSH Portable. +# +# Report bugs to <openssh-unix-dev@mindrot.org>. +# +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 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 + +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" + 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 : + # 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 + export CONFIG_SHELL + 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+"$@"} +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_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; } + + # 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 -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +test -n "$DJDIR" || exec 7<&0 </dev/null +exec 6>&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 <stdio.h> +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#ifdef HAVE_SYS_STAT_H +# include <sys/stat.h> +#endif +#ifdef STDC_HEADERS +# include <stdlib.h> +# include <stddef.h> +#else +# ifdef HAVE_STDLIB_H +# include <stdlib.h> +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include <memory.h> +# endif +# include <string.h> +#endif +#ifdef HAVE_STRINGS_H +# include <strings.h> +#endif +#ifdef HAVE_INTTYPES_H +# include <inttypes.h> +#endif +#ifdef HAVE_STDINT_H +# include <stdint.h> +#endif +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif" + +ac_subst_vars='LTLIBOBJS +LIBOBJS +TEST_SSH_IPV6 +piddir +user_path +mansubdir +MANTYPE +XAUTH_PATH +STRIP_OPT +xauth_path +PRIVSEP_PATH +KRB5CONF +SSHDLIBS +SSHLIBS +SSH_PRIVSEP_USER +COMMENT_OUT_ECC +TEST_SSH_ECC +TEST_SSH_SHA256 +LIBEDIT +PKGCONFIG +LD +PATH_PASSWD_PROG +LOGIN_PROGRAM_FALLBACK +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 +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_stackprotect +with_rpath +with_cflags +with_cppflags +with_ldflags +with_libs +with_Werror +with_solaris_contracts +with_solaris_projects +with_osfsia +with_zlib +with_zlib_version_check +with_skey +with_tcp_wrappers +with_ldns +with_libedit +with_audit +with_ssl_dir +with_openssl_header_check +with_ssl_engine +with_prngd_port +with_prngd_socket +with_pam +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 + $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used" >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + 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-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-stackprotect Don't use compiler's stack protection + --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-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-tcp-wrappers[=PATH] Enable tcpwrappers 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-ssl-dir=PATH Specify path to OpenSSL installation + --without-openssl-header-check Disable OpenSSL version consistency check + --with-ssl-engine Enable OpenSSL (hardware) ENGINE support + --with-prngd-port=PORT read entropy from PRNGD/EGD TCP localhost:PORT + --with-prngd-socket=FILE read entropy from PRNGD/EGD socket FILE (default=/var/run/egd-pool) + --with-pam Enable PAM support + --with-privsep-user=user Specify non-privileged user for privilege separation + --with-sandbox=style Specify privilege separation sandbox (no, darwin, rlimit, systrace, seccomp_filter) + --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<lib dir> if you have libraries in a + nonstandard directory <lib dir> + LIBS libraries to pass to the linker, e.g. -l<library> + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if + you have headers in a nonstandard directory <include dir> + 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 <openssh-unix-dev@mindrot.org>. +_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.68 + +Copyright (C) 2010 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 || + $as_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 <limits.h> declares $2. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#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 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 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 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 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 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 <stdio.h> +#include <stdlib.h> +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 <conftest.val; ac_retval=0 +else + ac_retval=1 +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +rm -f conftest.val + + fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_compute_int + +# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES +# ---------------------------------------------------- +# Tries to find if the field MEMBER exists in type AGGR, after including +# INCLUDES, setting cache variable VAR accordingly. +ac_fn_c_check_member () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$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.68. 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + $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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $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 <stdio.h> +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 <stdarg.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +/* 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 <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> 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 <limits.h> +#else +# include <assert.h> +#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 <ac_nonexistent.h> +_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 <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> 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 <limits.h> +#else +# include <assert.h> +#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 <ac_nonexistent.h> +_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" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $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" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $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 <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <float.h> + +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 <string.h> + +_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 <stdlib.h> + +_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 <ctype.h> +#include <stdlib.h> +#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 <sys/types.h> + #include <sys/param.h> + +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 <sys/types.h> + #include <sys/param.h> + +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 <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <limits.h> + +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 <limits.h> + +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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + $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 <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> 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 <limits.h> +#else +# include <assert.h> +#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 <ac_nonexistent.h> +_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 <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> 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 <limits.h> +#else +# include <assert.h> +#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 <ac_nonexistent.h> +_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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $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 { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + 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" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $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" + + +# Extract the first word of "ar", so it can be a program name with args. +set dummy ar; 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_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $AR in + [\\/]* | ?:[\\/]*) + ac_cv_path_AR="$AR" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_AR="$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 +AR=$ac_cv_path_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 + + +# 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_CAT="$as_dir/$ac_word$ac_exec_ext" + $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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_KILL="$as_dir/$ac_word$ac_exec_ext" + $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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext" + $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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_SED="$as_dir/$ac_word$ac_exec_ext" + $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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_ENT="$as_dir/$ac_word$ac_exec_ext" + $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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_TEST_MINUS_S_SH="$as_dir/$ac_word$ac_exec_ext" + $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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_TEST_MINUS_S_SH="$as_dir/$ac_word$ac_exec_ext" + $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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_TEST_MINUS_S_SH="$as_dir/$ac_word$ac_exec_ext" + $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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_SH="$as_dir/$ac_word$ac_exec_ext" + $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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_GROFF="$as_dir/$ac_word$ac_exec_ext" + $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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_NROFF="$as_dir/$ac_word$ac_exec_ext" + $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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_MANDOC="$as_dir/$ac_word$ac_exec_ext" + $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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_PATH_GROUPADD_PROG="$as_dir/$ac_word$ac_exec_ext" + $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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_PATH_USERADD_PROG="$as_dir/$ac_word$ac_exec_ext" + $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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_MAKE_PACKAGE_SUPPORTED="yes" + $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 <sys/types.h> + /* 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 <sys/types.h> + /* 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 <sys/types.h> + /* 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 <sys/types.h> + /* 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 <sys/types.h> + /* 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 + +# Use LOGIN_PROGRAM from environment if possible +if test ! -z "$LOGIN_PROGRAM" ; then + +cat >>confdefs.h <<_ACEOF +#define LOGIN_PROGRAM_FALLBACK "$LOGIN_PROGRAM" +_ACEOF + +else + # Search for login + # Extract the first word of "login", so it can be a program name with args. +set dummy login; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_LOGIN_PROGRAM_FALLBACK+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $LOGIN_PROGRAM_FALLBACK in + [\\/]* | ?:[\\/]*) + ac_cv_path_LOGIN_PROGRAM_FALLBACK="$LOGIN_PROGRAM_FALLBACK" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_LOGIN_PROGRAM_FALLBACK="$as_dir/$ac_word$ac_exec_ext" + $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 +LOGIN_PROGRAM_FALLBACK=$ac_cv_path_LOGIN_PROGRAM_FALLBACK +if test -n "$LOGIN_PROGRAM_FALLBACK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LOGIN_PROGRAM_FALLBACK" >&5 +$as_echo "$LOGIN_PROGRAM_FALLBACK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test ! -z "$LOGIN_PROGRAM_FALLBACK" ; then + cat >>confdefs.h <<_ACEOF +#define LOGIN_PROGRAM_FALLBACK "$LOGIN_PROGRAM_FALLBACK" +_ACEOF + + fi +fi + +# Extract the first word of "passwd", so it can be a program name with args. +set dummy passwd; ac_word=$2 +{ $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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_PATH_PASSWD_PROG="$as_dir/$ac_word$ac_exec_ext" + $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 <limits.h> +" +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 <sys/types.h> + #include <sys/param.h> + #include <dev/systrace.h> + +" +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 <sys/types.h> + #include <sys/resource.h> + +" +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 <sys/types.h> + #include <linux/prctl.h> + +" +if test "x$ac_cv_have_decl_PR_SET_NO_NEW_PRIVS" = xyes; then : + have_linux_no_new_privs=1 +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 <sys/types.h> + #include <linux/seccomp.h> + +" +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; } +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 <errno.h> + #include <linux/seccomp.h> + #include <stdlib.h> + #include <sys/prctl.h> + +int +main () +{ + 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_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; } + # Disable seccomp filter as a target + have_seccomp_filter=0 + +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi + +use_stack_protector=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 + + + +if test "$GCC" = "yes" || test "$GCC" = "egcs"; then + { + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports -Wall" >&5 +$as_echo_n "checking if $CC supports -Wall... " >&6; } + saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Wall" + _define_flag="" + test "x$_define_flag" = "x" && _define_flag="-Wall" + 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; } + CFLAGS="$saved_CFLAGS $_define_flag" +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 -Wpointer-arith" >&5 +$as_echo_n "checking if $CC supports -Wpointer-arith... " >&6; } + saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Wpointer-arith" + _define_flag="" + test "x$_define_flag" = "x" && _define_flag="-Wpointer-arith" + 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; } + CFLAGS="$saved_CFLAGS $_define_flag" +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 -Wuninitialized" >&5 +$as_echo_n "checking if $CC supports -Wuninitialized... " >&6; } + saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Wuninitialized" + _define_flag="" + test "x$_define_flag" = "x" && _define_flag="-Wuninitialized" + 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; } + CFLAGS="$saved_CFLAGS $_define_flag" +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 -Wsign-compare" >&5 +$as_echo_n "checking if $CC supports -Wsign-compare... " >&6; } + saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Wsign-compare" + _define_flag="" + test "x$_define_flag" = "x" && _define_flag="-Wsign-compare" + 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; } + CFLAGS="$saved_CFLAGS $_define_flag" +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 -Wformat-security" >&5 +$as_echo_n "checking if $CC supports -Wformat-security... " >&6; } + saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Wformat-security" + _define_flag="" + test "x$_define_flag" = "x" && _define_flag="-Wformat-security" + 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; } + CFLAGS="$saved_CFLAGS $_define_flag" +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 -Wpointer-sign" >&5 +$as_echo_n "checking if $CC supports -Wpointer-sign... " >&6; } + saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -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. */ +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; } + CFLAGS="$saved_CFLAGS $_define_flag" +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 -Wunused-result" >&5 +$as_echo_n "checking if $CC supports -Wunused-result... " >&6; } + saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -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. */ +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; } + CFLAGS="$saved_CFLAGS $_define_flag" +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 -fno-strict-aliasing" >&5 +$as_echo_n "checking if $CC supports -fno-strict-aliasing... " >&6; } + saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -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. */ +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; } + CFLAGS="$saved_CFLAGS $_define_flag" +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 -D_FORTIFY_SOURCE=2" >&5 +$as_echo_n "checking if $CC supports -D_FORTIFY_SOURCE=2... " >&6; } + saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -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. */ +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; } + CFLAGS="$saved_CFLAGS $_define_flag" +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 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 <string.h> +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-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 <stdio.h> +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 <stdio.h> +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 <limits.h> + +" +if test "x$ac_cv_have_decl_LLONG_MAX" = xyes; then : + have_llong_max=1 +else + CFLAGS="$saved_CFLAGS" +fi + + fi +fi + +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 \ + bstring.h \ + crypt.h \ + crypto/sha2.h \ + dirent.h \ + endian.h \ + features.h \ + fcntl.h \ + floatingpoint.h \ + getopt.h \ + glob.h \ + ia.h \ + iaf.h \ + limits.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/cdefs.h \ + sys/dir.h \ + sys/mman.h \ + sys/ndir.h \ + sys/poll.h \ + sys/prctl.h \ + sys/pstat.h \ + sys/select.h \ + sys/stat.h \ + sys/stream.h \ + sys/stropts.h \ + sys/strtio.h \ + sys/statvfs.h \ + sys/sysmacros.h \ + sys/time.h \ + sys/timers.h \ + sys/un.h \ + time.h \ + tmpdir.h \ + ttyent.h \ + ucred.h \ + unistd.h \ + usersec.h \ + util.h \ + utime.h \ + utmp.h \ + utmpx.h \ + vis.h \ + +do : + as_ac_Header=`$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 <sys/time.h> +#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 <sys/stream.h> +#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 <sys/types.h> + +" +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 <sys/param.h> + +" +if test "x$ac_cv_header_sys_mount_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SYS_MOUNT_H 1 +_ACEOF + +fi + +done + + +# Messages for features tested for in target-specific section +SIA_MSG="no" +SPC_MSG="no" +SP_MSG="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 <usersec.h> +" +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 <usersec.h> +" +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 <usersec.h> +" +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 <usersec.h> +" +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 <usersec.h> +" +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 <usersec.h> + +" +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 <usersec.h> +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 <limits.h> + #include <fcntl.h> + +" +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 + + ;; +*-*-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 DISABLE_SHADOW 1" >>confdefs.h + + +$as_echo "#define NO_X11_UNIX_SOCKETS 1" >>confdefs.h + + +$as_echo "#define NO_IPPORT_RESERVED_CONCEPT 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 + + ;; +*-*-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*) + { $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 <mach-o/dyld.h> +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 <bsm/audit.h> + +$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 + + ;; +*-*-dragonfly*) + SSHDLIBS="$SSHDLIBS -lcrypt" + ;; +*-*-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_NO_ENDOPT 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 + + 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 + check_for_libcrypt_later=1 + check_for_openpty_ctty_bug=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 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_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_func in prctl +do : + ac_fn_c_check_func "$LINENO" "prctl" "ac_cv_func_prctl" +if test "x$ac_cv_func_prctl" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_PRCTL 1 +_ACEOF + +fi +done + + have_seccomp_audit_arch=1 + case "$host" in + x86_64-*) + +$as_echo "#define SECCOMP_AUDIT_ARCH AUDIT_ARCH_X86_64" >>confdefs.h + + ;; + i*86-*) + +$as_echo "#define SECCOMP_AUDIT_ARCH AUDIT_ARCH_I386" >>confdefs.h + + ;; + *) + have_seccomp_audit_arch=0 + ;; + esac + ;; +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 + +$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 + + ;; +*-*-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 + + ;; +*-*-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*) + +$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 + + ;; +*-*-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 LOGIN_NEEDS_TERM 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 + +# 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 + + SSHDLIBS="$SSHDLIBS -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 + + SSHDLIBS="$SSHDLIBS -lproject" + SP_MSG="yes" +fi + + +fi + + ;; +*-*-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 + + ;; +# 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 + + case "$host" in + *-*-sysv5SCO_SV*) # SCO OpenServer 6.x + maildir=/var/spool/mail + TEST_SHELL=/u95/bin/sh + +$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=ksh + ;; +*-*-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 MISSING_NFDBITS 1" >>confdefs.h + + +$as_echo "#define MISSING_HOWMANY 1" >>confdefs.h + + +$as_echo "#define MISSING_FD_MASK 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 BROKEN_MMAP 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 MISSING_HOWMANY 1" >>confdefs.h + + +$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 <stdio.h> +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" "yp_match" "ac_cv_func_yp_match" +if test "x$ac_cv_func_yp_match" = xyes; then : + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for yp_match in -lnsl" >&5 +$as_echo_n "checking for yp_match in -lnsl... " >&6; } +if ${ac_cv_lib_nsl_yp_match+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lnsl $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 yp_match (); +int +main () +{ +return yp_match (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_nsl_yp_match=yes +else + ac_cv_lib_nsl_yp_match=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_nsl_yp_match" >&5 +$as_echo "$ac_cv_lib_nsl_yp_match" >&6; } +if test "x$ac_cv_lib_nsl_yp_match" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBNSL 1 +_ACEOF + + LIBS="-lnsl $LIBS" + +fi + +fi + +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 <libgen.h> +#include <string.h> + +int main(int argc, char **argv) { + char *s, buf[32]; + + strncpy(buf,"/etc", 32); + s = dirname(buf); + if (!s || strncmp(s, "/", 32) != 0) { + exit(1); + } else { + exit(0); + } +} + +_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 <stdio.h> +#include <zlib.h> + +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 libutil.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "libutil.h" "ac_cv_header_libutil_h" "$ac_includes_default" +if test "x$ac_cv_header_libutil_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBUTIL_H 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 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 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 + + +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 <glob.h> + #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 <glob.h> +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 <glob.h> +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 <glob.h> +" +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 + + +{ $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 <sys/types.h> +#include <dirent.h> +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 <stdio.h> +#include <skey.h> + +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 <stdio.h> +#include <skey.h> + +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 TCP wrappers support +TCPW_MSG="no" + +# Check whether --with-tcp-wrappers was given. +if test "${with_tcp_wrappers+set}" = set; then : + withval=$with_tcp_wrappers; + if test "x$withval" != "xno" ; then + saved_LIBS="$LIBS" + saved_LDFLAGS="$LDFLAGS" + saved_CPPFLAGS="$CPPFLAGS" + if test -n "${withval}" && \ + 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 + LIBS="-lwrap $LIBS" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libwrap" >&5 +$as_echo_n "checking for libwrap... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <tcpd.h> +int deny_severity = 0, allow_severity = 0; + +int +main () +{ + + hosts_access(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 LIBWRAP 1" >>confdefs.h + + SSHDLIBS="$SSHDLIBS -lwrap" + TCPW_MSG="yes" + +else + + as_fn_error $? "*** libwrap missing" "$LINENO" 5 + + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS="$saved_LIBS" + fi + + +fi + + +# Check whether user wants to use ldns +LDNS_MSG="no" + +# Check whether --with-ldns was given. +if test "${with_ldns+set}" = set; then : + withval=$with_ldns; + if test "x$withval" != "xno" ; then + + if test "x$withval" != "xyes" ; then + CPPFLAGS="$CPPFLAGS -I${withval}/include" + LDFLAGS="$LDFLAGS -L${withval}/lib" + fi + + +$as_echo "#define HAVE_LDNS 1" >>confdefs.h + + LIBS="-lldns $LIBS" + 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 <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <ldns/ldns.h> +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 + # 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_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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_PKGCONFIG="$as_dir/$ac_word$ac_exec_ext" + $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_PKGCONFIG" && ac_cv_path_PKGCONFIG="no" + ;; +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 + + + 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-only-l 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 <histedit.h> +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 <time.h> +#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" -eq 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 + + +for ac_func in \ + arc4random \ + arc4random_buf \ + arc4random_uniform \ + asprintf \ + b64_ntop \ + __b64_ntop \ + b64_pton \ + __b64_pton \ + bcopy \ + bindresvport_sa \ + clock \ + closefrom \ + dirfd \ + fchmod \ + fchown \ + freeaddrinfo \ + fstatvfs \ + futimes \ + getaddrinfo \ + getcwd \ + getgrouplist \ + getnameinfo \ + getopt \ + getpeereid \ + getpeerucred \ + _getpty \ + getrlimit \ + getttyent \ + glob \ + group_from_gid \ + inet_aton \ + inet_ntoa \ + inet_ntop \ + innetgr \ + login_getcapbool \ + md5_crypt \ + memmove \ + mkdtemp \ + mmap \ + ngetaddrinfo \ + nsleep \ + ogetaddrinfo \ + openlog_r \ + poll \ + prctl \ + pstat \ + readpassphrase \ + realpath \ + recvmsg \ + rresvport_af \ + sendmsg \ + setdtablesize \ + setegid \ + setenv \ + seteuid \ + setgroupent \ + setgroups \ + setlogin \ + setpassent\ + setpcred \ + setproctitle \ + setregid \ + setreuid \ + setrlimit \ + setsid \ + setvbuf \ + sigaction \ + sigvec \ + snprintf \ + socketpair \ + statfs \ + statvfs \ + strdup \ + strerror \ + strlcat \ + strlcpy \ + strmode \ + strnlen \ + strnvis \ + strptime \ + strtonum \ + strtoll \ + strtoul \ + swap32 \ + sysconf \ + tcgetpgrp \ + timingsafe_bcmp \ + truncate \ + unsetenv \ + updwtmpx \ + user_from_uid \ + vasprintf \ + vhangup \ + vsnprintf \ + waitpid \ + +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 + + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + #include <ctype.h> +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 + +# 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 + + +# 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 <sys/types.h> +#include <sys/socket.h> +#include <netdb.h> + +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 + + +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 <string.h> +#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 <termios.h> + +" +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 <netdb.h> +" +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 <sys/types.h> +#include <sys/socket.h> + +" +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 <sys/types.h> +#ifdef HAVE_SYS_STAT_H +# include <sys/stat.h> +#endif +#ifdef HAVE_FCNTL_H +# include <fcntl.h> +#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 <sys/types.h> +#include <sys/uio.h> +#include <unistd.h> + +" +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 <sys/param.h> + +" +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 <stddef.h> + +" +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 + + +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 <stdlib.h> +#include <errno.h> + +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 <stdlib.h> +#include <errno.h> + +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 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 <stdio.h> +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 + +# If we don't have a working asprintf, then we strongly 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_asprintf" != "xyes" && \ + 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 <sys/types.h> +#include <stdio.h> +#include <stdarg.h> + +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]; + exit(x_snprintf(x, 1, "%s %d", "hello", 12345) == 11 ? 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; } + +$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 <stdio.h> +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 <sys/types.h> +#include <sys/socket.h> +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 <stdlib.h> + +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 <stdio.h> +#include <sys/fcntl.h> +#include <sys/types.h> +#include <sys/wait.h> + +int +main () +{ + + pid_t pid; + int fd, ptyfd, ttyfd, status; + + pid = fork(); + if (pid < 0) { /* failed */ + exit(1); + } else if (pid > 0) { /* parent */ + waitpid(pid, &status, 0); + if (WIFEXITED(status)) + exit(WEXITSTATUS(status)); + else + exit(2); + } else { /* child */ + close(0); close(1); close(2); + setsid(); + openpty(&ptyfd, &ttyfd, NULL, NULL, NULL); + fd = open("/dev/tty", O_RDWR | O_NOCTTY); + if (fd >= 0) + exit(3); /* Acquired ctty: broken */ + else + exit(0); /* Did not acquire ctty: OK */ + } + + ; + 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 <stdio.h> +#include <sys/socket.h> +#include <netdb.h> +#include <errno.h> +#include <netinet/in.h> + +#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 <stdio.h> +#include <sys/socket.h> +#include <netdb.h> +#include <errno.h> +#include <netinet/in.h> + +#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$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 <shadow.h> +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 + +{ $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$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 + +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 <stdio.h> +#include <string.h> +#include <openssl/opensslv.h> +#define DATA "conftest.sslincver" + +int +main () +{ + + FILE *fd; + int rc; + + fd = fopen(DATA,"w"); + if(fd == NULL) + exit(1); + + if ((rc = fprintf(fd ,"%x (%s)\n", 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 <stdio.h> +#include <string.h> +#include <openssl/opensslv.h> +#include <openssl/crypto.h> +#define DATA "conftest.ssllibver" + +int +main () +{ + + FILE *fd; + int rc; + + fd = fopen(DATA,"w"); + if(fd == NULL) + exit(1); + + if ((rc = fprintf(fd ,"%x (%s)\n", 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` + { $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 + + + +# 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 + + +# 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 <string.h> +#include <openssl/opensslv.h> + +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 <openssl/evp.h> +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 <openssl/evp.h> +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 RSA_generate_key_ex DSA_generate_parameters_ex BN_is_prime_ex RSA_get_default_method HMAC_CTX_init +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 + + + +# 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 + { $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 <openssl/engine.h> + +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 + +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 <string.h> +#include <openssl/evp.h> + +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 + +{ $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 <string.h> +#include <openssl/evp.h> + +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 + +# 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 + TEST_SSH_SHA256=yes +else + TEST_SSH_SHA256=no +fi +done + + + +# Check complete ECC support in OpenSSL +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL has complete ECC support" >&5 +$as_echo_n "checking whether OpenSSL has complete ECC support... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include <openssl/ec.h> +#include <openssl/ecdh.h> +#include <openssl/ecdsa.h> +#include <openssl/evp.h> +#include <openssl/objects.h> +#include <openssl/opensslv.h> +#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 "#define OPENSSL_HAS_ECC 1" >>confdefs.h + + TEST_SSH_ECC=yes + COMMENT_OUT_ECC="" + +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + TEST_SSH_ECC=no + COMMENT_OUT_ECC="#no ecc#" + + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + + +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 +{ $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 <string.h> +#include <openssl/rand.h> + +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 + + +# 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" +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 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 <stdlib.h> +#if defined(HAVE_SECURITY_PAM_APPL_H) +#include <security/pam_appl.h> +#elif defined (HAVE_PAM_PAM_APPL_H) +#include <pam/pam_appl.h> +#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 + +SSH_PRIVSEP_USER=sshd + +# 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 + + +cat >>confdefs.h <<_ACEOF +#define SSH_PRIVSEP_USER "$SSH_PRIVSEP_USER" +_ACEOF + + + +# 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 + +if 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_linux_audit_h" = "xyes" && \ + test "x$have_seccomp_audit_arch" = "x1" && \ + test "x$have_linux_no_new_privs" = "x1" && \ + test "x$ac_cv_func_prctl" = "xyes" ) ; then + test "x$have_seccomp_audit_arch" != "x1" && \ + 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" = "xrlimit" || \ + ( test -z "$sandbox_arg" && test "x$ac_cv_func_setrlimit" = "xyes" ) ; then + test "x$ac_cv_func_setrlimit" != "xyes" && \ + as_fn_error $? "rlimit sandbox requires setrlimit function" "$LINENO" 5 + SANDBOX_STYLE="rlimit" + +$as_echo "#define SANDBOX_RLIMIT 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 <stdio.h> +/* Why is this so damn hard? */ +#ifdef __GNUC__ +# undef __GNUC__ +#endif +#define __USE_ISOC99 +#include <limits.h> +#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 <sys/types.h> +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 <sys/types.h> +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 <stdint.h> +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 <sys/types.h> +#ifdef HAVE_STDINT_H +# include <stdint.h> +#endif +#include <sys/socket.h> +#ifdef HAVE_SYS_BITYPES_H +# include <sys/bitypes.h> +#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 <sys/types.h> +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 <sys/socket.h> +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 <sys/types.h> +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" ; 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 <sys/bitypes.h> +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 <sys/types.h> + +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" ; 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 <stdint.h> +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 <sys/bitypes.h> + +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 <sys/types.h> +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" "socklen_t" "ac_cv_type_socklen_t" "#include <sys/types.h> +#include <sys/socket.h> +" +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 <sys/types.h> + #include <sys/socket.h> + + 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 <signal.h> +" +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 <sys/types.h> +#ifdef HAVE_SYS_BITYPES_H +#include <sys/bitypes.h> +#endif +#ifdef HAVE_SYS_STATFS_H +#include <sys/statfs.h> +#endif +#ifdef HAVE_SYS_STATVFS_H +#include <sys/statvfs.h> +#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 <sys/types.h> +#ifdef HAVE_SYS_BITYPES_H +#include <sys/bitypes.h> +#endif +#ifdef HAVE_SYS_STATFS_H +#include <sys/statfs.h> +#endif +#ifdef HAVE_SYS_STATVFS_H +#include <sys/statvfs.h> +#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 <sys/types.h> +#include <netinet/in.h> +" +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 <sys/types.h> +#include <netinet/in.h> +" +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 <sys/types.h> +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 <sys/types.h> +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 <time.h> +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 <sys/types.h> +#include <sys/socket.h> + +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 <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> + +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 <sys/types.h> +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 <sys/types.h> +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 <sys/types.h> +#include <sys/socket.h> + +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 <sys/types.h> +#include <netinet/in.h> + +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 <sys/types.h> +#include <netinet/in.h> + +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 <sys/types.h> +#endif +#include <netinet/in.h> + +" +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 <sys/types.h> +#include <sys/socket.h> +#include <netdb.h> + +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 <sys/time.h> +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 <stdio.h> +#include <string.h> +#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 <utmp.h> + +_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 <utmpx.h> + +_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 <utmpx.h> + +_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 <utmp.h> + +_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 <utmp.h> + +_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 <utmpx.h> + +_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 <utmp.h> + +_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 <utmp.h> + +_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 <utmpx.h> + +_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 <utmp.h> + +_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 <utmpx.h> + +_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 <utmp.h> + +_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 <utmpx.h> + +_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 <utmp.h> + +_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 <utmp.h> + +_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 <utmpx.h> + +_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 <utmpx.h> + +_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 __res_state" "retrans" "ac_cv_member_struct___res_state_retrans" " +#include <stdio.h> +#if HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#include <netinet/in.h> +#include <arpa/nameser.h> +#include <resolv.h> + +" +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 <sys/types.h> +#include <sys/socket.h> + +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 <sys/types.h> +#include <sys/socket.h> + +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 pw_class field in struct passwd" >&5 +$as_echo_n "checking for pw_class field in struct passwd... " >&6; } +if ${ac_cv_have_pw_class_in_struct_passwd+:} false; then : + $as_echo_n "(cached) " >&6 +else + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + #include <pwd.h> +int +main () +{ + struct passwd p; p.pw_class = 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_have_pw_class_in_struct_passwd="yes" +else + ac_cv_have_pw_class_in_struct_passwd="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_pw_class_in_struct_passwd" >&5 +$as_echo "$ac_cv_have_pw_class_in_struct_passwd" >&6; } +if test "x$ac_cv_have_pw_class_in_struct_passwd" = "xyes" ; then + +$as_echo "#define HAVE_PW_CLASS_IN_PASSWD 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pw_expire field in struct passwd" >&5 +$as_echo_n "checking for pw_expire field in struct passwd... " >&6; } +if ${ac_cv_have_pw_expire_in_struct_passwd+:} false; then : + $as_echo_n "(cached) " >&6 +else + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + #include <pwd.h> +int +main () +{ + struct passwd p; p.pw_expire = 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_have_pw_expire_in_struct_passwd="yes" +else + ac_cv_have_pw_expire_in_struct_passwd="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_pw_expire_in_struct_passwd" >&5 +$as_echo "$ac_cv_have_pw_expire_in_struct_passwd" >&6; } +if test "x$ac_cv_have_pw_expire_in_struct_passwd" = "xyes" ; then + +$as_echo "#define HAVE_PW_EXPIRE_IN_PASSWD 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pw_change field in struct passwd" >&5 +$as_echo_n "checking for pw_change field in struct passwd... " >&6; } +if ${ac_cv_have_pw_change_in_struct_passwd+:} false; then : + $as_echo_n "(cached) " >&6 +else + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + #include <pwd.h> +int +main () +{ + struct passwd p; p.pw_change = 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_have_pw_change_in_struct_passwd="yes" +else + ac_cv_have_pw_change_in_struct_passwd="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_pw_change_in_struct_passwd" >&5 +$as_echo "$ac_cv_have_pw_change_in_struct_passwd" >&6; } +if test "x$ac_cv_have_pw_change_in_struct_passwd" = "xyes" ; then + +$as_echo "#define HAVE_PW_CHANGE_IN_PASSWD 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 <sys/types.h> +#include <sys/socket.h> +#include <sys/uio.h> + +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 <sys/types.h> +#include <sys/stat.h> +#ifdef HAVE_SYS_TIME_H +# include <sys/time.h> +#endif +#ifdef HAVE_SYS_MOUNT_H +#include <sys/mount.h> +#endif +#ifdef HAVE_SYS_STATVFS_H +#include <sys/statvfs.h> +#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 <sys/types.h> +#include <sys/statvfs.h> + +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 <sys/types.h> +#include <sys/statvfs.h> + +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 <sys/types.h> +#include <sys/socket.h> +#include <sys/uio.h> + +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 <stdio.h> +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 <stdio.h> +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 <stdarg.h> +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 <stdarg.h> +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 <getopt.h> +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 <sys/types.h> +#include <netinet/in.h> +#include <arpa/nameser.h> +#include <netdb.h> +#include <resolv.h> + +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 <sys/types.h> +#include <netinet/in.h> +#include <arpa/nameser.h> +#include <netdb.h> +#include <resolv.h> + +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 <sys/types.h> + #include <arpa/nameser.h> +" +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 <sys/types.h> + #include <arpa/nameser.h> +" +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 <arpa/nameser.h> +" +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 <stdio.h> +#if HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#include <netinet/in.h> +#include <arpa/nameser.h> +#include <resolv.h> +extern struct __res_state _res; + +int +main () +{ + + ; + 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" + + # 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_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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_KRB5CONF="$as_dir/$ac_word$ac_exec_ext" + $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_KRB5CONF" && ac_cv_path_KRB5CONF="$KRB5ROOT/bin/krb5-config" + ;; +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 + + + if test -x $KRB5CONF ; then + + { $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 + + k5confopts=gssapi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + k5confopts="" + fi + K5CFLAGS="`$KRB5CONF --cflags $k5confopts`" + K5LIBS="`$KRB5CONF --libs $k5confopts`" + CPPFLAGS="$CPPFLAGS $K5CFLAGS" + { $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 <krb5.h> + +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 <krb5.h> + +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 $K5LIBS $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 + + K5LIBS="-lgssapi_krb5 $K5LIBS" +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 $K5LIBS $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 + + K5LIBS="-lgssapi $K5LIBS" +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 + + + 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 + + + LIBS="$LIBS $K5LIBS" + { $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 + + 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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_xauth_path="$as_dir/$ac_word$ac_exec_ext" + $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 <stdio.h> +#include <string.h> +#ifdef HAVE_PATHS_H +#include <paths.h> +#endif +#ifdef HAVE_MAILLOCK_H +#include <maillock.h> +#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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_NROFF="$as_dir/$ac_word$ac_exec_ext" + $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 <sys/types.h> +#include <shadow.h> +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 <stdio.h> +#ifdef HAVE_PATHS_H +# include <paths.h> +#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 <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#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=`eval echo ${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 + 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 <sys/types.h> +#include <utmp.h> +#ifdef HAVE_LASTLOG_H +# include <lastlog.h> +#endif +#ifdef HAVE_PATHS_H +# include <paths.h> +#endif +#ifdef HAVE_LOGIN_H +# include <login.h> +#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 <sys/types.h> +#include <utmp.h> +#ifdef HAVE_LASTLOG_H +# include <lastlog.h> +#endif +#ifdef HAVE_PATHS_H +# include <paths.h> +#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 <sys/types.h> +#include <utmp.h> +#ifdef HAVE_PATHS_H +# include <paths.h> +#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 <sys/types.h> +#include <utmp.h> +#ifdef HAVE_PATHS_H +# include <paths.h> +#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 <sys/types.h> +#include <utmp.h> +#ifdef HAVE_UTMPX_H +#include <utmpx.h> +#endif +#ifdef HAVE_PATHS_H +# include <paths.h> +#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 + +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 + + + +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 -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +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 + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## 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.68. 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 <openssh-unix-dev@mindrot.org>." + +_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.68, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2010 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 2>/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 +' <conf$$subs.awk | sed ' +/^[^""]/{ + N + s/\n// +} +' >>$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 +' <confdefs.h | sed ' +s/'"$ac_delim"'/"\\\ +"/g' >>$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 " TCP Wrappers support: $TCPW_MSG" +echo " MD5 password support: $MD5_MSG" +echo " libedit support: $LIBEDIT_MSG" +echo " Solaris process contract support: $SPC_MSG" +echo " Solaris project support: $SP_MSG" +echo " 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
diff --git a/openssh-6.0p1/configure.ac b/openssh-6.0p1/configure.ac new file mode 100644 index 0000000..1457b8a --- /dev/null +++ b/openssh-6.0p1/configure.ac
@@ -0,0 +1,4397 @@ +# $Id: configure.ac,v 1.489 2012/04/19 11:46:38 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.489 $) +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_PATH_PROG([AR], [ar]) +AC_PATH_PROG([CAT], [cat]) +AC_PATH_PROG([KILL], [kill]) +AC_PATH_PROGS([PERL], [perl5 perl]) +AC_PATH_PROG([SED], [sed]) +AC_SUBST([PERL]) +AC_PATH_PROG([ENT], [ent]) +AC_SUBST([ENT]) +AC_PATH_PROG([TEST_MINUS_S_SH], [bash]) +AC_PATH_PROG([TEST_MINUS_S_SH], [ksh]) +AC_PATH_PROG([TEST_MINUS_S_SH], [sh]) +AC_PATH_PROG([SH], [sh]) +AC_PATH_PROG([GROFF], [groff]) +AC_PATH_PROG([NROFF], [nroff]) +AC_PATH_PROG([MANDOC], [mandoc]) +AC_SUBST([TEST_SHELL], [sh]) + +dnl select manpage formatter +if test "x$MANDOC" != "x" ; then + MANFMT="$MANDOC" +elif test "x$NROFF" != "x" ; then + MANFMT="$NROFF -mandoc" +elif test "x$GROFF" != "x" ; then + MANFMT="$GROFF -mandoc -Tascii" +else + AC_MSG_WARN([no manpage formatted found]) + MANFMT="false" +fi +AC_SUBST([MANFMT]) + +dnl for buildpkg.sh +AC_PATH_PROG([PATH_GROUPADD_PROG], [groupadd], [groupadd], + [/usr/sbin${PATH_SEPARATOR}/etc]) +AC_PATH_PROG([PATH_USERADD_PROG], [useradd], [useradd], + [/usr/sbin${PATH_SEPARATOR}/etc]) +AC_CHECK_PROG([MAKE_PACKAGE_SUPPORTED], [pkgmk], [yes], [no]) +if test -x /sbin/sh; then + AC_SUBST([STARTUP_SCRIPT_SHELL], [/sbin/sh]) +else + AC_SUBST([STARTUP_SCRIPT_SHELL], [/bin/sh]) +fi + +# System features +AC_SYS_LARGEFILE + +if test -z "$AR" ; then + AC_MSG_ERROR([*** 'ar' missing, please install or fix your \$PATH ***]) +fi + +# Use LOGIN_PROGRAM from environment if possible +if test ! -z "$LOGIN_PROGRAM" ; then + AC_DEFINE_UNQUOTED([LOGIN_PROGRAM_FALLBACK], ["$LOGIN_PROGRAM"], + [If your header files don't define LOGIN_PROGRAM, + then use this (detected) from environment and PATH]) +else + # Search for login + AC_PATH_PROG([LOGIN_PROGRAM_FALLBACK], [login]) + if test ! -z "$LOGIN_PROGRAM_FALLBACK" ; then + AC_DEFINE_UNQUOTED([LOGIN_PROGRAM_FALLBACK], ["$LOGIN_PROGRAM_FALLBACK"]) + fi +fi + +AC_PATH_PROG([PATH_PASSWD_PROG], [passwd]) +if test ! -z "$PATH_PASSWD_PROG" ; then + AC_DEFINE_UNQUOTED([_PATH_PASSWD_PROG], ["$PATH_PASSWD_PROG"], + [Full path of your "passwd" program]) +fi + +if test -z "$LD" ; then + LD=$CC +fi +AC_SUBST([LD]) + +AC_C_INLINE + +AC_CHECK_DECL([LLONG_MAX], [have_llong_max=1], , [#include <limits.h>]) +AC_CHECK_DECL([SYSTR_POLICY_KILL], [have_systr_policy_kill=1], , [ + #include <sys/types.h> + #include <sys/param.h> + #include <dev/systrace.h> +]) +AC_CHECK_DECL([RLIMIT_NPROC], + [AC_DEFINE([HAVE_RLIMIT_NPROC], [], [sys/resource.h has RLIMIT_NPROC])], , [ + #include <sys/types.h> + #include <sys/resource.h> +]) +AC_CHECK_DECL([PR_SET_NO_NEW_PRIVS], [have_linux_no_new_privs=1], , [ + #include <sys/types.h> + #include <linux/prctl.h> +]) +if test "x$have_linux_no_new_privs" = "x1" ; then +AC_CHECK_DECL([SECCOMP_MODE_FILTER], [have_seccomp_filter=1], , [ + #include <sys/types.h> + #include <linux/seccomp.h> +]) +fi +if test "x$have_seccomp_filter" = "x1" ; then +AC_MSG_CHECKING([kernel for seccomp_filter support]) +AC_RUN_IFELSE([AC_LANG_PROGRAM([[ + #include <errno.h> + #include <linux/seccomp.h> + #include <stdlib.h> + #include <sys/prctl.h> + ]], + [[ 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 + ], + [ AC_MSG_RESULT([cross-compiling, assuming yes]) ] +) +fi + +use_stack_protector=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 ]) + + +if test "$GCC" = "yes" || test "$GCC" = "egcs"; then + 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([-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]) + 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 <string.h> ]], + [[ 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-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 <stdio.h> ]], + [[ + 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 <stdio.h> ]], + [[ + 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 <limits.h>] + ) + fi +fi + +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([ \ + bstring.h \ + crypt.h \ + crypto/sha2.h \ + dirent.h \ + endian.h \ + features.h \ + fcntl.h \ + floatingpoint.h \ + getopt.h \ + glob.h \ + ia.h \ + iaf.h \ + limits.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/cdefs.h \ + sys/dir.h \ + sys/mman.h \ + sys/ndir.h \ + sys/poll.h \ + sys/prctl.h \ + sys/pstat.h \ + sys/select.h \ + sys/stat.h \ + sys/stream.h \ + sys/stropts.h \ + sys/strtio.h \ + sys/statvfs.h \ + sys/sysmacros.h \ + sys/time.h \ + sys/timers.h \ + sys/un.h \ + time.h \ + tmpdir.h \ + ttyent.h \ + ucred.h \ + unistd.h \ + usersec.h \ + util.h \ + utime.h \ + utmp.h \ + utmpx.h \ + vis.h \ +]) + +# lastlog.h requires sys/time.h to be included first on Solaris +AC_CHECK_HEADERS([lastlog.h], [], [], [ +#ifdef HAVE_SYS_TIME_H +# include <sys/time.h> +#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 <sys/stream.h> +#endif +]) + +# login_cap.h requires sys/types.h on NetBSD +AC_CHECK_HEADERS([login_cap.h], [], [], [ +#include <sys/types.h> +]) + +# older BSDs need sys/param.h before sys/mount.h +AC_CHECK_HEADERS([sys/mount.h], [], [], [ +#include <sys/param.h> +]) + +# Messages for features tested for in target-specific section +SIA_MSG="no" +SPC_MSG="no" +SP_MSG="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 <usersec.h>]) + 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 <usersec.h> ]], + [[ (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 <usersec.h>] + ) + AC_CHECK_FUNCS([getgrset setauthdb]) + AC_CHECK_DECL([F_CLOSEM], + AC_DEFINE([HAVE_FCNTL_CLOSEM], [1], [Use F_CLOSEM fcntl for closefrom]), + [], + [ #include <limits.h> + #include <fcntl.h> ] + ) + 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]) + ;; +*-*-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([DISABLE_SHADOW], [1], + [Define if you want to disable shadow passwords]) + AC_DEFINE([NO_X11_UNIX_SOCKETS], [1], + [Define if X11 doesn't support AF_UNIX sockets on that system]) + AC_DEFINE([NO_IPPORT_RESERVED_CONCEPT], [1], + [Define if the concept of ports only accessible to + superusers isn't known]) + AC_DEFINE([DISABLE_FD_PASSING], [1], + [Define if your platform needs to skip post auth + file descriptor passing]) + AC_DEFINE([SSH_IOBUFSZ], [65535], [Windows is sensitive to read buffer size]) + AC_DEFINE([FILESYSTEM_NO_BACKSLASH], [1], [File names may not contain backslash characters]) + ;; +*-*-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*) + AC_MSG_CHECKING([if we have working getaddrinfo]) + AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include <mach-o/dyld.h> +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 <bsm/audit.h>] + 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]) + ;; +*-*-dragonfly*) + SSHDLIBS="$SSHDLIBS -lcrypt" + ;; +*-*-haiku*) + LIBS="$LIBS -lbsd " + AC_CHECK_LIB([network], [socket]) + AC_DEFINE([HAVE_U_INT64_T]) + MANTYPE=man + ;; +*-*-hpux*) + # first we define all of the options common to all HP-UX releases + CPPFLAGS="$CPPFLAGS -D_HPUX_SOURCE -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED=1" + IPADDR_IN_DISPLAY=yes + AC_DEFINE([USE_PIPES]) + AC_DEFINE([LOGIN_NO_ENDOPT], [1], + [Define if your login program cannot handle end of options ("--")]) + AC_DEFINE([LOGIN_NEEDS_UTMPX]) + AC_DEFINE([LOCKED_PASSWD_STRING], ["*"], + [String used in /etc/passwd to denote locked account]) + AC_DEFINE([SPT_TYPE], [SPT_PSTAT]) + 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 + check_for_libcrypt_later=1 + check_for_openpty_ctty_bug=1 + AC_DEFINE([PAM_TTY_KLUDGE], [1], + [Work around problematic Linux PAM modules handling of PAM_TTY]) + AC_DEFINE([LOCKED_PASSWD_PREFIX], ["!"], + [String used in /etc/passwd to denote locked account]) + AC_DEFINE([SPT_TYPE], [SPT_REUSEARGV]) + AC_DEFINE([LINK_OPNOTSUPP_ERRNO], [EPERM], + [Define to whatever link() returns for "not supported" + if it doesn't return EOPNOTSUPP.]) + AC_DEFINE([_PATH_BTMP], ["/var/log/btmp"], [log for bad login attempts]) + AC_DEFINE([USE_BTMP]) + AC_DEFINE([LINUX_OOM_ADJUST], [1], [Adjust Linux out-of-memory killer]) + inet6_default_4in6=yes + case `uname -r` in + 1.*|2.0.*) + AC_DEFINE([BROKEN_CMSG_TYPE], [1], + [Define if cmsg_type is not passed correctly]) + ;; + esac + # tun(4) forwarding compat code + AC_CHECK_HEADERS([linux/if_tun.h]) + if test "x$ac_cv_header_linux_if_tun_h" = "xyes" ; then + AC_DEFINE([SSH_TUN_LINUX], [1], + [Open tunnel devices the Linux tun/tap way]) + AC_DEFINE([SSH_TUN_COMPAT_AF], [1], + [Use tunnel device compatibility to OpenBSD]) + AC_DEFINE([SSH_TUN_PREPEND_AF], [1], + [Prepend the address family to IP tunnel traffic]) + fi + AC_CHECK_HEADERS([linux/seccomp.h linux/filter.h linux/audit.h]) + AC_CHECK_FUNCS([prctl]) + have_seccomp_audit_arch=1 + case "$host" in + x86_64-*) + AC_DEFINE([SECCOMP_AUDIT_ARCH], [AUDIT_ARCH_X86_64], + [Specify the system call convention in use]) + ;; + i*86-*) + AC_DEFINE([SECCOMP_AUDIT_ARCH], [AUDIT_ARCH_I386], + [Specify the system call convention in use]) + ;; + *) + have_seccomp_audit_arch=0 + ;; + esac + ;; +mips-sony-bsd|mips-sony-newsos4) + AC_DEFINE([NEED_SETPGRP], [1], [Need setpgrp to acquire controlling tty]) + SONY=1 + ;; +*-*-netbsd*) + check_for_libcrypt_before=1 + if test "x$withval" != "xno" ; then + need_dash_r=1 + fi + AC_DEFINE([SSH_TUN_FREEBSD], [1], [Open tunnel devices the FreeBSD way]) + AC_CHECK_HEADER([net/if_tap.h], , + AC_DEFINE([SSH_TUN_NO_L2], [1], [No layer 2 tunnel support])) + AC_DEFINE([SSH_TUN_PREPEND_AF], [1], + [Prepend the address family to IP tunnel traffic]) + ;; +*-*-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]) + ;; +*-*-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*) + 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]) + ;; +*-*-solaris*) + if test "x$withval" != "xno" ; then + need_dash_r=1 + fi + AC_DEFINE([PAM_SUN_CODEBASE]) + AC_DEFINE([LOGIN_NEEDS_UTMPX]) + AC_DEFINE([LOGIN_NEEDS_TERM], [1], + [Some versions of /bin/login need the TERM supplied + on the commandline]) + AC_DEFINE([PAM_TTY_KLUDGE]) + AC_DEFINE([SSHPAM_CHAUTHTOK_NEEDS_RUID], [1], + [Define if pam_chauthtok wants real uid set + to the unpriv'ed user]) + AC_DEFINE([LOCKED_PASSWD_STRING], ["*LK*"]) + # Pushing STREAMS modules will cause sshd to acquire a controlling tty. + AC_DEFINE([SSHD_ACQUIRES_CTTY], [1], + [Define if sshd somehow reacquires a controlling TTY + after setsid()]) + AC_DEFINE([PASSWD_NEEDS_USERNAME], [1], [must supply username to passwd + in case the name is longer than 8 chars]) + AC_DEFINE([BROKEN_TCGETATTR_ICANON], [1], [tcgetattr with ICANON may hang]) + external_path_file=/etc/default/login + # hardwire lastlog location (can't detect it on some versions) + conf_lastlog_location="/var/adm/lastlog" + AC_MSG_CHECKING([for obsolete utmp and wtmp in solaris2.x]) + sol2ver=`echo "$host"| sed -e 's/.*[[0-9]]\.//'` + if test "$sol2ver" -ge 8; then + AC_MSG_RESULT([yes]) + AC_DEFINE([DISABLE_UTMP]) + AC_DEFINE([DISABLE_WTMP], [1], + [Define if you don't want to use wtmp]) + else + AC_MSG_RESULT([no]) + fi + AC_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]) + SSHDLIBS="$SSHDLIBS -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]) + SSHDLIBS="$SSHDLIBS -lproject" + SP_MSG="yes" ], ) + ], + ) + ;; +*-*-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*"]) + ;; +# 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]) + case "$host" in + *-*-sysv5SCO_SV*) # SCO OpenServer 6.x + maildir=/var/spool/mail + TEST_SHELL=/u95/bin/sh + 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=ksh + ;; +*-*-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([MISSING_NFDBITS], [1], [Define on *nto-qnx systems]) + AC_DEFINE([MISSING_HOWMANY], [1], [Define on *nto-qnx systems]) + AC_DEFINE([MISSING_FD_MASK], [1], [Define on *nto-qnx systems]) + AC_DEFINE([DISABLE_LASTLOG]) + AC_DEFINE([SSHD_ACQUIRES_CTTY]) + AC_DEFINE([BROKEN_SHADOW_EXPIRE], [1], [QNX shadow support is broken]) + enable_etc_default_login=no # has incompatible /etc/default/login + case "$host" in + *-*-nto-qnx6*) + AC_DEFINE([DISABLE_FD_PASSING]) + ;; + esac + ;; + +*-*-ultrix*) + AC_DEFINE([BROKEN_GETGROUPS], [1], [getgroups(0,NULL) will return -1]) + AC_DEFINE([BROKEN_MMAP], [1], [Ultrix mmap can't map files]) + AC_DEFINE([NEED_SETPGRP]) + AC_DEFINE([HAVE_SYS_SYSLOG_H], [1], [Force use of sys/syslog.h on Ultrix]) + ;; + +*-*-lynxos) + CFLAGS="$CFLAGS -D__NO_INCLUDE_WARN__" + AC_DEFINE([MISSING_HOWMANY]) + 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 <stdio.h> ]], [[ 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([yp_match], , [AC_CHECK_LIB([nsl], [yp_match])]) +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 <libgen.h> +#include <string.h> + +int main(int argc, char **argv) { + char *s, buf[32]; + + strncpy(buf,"/etc", 32); + s = dirname(buf); + if (!s || strncmp(s, "/", 32) != 0) { + exit(1); + } else { + exit(0); + } +} + ]])], + [ ac_cv_have_broken_dirname="no" ], + [ ac_cv_have_broken_dirname="yes" ], + [ 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 <stdio.h> +#include <zlib.h> + ]], + [[ + 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([libutil.h]) +AC_SEARCH_LIBS([fmt_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 login logout openpty updwtmp logwtmp]) + +AC_FUNC_STRFTIME + +# Check for ALTDIRFUNC glob() extension +AC_MSG_CHECKING([for GLOB_ALTDIRFUNC support]) +AC_EGREP_CPP([FOUNDIT], + [ + #include <glob.h> + #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.h> ]], + [[ 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 <glob.h> ]], [[ +#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 <glob.h>]) + +AC_MSG_CHECKING([whether struct dirent allocates space for d_name]) +AC_RUN_IFELSE( + [AC_LANG_PROGRAM([[ +#include <sys/types.h> +#include <dirent.h>]], + [[ + 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 <stdio.h> +#include <skey.h> + ]], [[ + 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 <stdio.h> +#include <skey.h> + ]], [[ + (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 TCP wrappers support +TCPW_MSG="no" +AC_ARG_WITH([tcp-wrappers], + [ --with-tcp-wrappers[[=PATH]] Enable tcpwrappers support (optionally in PATH)], + [ + if test "x$withval" != "xno" ; then + saved_LIBS="$LIBS" + saved_LDFLAGS="$LDFLAGS" + saved_CPPFLAGS="$CPPFLAGS" + if test -n "${withval}" && \ + 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 + LIBS="-lwrap $LIBS" + AC_MSG_CHECKING([for libwrap]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <tcpd.h> +int deny_severity = 0, allow_severity = 0; + ]], [[ + hosts_access(0); + ]])], [ + AC_MSG_RESULT([yes]) + AC_DEFINE([LIBWRAP], [1], + [Define if you want + TCP Wrappers support]) + SSHDLIBS="$SSHDLIBS -lwrap" + TCPW_MSG="yes" + ], [ + AC_MSG_ERROR([*** libwrap missing]) + + ]) + LIBS="$saved_LIBS" + fi + ] +) + +# Check whether user wants to use ldns +LDNS_MSG="no" +AC_ARG_WITH(ldns, + [ --with-ldns[[=PATH]] Use ldns for DNSSEC support (optionally in PATH)], + [ + if test "x$withval" != "xno" ; then + + if test "x$withval" != "xyes" ; then + CPPFLAGS="$CPPFLAGS -I${withval}/include" + LDFLAGS="$LDFLAGS -L${withval}/lib" + fi + + AC_DEFINE(HAVE_LDNS, 1, [Define if you want ldns support]) + LIBS="-lldns $LIBS" + LDNS_MSG="yes" + + AC_MSG_CHECKING([for ldns support]) + AC_LINK_IFELSE( + [AC_LANG_SOURCE([[ +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <ldns/ldns.h> +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_PROG([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-only-l 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 <histedit.h> ]], + [[ + 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 <time.h> +#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" -eq 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 ] +) + +dnl Checks for library functions. Please keep in alphabetical order +AC_CHECK_FUNCS([ \ + arc4random \ + arc4random_buf \ + arc4random_uniform \ + asprintf \ + b64_ntop \ + __b64_ntop \ + b64_pton \ + __b64_pton \ + bcopy \ + bindresvport_sa \ + clock \ + closefrom \ + dirfd \ + fchmod \ + fchown \ + freeaddrinfo \ + fstatvfs \ + futimes \ + getaddrinfo \ + getcwd \ + getgrouplist \ + getnameinfo \ + getopt \ + getpeereid \ + getpeerucred \ + _getpty \ + getrlimit \ + getttyent \ + glob \ + group_from_gid \ + inet_aton \ + inet_ntoa \ + inet_ntop \ + innetgr \ + login_getcapbool \ + md5_crypt \ + memmove \ + mkdtemp \ + mmap \ + ngetaddrinfo \ + nsleep \ + ogetaddrinfo \ + openlog_r \ + poll \ + prctl \ + pstat \ + readpassphrase \ + realpath \ + recvmsg \ + rresvport_af \ + sendmsg \ + setdtablesize \ + setegid \ + setenv \ + seteuid \ + setgroupent \ + setgroups \ + setlogin \ + setpassent\ + setpcred \ + setproctitle \ + setregid \ + setreuid \ + setrlimit \ + setsid \ + setvbuf \ + sigaction \ + sigvec \ + snprintf \ + socketpair \ + statfs \ + statvfs \ + strdup \ + strerror \ + strlcat \ + strlcpy \ + strmode \ + strnlen \ + strnvis \ + strptime \ + strtonum \ + strtoll \ + strtoul \ + swap32 \ + sysconf \ + tcgetpgrp \ + timingsafe_bcmp \ + truncate \ + unsetenv \ + updwtmpx \ + user_from_uid \ + vasprintf \ + vhangup \ + vsnprintf \ + waitpid \ +]) + +AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[ #include <ctype.h> ]], + [[ return (isblank('a')); ]])], + [AC_DEFINE([HAVE_ISBLANK], [1], [Define if you have isblank(3C).]) +]) + +# PKCS#11 support requires dlopen() and co +AC_SEARCH_LIBS([dlopen], [dl], + [AC_DEFINE([ENABLE_PKCS11], [], [Enable for PKCS#11 support])] +) + +# 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 <sys/types.h> +#include <sys/socket.h> +#include <netdb.h> + +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])]) + +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 <string.h> +#endif + ]) + +dnl tcsendbreak might be a macro +AC_CHECK_DECL([tcsendbreak], + [AC_DEFINE([HAVE_TCSENDBREAK])], + [AC_CHECK_FUNCS([tcsendbreak])], + [#include <termios.h>] +) + +AC_CHECK_DECLS([h_errno], , ,[#include <netdb.h>]) + +AC_CHECK_DECLS([SHUT_RD], , , + [ +#include <sys/types.h> +#include <sys/socket.h> + ]) + +AC_CHECK_DECLS([O_NONBLOCK], , , + [ +#include <sys/types.h> +#ifdef HAVE_SYS_STAT_H +# include <sys/stat.h> +#endif +#ifdef HAVE_FCNTL_H +# include <fcntl.h> +#endif + ]) + +AC_CHECK_DECLS([writev], , , [ +#include <sys/types.h> +#include <sys/uio.h> +#include <unistd.h> + ]) + +AC_CHECK_DECLS([MAXSYMLINKS], , , [ +#include <sys/param.h> + ]) + +AC_CHECK_DECLS([offsetof], , , [ +#include <stddef.h> + ]) + +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 <stdlib.h> +#include <errno.h> + ]], [[ + 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 <stdlib.h> +#include <errno.h> + ]], [[ + 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])] + ) +]) + +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 <stdio.h> ]], + [[ + 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 + +# If we don't have a working asprintf, then we strongly 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_asprintf" != "xyes" && \ + 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 <sys/types.h> +#include <stdio.h> +#include <stdarg.h> + +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]; + exit(x_snprintf(x, 1, "%s %d", "hello", 12345) == 11 ? 0 : 1); + ]])], + [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 <stdio.h> +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 <sys/types.h> +#include <sys/socket.h>]], [[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 <stdlib.h> + ]], [[ + 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 <stdio.h> +#include <sys/fcntl.h> +#include <sys/types.h> +#include <sys/wait.h> + ]], [[ + 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 <stdio.h> +#include <sys/socket.h> +#include <netdb.h> +#include <errno.h> +#include <netinet/in.h> + +#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 <stdio.h> +#include <sys/socket.h> +#include <netdb.h> +#include <errno.h> +#include <netinet/in.h> + +#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$check_for_conflicting_getspnam" = "x1"; then + AC_MSG_CHECKING([for conflicting getspnam in shadow.h]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <shadow.h> ]], + [[ exit(0); ]])], + [ + AC_MSG_RESULT([no]) + ], + [ + AC_MSG_RESULT([yes]) + AC_DEFINE([GETSPNAM_CONFLICTING_DEFS], [1], + [Conflicting defs for getspnam]) + ] + ) +fi + +AC_FUNC_GETPGRP + +# Search for OpenSSL +saved_CPPFLAGS="$CPPFLAGS" +saved_LDFLAGS="$LDFLAGS" +AC_ARG_WITH([ssl-dir], + [ --with-ssl-dir=PATH Specify path to OpenSSL installation ], + [ + if test "x$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 + ] +) +LIBS="-lcrypto $LIBS" +AC_TRY_LINK_FUNC([RAND_add], [AC_DEFINE([HAVE_OPENSSL], [1], + [Define if your ssl headers are included + with #include <openssl/header.h>])], + [ + 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 <stdio.h> +#include <string.h> +#include <openssl/opensslv.h> +#define DATA "conftest.sslincver" + ]], [[ + FILE *fd; + int rc; + + fd = fopen(DATA,"w"); + if(fd == NULL) + exit(1); + + if ((rc = fprintf(fd ,"%x (%s)\n", 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 <stdio.h> +#include <string.h> +#include <openssl/opensslv.h> +#include <openssl/crypto.h> +#define DATA "conftest.ssllibver" + ]], [[ + FILE *fd; + int rc; + + fd = fopen(DATA,"w"); + if(fd == NULL) + exit(1); + + if ((rc = fprintf(fd ,"%x (%s)\n", SSLeay(), SSLeay_version(SSLEAY_VERSION))) <0) + exit(1); + + exit(0); + ]])], + [ + ssl_library_ver=`cat conftest.ssllibver` + 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]) + ] +) + +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 + ] +) + +# Sanity check OpenSSL headers +AC_MSG_CHECKING([whether OpenSSL's headers match the library]) +AC_RUN_IFELSE( + [AC_LANG_PROGRAM([[ +#include <string.h> +#include <openssl/opensslv.h> + ]], [[ + 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 <openssl/evp.h> ]], + [[ 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 <openssl/evp.h> ]], + [[ SSLeay_add_all_algorithms(); ]])], + [ + AC_MSG_RESULT([yes]) + ], + [ + AC_MSG_RESULT([no]) + LIBS="$saved_LIBS" + ] + ) + ] +) + +AC_CHECK_FUNCS([RSA_generate_key_ex DSA_generate_parameters_ex BN_is_prime_ex RSA_get_default_method HMAC_CTX_init]) + +AC_ARG_WITH([ssl-engine], + [ --with-ssl-engine Enable OpenSSL (hardware) ENGINE support ], + [ if test "x$withval" != "xno" ; then + AC_MSG_CHECKING([for OpenSSL ENGINE support]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include <openssl/engine.h> + ]], [[ + 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 <string.h> +#include <openssl/evp.h> + ]], [[ + 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]) + ] +) + +AC_MSG_CHECKING([if EVP_DigestUpdate returns an int]) +AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[ +#include <string.h> +#include <openssl/evp.h> + ]], [[ + 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 + +# Search for SHA256 support in libc and/or OpenSSL +AC_CHECK_FUNCS([SHA256_Update EVP_sha256], [TEST_SSH_SHA256=yes], + [TEST_SSH_SHA256=no]) +AC_SUBST([TEST_SSH_SHA256]) + +# Check complete ECC support in OpenSSL +AC_MSG_CHECKING([whether OpenSSL has complete ECC support]) +AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[ +#include <openssl/ec.h> +#include <openssl/ecdh.h> +#include <openssl/ecdsa.h> +#include <openssl/evp.h> +#include <openssl/objects.h> +#include <openssl/opensslv.h> +#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_DEFINE([OPENSSL_HAS_ECC], [1], + [libcrypto includes complete ECC support]) + TEST_SSH_ECC=yes + COMMENT_OUT_ECC="" + ], + [ + AC_MSG_RESULT([no]) + TEST_SSH_ECC=no + COMMENT_OUT_ECC="#no ecc#" + ] +) +AC_SUBST([TEST_SSH_ECC]) +AC_SUBST([COMMENT_OUT_ECC]) + +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 +AC_MSG_CHECKING([whether OpenSSL's PRNG is internally seeded]) +AC_RUN_IFELSE( + [AC_LANG_PROGRAM([[ +#include <string.h> +#include <openssl/rand.h> + ]], [[ + 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 + ] +) + +# 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 OpenSSL's internally seeded PRNG only]) + RAND_MSG="OpenSSL internal ONLY" +else + AC_MSG_ERROR([OpenSSH has no source of random numbers. Please configure OpenSSL with an entropy source or re-run configure using one of the --with-prngd-port or --with-prngd-socket options]) +fi + +# Check for PAM libs +PAM_MSG="no" +AC_ARG_WITH([pam], + [ --with-pam Enable PAM support ], + [ + if test "x$withval" != "xno" ; then + if test "x$ac_cv_header_security_pam_appl_h" != "xyes" && \ + test "x$ac_cv_header_pam_pam_appl_h" != "xyes" ; then + AC_MSG_ERROR([PAM headers not found]) + fi + + saved_LIBS="$LIBS" + AC_CHECK_LIB([dl], [dlopen], , ) + AC_CHECK_LIB([pam], [pam_set_item], , [AC_MSG_ERROR([*** libpam missing])]) + AC_CHECK_FUNCS([pam_getenvlist]) + AC_CHECK_FUNCS([pam_putenv]) + LIBS="$saved_LIBS" + + PAM_MSG="yes" + + SSHDLIBS="$SSHDLIBS -lpam" + AC_DEFINE([USE_PAM], [1], + [Define if you want to enable PAM support]) + + if test $ac_cv_lib_dl_dlopen = yes; then + case "$LIBS" in + *-ldl*) + # libdl already in LIBS + ;; + *) + SSHDLIBS="$SSHDLIBS -ldl" + ;; + esac + fi + fi + ] +) + +# Check for older PAM +if test "x$PAM_MSG" = "xyes" ; then + # Check PAM strerror arguments (old PAM) + AC_MSG_CHECKING([whether pam_strerror takes only one argument]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include <stdlib.h> +#if defined(HAVE_SECURITY_PAM_APPL_H) +#include <security/pam_appl.h> +#elif defined (HAVE_PAM_PAM_APPL_H) +#include <pam/pam_appl.h> +#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 + +SSH_PRIVSEP_USER=sshd +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 + ] +) +AC_DEFINE_UNQUOTED([SSH_PRIVSEP_USER], ["$SSH_PRIVSEP_USER"], + [non-privileged user for privilege separation]) +AC_SUBST([SSH_PRIVSEP_USER]) + +# Decide which sandbox style to use +sandbox_arg="" +AC_ARG_WITH([sandbox], + [ --with-sandbox=style Specify privilege separation sandbox (no, darwin, rlimit, systrace, seccomp_filter)], + [ + if test "x$withval" = "xyes" ; then + sandbox_arg="" + else + sandbox_arg="$withval" + fi + ] +) +if 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_linux_audit_h" = "xyes" && \ + test "x$have_seccomp_audit_arch" = "x1" && \ + test "x$have_linux_no_new_privs" = "x1" && \ + test "x$ac_cv_func_prctl" = "xyes" ) ; then + test "x$have_seccomp_audit_arch" != "x1" && \ + 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" = "xrlimit" || \ + ( test -z "$sandbox_arg" && test "x$ac_cv_func_setrlimit" = "xyes" ) ; then + test "x$ac_cv_func_setrlimit" != "xyes" && \ + AC_MSG_ERROR([rlimit sandbox requires setrlimit function]) + SANDBOX_STYLE="rlimit" + AC_DEFINE([SANDBOX_RLIMIT], [1], [Sandbox using setrlimit(2)]) +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 <stdio.h> +/* Why is this so damn hard? */ +#ifdef __GNUC__ +# undef __GNUC__ +#endif +#define __USE_ISOC99 +#include <limits.h> +#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 <sys/types.h> ]], + [[ 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 <sys/types.h> ]], + [[ 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 <stdint.h> ]], + [[ 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 <sys/types.h> +#ifdef HAVE_STDINT_H +# include <stdint.h> +#endif +#include <sys/socket.h> +#ifdef HAVE_SYS_BITYPES_H +# include <sys/bitypes.h> +#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 <sys/types.h> ]], + [[ 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 <sys/socket.h> ]], + [[ 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 <sys/types.h> ]], + [[ 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" ; then + AC_MSG_CHECKING([for u_int64_t type in sys/bitypes.h]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <sys/bitypes.h> ]], + [[ 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 <sys/types.h> + ]], [[ + 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" ; then + AC_MSG_CHECKING([for uintXX_t types in stdint.h]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <stdint.h> ]], + [[ 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 <sys/bitypes.h> + ]], [[ + 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 <sys/types.h> ]], + [[ 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 + +TYPE_SOCKLEN_T + +AC_CHECK_TYPES([sig_atomic_t], , , [#include <signal.h>]) +AC_CHECK_TYPES([fsblkcnt_t, fsfilcnt_t], , , [ +#include <sys/types.h> +#ifdef HAVE_SYS_BITYPES_H +#include <sys/bitypes.h> +#endif +#ifdef HAVE_SYS_STATFS_H +#include <sys/statfs.h> +#endif +#ifdef HAVE_SYS_STATVFS_H +#include <sys/statvfs.h> +#endif +]) + +AC_CHECK_TYPES([in_addr_t, in_port_t], , , +[#include <sys/types.h> +#include <netinet/in.h>]) + +AC_CACHE_CHECK([for size_t], ac_cv_have_size_t, [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <sys/types.h> ]], + [[ 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 <sys/types.h> ]], + [[ 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 <time.h> ]], + [[ 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 <sys/types.h> +#include <sys/socket.h> + ]], [[ sa_family_t foo; foo = 1235; ]])], + [ ac_cv_have_sa_family_t="yes" ], + [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> + ]], [[ 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 <sys/types.h> ]], + [[ 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 <sys/types.h> ]], + [[ 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 <sys/types.h> +#include <sys/socket.h> + ]], [[ 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 <sys/types.h> +#include <netinet/in.h> + ]], [[ 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 <sys/types.h> +#include <netinet/in.h> + ]], [[ 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 <sys/types.h> +#endif +#include <netinet/in.h> + ]) +fi + +AC_CACHE_CHECK([for struct addrinfo], ac_cv_have_struct_addrinfo, [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include <sys/types.h> +#include <sys/socket.h> +#include <netdb.h> + ]], [[ 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 <sys/time.h> ]], + [[ 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 <stdio.h> +#include <string.h> +#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_MEMBER([struct __res_state.retrans], [], [AC_DEFINE([__res_state], [state], + [Define if we don't have struct __res_state in resolv.h])], +[ +#include <stdio.h> +#if HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#include <netinet/in.h> +#include <arpa/nameser.h> +#include <resolv.h> +]) + +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 <sys/types.h> +#include <sys/socket.h> + ]], [[ 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 <sys/types.h> +#include <sys/socket.h> + ]], [[ 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 pw_class field in struct passwd], + ac_cv_have_pw_class_in_struct_passwd, [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <pwd.h> ]], + [[ struct passwd p; p.pw_class = 0; ]])], + [ ac_cv_have_pw_class_in_struct_passwd="yes" ], + [ ac_cv_have_pw_class_in_struct_passwd="no" + ]) +]) +if test "x$ac_cv_have_pw_class_in_struct_passwd" = "xyes" ; then + AC_DEFINE([HAVE_PW_CLASS_IN_PASSWD], [1], + [Define if your password has a pw_class field]) +fi + +AC_CACHE_CHECK([for pw_expire field in struct passwd], + ac_cv_have_pw_expire_in_struct_passwd, [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <pwd.h> ]], + [[ struct passwd p; p.pw_expire = 0; ]])], + [ ac_cv_have_pw_expire_in_struct_passwd="yes" ], + [ ac_cv_have_pw_expire_in_struct_passwd="no" + ]) +]) +if test "x$ac_cv_have_pw_expire_in_struct_passwd" = "xyes" ; then + AC_DEFINE([HAVE_PW_EXPIRE_IN_PASSWD], [1], + [Define if your password has a pw_expire field]) +fi + +AC_CACHE_CHECK([for pw_change field in struct passwd], + ac_cv_have_pw_change_in_struct_passwd, [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <pwd.h> ]], + [[ struct passwd p; p.pw_change = 0; ]])], + [ ac_cv_have_pw_change_in_struct_passwd="yes" ], + [ ac_cv_have_pw_change_in_struct_passwd="no" + ]) +]) +if test "x$ac_cv_have_pw_change_in_struct_passwd" = "xyes" ; then + AC_DEFINE([HAVE_PW_CHANGE_IN_PASSWD], [1], + [Define if your password has a pw_change field]) +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 <sys/types.h> +#include <sys/socket.h> +#include <sys/uio.h> + ]], [[ +#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 <sys/types.h> +#include <sys/stat.h> +#ifdef HAVE_SYS_TIME_H +# include <sys/time.h> +#endif +#ifdef HAVE_SYS_MOUNT_H +#include <sys/mount.h> +#endif +#ifdef HAVE_SYS_STATVFS_H +#include <sys/statvfs.h> +#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 <sys/types.h> +#include <sys/statvfs.h> + ]], [[ 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 <sys/types.h> +#include <sys/statvfs.h> + ]], [[ 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 <sys/types.h> +#include <sys/socket.h> +#include <sys/uio.h> + ]], [[ +#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 <stdio.h> ]], + [[ 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 <stdio.h> ]], + [[ 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 <stdarg.h> +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 <stdarg.h> +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 <getopt.h> ]], + [[ 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 <sys/types.h> +#include <netinet/in.h> +#include <arpa/nameser.h> +#include <netdb.h> +#include <resolv.h> + ]], [[ + 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 <sys/types.h> +#include <netinet/in.h> +#include <arpa/nameser.h> +#include <netdb.h> +#include <resolv.h> + ]], [[ + 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 <sys/types.h> + #include <arpa/nameser.h>]) + AC_CHECK_MEMBER([HEADER.ad], + [AC_DEFINE([HAVE_HEADER_AD], [1], + [Define if HEADER.ad exists in arpa/nameser.h])], , + [#include <arpa/nameser.h>]) + ]) + +AC_MSG_CHECKING([if struct __res_state _res is an extern]) +AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include <stdio.h> +#if HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#include <netinet/in.h> +#include <arpa/nameser.h> +#include <resolv.h> +extern struct __res_state _res; + ]], [[ ]])], + [AC_MSG_RESULT([yes]) + AC_DEFINE([HAVE__RES_EXTERN], [1], + [Define if you have struct __res_state _res as an extern]) + ], + [ AC_MSG_RESULT([no]) ] +) + +# Check whether user wants SELinux support +SELINUX_MSG="no" +LIBSELINUX="" +AC_ARG_WITH([selinux], + [ --with-selinux Enable SELinux support], + [ if test "x$withval" != "xno" ; then + save_LIBS="$LIBS" + AC_DEFINE([WITH_SELINUX], [1], + [Define if you want SELinux support.]) + SELINUX_MSG="yes" + AC_CHECK_HEADER([selinux/selinux.h], , + AC_MSG_ERROR([SELinux support requires selinux.h header])) + AC_CHECK_LIB([selinux], [setexeccon], + [ LIBSELINUX="-lselinux" + LIBS="$LIBS -lselinux" + ], + AC_MSG_ERROR([SELinux support requires libselinux library])) + SSHLIBS="$SSHLIBS $LIBSELINUX" + SSHDLIBS="$SSHDLIBS $LIBSELINUX" + AC_CHECK_FUNCS([getseuserbyname get_default_context_with_level]) + LIBS="$save_LIBS" + fi ] +) +AC_SUBST([SSHLIBS]) +AC_SUBST([SSHDLIBS]) + +# Check whether user wants Kerberos 5 support +KRB5_MSG="no" +AC_ARG_WITH([kerberos5], + [ --with-kerberos5=PATH Enable Kerberos 5 support], + [ if test "x$withval" != "xno" ; then + if test "x$withval" = "xyes" ; then + KRB5ROOT="/usr/local" + else + KRB5ROOT=${withval} + fi + + AC_DEFINE([KRB5], [1], [Define if you want Kerberos 5 support]) + KRB5_MSG="yes" + + AC_PATH_PROG([KRB5CONF], [krb5-config], + [$KRB5ROOT/bin/krb5-config], + [$KRB5ROOT/bin:$PATH]) + if test -x $KRB5CONF ; then + + 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]) + k5confopts=gssapi + else + AC_MSG_RESULT([no]) + k5confopts="" + fi + K5CFLAGS="`$KRB5CONF --cflags $k5confopts`" + K5LIBS="`$KRB5CONF --libs $k5confopts`" + CPPFLAGS="$CPPFLAGS $K5CFLAGS" + AC_MSG_CHECKING([whether we are using Heimdal]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <krb5.h> + ]], [[ 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 <krb5.h> + ]], [[ 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]) + K5LIBS="-lgssapi_krb5 $K5LIBS" ], + [ AC_CHECK_LIB([gssapi], [gss_init_sec_context], + [ AC_DEFINE([GSSAPI]) + K5LIBS="-lgssapi $K5LIBS" ], + AC_MSG_WARN([Cannot find any suitable gss-api library - build may fail]), + $K5LIBS) + ], + $K5LIBS) + + AC_CHECK_HEADER([gssapi.h], , + [ unset ac_cv_header_gssapi_h + CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include/gssapi" + AC_CHECK_HEADERS([gssapi.h], , + AC_MSG_WARN([Cannot find any suitable gss-api header - build may fail]) + ) + ] + ) + + oldCPP="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include/gssapi" + AC_CHECK_HEADER([gssapi_krb5.h], , + [ CPPFLAGS="$oldCPP" ]) + + 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]) + + LIBS="$LIBS $K5LIBS" + AC_SEARCH_LIBS([k_hasafs], [kafs], [AC_DEFINE([USE_AFS], [1], + [Define this if you want to use libkafs' AFS support])]) + fi + ] +) + +# 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 <stdio.h> +#include <string.h> +#ifdef HAVE_PATHS_H +#include <paths.h> +#endif +#ifdef HAVE_MAILLOCK_H +#include <maillock.h> +#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 <sys/types.h> +#include <shadow.h> +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 <stdio.h> +#ifdef HAVE_PATHS_H +# include <paths.h> +#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 <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#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=`eval echo ${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 + 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 <sys/types.h> +#include <utmp.h> +#ifdef HAVE_LASTLOG_H +# include <lastlog.h> +#endif +#ifdef HAVE_PATHS_H +# include <paths.h> +#endif +#ifdef HAVE_LOGIN_H +# include <login.h> +#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 <sys/types.h> +#include <utmp.h> +#ifdef HAVE_LASTLOG_H +# include <lastlog.h> +#endif +#ifdef HAVE_PATHS_H +# include <paths.h> +#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 <sys/types.h> +#include <utmp.h> +#ifdef HAVE_PATHS_H +# include <paths.h> +#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 <sys/types.h> +#include <utmp.h> +#ifdef HAVE_PATHS_H +# include <paths.h> +#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 <sys/types.h> +#include <utmp.h> +#ifdef HAVE_UTMPX_H +#include <utmpx.h> +#endif +#ifdef HAVE_PATHS_H +# include <paths.h> +#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 + +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_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 " TCP Wrappers support: $TCPW_MSG" +echo " MD5 password support: $MD5_MSG" +echo " libedit support: $LIBEDIT_MSG" +echo " Solaris process contract support: $SPC_MSG" +echo " Solaris project support: $SP_MSG" +echo " 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
diff --git a/openssh-6.0p1/contrib/Makefile b/openssh-6.0p1/contrib/Makefile new file mode 100644 index 0000000..8b34eb2 --- /dev/null +++ b/openssh-6.0p1/contrib/Makefile
@@ -0,0 +1,15 @@ +all: + @echo "Valid targets: gnome-ssh-askpass1 gnome-ssh-askpass2" + +gnome-ssh-askpass1: gnome-ssh-askpass1.c + $(CC) `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) `pkg-config --cflags gtk+-2.0` \ + gnome-ssh-askpass2.c -o gnome-ssh-askpass2 \ + `pkg-config --libs gtk+-2.0 x11` + +clean: + rm -f *.o gnome-ssh-askpass1 gnome-ssh-askpass2 gnome-ssh-askpass
diff --git a/openssh-6.0p1/contrib/README b/openssh-6.0p1/contrib/README new file mode 100644 index 0000000..c002238 --- /dev/null +++ b/openssh-6.0p1/contrib/README
@@ -0,0 +1,70 @@ +Other patches and addons for OpenSSH. Please send submissions to +djm@mindrot.org + +Externally maintained +--------------------- + +SSH Proxy Command -- connect.c + +Shun-ichi GOTO <gotoh@imasy.or.jp> 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. + +http://www.taiyo.co.jp/~gotoh/ssh/connect.html + + +X11 SSH Askpass: + +Jim Knoble <jmknoble@pobox.com> 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' <phil@hands.com> 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 <domi@saargate.de> + +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 +
diff --git a/openssh-6.0p1/contrib/aix/README b/openssh-6.0p1/contrib/aix/README new file mode 100644 index 0000000..2a29935 --- /dev/null +++ b/openssh-6.0p1/contrib/aix/README
@@ -0,0 +1,50 @@ +Overview: + +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 $
diff --git a/openssh-6.0p1/contrib/aix/buildbff.sh b/openssh-6.0p1/contrib/aix/buildbff.sh new file mode 100755 index 0000000..81d8cc3 --- /dev/null +++ b/openssh-6.0p1/contrib/aix/buildbff.sh
@@ -0,0 +1,381 @@ +#!/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 <<EOD >../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 <<EOF >>../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 <<EOF >../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. +
diff --git a/openssh-6.0p1/contrib/aix/inventory.sh b/openssh-6.0p1/contrib/aix/inventory.sh new file mode 100755 index 0000000..e2641e7 --- /dev/null +++ b/openssh-6.0p1/contrib/aix/inventory.sh
@@ -0,0 +1,63 @@ +#!/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"; + } +}'
diff --git a/openssh-6.0p1/contrib/aix/pam.conf b/openssh-6.0p1/contrib/aix/pam.conf new file mode 100644 index 0000000..f1528b0 --- /dev/null +++ b/openssh-6.0p1/contrib/aix/pam.conf
@@ -0,0 +1,20 @@ +# +# 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
diff --git a/openssh-6.0p1/contrib/caldera/openssh.spec b/openssh-6.0p1/contrib/caldera/openssh.spec new file mode 100644 index 0000000..90be57d --- /dev/null +++ b/openssh-6.0p1/contrib/caldera/openssh.spec
@@ -0,0 +1,366 @@ + +# Some of this will need re-evaluation post-LSB. The SVIdir is there +# because the link appeared broken. The rest is for easy compilation, +# the tradeoff open to discussion. (LC957) + +%define SVIdir /etc/rc.d/init.d +%{!?_defaultdocdir:%define _defaultdocdir %{_prefix}/share/doc/packages} +%{!?SVIcdir:%define SVIcdir /etc/sysconfig/daemons} + +%define _mandir %{_prefix}/share/man/en +%define _sysconfdir /etc/ssh +%define _libexecdir %{_libdir}/ssh + +# Do we want to disable root_login? (1=yes 0=no) +%define no_root_login 0 + +#old cvs stuff. please update before use. may be deprecated. +%define use_stable 1 +%define version 6.0p1 +%if %{use_stable} + %define cvs %{nil} + %define release 1 +%else + %define cvs cvs20050315 + %define release 0r1 +%endif +%define xsa x11-ssh-askpass +%define askpass %{xsa}-1.2.4.1 + +# OpenSSH privilege separation requires a user & group ID +%define sshd_uid 67 +%define sshd_gid 67 + +Name : openssh +Version : %{version}%{cvs} +Release : %{release} +Group : System/Network + +Summary : OpenSSH free Secure Shell (SSH) implementation. +Summary(de) : OpenSSH - freie Implementation der Secure Shell (SSH). +Summary(es) : OpenSSH implementación libre de Secure Shell (SSH). +Summary(fr) : Implémentation libre du shell sécurisé OpenSSH (SSH). +Summary(it) : Implementazione gratuita OpenSSH della Secure Shell. +Summary(pt) : Implementação livre OpenSSH do protocolo 'Secure Shell' (SSH). +Summary(pt_BR) : Implementação livre OpenSSH do protocolo Secure Shell (SSH). + +Copyright : BSD +Packager : Raymund Will <ray@caldera.de> +URL : http://www.openssh.com/ + +Obsoletes : ssh, ssh-clients, openssh-clients + +BuildRoot : /tmp/%{name}-%{version} +BuildRequires : XFree86-imake + +# %{use_stable}==1: ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable +# %{use_stable}==0: :pserver:cvs@bass.directhit.com:/cvs/openssh_cvs +Source0: see-above:/.../openssh-%{version}.tar.gz +%if %{use_stable} +Source1: see-above:/.../openssh-%{version}.tar.gz.asc +%endif +Source2: http://www.jmknoble.net/software/%{xsa}/%{askpass}.tar.gz +Source3: http://www.openssh.com/faq.html + +%Package server +Group : System/Network +Requires : openssh = %{version} +Obsoletes : ssh-server + +Summary : OpenSSH Secure Shell protocol server (sshd). +Summary(de) : OpenSSH Secure Shell Protocol-Server (sshd). +Summary(es) : Servidor del protocolo OpenSSH Secure Shell (sshd). +Summary(fr) : Serveur de protocole du shell sécurisé OpenSSH (sshd). +Summary(it) : Server OpenSSH per il protocollo Secure Shell (sshd). +Summary(pt) : Servidor do protocolo 'Secure Shell' OpenSSH (sshd). +Summary(pt_BR) : Servidor do protocolo Secure Shell OpenSSH (sshd). + + +%Package askpass +Group : System/Network +Requires : openssh = %{version} +URL : http://www.jmknoble.net/software/x11-ssh-askpass/ +Obsoletes : ssh-extras + +Summary : OpenSSH X11 pass-phrase dialog. +Summary(de) : OpenSSH X11 Passwort-Dialog. +Summary(es) : Aplicación de petición de frase clave OpenSSH X11. +Summary(fr) : Dialogue pass-phrase X11 d'OpenSSH. +Summary(it) : Finestra di dialogo X11 per la frase segreta di OpenSSH. +Summary(pt) : Diálogo de pedido de senha para X11 do OpenSSH. +Summary(pt_BR) : Diálogo de pedido de senha para X11 do OpenSSH. + + +%Description +OpenSSH (Secure Shell) provides access to a remote system. It replaces +telnet, rlogin, rexec, and rsh, and provides 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. + +%Description -l de +OpenSSH (Secure Shell) stellt den Zugang zu anderen Rechnern her. Es ersetzt +telnet, rlogin, rexec und rsh und stellt eine sichere, verschlüsselte +Verbindung zwischen zwei nicht vertrauenswürdigen Hosts über eine unsicheres +Netzwerk her. X11 Verbindungen und beliebige andere TCP/IP Ports können ebenso +über den sicheren Channel weitergeleitet werden. + +%Description -l es +OpenSSH (Secure Shell) proporciona acceso a sistemas remotos. Reemplaza a +telnet, rlogin, rexec, y rsh, y proporciona comunicaciones seguras encriptadas +entre dos equipos entre los que no se ha establecido confianza a través de una +red insegura. Las conexiones X11 y puertos TCP/IP arbitrarios también pueden +ser canalizadas sobre el canal seguro. + +%Description -l fr +OpenSSH (Secure Shell) fournit un accès à un système distant. Il remplace +telnet, rlogin, rexec et rsh, tout en assurant des communications cryptées +securisées entre deux hôtes non fiabilisés sur un réseau non sécurisé. Des +connexions X11 et des ports TCP/IP arbitraires peuvent également être +transmis sur le canal sécurisé. + +%Description -l it +OpenSSH (Secure Shell) fornisce l'accesso ad un sistema remoto. +Sostituisce telnet, rlogin, rexec, e rsh, e fornisce comunicazioni sicure +e crittate tra due host non fidati su una rete non sicura. Le connessioni +X11 ad una porta TCP/IP arbitraria possono essere inoltrate attraverso +un canale sicuro. + +%Description -l pt +OpenSSH (Secure Shell) fornece acesso a um sistema remoto. Substitui o +telnet, rlogin, rexec, e o rsh e fornece comunicações seguras e cifradas +entre duas máquinas sem confiança mútua sobre uma rede insegura. +Ligações X11 e portos TCP/IP arbitrários também poder ser reenviados +pelo canal seguro. + +%Description -l pt_BR +O OpenSSH (Secure Shell) fornece acesso a um sistema remoto. Substitui o +telnet, rlogin, rexec, e o rsh e fornece comunicações seguras e criptografadas +entre duas máquinas sem confiança mútua sobre uma rede insegura. +Ligações X11 e portas TCP/IP arbitrárias também podem ser reenviadas +pelo canal seguro. + +%Description server +This package installs the sshd, the server portion of OpenSSH. + +%Description -l de server +Dieses Paket installiert den sshd, den Server-Teil der OpenSSH. + +%Description -l es server +Este paquete instala sshd, la parte servidor de OpenSSH. + +%Description -l fr server +Ce paquetage installe le 'sshd', partie serveur de OpenSSH. + +%Description -l it server +Questo pacchetto installa sshd, il server di OpenSSH. + +%Description -l pt server +Este pacote intala o sshd, o servidor do OpenSSH. + +%Description -l pt_BR server +Este pacote intala o sshd, o servidor do OpenSSH. + +%Description askpass +This package contains an X11-based pass-phrase dialog used per +default by ssh-add(1). It is based on %{askpass} +by Jim Knoble <jmknoble@pobox.com>. + + +%Prep +%setup %([ -z "%{cvs}" ] || echo "-n %{name}_cvs") -a2 +%if ! %{use_stable} + autoreconf +%endif + + +%Build +CFLAGS="$RPM_OPT_FLAGS" \ +%configure \ + --with-pam \ + --with-tcp-wrappers \ + --with-privsep-path=%{_var}/empty/sshd \ + #leave this line for easy edits. + +%__make + +cd %{askpass} +%configure \ + #leave this line for easy edits. + +xmkmf +%__make includes +%__make + + +%Install +[ %{buildroot} != "/" ] && rm -rf %{buildroot} + +make install DESTDIR=%{buildroot} +%makeinstall -C %{askpass} \ + BINDIR=%{_libexecdir} \ + MANPATH=%{_mandir} \ + DESTDIR=%{buildroot} + +# OpenLinux specific configuration +mkdir -p %{buildroot}{/etc/pam.d,%{SVIcdir},%{SVIdir}} +mkdir -p %{buildroot}%{_var}/empty/sshd + +# enabling X11 forwarding on the server is convenient and okay, +# on the client side it's a potential security risk! +%__perl -pi -e 's:#X11Forwarding no:X11Forwarding yes:g' \ + %{buildroot}%{_sysconfdir}/sshd_config + +%if %{no_root_login} +%__perl -pi -e 's:#PermitRootLogin yes:PermitRootLogin no:g' \ + %{buildroot}%{_sysconfdir}/sshd_config +%endif + +install -m644 contrib/caldera/sshd.pam %{buildroot}/etc/pam.d/sshd +# FIXME: disabled, find out why this doesn't work with nis +%__perl -pi -e 's:(.*pam_limits.*):#$1:' \ + %{buildroot}/etc/pam.d/sshd + +install -m 0755 contrib/caldera/sshd.init %{buildroot}%{SVIdir}/sshd + +# the last one is needless, but more future-proof +find %{buildroot}%{SVIdir} -type f -exec \ + %__perl -pi -e 's:\@SVIdir\@:%{SVIdir}:g;\ + s:\@sysconfdir\@:%{_sysconfdir}:g; \ + s:/usr/sbin:%{_sbindir}:g'\ + \{\} \; + +cat <<-EoD > %{buildroot}%{SVIcdir}/sshd + IDENT=sshd + DESCRIPTIVE="OpenSSH secure shell daemon" + # This service will be marked as 'skipped' on boot if there + # is no host key. Use ssh-host-keygen to generate one + ONBOOT="yes" + OPTIONS="" +EoD + +SKG=%{buildroot}%{_sbindir}/ssh-host-keygen +install -m 0755 contrib/caldera/ssh-host-keygen $SKG +# Fix up some path names in the keygen toy^Hol + %__perl -pi -e 's:\@sysconfdir\@:%{_sysconfdir}:g; \ + s:\@sshkeygen\@:%{_bindir}/ssh-keygen:g' \ + %{buildroot}%{_sbindir}/ssh-host-keygen + +# This looks terrible. Expect it to change. +# install remaining docs +DocD="%{buildroot}%{_defaultdocdir}/%{name}-%{version}" +mkdir -p $DocD/%{askpass} +cp -a CREDITS ChangeLog LICENCE OVERVIEW README* TODO PROTOCOL* $DocD +install -p -m 0444 %{SOURCE3} $DocD/faq.html +cp -a %{askpass}/{README,ChangeLog,TODO,SshAskpass*.ad} $DocD/%{askpass} +%if %{use_stable} + cp -p %{askpass}/%{xsa}.man $DocD/%{askpass}/%{xsa}.1 +%else + cp -p %{askpass}/%{xsa}.man %{buildroot}%{_mandir}man1/%{xsa}.1 + ln -s %{xsa}.1 %{buildroot}%{_mandir}man1/ssh-askpass.1 +%endif + +find %{buildroot}%{_mandir} -type f -not -name '*.gz' -print0 | xargs -0r %__gzip -9nf +rm %{buildroot}%{_mandir}/man1/slogin.1 && \ + ln -s %{_mandir}/man1/ssh.1.gz \ + %{buildroot}%{_mandir}/man1/slogin.1.gz + + +%Clean +#%{rmDESTDIR} +[ %{buildroot} != "/" ] && rm -rf %{buildroot} + +%Post +# Generate host key when none is present to get up and running, +# both client and server require this for host-based auth! +# ssh-host-keygen checks for existing keys. +/usr/sbin/ssh-host-keygen +: # to protect the rpm database + +%pre server +%{_sbindir}/groupadd -g %{sshd_gid} sshd 2>/dev/null || : +%{_sbindir}/useradd -d /var/empty/sshd -s /bin/false -u %{sshd_uid} \ + -c "SSH Daemon virtual user" -g sshd sshd 2>/dev/null || : +: # to protect the rpm database + +%Post server +if [ -x %{LSBinit}-install ]; then + %{LSBinit}-install sshd +else + lisa --SysV-init install sshd S55 2:3:4:5 K45 0:1:6 +fi + +! %{SVIdir}/sshd status || %{SVIdir}/sshd restart +: # to protect the rpm database + + +%PreUn server +[ "$1" = 0 ] || exit 0 +! %{SVIdir}/sshd status || %{SVIdir}/sshd stop +if [ -x %{LSBinit}-remove ]; then + %{LSBinit}-remove sshd +else + lisa --SysV-init remove sshd $1 +fi +: # to protect the rpm database + +%Files +%defattr(-,root,root) +%dir %{_sysconfdir} +%config %{_sysconfdir}/ssh_config +%{_bindir}/scp +%{_bindir}/sftp +%{_bindir}/ssh +%{_bindir}/slogin +%{_bindir}/ssh-add +%attr(2755,root,nobody) %{_bindir}/ssh-agent +%{_bindir}/ssh-keygen +%{_bindir}/ssh-keyscan +%dir %{_libexecdir} +%attr(4711,root,root) %{_libexecdir}/ssh-keysign +%{_libexecdir}/ssh-pkcs11-helper +%{_sbindir}/ssh-host-keygen +%dir %{_defaultdocdir}/%{name}-%{version} +%{_defaultdocdir}/%{name}-%{version}/CREDITS +%{_defaultdocdir}/%{name}-%{version}/ChangeLog +%{_defaultdocdir}/%{name}-%{version}/LICENCE +%{_defaultdocdir}/%{name}-%{version}/OVERVIEW +%{_defaultdocdir}/%{name}-%{version}/README* +%{_defaultdocdir}/%{name}-%{version}/TODO +%{_defaultdocdir}/%{name}-%{version}/faq.html +%{_mandir}/man1/* +%{_mandir}/man8/ssh-keysign.8.gz +%{_mandir}/man8/ssh-pkcs11-helper.8.gz +%{_mandir}/man5/ssh_config.5.gz + +%Files server +%defattr(-,root,root) +%dir %{_var}/empty/sshd +%config %{SVIdir}/sshd +%config /etc/pam.d/sshd +%config %{_sysconfdir}/moduli +%config %{_sysconfdir}/sshd_config +%config %{SVIcdir}/sshd +%{_libexecdir}/sftp-server +%{_sbindir}/sshd +%{_mandir}/man5/moduli.5.gz +%{_mandir}/man5/sshd_config.5.gz +%{_mandir}/man8/sftp-server.8.gz +%{_mandir}/man8/sshd.8.gz + +%Files askpass +%defattr(-,root,root) +%{_libexecdir}/ssh-askpass +%{_libexecdir}/x11-ssh-askpass +%{_defaultdocdir}/%{name}-%{version}/%{askpass} + + +%ChangeLog +* Tue Jan 18 2011 Tim Rice <tim@multitalents.net> +- Use CFLAGS from Makefile instead of RPM so build completes. +- Signatures were changed to .asc since 4.1p1. + +* Mon Jan 01 1998 ... +Template Version: 1.31 + +$Id: openssh.spec,v 1.77 2012/04/20 00:58:43 djm Exp $
diff --git a/openssh-6.0p1/contrib/caldera/ssh-host-keygen b/openssh-6.0p1/contrib/caldera/ssh-host-keygen new file mode 100755 index 0000000..86382dd --- /dev/null +++ b/openssh-6.0p1/contrib/caldera/ssh-host-keygen
@@ -0,0 +1,36 @@ +#! /bin/sh +# +# $Id: ssh-host-keygen,v 1.3 2008/11/03 09:16:01 djm Exp $ +# +# This script is normally run only *once* for a given host +# (in a given period of time) -- on updates/upgrades/recovery +# the ssh_host_key* files _should_ be retained! Otherwise false +# "man-in-the-middle-attack" alerts will frighten unsuspecting +# clients... + +keydir=@sysconfdir@ +keygen=@sshkeygen@ + +if [ -f $keydir/ssh_host_key -o \ + -f $keydir/ssh_host_key.pub ]; then + echo "You already have an SSH1 RSA host key in $keydir/ssh_host_key." +else + echo "Generating SSH1 RSA host key." + $keygen -t rsa1 -f $keydir/ssh_host_key -C '' -N '' +fi + +if [ -f $keydir/ssh_host_rsa_key -o \ + -f $keydir/ssh_host_rsa_key.pub ]; then + echo "You already have an SSH2 RSA host key in $keydir/ssh_host_rsa_key." +else + echo "Generating SSH2 RSA host key." + $keygen -t rsa -f $keydir/ssh_host_rsa_key -C '' -N '' +fi + +if [ -f $keydir/ssh_host_dsa_key -o \ + -f $keydir/ssh_host_dsa_key.pub ]; then + echo "You already have an SSH2 DSA host key in $keydir/ssh_host_dsa_key." +else + echo "Generating SSH2 DSA host key." + $keygen -t dsa -f $keydir/ssh_host_dsa_key -C '' -N '' +fi
diff --git a/openssh-6.0p1/contrib/caldera/sshd.init b/openssh-6.0p1/contrib/caldera/sshd.init new file mode 100755 index 0000000..983146f --- /dev/null +++ b/openssh-6.0p1/contrib/caldera/sshd.init
@@ -0,0 +1,125 @@ +#! /bin/bash +# +# $Id: sshd.init,v 1.4 2003/11/21 12:48:57 djm Exp $ +# +### BEGIN INIT INFO +# Provides: +# Required-Start: $network +# Required-Stop: +# Default-Start: 3 4 5 +# Default-Stop: 0 1 2 6 +# Description: sshd +# Bring up/down the OpenSSH secure shell daemon. +### END INIT INFO +# +# Written by Miquel van Smoorenburg <miquels@drinkel.ow.org>. +# Modified for Debian GNU/Linux by Ian Murdock <imurdock@gnu.ai.mit.edu>. +# Modified for OpenLinux by Raymund Will <ray@caldera.de> + +NAME=sshd +DAEMON=/usr/sbin/$NAME +# Hack-Alert(TM)! This is necessary to get around the 'reload'-problem +# created by recent OpenSSH daemon/ssd combinations. See Caldera internal +# PR [linux/8278] for details... +PIDF=/var/run/$NAME.pid +NAME=$DAEMON + +_status() { + [ -z "$1" ] || local pidf="$1" + local ret=-1 + local pid + if [ -n "$pidf" ] && [ -r "$pidf" ]; then + pid=$(head -1 $pidf) + else + pid=$(pidof $NAME) + fi + + if [ ! -e $SVIlock ]; then + # no lock-file => not started == stopped? + ret=3 + elif [ -n "$pidf" -a ! -f "$pidf" ] || [ -z "$pid" ]; then + # pid-file given but not present or no pid => died, but was not stopped + ret=2 + elif [ -r /proc/$pid/cmdline ] && + echo -ne $NAME'\000' | cmp -s - /proc/$pid/cmdline; then + # pid-file given and present or pid found => check process... + # but don't compare exe, as this will fail after an update! + # compares OK => all's well, that ends well... + ret=0 + else + # no such process or exe does not match => stale pid-file or process died + # just recently... + ret=1 + fi + return $ret +} + +# Source function library (and set vital variables). +. @SVIdir@/functions + +case "$1" in + start) + [ ! -e $SVIlock ] || exit 0 + [ -x $DAEMON ] || exit 5 + SVIemptyConfig @sysconfdir@/sshd_config && exit 6 + + if [ ! \( -f @sysconfdir@/ssh_host_key -a \ + -f @sysconfdir@/ssh_host_key.pub \) -a \ + ! \( -f @sysconfdir@/ssh_host_rsa_key -a \ + -f @sysconfdir@/ssh_host_rsa_key.pub \) -a \ + ! \( -f @sysconfdir@/ssh_host_dsa_key -a \ + -f @sysconfdir@/ssh_host_dsa_key.pub \) ]; then + + echo "$SVIsubsys: host key not initialized: skipped!" + echo "$SVIsubsys: use ssh-host-keygen to generate one!" + exit 6 + fi + + echo -n "Starting $SVIsubsys services: " + ssd -S -x $DAEMON -n $NAME -- $OPTIONS + ret=$? + + echo "." + touch $SVIlock + ;; + + stop) + [ -e $SVIlock ] || exit 0 + + echo -n "Stopping $SVIsubsys services: " + ssd -K -p $PIDF -n $NAME + ret=$? + + echo "." + rm -f $SVIlock + ;; + + force-reload|reload) + [ -e $SVIlock ] || exit 0 + + echo "Reloading $SVIsubsys configuration files: " + ssd -K --signal 1 -q -p $PIDF -n $NAME + ret=$? + echo "done." + ;; + + restart) + $0 stop + $0 start + ret=$? + ;; + + status) + _status $PIDF + ret=$? + ;; + + *) + echo "Usage: $SVIscript {[re]start|stop|[force-]reload|status}" + ret=2 + ;; + +esac + +exit $ret +
diff --git a/openssh-6.0p1/contrib/caldera/sshd.pam b/openssh-6.0p1/contrib/caldera/sshd.pam new file mode 100644 index 0000000..f050a9a --- /dev/null +++ b/openssh-6.0p1/contrib/caldera/sshd.pam
@@ -0,0 +1,8 @@ +#%PAM-1.0 +auth required /lib/security/pam_pwdb.so shadow nodelay +account 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
diff --git a/openssh-6.0p1/contrib/cygwin/Makefile b/openssh-6.0p1/contrib/cygwin/Makefile new file mode 100644 index 0000000..a0261f4 --- /dev/null +++ b/openssh-6.0p1/contrib/cygwin/Makefile
@@ -0,0 +1,77 @@ +srcdir=../.. +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."
diff --git a/openssh-6.0p1/contrib/cygwin/README b/openssh-6.0p1/contrib/cygwin/README new file mode 100644 index 0000000..5f911e9 --- /dev/null +++ b/openssh-6.0p1/contrib/cygwin/README
@@ -0,0 +1,237 @@ +This 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. + +Build instructions are at the end of the file. + +=========================================================================== +Important change since 3.7.1p2-2: + +The ssh-host-config file doesn't create the /etc/ssh_config and +/etc/sshd_config files from builtin here-scripts anymore, but it uses +skeleton files installed in /etc/defaults/etc. + +Also it now tries hard to create appropriate permissions on files. +Same applies for ssh-user-config. + +After creating the sshd service with ssh-host-config, it's advisable to +call ssh-user-config for all affected users, also already exising user +configurations. In the latter case, file and directory permissions are +checked and changed, if requireed to match the host configuration. + +Important note for Windows 2003 Server users: +--------------------------------------------- + +2003 Server has a funny new feature. When starting services under SYSTEM +account, these services have nearly all user rights which SYSTEM holds... +except for the "Create a token object" right, which is needed to allow +public key authentication :-( + +There's no way around this, except for creating a substitute account which +has the appropriate privileges. Basically, this account should be member +of the administrators group, plus it should have the following user rights: + + Create a token object + Logon as a service + Replace a process level token + Increase Quota + +The ssh-host-config script asks you, if it should create such an account, +called "sshd_server". If you say "no" here, you're on your own. Please +follow the instruction in ssh-host-config exactly if possible. Note that +ssh-user-config sets the permissions on 2003 Server machines dependent of +whether a sshd_server account exists or not. +=========================================================================== + +=========================================================================== +Important change since 3.4p1-2: + +This version adds privilege separation as default setting, see +/usr/doc/openssh/README.privsep. According to that document the +privsep feature requires a non-privileged account called 'sshd'. + +The new ssh-host-config file which is part of this version asks +to create 'sshd' as local user if you want to use privilege +separation. If you confirm, it creates that NT user and adds +the necessary entry to /etc/passwd. + +On 9x/Me systems the script just sets UsePrivilegeSeparation to "no" +since that feature doesn't make any sense on a system which doesn't +differ between privileged and unprivileged users. + +The new ssh-host-config script also adds the /var/empty directory +needed by privilege separation. When creating the /var/empty directory +by yourself, please note that in contrast to the README.privsep document +the owner sshould not be "root" but the user which is running sshd. So, +in the standard configuration this is SYSTEM. The ssh-host-config script +chowns /var/empty accordingly. +=========================================================================== + +=========================================================================== +Important change since 3.0.1p1-2: + +This version introduces the ability to register sshd as service on +Windows 9x/Me systems. This is done only when the options -D and/or +-d are not given. +=========================================================================== + +=========================================================================== +Important change since 2.9p2: + +Since Cygwin is able to switch user context without password beginning +with version 1.3.2, OpenSSH now allows to do so when it's running under +a version >= 1.3.2. Keep in mind that `ntsec' has to be activated to +allow that feature. +=========================================================================== + +=========================================================================== +Important change since 2.3.0p1: + +When using `ntea' or `ntsec' you now have to care for the ownership +and permission bits of your host key files and your private key files. +The host key files have to be owned by the NT account which starts +sshd. The user key files have to be owned by the user. The permission +bits of the private key files (host and user) have to be at least +rw------- (0600)! + +Note that this is forced under `ntsec' only if the files are on a NTFS +filesystem (which is recommended) due to the lack of any basic security +features of the FAT/FAT32 filesystems. +=========================================================================== + +If you are installing OpenSSH the first time, you can generate global config +files and server keys 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. + +If you are updating your installation you may run the above ssh-host-config +as well to move your configuration files to the new location and to +erase the files at the old location. + +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 <options> Use "options" as value for CYGWIN environment var. + --port -p <n> sshd listens on port n. + --pwd -w <passwd> Use "pwd" as password for user 'sshd_server'. + +Additionally ssh-host-config now asks if it should install sshd as a +service when running under NT/W2K. This requires cygrunsrv installed. + +You can create the private and public keys for a user now by running + + /usr/bin/ssh-user-config + +under the users account. + +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. + +Install sshd as daemon via cygrunsrv.exe (recommended on NT/W2K), via inetd +(results in very slow deamon startup!) or from the command line (recommended +on 9X/ME). + +If you start sshd as deamon via cygrunsrv.exe you MUST give the +"-D" option to sshd. Otherwise the service can't get started at all. + +If starting via inetd, copy sshd to eg. /usr/sbin/in.sshd and add the +following line to your inetd.conf file: + +ssh stream tcp nowait root /usr/sbin/in.sshd sshd -i + +Moreover you'll have to add the following line to your +${SYSTEMROOT}/system32/drivers/etc/services file: + + ssh 22/tcp #SSH daemon + +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! + +You may use all features of the CYGWIN=ntsec setting the same +way as they are used by Cygwin's login(1) port: + + The pw_gecos field may contain an additional field, that begins + with (upper case!) "U-", followed by the domain and the username + separated by a backslash. + CAUTION: The SID _must_ remain the _last_ field in pw_gecos! + BTW: The field separator in pw_gecos is the comma. + The username in pw_name itself may be any nice name: + + domuser::1104:513:John Doe,U-domain\user,S-1-5-21-... + + Now you may use `domuser' as your login name with telnet! + This is possible additionally for local users, if you don't like + your NT login name ;-) You only have to leave out the domain: + + locuser::1104:513:John Doe,U-user,S-1-5-21-... + +Note that the CYGWIN=ntsec setting is required for public key authentication. + +SSH2 server and user keys are generated by the `ssh-*-config' scripts +as well. + +If you want to build from source, the following options to +configure are used for the Cygwin binary distribution: + + --prefix=/usr \ + --sysconfdir=/etc \ + --libexecdir='${sbindir}' \ + --localstatedir=/var \ + --datadir='${prefix}/share' \ + --mandir='${datadir}/man' \ + --infodir='${datadir}/info' + --with-tcp-wrappers + --with-libedit + +If you want to create a Cygwin package, equivalent to the one +in the Cygwin binary distribution, install like this: + + mkdir /tmp/cygwin-ssh + cd ${builddir} + make install DESTDIR=/tmp/cygwin-ssh + cd ${srcdir}/contrib/cygwin + make cygwin-postinstall DESTDIR=/tmp/cygwin-ssh + cd /tmp/cygwin-ssh + find * \! -type d | tar cvjfT my-openssh.tar.bz2 - + +You must have installed the following packages to be able to build OpenSSH: + +- zlib +- openssl-devel + +If you want to build with --with-tcp-wrappers, you also need the package + +- tcp_wrappers + +If you want to build with --with-libedit, you also need the package + +- libedit-devel + +Please send requests, error reports etc. to cygwin@cygwin.com. + + +Have fun, + +Corinna Vinschen +Cygwin Developer +Red Hat Inc.
diff --git a/openssh-6.0p1/contrib/cygwin/ssh-host-config b/openssh-6.0p1/contrib/cygwin/ssh-host-config new file mode 100644 index 0000000..3ac39a6 --- /dev/null +++ b/openssh-6.0p1/contrib/cygwin/ssh-host-config
@@ -0,0 +1,757 @@ +#!/bin/bash +# +# ssh-host-config, Copyright 2000-2011 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/mount cygwin + /usr/bin/ps cygwin + /usr/bin/setfacl 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 + +port_number=22 +privsep_configured=no +privsep_used=yes +cygwin_value="" +user_account= +password_value= +opt_force=no + +# ====================================================================== +# Routine: create_host_keys +# ====================================================================== +create_host_keys() { + local ret=0 + + if [ ! -f "${SYSCONFDIR}/ssh_host_key" ] + then + csih_inform "Generating ${SYSCONFDIR}/ssh_host_key" + if ! /usr/bin/ssh-keygen -t rsa1 -f ${SYSCONFDIR}/ssh_host_key -N '' > /dev/null + then + csih_warning "Generating ${SYSCONFDIR}/ssh_host_key failed!" + let ++ret + fi + fi + + if [ ! -f "${SYSCONFDIR}/ssh_host_rsa_key" ] + then + csih_inform "Generating ${SYSCONFDIR}/ssh_host_rsa_key" + if ! /usr/bin/ssh-keygen -t rsa -f ${SYSCONFDIR}/ssh_host_rsa_key -N '' > /dev/null + then + csih_warning "Generating ${SYSCONFDIR}/ssh_host_key failed!" + let ++ret + fi + fi + + if [ ! -f "${SYSCONFDIR}/ssh_host_dsa_key" ] + then + csih_inform "Generating ${SYSCONFDIR}/ssh_host_dsa_key" + if ! /usr/bin/ssh-keygen -t dsa -f ${SYSCONFDIR}/ssh_host_dsa_key -N '' > /dev/null + then + csih_warning "Generating ${SYSCONFDIR}/ssh_host_key failed!" + let ++ret + fi + fi + + if [ ! -f "${SYSCONFDIR}/ssh_host_ecdsa_key" ] + then + csih_inform "Generating ${SYSCONFDIR}/ssh_host_ecdsa_key" + if ! /usr/bin/ssh-keygen -t ecdsa -f ${SYSCONFDIR}/ssh_host_ecdsa_key -N '' > /dev/null + then + csih_warning "Generating ${SYSCONFDIR}/ssh_host_key failed!" + let ++ret + fi + fi + return $ret +} # --- End of create_host_keys --- # + +# ====================================================================== +# 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}"` + + # Remove sshd 22/port from services + if [ `/usr/bin/grep -q 'sshd[ \t][ \t]*22' "${_services}"; echo $?` -eq 0 ] + then + /usr/bin/grep -v 'sshd[ \t][ \t]*22' "${_services}" > "${_serv_tmp}" + if [ -f "${_serv_tmp}" ] + then + if /usr/bin/mv "${_serv_tmp}" "${_services}" + then + csih_inform "Removing sshd from ${_wservices}" + else + csih_warning "Removing sshd from ${_wservices} failed!" + let ++ret + fi + /usr/bin/rm -f "${_serv_tmp}" + else + csih_warning "Removing sshd from ${_wservices} failed!" + let ++ret + fi + fi + + # Add ssh 22/tcp and ssh 22/udp to services + if [ `/usr/bin/grep -q 'ssh[ \t][ \t]*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_privsep +# MODIFIES: privsep_configured privsep_used +# ====================================================================== +sshd_privsep() { + local sshdconfig_tmp + local ret=0 + + if [ "${privsep_configured}" != "yes" ] + then + csih_inform "Privilege separation is set to yes by default since OpenSSH 3.3." + csih_inform "However, this requires a non-privileged account called 'sshd'." + csih_inform "For more info on privilege separation read /usr/share/doc/openssh/README.privsep." + if csih_request "Should privilege separation be used?" + then + privsep_used=yes + if ! csih_create_unprivileged_user sshd + then + csih_error_recoverable "Couldn't create user 'sshd'!" + csih_error_recoverable "Privilege separation set to 'no' again!" + csih_error_recoverable "Check your ${SYSCONFDIR}/sshd_config file!" + let ++ret + privsep_used=no + fi + else + privsep_used=no + fi + fi + + # Create default sshd_config from skeleton files in /etc/defaults/etc or + # modify to add the missing privsep configuration option + if /usr/bin/cmp "${SYSCONFDIR}/sshd_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/sshd_config" >/dev/null 2>&1 + then + csih_inform "Updating ${SYSCONFDIR}/sshd_config file" + sshdconfig_tmp=${SYSCONFDIR}/sshd_config.$$ + /usr/bin/sed -e "s/^#UsePrivilegeSeparation yes/UsePrivilegeSeparation ${privsep_used}/ + s/^#Port 22/Port ${port_number}/ + s/^#StrictModes yes/StrictModes no/" \ + < ${SYSCONFDIR}/sshd_config \ + > "${sshdconfig_tmp}" + if ! /usr/bin/mv "${sshdconfig_tmp}" ${SYSCONFDIR}/sshd_config + then + csih_warning "Setting privilege separation to 'yes' failed!" + csih_warning "Check your ${SYSCONFDIR}/sshd_config file!" + let ++ret + fi + elif [ "${privsep_configured}" != "yes" ] + then + echo >> ${SYSCONFDIR}/sshd_config + if ! echo "UsePrivilegeSeparation ${privsep_used}" >> ${SYSCONFDIR}/sshd_config + then + csih_warning "Setting privilege separation to 'yes' failed!" + csih_warning "Check your ${SYSCONFDIR}/sshd_config file!" + let ++ret + fi + fi + return $ret +} # --- End of sshd_privsep --- # + +# ====================================================================== +# 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 '^[ \t]*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@[ \t]*//' < "${_sshd_inetd_conf}" > "${_sshd_inetd_conf_tmp}" + else + /usr/bin/sed -e 's/@COMMENT@[ \t]*/# /' < "${_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 '^[ \t]*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 '^[# \t]*sshd' "${_inetcnf}"; echo $?` -eq 0 ] + then + /usr/bin/grep -v '^[# \t]*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 + accnt_name="SYSTEM:" + elif [[ "${accnt_name}" =~ ^\.\\ ]] + then + # Convert "." domain to local machine name + accnt_name="U-${COMPUTERNAME}${accnt_name#.}," + fi + run_service_as=$(/usr/bin/grep -Fi "${accnt_name}" /etc/passwd | /usr/bin/awk -F: '{print $1;}') + if [ -z "${run_service_as}" ] + then + csih_warning "Couldn't determine name of user running sshd service from /etc/passwd!" + 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." + csih_warning "Please re-run the mkpasswd tool to make sure the /etc/passwd" + csih_warning "file is in a good shape." + 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 sshd >/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 sshd -d "CYGWIN sshd" -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 sshd -d "CYGWIN sshd" -p /usr/sbin/sshd \ + -a "-D" -y tcpip "${cygwin_env[@]}" \ + -u "${run_service_as}" -w "${password}" + then + 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 sshd' or" + csih_inform "\`cygrunsrv -S sshd'. Otherwise, it will start automatically" + csih_inform "after the next reboot." + fi + fi + + if /usr/bin/cygrunsrv -Q sshd >/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 + ;; + + -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 <options> Use \"options\" as value for CYGWIN environment var." + echo " --port -p <n> sshd listens on port n." + echo " --user -u <account> privileged user for service." + echo " --pwd -w <passwd> Use \"pwd\" as password for privileged user." + echo " --privileged On Windows NT/2k/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 + for i in $(/usr/bin/id -G) + do + /usr/bin/awk -F: "/[^:]*:[^:]*:$i:/{ print \" \" \$1; }" /etc/group + done + 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 + +# Check for ${SYSCONFDIR} directory +csih_make_dir "${SYSCONFDIR}" "Cannot create global configuration files." +if ! /usr/bin/chmod 775 "${SYSCONFDIR}" >/dev/null 2>&1 +then + csih_warning "Can't set permissions on ${SYSCONFDIR}!" + let ++warning_cnt +fi +if ! /usr/bin/setfacl -m u:system:rwx "${SYSCONFDIR}" >/dev/null 2>&1 +then + csih_warning "Can't set extended permissions on ${SYSCONFDIR}!" + let ++warning_cnt +fi + +# Check for /var/log directory +csih_make_dir "${LOCALSTATEDIR}/log" "Cannot create log directory." +if ! /usr/bin/chmod 775 "${LOCALSTATEDIR}/log" >/dev/null 2>&1 +then + csih_warning "Can't set permissions on ${LOCALSTATEDIR}/log!" + let ++warning_cnt +fi +if ! /usr/bin/setfacl -m u:system:rwx "${LOCALSTATEDIR}/log" >/dev/null 2>&1 +then + csih_warning "Can't set extended permissions on ${LOCALSTATEDIR}/log!" + let ++warning_cnt +fi + +# 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 +if ! /usr/bin/setfacl -m u:system:rwx "${LOCALSTATEDIR}/empty" >/dev/null 2>&1 +then + csih_warning "Can't set extended permissions on ${LOCALSTATEDIR}/empty!" + let ++warning_cnt +fi + +# host keys +create_host_keys || let warning_cnt+=$? + +# handle ssh_config +csih_install_config "${SYSCONFDIR}/ssh_config" "${SYSCONFDIR}/defaults" || let ++warning_cnt +if /usr/bin/cmp "${SYSCONFDIR}/ssh_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/ssh_config" >/dev/null 2>&1 +then + if [ "${port_number}" != "22" ] + then + csih_inform "Updating ${SYSCONFDIR}/ssh_config file with requested port" + echo "Host localhost" >> ${SYSCONFDIR}/ssh_config + echo " Port ${port_number}" >> ${SYSCONFDIR}/ssh_config + fi +fi + +# handle sshd_config (and privsep) +csih_install_config "${SYSCONFDIR}/sshd_config" "${SYSCONFDIR}/defaults" || let ++warning_cnt +if ! /usr/bin/cmp "${SYSCONFDIR}/sshd_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/sshd_config" >/dev/null 2>&1 +then + /usr/bin/grep -q UsePrivilegeSeparation ${SYSCONFDIR}/sshd_config && privsep_configured=yes +fi +sshd_privsep || 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
diff --git a/openssh-6.0p1/contrib/cygwin/ssh-user-config b/openssh-6.0p1/contrib/cygwin/ssh-user-config new file mode 100644 index 0000000..027ae60 --- /dev/null +++ b/openssh-6.0p1/contrib/cygwin/ssh-user-config
@@ -0,0 +1,272 @@ +#!/bin/bash +# +# ssh-user-config, Copyright 2000-2008 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() { + local uid=$(id -u) + pwdhome=$(awk -F: '{ if ( $3 == '${uid}' ) print $6; }' < ${SYSCONFDIR}/passwd) + if [ "X${pwdhome}" = "X" ] + then + csih_error_multi \ + "There is no home directory set for you in ${SYSCONFDIR}/passwd." \ + 'Setting $HOME is not sufficient!' + fi + + if [ ! -d "${pwdhome}" ] + then + csih_error_multi \ + "${pwdhome} is set in ${SYSCONFDIR}/passwd 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 ${SYSCONFDIR}/passwd 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 csih_is_nt -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 [ csih_is_nt -a -e "${pwdhome}/.ssh/authorized_keys" ] + then + if ! setfacl -m "u::rw-,g::---,o::---" "${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 + ;; + + --privileged ) + csih_FORCE_PRIVILEGED_USER=yes + ;; + + *) + 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 " --privileged On Windows NT/2k/XP, assume privileged user" + echo " instead of LocalSystem for sshd service." + echo + exit 1 + ;; + + esac +done + +# ====================================================================== +# Action! +# ====================================================================== + +# Check passwd file +if [ ! -f ${SYSCONFDIR}/passwd ] +then + csih_error_multi \ + "${SYSCONFDIR}/passwd is nonexistant. Please generate an ${SYSCONFDIR}/passwd file" \ + 'first using mkpasswd. Check if it contains an entry for you and' \ + 'please care for the home directory in your entry as well.' +fi + +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!" + +
diff --git a/openssh-6.0p1/contrib/cygwin/sshd-inetd b/openssh-6.0p1/contrib/cygwin/sshd-inetd new file mode 100644 index 0000000..aa6bf07 --- /dev/null +++ b/openssh-6.0p1/contrib/cygwin/sshd-inetd
@@ -0,0 +1,4 @@ +# 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 +
diff --git a/openssh-6.0p1/contrib/findssl.sh b/openssh-6.0p1/contrib/findssl.sh new file mode 100644 index 0000000..263fd26 --- /dev/null +++ b/openssh-6.0p1/contrib/findssl.sh
@@ -0,0 +1,186 @@ +#!/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 <<EOD +#include <stdio.h> +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
diff --git a/openssh-6.0p1/contrib/gnome-ssh-askpass1.c b/openssh-6.0p1/contrib/gnome-ssh-askpass1.c new file mode 100644 index 0000000..4d51032 --- /dev/null +++ b/openssh-6.0p1/contrib/gnome-ssh-askpass1.c
@@ -0,0 +1,171 @@ +/* + * 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 <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <gnome.h> +#include <X11/Xlib.h> +#include <gdk/gdkx.h> + +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 <enter> 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); +}
diff --git a/openssh-6.0p1/contrib/gnome-ssh-askpass2.c b/openssh-6.0p1/contrib/gnome-ssh-askpass2.c new file mode 100644 index 0000000..9d97c30 --- /dev/null +++ b/openssh-6.0p1/contrib/gnome-ssh-askpass2.c
@@ -0,0 +1,223 @@ +/* + * 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 <nalin@redhat.com> */ + +/* + * 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 <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <X11/Xlib.h> +#include <gtk/gtk.h> +#include <gdk/gdkx.h> + +static void +report_failed_grab (const char *what) +{ + GtkWidget *err; + + err = gtk_message_dialog_new(NULL, 0, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + "Could not grab %s. " + "A malicious client may be eavesdropping " + "on your session.", what); + gtk_window_set_position(GTK_WINDOW(err), GTK_WIN_POS_CENTER); + gtk_label_set_line_wrap(GTK_LABEL((GTK_MESSAGE_DIALOG(err))->label), + TRUE); + + gtk_dialog_run(GTK_DIALOG(err)); + + gtk_widget_destroy(err); +} + +static void +ok_dialog(GtkWidget *entry, gpointer dialog) +{ + g_return_if_fail(GTK_IS_DIALOG(dialog)); + gtk_dialog_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); +} + +static int +passphrase_dialog(char *message) +{ + const char *failed; + char *passphrase, *local; + int result, grab_tries, grab_server, grab_pointer; + GtkWidget *dialog, *entry; + GdkGrabStatus status; + + grab_server = (getenv("GNOME_SSH_ASKPASS_GRAB_SERVER") != NULL); + grab_pointer = (getenv("GNOME_SSH_ASKPASS_GRAB_POINTER") != NULL); + grab_tries = 0; + + dialog = gtk_message_dialog_new(NULL, 0, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_OK_CANCEL, + "%s", + message); + + entry = gtk_entry_new(); + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), entry, FALSE, + FALSE, 0); + gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); + gtk_widget_grab_focus(entry); + gtk_widget_show(entry); + + gtk_window_set_title(GTK_WINDOW(dialog), "OpenSSH"); + gtk_window_set_position (GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); + gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE); + gtk_label_set_line_wrap(GTK_LABEL((GTK_MESSAGE_DIALOG(dialog))->label), + TRUE); + + /* Make <enter> close dialog */ + gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); + g_signal_connect(G_OBJECT(entry), "activate", + G_CALLBACK(ok_dialog), dialog); + + gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE); + + /* Grab focus */ + gtk_widget_show_now(dialog); + if (grab_pointer) { + for(;;) { + status = gdk_pointer_grab( + (GTK_WIDGET(dialog))->window, TRUE, 0, NULL, + NULL, GDK_CURRENT_TIME); + if (status == GDK_GRAB_SUCCESS) + break; + usleep(GRAB_WAIT * 1000); + if (++grab_tries > GRAB_TRIES) { + failed = "mouse"; + goto nograb; + } + } + } + for(;;) { + status = gdk_keyboard_grab((GTK_WIDGET(dialog))->window, + FALSE, GDK_CURRENT_TIME); + if (status == GDK_GRAB_SUCCESS) + break; + usleep(GRAB_WAIT * 1000); + if (++grab_tries > GRAB_TRIES) { + failed = "keyboard"; + goto nograbkb; + } + } + if (grab_server) { + gdk_x11_grab_server(); + } + + result = gtk_dialog_run(GTK_DIALOG(dialog)); + + /* Ungrab */ + if (grab_server) + XUngrabServer(GDK_DISPLAY()); + if (grab_pointer) + gdk_pointer_ungrab(GDK_CURRENT_TIME); + gdk_keyboard_ungrab(GDK_CURRENT_TIME); + gdk_flush(); + + /* Report passphrase if user selected OK */ + passphrase = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry))); + if (result == GTK_RESPONSE_OK) { + local = g_locale_from_utf8(passphrase, strlen(passphrase), + NULL, NULL, NULL); + if (local != NULL) { + puts(local); + memset(local, '\0', strlen(local)); + g_free(local); + } else { + puts(passphrase); + } + } + + /* Zero passphrase in memory */ + memset(passphrase, '\b', strlen(passphrase)); + gtk_entry_set_text(GTK_ENTRY(entry), passphrase); + memset(passphrase, '\0', strlen(passphrase)); + g_free(passphrase); + + gtk_widget_destroy(dialog); + return (result == GTK_RESPONSE_OK ? 0 : -1); + + /* At least one grab failed - ungrab what we got, and report + the failure to the user. Note that XGrabServer() cannot + fail. */ + nograbkb: + gdk_pointer_ungrab(GDK_CURRENT_TIME); + nograb: + if (grab_server) + XUngrabServer(GDK_DISPLAY()); + gtk_widget_destroy(dialog); + + report_failed_grab(failed); + + return (-1); +} + +int +main(int argc, char **argv) +{ + char *message; + int result; + + gtk_init(&argc, &argv); + + if (argc > 1) { + message = g_strjoinv(" ", argv + 1); + } else { + message = g_strdup("Enter your OpenSSH passphrase:"); + } + + setvbuf(stdout, 0, _IONBF, 0); + result = passphrase_dialog(message); + g_free(message); + + return (result); +}
diff --git a/openssh-6.0p1/contrib/hpux/README b/openssh-6.0p1/contrib/hpux/README new file mode 100644 index 0000000..f8bfa84 --- /dev/null +++ b/openssh-6.0p1/contrib/hpux/README
@@ -0,0 +1,45 @@ +README for OpenSSH HP-UX contrib files +Kevin Steves <stevesk@pobox.com> + +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
diff --git a/openssh-6.0p1/contrib/hpux/egd b/openssh-6.0p1/contrib/hpux/egd new file mode 100644 index 0000000..21af0bd --- /dev/null +++ b/openssh-6.0p1/contrib/hpux/egd
@@ -0,0 +1,15 @@ +# 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=
diff --git a/openssh-6.0p1/contrib/hpux/egd.rc b/openssh-6.0p1/contrib/hpux/egd.rc new file mode 100755 index 0000000..919dea7 --- /dev/null +++ b/openssh-6.0p1/contrib/hpux/egd.rc
@@ -0,0 +1,98 @@ +#!/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
diff --git a/openssh-6.0p1/contrib/hpux/sshd b/openssh-6.0p1/contrib/hpux/sshd new file mode 100644 index 0000000..8eb5e92 --- /dev/null +++ b/openssh-6.0p1/contrib/hpux/sshd
@@ -0,0 +1,5 @@ +# SSHD_START: Set to 1 to start SSH daemon +# SSHD_ARGS: Command line arguments to pass to sshd +# +SSHD_START=1 +SSHD_ARGS=
diff --git a/openssh-6.0p1/contrib/hpux/sshd.rc b/openssh-6.0p1/contrib/hpux/sshd.rc new file mode 100755 index 0000000..f9a1099 --- /dev/null +++ b/openssh-6.0p1/contrib/hpux/sshd.rc
@@ -0,0 +1,90 @@ +#!/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
diff --git a/openssh-6.0p1/contrib/redhat/gnome-ssh-askpass.csh b/openssh-6.0p1/contrib/redhat/gnome-ssh-askpass.csh new file mode 100644 index 0000000..dd77712 --- /dev/null +++ b/openssh-6.0p1/contrib/redhat/gnome-ssh-askpass.csh
@@ -0,0 +1 @@ +setenv SSH_ASKPASS /usr/libexec/openssh/gnome-ssh-askpass
diff --git a/openssh-6.0p1/contrib/redhat/gnome-ssh-askpass.sh b/openssh-6.0p1/contrib/redhat/gnome-ssh-askpass.sh new file mode 100644 index 0000000..355189f --- /dev/null +++ b/openssh-6.0p1/contrib/redhat/gnome-ssh-askpass.sh
@@ -0,0 +1,2 @@ +SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass +export SSH_ASKPASS
diff --git a/openssh-6.0p1/contrib/redhat/openssh.spec b/openssh-6.0p1/contrib/redhat/openssh.spec new file mode 100644 index 0000000..d4e44d2 --- /dev/null +++ b/openssh-6.0p1/contrib/redhat/openssh.spec
@@ -0,0 +1,812 @@ +%define ver 6.0p1 +%define rel 1 + +# OpenSSH privilege separation requires a user & group ID +%define sshd_uid 74 +%define sshd_gid 74 + +# Version of ssh-askpass +%define aversion 1.2.4.1 + +# Do we want to disable building of x11-askpass? (1=yes 0=no) +%define no_x11_askpass 0 + +# Do we want to disable building of gnome-askpass? (1=yes 0=no) +%define no_gnome_askpass 0 + +# Do we want to link against a static libcrypto? (1=yes 0=no) +%define static_libcrypto 0 + +# Do we want smartcard support (1=yes 0=no) +%define scard 0 + +# Use GTK2 instead of GNOME in gnome-ssh-askpass +%define gtk2 1 + +# Is this build for RHL 6.x? +%define build6x 0 + +# Do we want kerberos5 support (1=yes 0=no) +%define kerberos5 1 + +# Reserve options to override askpass settings with: +# rpm -ba|--rebuild --define 'skip_xxx 1' +%{?skip_x11_askpass:%define no_x11_askpass 1} +%{?skip_gnome_askpass:%define no_gnome_askpass 1} + +# Add option to build without GTK2 for older platforms with only GTK+. +# RedHat <= 7.2 and Red Hat Advanced Server 2.1 are examples. +# rpm -ba|--rebuild --define 'no_gtk2 1' +%{?no_gtk2:%define gtk2 0} + +# Is this a build for RHL 6.x or earlier? +%{?build_6x:%define build6x 1} + +# If this is RHL 6.x, the default configuration has sysconfdir in /usr/etc. +%if %{build6x} +%define _sysconfdir /etc +%endif + +# Options for static OpenSSL link: +# rpm -ba|--rebuild --define "static_openssl 1" +%{?static_openssl:%define static_libcrypto 1} + +# Options for Smartcard support: (needs libsectok and openssl-engine) +# rpm -ba|--rebuild --define "smartcard 1" +%{?smartcard:%define scard 1} + +# Is this a build for the rescue CD (without PAM, with MD5)? (1=yes 0=no) +%define rescue 0 +%{?build_rescue:%define rescue 1} + +# Turn off some stuff for resuce builds +%if %{rescue} +%define kerberos5 0 +%endif + +Summary: The OpenSSH implementation of SSH protocol versions 1 and 2. +Name: openssh +Version: %{ver} +%if %{rescue} +Release: %{rel}rescue +%else +Release: %{rel} +%endif +URL: http://www.openssh.com/portable.html +Source0: ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-%{version}.tar.gz +%if ! %{no_x11_askpass} +Source1: http://www.jmknoble.net/software/x11-ssh-askpass/x11-ssh-askpass-%{aversion}.tar.gz +%endif +License: BSD +Group: Applications/Internet +BuildRoot: %{_tmppath}/%{name}-%{version}-buildroot +Obsoletes: ssh +%if %{build6x} +PreReq: initscripts >= 5.00 +%else +Requires: initscripts >= 5.20 +%endif +BuildRequires: perl, openssl-devel, tcp_wrappers +BuildRequires: /bin/login +%if ! %{build6x} +BuildPreReq: 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-tcp-wrappers \ + --with-rsh=%{_bindir}/rsh \ + --with-default-path=/usr/local/bin:/bin:/usr/bin \ + --with-superuser-path=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin \ + --with-privsep-path=%{_var}/empty/sshd \ + --with-md5-passwords \ +%if %{scard} + --with-smartcard \ +%endif +%if %{rescue} + --without-pam \ +%else + --with-pam \ +%endif +%if %{kerberos5} + --with-kerberos5=$K5DIR \ +%endif + + +%if %{static_libcrypto} +perl -pi -e "s|-lcrypto|%{_libdir}/libcrypto.a|g" Makefile +%endif + +make + +%if ! %{no_x11_askpass} +pushd x11-ssh-askpass-%{aversion} +%configure --libexecdir=%{_libexecdir}/openssh +xmkmf -a +make +popd +%endif + +# Define a variable to toggle gnome1/gtk2 building. This is necessary +# because RPM doesn't handle nested %if statements. +%if %{gtk2} + gtk2=yes +%else + gtk2=no +%endif + +%if ! %{no_gnome_askpass} +pushd contrib +if [ $gtk2 = yes ] ; then + make gnome-ssh-askpass2 + mv gnome-ssh-askpass2 gnome-ssh-askpass +else + make gnome-ssh-askpass1 + mv gnome-ssh-askpass1 gnome-ssh-askpass +fi +popd +%endif + +%install +rm -rf $RPM_BUILD_ROOT +mkdir -p -m755 $RPM_BUILD_ROOT%{_sysconfdir}/ssh +mkdir -p -m755 $RPM_BUILD_ROOT%{_libexecdir}/openssh +mkdir -p -m755 $RPM_BUILD_ROOT%{_var}/empty/sshd + +make install DESTDIR=$RPM_BUILD_ROOT + +install -d $RPM_BUILD_ROOT/etc/pam.d/ +install -d $RPM_BUILD_ROOT/etc/rc.d/init.d +install -d $RPM_BUILD_ROOT%{_libexecdir}/openssh +%if %{build6x} +install -m644 contrib/redhat/sshd.pam.old $RPM_BUILD_ROOT/etc/pam.d/sshd +%else +install -m644 contrib/redhat/sshd.pam $RPM_BUILD_ROOT/etc/pam.d/sshd +%endif +install -m755 contrib/redhat/sshd.init $RPM_BUILD_ROOT/etc/rc.d/init.d/sshd + +%if ! %{no_x11_askpass} +install -s x11-ssh-askpass-%{aversion}/x11-ssh-askpass $RPM_BUILD_ROOT%{_libexecdir}/openssh/x11-ssh-askpass +ln -s x11-ssh-askpass $RPM_BUILD_ROOT%{_libexecdir}/openssh/ssh-askpass +%endif + +%if ! %{no_gnome_askpass} +install -s contrib/gnome-ssh-askpass $RPM_BUILD_ROOT%{_libexecdir}/openssh/gnome-ssh-askpass +%endif + +%if ! %{scard} + rm -f $RPM_BUILD_ROOT/usr/share/openssh/Ssh.bin +%endif + +%if ! %{no_gnome_askpass} +install -m 755 -d $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/ +install -m 755 contrib/redhat/gnome-ssh-askpass.csh $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/ +install -m 755 contrib/redhat/gnome-ssh-askpass.sh $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/ +%endif + +perl -pi -e "s|$RPM_BUILD_ROOT||g" $RPM_BUILD_ROOT%{_mandir}/man*/* + +%clean +rm -rf $RPM_BUILD_ROOT + +%triggerun server -- ssh-server +if [ "$1" != 0 -a -r /var/run/sshd.pid ] ; then + touch /var/run/sshd.restart +fi + +%triggerun server -- openssh-server < 2.5.0p1 +# Count the number of HostKey and HostDsaKey statements we have. +gawk 'BEGIN {IGNORECASE=1} + /^hostkey/ || /^hostdsakey/ {sawhostkey = sawhostkey + 1} + END {exit sawhostkey}' /etc/ssh/sshd_config +# And if we only found one, we know the client was relying on the old default +# behavior, which loaded the the SSH2 DSA host key when HostDsaKey wasn't +# specified. Now that HostKey is used for both SSH1 and SSH2 keys, specifying +# one nullifies the default, which would have loaded both. +if [ $? -eq 1 ] ; then + echo HostKey /etc/ssh/ssh_host_rsa_key >> /etc/ssh/sshd_config + echo HostKey /etc/ssh/ssh_host_dsa_key >> /etc/ssh/sshd_config +fi + +%triggerpostun server -- ssh-server +if [ "$1" != 0 ] ; then + /sbin/chkconfig --add sshd + if test -f /var/run/sshd.restart ; then + rm -f /var/run/sshd.restart + /sbin/service sshd start > /dev/null 2>&1 || : + fi +fi + +%pre server +%{_sbindir}/groupadd -r -g %{sshd_gid} sshd 2>/dev/null || : +%{_sbindir}/useradd -d /var/empty/sshd -s /bin/false -u %{sshd_uid} \ + -g sshd -M -r sshd 2>/dev/null || : + +%post server +/sbin/chkconfig --add sshd + +%postun server +/sbin/service sshd condrestart > /dev/null 2>&1 || : + +%preun server +if [ "$1" = 0 ] +then + /sbin/service sshd stop > /dev/null 2>&1 || : + /sbin/chkconfig --del sshd +fi + +%files +%defattr(-,root,root) +%doc CREDITS ChangeLog INSTALL LICENCE OVERVIEW README* PROTOCOL* TODO +%attr(0755,root,root) %{_bindir}/scp +%attr(0644,root,root) %{_mandir}/man1/scp.1* +%attr(0755,root,root) %dir %{_sysconfdir}/ssh +%attr(0600,root,root) %config(noreplace) %{_sysconfdir}/ssh/moduli +%if ! %{rescue} +%attr(0755,root,root) %{_bindir}/ssh-keygen +%attr(0644,root,root) %{_mandir}/man1/ssh-keygen.1* +%attr(0755,root,root) %dir %{_libexecdir}/openssh +%attr(4711,root,root) %{_libexecdir}/openssh/ssh-keysign +%attr(0755,root,root) %{_libexecdir}/openssh/ssh-pkcs11-helper +%attr(0644,root,root) %{_mandir}/man8/ssh-keysign.8* +%attr(0644,root,root) %{_mandir}/man8/ssh-pkcs11-helper.8* +%endif +%if %{scard} +%attr(0755,root,root) %dir %{_datadir}/openssh +%attr(0644,root,root) %{_datadir}/openssh/Ssh.bin +%endif + +%files clients +%defattr(-,root,root) +%attr(0755,root,root) %{_bindir}/ssh +%attr(0644,root,root) %{_mandir}/man1/ssh.1* +%attr(0644,root,root) %{_mandir}/man5/ssh_config.5* +%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/ssh/ssh_config +%attr(-,root,root) %{_bindir}/slogin +%attr(-,root,root) %{_mandir}/man1/slogin.1* +%if ! %{rescue} +%attr(2755,root,nobody) %{_bindir}/ssh-agent +%attr(0755,root,root) %{_bindir}/ssh-add +%attr(0755,root,root) %{_bindir}/ssh-keyscan +%attr(0755,root,root) %{_bindir}/sftp +%attr(0644,root,root) %{_mandir}/man1/ssh-agent.1* +%attr(0644,root,root) %{_mandir}/man1/ssh-add.1* +%attr(0644,root,root) %{_mandir}/man1/ssh-keyscan.1* +%attr(0644,root,root) %{_mandir}/man1/sftp.1* +%endif + +%if ! %{rescue} +%files server +%defattr(-,root,root) +%dir %attr(0111,root,root) %{_var}/empty/sshd +%attr(0755,root,root) %{_sbindir}/sshd +%attr(0755,root,root) %{_libexecdir}/openssh/sftp-server +%attr(0644,root,root) %{_mandir}/man8/sshd.8* +%attr(0644,root,root) %{_mandir}/man5/moduli.5* +%attr(0644,root,root) %{_mandir}/man5/sshd_config.5* +%attr(0644,root,root) %{_mandir}/man8/sftp-server.8* +%attr(0755,root,root) %dir %{_sysconfdir}/ssh +%attr(0600,root,root) %config(noreplace) %{_sysconfdir}/ssh/sshd_config +%attr(0600,root,root) %config(noreplace) /etc/pam.d/sshd +%attr(0755,root,root) %config /etc/rc.d/init.d/sshd +%endif + +%if ! %{no_x11_askpass} +%files askpass +%defattr(-,root,root) +%doc x11-ssh-askpass-%{aversion}/README +%doc x11-ssh-askpass-%{aversion}/ChangeLog +%doc x11-ssh-askpass-%{aversion}/SshAskpass*.ad +%attr(0755,root,root) %{_libexecdir}/openssh/ssh-askpass +%attr(0755,root,root) %{_libexecdir}/openssh/x11-ssh-askpass +%endif + +%if ! %{no_gnome_askpass} +%files askpass-gnome +%defattr(-,root,root) +%attr(0755,root,root) %config %{_sysconfdir}/profile.d/gnome-ssh-askpass.* +%attr(0755,root,root) %{_libexecdir}/openssh/gnome-ssh-askpass +%endif + +%changelog +* Wed Jul 14 2010 Tim Rice <tim@multitalents.net> +- test for skip_x11_askpass (line 77) should have been for no_x11_askpass + +* Mon Jun 2 2003 Damien Miller <djm@mindrot.org> +- Remove noip6 option. This may be controlled at run-time in client config + file using new AddressFamily directive + +* Mon May 12 2003 Damien Miller <djm@mindrot.org> +- Don't install profile.d scripts when not building with GNOME/GTK askpass + (patch from bet@rahul.net) + +* Wed Oct 01 2002 Damien Miller <djm@mindrot.org> +- Install ssh-agent setgid nobody to prevent ptrace() key theft attacks + +* Mon Sep 30 2002 Damien Miller <djm@mindrot.org> +- Use contrib/ Makefile for building askpass programs + +* Fri Jun 21 2002 Damien Miller <djm@mindrot.org> +- 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 <djm@mindrot.org> +- Merge in spec changes from RedHat, reorgansie a little +- Add Privsep user, group and directory + +* Thu Mar 7 2002 Nalin Dahyabhai <nalin@redhat.com> 3.1p1-2 +- bump and grind (through the build system) + +* Thu Mar 7 2002 Nalin Dahyabhai <nalin@redhat.com> 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 <nalin@redhat.com> 3.1p1-0 +- update to 3.1p1 + +* Tue Mar 5 2002 Nalin Dahyabhai <nalin@redhat.com> SNAP-20020305 +- update to SNAP-20020305 +- drop debug patch, fixed upstream + +* Wed Feb 20 2002 Nalin Dahyabhai <nalin@redhat.com> 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 <nalin@redhat.com> 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 <nalin@redhat.com> 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 <nalin@redhat.com> +- adjust build dependencies so that build6x actually works right (fix + from Hugo van der Kooij) + +* Tue Dec 4 2001 Nalin Dahyabhai <nalin@redhat.com> 3.0.2p1-1 +- update to 3.0.2p1 + +* Fri Nov 16 2001 Nalin Dahyabhai <nalin@redhat.com> 3.0.1p1-1 +- update to 3.0.1p1 + +* Tue Nov 13 2001 Nalin Dahyabhai <nalin@redhat.com> +- update to current CVS (not for use in distribution) + +* Thu Nov 8 2001 Nalin Dahyabhai <nalin@redhat.com> 3.0p1-1 +- merge some of Damien Miller <djm@mindrot.org> changes from the upstream + 3.0p1 spec file and init script + +* Wed Nov 7 2001 Nalin Dahyabhai <nalin@redhat.com> +- 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 <nalin@redhat.com> 2.9p2-9 +- incorporate fix from Markus Friedl's advisory for IP-based authorization bugs + +* Thu Sep 13 2001 Bernhard Rosenkraenzer <bero@redhat.com> 2.9p2-8 +- Merge changes to rescue build from current sysadmin survival cd + +* Thu Sep 6 2001 Nalin Dahyabhai <nalin@redhat.com> 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 <nalin@redhat.com> 2.9p2-6 +- add db1-devel as a BuildPrerequisite (noted by Hans Ecke) + +* Thu Aug 16 2001 Nalin Dahyabhai <nalin@redhat.com> +- pull cvs patch to fix remote port forwarding with protocol 2 + +* Thu Aug 9 2001 Nalin Dahyabhai <nalin@redhat.com> +- 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 <nalin@redhat.com> +- don't apply patches to code we don't intend to build (spotted by Matt Galgoci) + +* Mon Aug 6 2001 Nalin Dahyabhai <nalin@redhat.com> +- pass OPTIONS correctly to initlog (#50151) + +* Wed Jul 25 2001 Nalin Dahyabhai <nalin@redhat.com> +- switch to x11-ssh-askpass 1.2.2 + +* Wed Jul 11 2001 Nalin Dahyabhai <nalin@redhat.com> +- rebuild in new environment + +* Mon Jun 25 2001 Nalin Dahyabhai <nalin@redhat.com> +- disable the gssapi patch + +* Mon Jun 18 2001 Nalin Dahyabhai <nalin@redhat.com> +- update to 2.9p2 +- refresh to a new version of the gssapi patch + +* Thu Jun 7 2001 Nalin Dahyabhai <nalin@redhat.com> +- 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 <nalin@redhat.com> +- 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 <nalin@redhat.com> +- 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 <nalin@redhat.com> +- 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 <nalin@redhat.com> +- update to 2.9 +- drop various patches that came from or went upstream or to or from CVS + +* Wed Apr 18 2001 Nalin Dahyabhai <nalin@redhat.com> +- only require initscripts 5.00 on 6.2 (reported by Peter Bieringer) + +* Sun Apr 8 2001 Preston Brown <pbrown@redhat.com> +- 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 <nalin@redhat.com> +- 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 <nalin@redhat.com> +- 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 <nalin@redhat.com> +- update to 2.5.2p2 +- call setcred() again after initgroups, because the "creds" could actually + be group memberships + +* Tue Mar 20 2001 Nalin Dahyabhai <nalin@redhat.com> +- 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 <nalin@redhat.com> +- remove dependency on openssl -- would need to be too precise + +* Fri Mar 2 2001 Nalin Dahyabhai <nalin@redhat.com> +- rebuild in new environment + +* Mon Feb 26 2001 Nalin Dahyabhai <nalin@redhat.com> +- 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 <nalin@redhat.com> +- 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 <nalin@redhat.com> +- 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 <nalin@redhat.com> +- 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 <nalin@redhat.com> +- 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 <nalin@redhat.com> +- 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 <teg@redhat.com> +- i18n-tweak to initscript. + +* Tue Jan 23 2001 Nalin Dahyabhai <nalin@redhat.com> +- 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 <nalin@redhat.com> +- Finish with the gettextizing. + +* Thu Jan 18 2001 Nalin Dahyabhai <nalin@redhat.com> +- Fix a bug in auth2-pam.c (#23877) +- Gettextize the init script. + +* Wed Dec 20 2000 Nalin Dahyabhai <nalin@redhat.com> +- Incorporate a switch for using PAM configs for 6.x, just in case. + +* Tue Dec 5 2000 Nalin Dahyabhai <nalin@redhat.com> +- Incorporate Bero's changes for a build specifically for rescue CDs. + +* Wed Nov 29 2000 Nalin Dahyabhai <nalin@redhat.com> +- 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 <nalin@redhat.com> +- 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 <nalin@redhat.com> +- Merge multiple PAM text messages into subsequent prompts when possible when + doing keyboard-interactive authentication. + +* Sun Nov 26 2000 Nalin Dahyabhai <nalin@redhat.com> +- 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 <nalin@redhat.com> +- Use DESTDIR instead of %%makeinstall. +- Remove /usr/X11R6/bin from the path-fixing patch. + +* Mon Nov 20 2000 Nalin Dahyabhai <nalin@redhat.com> +- 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 <nalin@redhat.com> +- 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 <nalin@redhat.com> +- Update to OpenSSH 2.3.0p1. +- Update to x11-askpass 1.1.0. +- Enable keyboard-interactive authentication. + +* Mon Oct 30 2000 Nalin Dahyabhai <nalin@redhat.com> +- Update to ssh-askpass-x11 1.0.3. +- Change authentication related messages to be private (#19966). + +* Tue Oct 10 2000 Nalin Dahyabhai <nalin@redhat.com> +- Patch ssh-keygen to be able to list signatures for DSA public key files + it generates. + +* Thu Oct 5 2000 Nalin Dahyabhai <nalin@redhat.com> +- 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 <nalin@redhat.com> +- 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 <nalin@redhat.com> +- Update to 2.2.0p1. (#17835) +- Tweak the init script to allow proper restarting. (#18023) + +* Wed Aug 23 2000 Nalin Dahyabhai <nalin@redhat.com> +- Update to 20000823 snapshot. +- Change subpackage requirements from %%{version} to %%{version}-%%{release} +- Back out the pipe patch. + +* Mon Jul 17 2000 Nalin Dahyabhai <nalin@redhat.com> +- 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 <nalin@redhat.com> +- Update to 2.1.1p3, which includes fixes for X11 forwarding and strtok(). + +* Thu Jul 6 2000 Nalin Dahyabhai <nalin@redhat.com> +- 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 <nalin@redhat.com> +- Fix X11 forwarding, from mail post by Chan Shih-Ping Richard. + +* Sun Jul 2 2000 Nalin Dahyabhai <nalin@redhat.com> +- Update to 2.1.1p2. +- Use of strtok() considered harmful. + +* Sat Jul 1 2000 Nalin Dahyabhai <nalin@redhat.com> +- Get the build root out of the man pages. + +* Thu Jun 29 2000 Nalin Dahyabhai <nalin@redhat.com> +- Add and use condrestart support in the init script. +- Add newer initscripts as a prereq. + +* Tue Jun 27 2000 Nalin Dahyabhai <nalin@redhat.com> +- Build in new environment (release 2) +- Move -clients subpackage to Applications/Internet group + +* Fri Jun 9 2000 Nalin Dahyabhai <nalin@redhat.com> +- Update to 2.2.1p1 + +* Sat Jun 3 2000 Nalin Dahyabhai <nalin@redhat.com> +- Patch to build with neither RSA nor RSAref. +- Miscellaneous FHS-compliance tweaks. +- Fix for possibly-compressed man pages. + +* Wed Mar 15 2000 Damien Miller <djm@ibs.com.au> +- Updated for new location +- Updated for new gnome-ssh-askpass build + +* Sun Dec 26 1999 Damien Miller <djm@mindrot.org> +- Added Jim Knoble's <jmknoble@pobox.com> askpass + +* Mon Nov 15 1999 Damien Miller <djm@mindrot.org> +- Split subpackages further based on patch from jim knoble <jmknoble@pobox.com> + +* Sat Nov 13 1999 Damien Miller <djm@mindrot.org> +- Added 'Obsoletes' directives + +* Tue Nov 09 1999 Damien Miller <djm@ibs.com.au> +- Use make install +- Subpackages + +* Mon Nov 08 1999 Damien Miller <djm@ibs.com.au> +- Added links for slogin +- Fixed perms on manpages + +* Sat Oct 30 1999 Damien Miller <djm@ibs.com.au> +- Renamed init script + +* Fri Oct 29 1999 Damien Miller <djm@ibs.com.au> +- Back to old binary names + +* Thu Oct 28 1999 Damien Miller <djm@ibs.com.au> +- Use autoconf +- New binary names + +* Wed Oct 27 1999 Damien Miller <djm@ibs.com.au> +- Initial RPMification, based on Jan "Yenya" Kasprzak's <kas@fi.muni.cz> spec.
diff --git a/openssh-6.0p1/contrib/redhat/sshd.init b/openssh-6.0p1/contrib/redhat/sshd.init new file mode 100755 index 0000000..e9a7517 --- /dev/null +++ b/openssh-6.0p1/contrib/redhat/sshd.init
@@ -0,0 +1,106 @@ +#!/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" = 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" = 0 ] && touch /var/lock/subsys/sshd + echo +} + +stop() +{ + echo -n $"Stopping $prog:" + killproc $SSHD -TERM + RETVAL=$? + [ "$RETVAL" = 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" = 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
diff --git a/openssh-6.0p1/contrib/redhat/sshd.init.old b/openssh-6.0p1/contrib/redhat/sshd.init.old new file mode 100755 index 0000000..0deb608 --- /dev/null +++ b/openssh-6.0p1/contrib/redhat/sshd.init.old
@@ -0,0 +1,172 @@ +#!/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
diff --git a/openssh-6.0p1/contrib/redhat/sshd.pam b/openssh-6.0p1/contrib/redhat/sshd.pam new file mode 100644 index 0000000..ffa5adb --- /dev/null +++ b/openssh-6.0p1/contrib/redhat/sshd.pam
@@ -0,0 +1,6 @@ +#%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
diff --git a/openssh-6.0p1/contrib/redhat/sshd.pam.old b/openssh-6.0p1/contrib/redhat/sshd.pam.old new file mode 100644 index 0000000..26dcb34 --- /dev/null +++ b/openssh-6.0p1/contrib/redhat/sshd.pam.old
@@ -0,0 +1,8 @@ +#%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
diff --git a/openssh-6.0p1/contrib/solaris/README b/openssh-6.0p1/contrib/solaris/README new file mode 100644 index 0000000..fefdd4b --- /dev/null +++ b/openssh-6.0p1/contrib/solaris/README
@@ -0,0 +1,30 @@ +The 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 +
diff --git a/openssh-6.0p1/contrib/ssh-copy-id b/openssh-6.0p1/contrib/ssh-copy-id new file mode 100644 index 0000000..9451ace --- /dev/null +++ b/openssh-6.0p1/contrib/ssh-copy-id
@@ -0,0 +1,54 @@ +#!/bin/sh + +# Shell script to install your public key on a remote machine +# Takes the remote machine name as an argument. +# Obviously, the remote machine must accept password authentication, +# or one of the other keys in your ssh-agent, for this to work. + +ID_FILE="${HOME}/.ssh/id_rsa.pub" + +if [ "-i" = "$1" ]; then + shift + # check if we have 2 parameters left, if so the first is the new ID file + if [ -n "$2" ]; then + if expr "$1" : ".*\.pub" > /dev/null ; then + ID_FILE="$1" + else + ID_FILE="$1.pub" + fi + shift # and this should leave $1 as the target name + fi +else + if [ x$SSH_AUTH_SOCK != x ] && ssh-add -L >/dev/null 2>&1; then + GET_ID="$GET_ID ssh-add -L" + fi +fi + +if [ -z "`eval $GET_ID`" ] && [ -r "${ID_FILE}" ] ; then + GET_ID="cat \"${ID_FILE}\"" +fi + +if [ -z "`eval $GET_ID`" ]; then + echo "$0: ERROR: No identities found" >&2 + exit 1 +fi + +if [ "$#" -lt 1 ] || [ "$1" = "-h" ] || [ "$1" = "--help" ]; then + echo "Usage: $0 [-i [identity_file]] [user@]machine" >&2 + exit 1 +fi + +# strip any trailing colon +host=`echo $1 | sed 's/:$//'` + +{ eval "$GET_ID" ; } | ssh $host "umask 077; test -d ~/.ssh || mkdir ~/.ssh ; cat >> ~/.ssh/authorized_keys" || exit 1 + +cat <<EOF +Now try logging into the machine, with "ssh '$host'", and check in: + + ~/.ssh/authorized_keys + +to make sure we haven't added extra keys that you weren't expecting. + +EOF +
diff --git a/openssh-6.0p1/contrib/ssh-copy-id.1 b/openssh-6.0p1/contrib/ssh-copy-id.1 new file mode 100644 index 0000000..cb15ab2 --- /dev/null +++ b/openssh-6.0p1/contrib/ssh-copy-id.1
@@ -0,0 +1,75 @@ +.ig \" -*- nroff -*- +Copyright (c) 1999 Philip Hands Computing <http://www.hands.com/> + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided that the +entire resulting derived work is distributed under the terms of a +permission notice identical to this one. + +Permission is granted to copy and distribute translations of this +manual into another language, under the above conditions for modified +versions, except that this permission notice may be included in +translations approved by the Free Software Foundation instead of in +the original English. +.. +.TH SSH-COPY-ID 1 "14 November 1999" "OpenSSH" +.SH NAME +ssh-copy-id \- install your public key in a remote machine's authorized_keys +.SH SYNOPSIS +.B ssh-copy-id [-i [identity_file]] +.I "[user@]machine" +.br +.SH DESCRIPTION +.BR ssh-copy-id +is a script that uses ssh to log into a remote machine and +append the indicated identity file to that machine's +.B ~/.ssh/authorized_keys +file. +.PP +If the +.B -i +option is given then the identity file (defaults to +.BR ~/.ssh/id_rsa.pub ) +is used, regardless of whether there are any keys in your +.BR ssh-agent . +Otherwise, if this: +.PP +.B " ssh-add -L" +.PP +provides any output, it uses that in preference to the identity file. +.PP +If the +.B -i +option is used, or the +.B ssh-add +produced no output, then it uses the contents of the identity +file. Once it has one or more fingerprints (by whatever means) it +uses ssh to append them to +.B ~/.ssh/authorized_keys +on the remote machine (creating the file, and directory, if necessary.) + +.SH NOTES +This program does not modify the permissions of any +pre-existing files or directories. Therefore, if the remote +.B sshd +has +.B StrictModes +set in its +configuration, then the user's home, +.B ~/.ssh +folder, and +.B ~/.ssh/authorized_keys +file may need to have group writability disabled manually, e.g. via + +.B " chmod go-w ~ ~/.ssh ~/.ssh/authorized_keys" + +on the remote machine. + +.SH "SEE ALSO" +.BR ssh (1), +.BR ssh-agent (1), +.BR sshd (8)
diff --git a/openssh-6.0p1/contrib/sshd.pam.freebsd b/openssh-6.0p1/contrib/sshd.pam.freebsd new file mode 100644 index 0000000..c0bc364 --- /dev/null +++ b/openssh-6.0p1/contrib/sshd.pam.freebsd
@@ -0,0 +1,5 @@ +sshd 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 +
diff --git a/openssh-6.0p1/contrib/sshd.pam.generic b/openssh-6.0p1/contrib/sshd.pam.generic new file mode 100644 index 0000000..215f0fe --- /dev/null +++ b/openssh-6.0p1/contrib/sshd.pam.generic
@@ -0,0 +1,8 @@ +#%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
diff --git a/openssh-6.0p1/contrib/suse/openssh.spec b/openssh-6.0p1/contrib/suse/openssh.spec new file mode 100644 index 0000000..8d99fb5 --- /dev/null +++ b/openssh-6.0p1/contrib/suse/openssh.spec
@@ -0,0 +1,246 @@ +# 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: 6.0p1 +URL: http://www.openssh.com/ +Release: 1 +Source0: openssh-%{version}.tar.gz +Source1: x11-ssh-askpass-%{xversion}.tar.gz +License: BSD +Group: Productivity/Networking/SSH +BuildRoot: %{_tmppath}/openssh-%{version}-buildroot +PreReq: openssl +Obsoletes: ssh +Provides: ssh +# +# (Build[ing] Prereq[uisites] only work for RPM 2.95 and newer.) +# building prerequisites -- stuff for +# OpenSSL (openssl-devel), +# TCP Wrappers (tcpd-devel), +# and Gnome (glibdev, gtkdev, and gnlibsd) +# +BuildPrereq: openssl +BuildPrereq: tcpd-devel +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 <imorgan@nas.nasa.gov> +- Removed accidental inclusion of --without-zlib-version-check +* Tue Oct 25 2005 Iain Morgan <imorgan@nas.nasa.gov> +- Overhaul to deal with newer versions of SuSE and OpenSSH +* Mon Jun 12 2000 Damien Miller <djm@mindrot.org> +- Glob manpages to catch compressed files +* Wed Mar 15 2000 Damien Miller <djm@ibs.com.au> +- Updated for new location +- Updated for new gnome-ssh-askpass build +* Sun Dec 26 1999 Chris Saia <csaia@wtower.com> +- Made symlink to gnome-ssh-askpass called ssh-askpass +* Wed Nov 24 1999 Chris Saia <csaia@wtower.com> +- 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 <csaia@wtower.com> +- 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 <csaia@wtower.com> +- 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 <djm@mindrot.org> +- Split subpackages further based on patch from jim knoble <jmknoble@pobox.com> +* Sat Nov 13 1999 Damien Miller <djm@mindrot.org> +- Added 'Obsoletes' directives +* Tue Nov 09 1999 Damien Miller <djm@ibs.com.au> +- Use make install +- Subpackages +* Mon Nov 08 1999 Damien Miller <djm@ibs.com.au> +- Added links for slogin +- Fixed perms on manpages +* Sat Oct 30 1999 Damien Miller <djm@ibs.com.au> +- Renamed init script +* Fri Oct 29 1999 Damien Miller <djm@ibs.com.au> +- Back to old binary names +* Thu Oct 28 1999 Damien Miller <djm@ibs.com.au> +- Use autoconf +- New binary names +* Wed Oct 27 1999 Damien Miller <djm@ibs.com.au> +- Initial RPMification, based on Jan "Yenya" Kasprzak's <kas@fi.muni.cz> 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 \ + --with-tcp-wrappers \ + --libexecdir=%{_libdir}/ssh +make + +%if %{build_x11_askpass} +cd x11-ssh-askpass-%{xversion} +%configure --mandir=/usr/X11R6/man \ + --libexecdir=%{_libdir}/ssh +xmkmf -a +make +cd .. +%endif + +%install +rm -rf $RPM_BUILD_ROOT +make install DESTDIR=$RPM_BUILD_ROOT/ +install -d $RPM_BUILD_ROOT/etc/pam.d/ +install -d $RPM_BUILD_ROOT/etc/init.d/ +install -d $RPM_BUILD_ROOT/var/adm/fillup-templates +install -m644 contrib/sshd.pam.generic $RPM_BUILD_ROOT/etc/pam.d/sshd +install -m744 contrib/suse/rc.sshd $RPM_BUILD_ROOT/etc/init.d/sshd +install -m744 contrib/suse/sysconfig.ssh \ + $RPM_BUILD_ROOT/var/adm/fillup-templates + +%if %{build_x11_askpass} +cd x11-ssh-askpass-%{xversion} +make install install.man BINDIR=%{_libdir}/ssh DESTDIR=$RPM_BUILD_ROOT/ +rm -f $RPM_BUILD_ROOT/usr/share/Ssh.bin +%endif + +%clean +rm -rf $RPM_BUILD_ROOT + +%pre +/usr/sbin/groupadd -g %{sshd_gid} -o -r sshd 2> /dev/null || : +/usr/sbin/useradd -r -o -g sshd -u %{sshd_uid} -s /bin/false -c "SSH Privilege Separation User" -d /var/lib/sshd sshd 2> /dev/null || : + +%post +/usr/bin/ssh-keygen -A +%{fillup_and_insserv -n -y ssh sshd} +%run_permissions + +%verifyscript +%verify_permissions -e /etc/ssh/sshd_config -e /etc/ssh/ssh_config -e /usr/bin/ssh + +%preun +%stop_on_removal sshd + +%postun +%restart_on_update sshd +%{insserv_cleanup} + +%files +%defattr(-,root,root) +%doc ChangeLog OVERVIEW README* PROTOCOL* +%doc TODO CREDITS LICENCE +%attr(0755,root,root) %dir %{_sysconfdir}/ssh +%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/ssh/ssh_config +%attr(0600,root,root) %config(noreplace) %{_sysconfdir}/ssh/sshd_config +%attr(0600,root,root) %config(noreplace) %{_sysconfdir}/ssh/moduli +%attr(0644,root,root) %config(noreplace) /etc/pam.d/sshd +%attr(0755,root,root) %config /etc/init.d/sshd +%attr(0755,root,root) %{_bindir}/ssh-keygen +%attr(0755,root,root) %{_bindir}/scp +%attr(0755,root,root) %{_bindir}/ssh +%attr(-,root,root) %{_bindir}/slogin +%attr(0755,root,root) %{_bindir}/ssh-agent +%attr(0755,root,root) %{_bindir}/ssh-add +%attr(0755,root,root) %{_bindir}/ssh-keyscan +%attr(0755,root,root) %{_bindir}/sftp +%attr(0755,root,root) %{_sbindir}/sshd +%attr(0755,root,root) %dir %{_libdir}/ssh +%attr(0755,root,root) %{_libdir}/ssh/sftp-server +%attr(4711,root,root) %{_libdir}/ssh/ssh-keysign +%attr(0755,root,root) %{_libdir}/ssh/ssh-pkcs11-helper +%attr(0644,root,root) %doc %{_mandir}/man1/scp.1* +%attr(0644,root,root) %doc %{_mandir}/man1/sftp.1* +%attr(-,root,root) %doc %{_mandir}/man1/slogin.1* +%attr(0644,root,root) %doc %{_mandir}/man1/ssh.1* +%attr(0644,root,root) %doc %{_mandir}/man1/ssh-add.1* +%attr(0644,root,root) %doc %{_mandir}/man1/ssh-agent.1* +%attr(0644,root,root) %doc %{_mandir}/man1/ssh-keygen.1* +%attr(0644,root,root) %doc %{_mandir}/man1/ssh-keyscan.1* +%attr(0644,root,root) %doc %{_mandir}/man5/moduli.5* +%attr(0644,root,root) %doc %{_mandir}/man5/ssh_config.5* +%attr(0644,root,root) %doc %{_mandir}/man5/sshd_config.5* +%attr(0644,root,root) %doc %{_mandir}/man8/sftp-server.8* +%attr(0644,root,root) %doc %{_mandir}/man8/ssh-keysign.8* +%attr(0644,root,root) %doc %{_mandir}/man8/ssh-pkcs11-helper.8* +%attr(0644,root,root) %doc %{_mandir}/man8/sshd.8* +%attr(0644,root,root) /var/adm/fillup-templates/sysconfig.ssh + +%if %{build_x11_askpass} +%files askpass +%defattr(-,root,root) +%doc x11-ssh-askpass-%{xversion}/README +%doc x11-ssh-askpass-%{xversion}/ChangeLog +%doc x11-ssh-askpass-%{xversion}/SshAskpass*.ad +%attr(0755,root,root) %{_libdir}/ssh/ssh-askpass +%attr(0755,root,root) %{_libdir}/ssh/x11-ssh-askpass +%attr(0644,root,root) %doc /usr/X11R6/man/man1/ssh-askpass.1x* +%attr(0644,root,root) %doc /usr/X11R6/man/man1/x11-ssh-askpass.1x* +%attr(0644,root,root) %config /usr/X11R6/lib/X11/app-defaults/SshAskpass +%endif
diff --git a/openssh-6.0p1/contrib/suse/rc.config.sshd b/openssh-6.0p1/contrib/suse/rc.config.sshd new file mode 100644 index 0000000..baaa7a5 --- /dev/null +++ b/openssh-6.0p1/contrib/suse/rc.config.sshd
@@ -0,0 +1,5 @@ +# +# Start the Secure Shell (SSH) Daemon? +# +START_SSHD="yes" +
diff --git a/openssh-6.0p1/contrib/suse/rc.sshd b/openssh-6.0p1/contrib/suse/rc.sshd new file mode 100644 index 0000000..4a3bc41 --- /dev/null +++ b/openssh-6.0p1/contrib/suse/rc.sshd
@@ -0,0 +1,121 @@ +#! /bin/sh +# Copyright (c) 1995-2000 SuSE GmbH Nuernberg, Germany. +# +# Author: Jiri Smid <feedback@suse.de> +# +# /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 /usr/sbin/sshd $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 /usr/sbin/sshd + + # 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 /usr/sbin/sshd + + 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 /usr/sbin/sshd + + 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
diff --git a/openssh-6.0p1/contrib/suse/sysconfig.ssh b/openssh-6.0p1/contrib/suse/sysconfig.ssh new file mode 100644 index 0000000..c6a37e5 --- /dev/null +++ b/openssh-6.0p1/contrib/suse/sysconfig.ssh
@@ -0,0 +1,9 @@ +## Path: Network/Remote access/SSH +## Description: SSH server settings +## Type: string +## Default: "" +## ServiceRestart: sshd +# +# Options for sshd +# +SSHD_OPTS=""
diff --git a/openssh-6.0p1/crc32.c b/openssh-6.0p1/crc32.c new file mode 100644 index 0000000..c192eb4 --- /dev/null +++ b/openssh-6.0p1/crc32.c
@@ -0,0 +1,105 @@ +/* $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; +}
diff --git a/openssh-6.0p1/crc32.h b/openssh-6.0p1/crc32.h new file mode 100644 index 0000000..5d7131a --- /dev/null +++ b/openssh-6.0p1/crc32.h
@@ -0,0 +1,30 @@ +/* $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
diff --git a/openssh-6.0p1/deattack.c b/openssh-6.0p1/deattack.c new file mode 100644 index 0000000..1b37e4d --- /dev/null +++ b/openssh-6.0p1/deattack.c
@@ -0,0 +1,160 @@ +/* $OpenBSD: deattack.c,v 1.30 2006/09/16 19:53:37 djm Exp $ */ +/* + * Cryptographic attack detector for ssh - source code + * + * Copyright (c) 1998 CORE SDI S.A., Buenos Aires, Argentina. + * + * All rights reserved. Redistribution and use in source and binary + * forms, with or without modification, are permitted provided that + * this copyright notice is retained. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES ARE DISCLAIMED. IN NO EVENT SHALL CORE SDI S.A. BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR + * CONSEQUENTIAL DAMAGES RESULTING FROM THE USE OR MISUSE OF THIS + * SOFTWARE. + * + * Ariel Futoransky <futo@core-sdi.com> + * <http://www.core-sdi.com> + */ + +#include "includes.h" + +#include <sys/types.h> + +#include <string.h> +#include <stdio.h> +#include <stdarg.h> + +#include "xmalloc.h" +#include "deattack.h" +#include "log.h" +#include "crc32.h" +#include "misc.h" + +/* + * CRC attack detection has a worst-case behaviour that is O(N^3) over + * the number of identical blocks in a packet. This behaviour can be + * exploited to create a limited denial of service attack. + * + * However, because we are dealing with encrypted data, identical + * blocks should only occur every 2^35 maximally-sized packets or so. + * Consequently, we can detect this DoS by looking for identical blocks + * in a packet. + * + * The parameter below determines how many identical blocks we will + * accept in a single packet, trading off between attack detection and + * likelihood of terminating a legitimate connection. A value of 32 + * corresponds to an average of 2^40 messages before an attack is + * misdetected + */ +#define MAX_IDENTICAL 32 + +/* SSH Constants */ +#define SSH_MAXBLOCKS (32 * 1024) +#define SSH_BLOCKSIZE (8) + +/* Hashing constants */ +#define HASH_MINSIZE (8 * 1024) +#define HASH_ENTRYSIZE (2) +#define HASH_FACTOR(x) ((x)*3/2) +#define HASH_UNUSEDCHAR (0xff) +#define HASH_UNUSED (0xffff) +#define HASH_IV (0xfffe) + +#define HASH_MINBLOCKS (7*SSH_BLOCKSIZE) + + +/* Hash function (Input keys are cipher results) */ +#define HASH(x) get_u32(x) + +#define CMP(a, b) (memcmp(a, b, SSH_BLOCKSIZE)) + +static void +crc_update(u_int32_t *a, u_int32_t b) +{ + b ^= *a; + *a = ssh_crc32((u_char *)&b, sizeof(b)); +} + +/* detect if a block is used in a particular pattern */ +static int +check_crc(u_char *S, u_char *buf, u_int32_t len) +{ + u_int32_t crc; + u_char *c; + + crc = 0; + for (c = buf; c < buf + len; c += SSH_BLOCKSIZE) { + if (!CMP(S, c)) { + crc_update(&crc, 1); + crc_update(&crc, 0); + } else { + crc_update(&crc, 0); + crc_update(&crc, 0); + } + } + return (crc == 0); +} + + +/* Detect a crc32 compensation attack on a packet */ +int +detect_attack(u_char *buf, u_int32_t len) +{ + static u_int16_t *h = (u_int16_t *) NULL; + static u_int32_t n = HASH_MINSIZE / HASH_ENTRYSIZE; + u_int32_t i, j; + u_int32_t l, same; + u_char *c; + u_char *d; + + if (len > (SSH_MAXBLOCKS * SSH_BLOCKSIZE) || + len % SSH_BLOCKSIZE != 0) { + fatal("detect_attack: bad length %d", len); + } + for (l = n; l < HASH_FACTOR(len / SSH_BLOCKSIZE); l = l << 2) + ; + + if (h == NULL) { + debug("Installing crc compensation attack detector."); + h = (u_int16_t *) xcalloc(l, HASH_ENTRYSIZE); + n = l; + } else { + if (l > n) { + h = (u_int16_t *)xrealloc(h, l, HASH_ENTRYSIZE); + n = l; + } + } + + if (len <= HASH_MINBLOCKS) { + for (c = buf; c < buf + len; c += SSH_BLOCKSIZE) { + for (d = buf; d < c; d += SSH_BLOCKSIZE) { + if (!CMP(c, d)) { + if ((check_crc(c, buf, len))) + return (DEATTACK_DETECTED); + else + break; + } + } + } + return (DEATTACK_OK); + } + memset(h, HASH_UNUSEDCHAR, n * HASH_ENTRYSIZE); + + for (c = buf, same = j = 0; c < (buf + len); c += SSH_BLOCKSIZE, j++) { + for (i = HASH(c) & (n - 1); h[i] != HASH_UNUSED; + i = (i + 1) & (n - 1)) { + if (!CMP(c, buf + h[i] * SSH_BLOCKSIZE)) { + if (++same > MAX_IDENTICAL) + return (DEATTACK_DOS_DETECTED); + if (check_crc(c, buf, len)) + return (DEATTACK_DETECTED); + else + break; + } + } + h[i] = j; + } + return (DEATTACK_OK); +}
diff --git a/openssh-6.0p1/deattack.h b/openssh-6.0p1/deattack.h new file mode 100644 index 0000000..0316fb2 --- /dev/null +++ b/openssh-6.0p1/deattack.h
@@ -0,0 +1,31 @@ +/* $OpenBSD: deattack.h,v 1.10 2006/09/16 19:53:37 djm Exp $ */ + +/* + * Cryptographic attack detector for ssh - Header file + * + * Copyright (c) 1998 CORE SDI S.A., Buenos Aires, Argentina. + * + * All rights reserved. Redistribution and use in source and binary + * forms, with or without modification, are permitted provided that + * this copyright notice is retained. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES ARE DISCLAIMED. IN NO EVENT SHALL CORE SDI S.A. BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR + * CONSEQUENTIAL DAMAGES RESULTING FROM THE USE OR MISUSE OF THIS + * SOFTWARE. + * + * Ariel Futoransky <futo@core-sdi.com> + * <http://www.core-sdi.com> + */ + +#ifndef _DEATTACK_H +#define _DEATTACK_H + +/* Return codes */ +#define DEATTACK_OK 0 +#define DEATTACK_DETECTED 1 +#define DEATTACK_DOS_DETECTED 2 + +int detect_attack(u_char *, u_int32_t); +#endif
diff --git a/openssh-6.0p1/defines.h b/openssh-6.0p1/defines.h new file mode 100644 index 0000000..53f83a1 --- /dev/null +++ b/openssh-6.0p1/defines.h
@@ -0,0 +1,807 @@ +/* + * Copyright (c) 1999-2003 Damien Miller. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _DEFINES_H +#define _DEFINES_H + +/* $Id: defines.h,v 1.169 2012/02/15 04:13:06 tim Exp $ */ + + +/* Constants */ + +#if defined(HAVE_DECL_SHUT_RD) && HAVE_DECL_SHUT_RD == 0 +enum +{ + SHUT_RD = 0, /* No more receptions. */ + SHUT_WR, /* No more transmissions. */ + SHUT_RDWR /* No more receptions or transmissions. */ +}; +# define SHUT_RD SHUT_RD +# define SHUT_WR SHUT_WR +# define SHUT_RDWR SHUT_RDWR +#endif + +/* + * Definitions for IP type of service (ip_tos) + */ +#include <netinet/in_systm.h> +#include <netinet/ip.h> +#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 */ + +#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 + +/* *-*-nto-qnx doesn't define this constant in the system headers */ +#ifdef MISSING_NFDBITS +# define NFDBITS (8 * sizeof(unsigned long)) +#endif + +/* +SCO Open Server 3 has INADDR_LOOPBACK defined in rpc/rpc.h but +including rpc/rpc.h breaks Solaris 6 +*/ +#ifndef INADDR_LOOPBACK +#define INADDR_LOOPBACK ((u_long)0x7f000001) +#endif + +/* Types */ + +/* If sys/types.h does not supply intXX_t, supply them ourselves */ +/* (or die trying) */ + +#ifndef HAVE_U_INT +typedef unsigned int u_int; +#endif + +#ifndef HAVE_INTXX_T +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 +# if (SIZEOF_CHAR == 1) +typedef unsigned char u_int8_t; +# else +# error "8 bit int type not found." +# endif +# if (SIZEOF_SHORT_INT == 2) +typedef unsigned short int u_int16_t; +# else +# ifdef _UNICOS +# if (SIZEOF_SHORT_INT == 4) +typedef unsigned short u_int16_t; +# else +typedef unsigned long u_int16_t; +# endif +# else +# error "16 bit int type not found." +# endif +# endif +# if (SIZEOF_INT == 4) +typedef unsigned int u_int32_t; +# else +# ifdef _UNICOS +typedef unsigned long u_int32_t; +# else +# error "32 bit int type not found." +# endif +# endif +# endif +#define __BIT_TYPES_DEFINED__ +#endif + +/* 64-bit types */ +#ifndef HAVE_INT64_T +# if (SIZEOF_LONG_INT == 8) +typedef long int int64_t; +# else +# if (SIZEOF_LONG_LONG_INT == 8) +typedef long long int int64_t; +# endif +# endif +#endif +#ifndef HAVE_U_INT64_T +# if (SIZEOF_LONG_INT == 8) +typedef unsigned long int u_int64_t; +# else +# if (SIZEOF_LONG_LONG_INT == 8) +typedef unsigned long long int u_int64_t; +# endif +# endif +#endif + +#ifndef HAVE_U_CHAR +typedef unsigned char u_char; +# define HAVE_U_CHAR +#endif /* HAVE_U_CHAR */ + +#ifndef SIZE_T_MAX +#define SIZE_T_MAX ULONG_MAX +#endif /* SIZE_T_MAX */ + +#ifndef HAVE_SIZE_T +typedef unsigned int size_t; +# define HAVE_SIZE_T +# define SIZE_T_MAX UINT_MAX +#endif /* HAVE_SIZE_T */ + +#ifndef 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 + +/* *-*-nto-qnx does not define this type in the system headers */ +#ifdef MISSING_FD_MASK + typedef unsigned long int fd_mask; +#endif + +/* Paths */ + +#ifndef _PATH_BSHELL +# define _PATH_BSHELL "/bin/sh" +#endif + +#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 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 + +/* *-*-nto-qnx doesn't define this macro in the system headers */ +#ifdef MISSING_HOWMANY +# define howmany(x,y) (((x)+((y)-1))/(y)) +#endif + +#ifndef OSSH_ALIGNBYTES +#define OSSH_ALIGNBYTES (sizeof(int) - 1) +#endif +#ifndef __CMSG_ALIGN +#define __CMSG_ALIGN(p) (((u_int)(p) + OSSH_ALIGNBYTES) &~ OSSH_ALIGNBYTES) +#endif + +/* Length of the contents of a control message of length len */ +#ifndef CMSG_LEN +#define CMSG_LEN(len) (__CMSG_ALIGN(sizeof(struct cmsghdr)) + (len)) +#endif + +/* Length of the space taken up by a padded control message of length len */ +#ifndef CMSG_SPACE +#define CMSG_SPACE(len) (__CMSG_ALIGN(sizeof(struct cmsghdr)) + __CMSG_ALIGN(len)) +#endif + +/* given pointer to struct cmsghdr, return pointer to data */ +#ifndef CMSG_DATA +#define CMSG_DATA(cmsg) ((u_char *)(cmsg) + __CMSG_ALIGN(sizeof(struct cmsghdr))) +#endif /* CMSG_DATA */ + +/* + * RFC 2292 requires to check msg_controllen, in case that the kernel returns + * an empty list for some reasons. + */ +#ifndef CMSG_FIRSTHDR +#define CMSG_FIRSTHDR(mhdr) \ + ((mhdr)->msg_controllen >= sizeof(struct cmsghdr) ? \ + (struct cmsghdr *)(mhdr)->msg_control : \ + (struct cmsghdr *)NULL) +#endif /* CMSG_FIRSTHDR */ + +#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(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) */ + +#if defined(HAVE_VHANGUP) && !defined(HAVE_DEV_PTMX) +# define USE_VHANGUP +#endif /* defined(HAVE_VHANGUP) && !defined(HAVE_DEV_PTMX) */ + +#ifndef GETPGRP_VOID +# include <unistd.h> +# define getpgrp() getpgrp(0) +#endif + +#ifdef USE_BSM_AUDIT +# define SSH_AUDIT_EVENTS +# define CUSTOM_SSH_AUDIT_EVENTS +#endif + +#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... <sigh> */ +# 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 + +#ifndef _NSIG +# ifdef NSIG +# define _NSIG NSIG +# else +# define _NSIG 128 +# endif +#endif + +#endif /* _DEFINES_H */
diff --git a/openssh-6.0p1/dh.c b/openssh-6.0p1/dh.c new file mode 100644 index 0000000..d943ca1 --- /dev/null +++ b/openssh-6.0p1/dh.c
@@ -0,0 +1,348 @@ +/* $OpenBSD: dh.c,v 1.49 2011/12/07 05:44:38 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. + */ + +#include "includes.h" + +#include <sys/param.h> + +#include <openssl/bn.h> +#include <openssl/dh.h> + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "dh.h" +#include "pathnames.h" +#include "log.h" +#include "misc.h" + +static int +parse_prime(int linenum, char *line, struct dhgroup *dhg) +{ + char *cp, *arg; + char *strsize, *gen, *prime; + const char *errstr = NULL; + long long n; + + cp = line; + if ((arg = strdelim(&cp)) == NULL) + return 0; + /* Ignore leading whitespace */ + if (*arg == '\0') + arg = strdelim(&cp); + if (!arg || !*arg || *arg == '#') + return 0; + + /* time */ + if (cp == NULL || *arg == '\0') + goto fail; + arg = strsep(&cp, " "); /* type */ + if (cp == NULL || *arg == '\0') + goto fail; + /* Ensure this is a safe prime */ + n = strtonum(arg, 0, 5, &errstr); + if (errstr != NULL || n != MODULI_TYPE_SAFE) + goto fail; + arg = strsep(&cp, " "); /* tests */ + if (cp == NULL || *arg == '\0') + goto fail; + /* 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)) + goto fail; + arg = strsep(&cp, " "); /* tries */ + if (cp == NULL || *arg == '\0') + goto fail; + n = strtonum(arg, 0, 1<<30, &errstr); + if (errstr != NULL || n == 0) + goto fail; + strsize = strsep(&cp, " "); /* size */ + if (cp == NULL || *strsize == '\0' || + (dhg->size = (int)strtonum(strsize, 0, 64*1024, &errstr)) == 0 || + errstr) + goto fail; + /* The whole group is one bit larger */ + dhg->size++; + gen = strsep(&cp, " "); /* gen */ + if (cp == NULL || *gen == '\0') + goto fail; + prime = strsep(&cp, " "); /* prime */ + if (cp != NULL || *prime == '\0') + goto fail; + + if ((dhg->g = BN_new()) == NULL) + fatal("parse_prime: BN_new failed"); + if ((dhg->p = BN_new()) == NULL) + fatal("parse_prime: BN_new failed"); + if (BN_hex2bn(&dhg->g, gen) == 0) + goto failclean; + + if (BN_hex2bn(&dhg->p, prime) == 0) + goto failclean; + + if (BN_num_bits(dhg->p) != dhg->size) + goto failclean; + + if (BN_is_zero(dhg->g) || BN_is_one(dhg->g)) + goto failclean; + + return (1); + + failclean: + BN_clear_free(dhg->g); + BN_clear_free(dhg->p); + fail: + error("Bad prime description in line %d", linenum); + return (0); +} + +DH * +choose_dh(int min, int wantbits, int max) +{ + FILE *f; + char line[4096]; + int best, bestcount, which; + int linenum; + struct dhgroup dhg; + + if ((f = fopen(_PATH_DH_MODULI, "r")) == NULL && + (f = fopen(_PATH_DH_PRIMES, "r")) == NULL) { + logit("WARNING: %s does not exist, using fixed modulus", + _PATH_DH_MODULI); + return (dh_new_group14()); + } + + linenum = 0; + best = bestcount = 0; + while (fgets(line, sizeof(line), f)) { + linenum++; + if (!parse_prime(linenum, line, &dhg)) + continue; + BN_clear_free(dhg.g); + BN_clear_free(dhg.p); + + if (dhg.size > max || dhg.size < min) + continue; + + if ((dhg.size > wantbits && dhg.size < best) || + (dhg.size > best && best < wantbits)) { + best = dhg.size; + bestcount = 0; + } + if (dhg.size == best) + bestcount++; + } + rewind(f); + + if (bestcount == 0) { + fclose(f); + logit("WARNING: no suitable primes in %s", _PATH_DH_PRIMES); + return (dh_new_group14()); + } + + linenum = 0; + which = arc4random_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) + fatal("WARNING: line %d disappeared in %s, giving up", + which, _PATH_DH_PRIMES); + + return (dh_new_group(dhg.g, dhg.p)); +} + +/* diffie-hellman-groupN-sha1 */ + +int +dh_pub_is_valid(DH *dh, BIGNUM *dh_pub) +{ + int i; + int n = BN_num_bits(dh_pub); + int bits_set = 0; + BIGNUM *tmp; + + if (dh_pub->neg) { + logit("invalid public DH value: negative"); + return 0; + } + if (BN_cmp(dh_pub, BN_value_one()) != 1) { /* pub_exp <= 1 */ + logit("invalid public DH value: <= 1"); + return 0; + } + + if ((tmp = BN_new()) == NULL) { + error("%s: BN_new failed", __func__); + return 0; + } + if (!BN_sub(tmp, dh->p, BN_value_one()) || + BN_cmp(dh_pub, tmp) != -1) { /* pub_exp > p-2 */ + BN_clear_free(tmp); + logit("invalid public DH value: >= p-1"); + return 0; + } + BN_clear_free(tmp); + + for (i = 0; i <= n; i++) + if (BN_is_bit_set(dh_pub, i)) + bits_set++; + debug2("bits set: %d/%d", bits_set, BN_num_bits(dh->p)); + + /* if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial */ + if (bits_set > 1) + return 1; + + logit("invalid public DH value (%d/%d)", bits_set, BN_num_bits(dh->p)); + return 0; +} + +void +dh_gen_key(DH *dh, int need) +{ + int i, bits_set, tries = 0; + + if (need < 0) + fatal("dh_gen_key: need < 0"); + if (dh->p == NULL) + fatal("dh_gen_key: dh->p == NULL"); + if (need > INT_MAX / 2 || 2 * need >= BN_num_bits(dh->p)) + fatal("dh_gen_key: group too small: %d (2*need %d)", + BN_num_bits(dh->p), 2*need); + do { + if (dh->priv_key != NULL) + BN_clear_free(dh->priv_key); + if ((dh->priv_key = BN_new()) == NULL) + fatal("dh_gen_key: BN_new failed"); + /* generate a 2*need bits random private exponent */ + if (!BN_rand(dh->priv_key, 2*need, 0, 0)) + fatal("dh_gen_key: BN_rand failed"); + if (DH_generate_key(dh) == 0) + fatal("DH_generate_key"); + for (i = 0, bits_set = 0; i <= BN_num_bits(dh->priv_key); i++) + if (BN_is_bit_set(dh->priv_key, i)) + bits_set++; + debug2("dh_gen_key: priv key bits set: %d/%d", + bits_set, BN_num_bits(dh->priv_key)); + if (tries++ > 10) + fatal("dh_gen_key: too many bad keys: giving up"); + } while (!dh_pub_is_valid(dh, dh->pub_key)); +} + +DH * +dh_new_group_asc(const char *gen, const char *modulus) +{ + DH *dh; + + if ((dh = DH_new()) == NULL) + fatal("dh_new_group_asc: DH_new"); + + if (BN_hex2bn(&dh->p, modulus) == 0) + fatal("BN_hex2bn p"); + if (BN_hex2bn(&dh->g, gen) == 0) + fatal("BN_hex2bn g"); + + return (dh); +} + +/* + * This just returns the group, we still need to generate the exchange + * value. + */ + +DH * +dh_new_group(BIGNUM *gen, BIGNUM *modulus) +{ + DH *dh; + + if ((dh = DH_new()) == NULL) + fatal("dh_new_group: DH_new"); + dh->p = modulus; + dh->g = gen; + + return (dh); +} + +DH * +dh_new_group1(void) +{ + static char *gen = "2", *group1 = + "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" + "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD" + "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245" + "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" + "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381" + "FFFFFFFF" "FFFFFFFF"; + + return (dh_new_group_asc(gen, group1)); +} + +DH * +dh_new_group14(void) +{ + static char *gen = "2", *group14 = + "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" + "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD" + "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245" + "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" + "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE45B3D" + "C2007CB8" "A163BF05" "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F" + "83655D23" "DCA3AD96" "1C62F356" "208552BB" "9ED52907" "7096966D" + "670C354E" "4ABC9804" "F1746C08" "CA18217C" "32905E46" "2E36CE3B" + "E39E772C" "180E8603" "9B2783A2" "EC07A28F" "B5C55DF0" "6F4C52C9" + "DE2BCBF6" "95581718" "3995497C" "EA956AE5" "15D22618" "98FA0510" + "15728E5A" "8AACAA68" "FFFFFFFF" "FFFFFFFF"; + + return (dh_new_group_asc(gen, group14)); +} + +/* + * Estimates the group order for a Diffie-Hellman group that has an + * attack complexity approximately the same as O(2**bits). Estimate + * with: O(exp(1.9223 * (ln q)^(1/3) (ln ln q)^(2/3))) + */ + +int +dh_estimate(int bits) +{ + + if (bits <= 128) + return (1024); /* O(2**86) */ + if (bits <= 192) + return (2048); /* O(2**116) */ + return (4096); /* O(2**156) */ +}
diff --git a/openssh-6.0p1/dh.h b/openssh-6.0p1/dh.h new file mode 100644 index 0000000..dfc1480 --- /dev/null +++ b/openssh-6.0p1/dh.h
@@ -0,0 +1,73 @@ +/* $OpenBSD: dh.h,v 1.10 2008/06/26 09:19:40 djm Exp $ */ + +/* + * Copyright (c) 2000 Niels Provos. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef DH_H +#define DH_H + +struct dhgroup { + int size; + BIGNUM *g; + BIGNUM *p; +}; + +DH *choose_dh(int, int, int); +DH *dh_new_group_asc(const char *, const char *); +DH *dh_new_group(BIGNUM *, BIGNUM *); +DH *dh_new_group1(void); +DH *dh_new_group14(void); + +void dh_gen_key(DH *, int); +int dh_pub_is_valid(DH *, BIGNUM *); + +int dh_estimate(int); + +#define DH_GRP_MIN 1024 +#define DH_GRP_MAX 8192 + +/* + * 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
diff --git a/openssh-6.0p1/dispatch.c b/openssh-6.0p1/dispatch.c new file mode 100644 index 0000000..64bb809 --- /dev/null +++ b/openssh-6.0p1/dispatch.c
@@ -0,0 +1,104 @@ +/* $OpenBSD: dispatch.c,v 1.22 2008/10/31 15:05:34 stevesk Exp $ */ +/* + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#include <sys/types.h> + +#include <signal.h> +#include <stdarg.h> + +#include "ssh1.h" +#include "ssh2.h" +#include "log.h" +#include "dispatch.h" +#include "packet.h" +#include "compat.h" + +#define DISPATCH_MAX 255 + +dispatch_fn *dispatch[DISPATCH_MAX]; + +void +dispatch_protocol_error(int type, u_int32_t seq, void *ctxt) +{ + logit("dispatch_protocol_error: type %d seq %u", type, seq); + if (!compat20) + fatal("protocol error"); + packet_start(SSH2_MSG_UNIMPLEMENTED); + packet_put_int(seq); + packet_send(); + packet_write_wait(); +} +void +dispatch_protocol_ignore(int type, u_int32_t seq, void *ctxt) +{ + logit("dispatch_protocol_ignore: type %d seq %u", type, seq); +} +void +dispatch_init(dispatch_fn *dflt) +{ + u_int i; + for (i = 0; i < DISPATCH_MAX; i++) + dispatch[i] = dflt; +} +void +dispatch_range(u_int from, u_int to, dispatch_fn *fn) +{ + u_int i; + + for (i = from; i <= to; i++) { + if (i >= DISPATCH_MAX) + break; + dispatch[i] = fn; + } +} +void +dispatch_set(int type, dispatch_fn *fn) +{ + dispatch[type] = fn; +} +void +dispatch_run(int mode, volatile sig_atomic_t *done, void *ctxt) +{ + for (;;) { + int type; + u_int32_t seqnr; + + if (mode == DISPATCH_BLOCK) { + type = packet_read_seqnr(&seqnr); + } else { + type = packet_read_poll_seqnr(&seqnr); + if (type == SSH_MSG_NONE) + return; + } + if (type > 0 && type < DISPATCH_MAX && dispatch[type] != NULL) + (*dispatch[type])(type, seqnr, ctxt); + else + packet_disconnect("protocol error: rcvd type %d", type); + if (done != NULL && *done) + return; + } +}
diff --git a/openssh-6.0p1/dispatch.h b/openssh-6.0p1/dispatch.h new file mode 100644 index 0000000..3e3d1a1 --- /dev/null +++ b/openssh-6.0p1/dispatch.h
@@ -0,0 +1,41 @@ +/* $OpenBSD: dispatch.h,v 1.11 2006/04/20 09:27:09 djm Exp $ */ + +/* + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <signal.h> + +enum { + DISPATCH_BLOCK, + DISPATCH_NONBLOCK +}; + +typedef void dispatch_fn(int, u_int32_t, void *); + +void dispatch_init(dispatch_fn *); +void dispatch_set(int, dispatch_fn *); +void dispatch_range(u_int, u_int, dispatch_fn *); +void dispatch_run(int, volatile sig_atomic_t *, void *); +void dispatch_protocol_error(int, u_int32_t, void *); +void dispatch_protocol_ignore(int, u_int32_t, void *);
diff --git a/openssh-6.0p1/dns.c b/openssh-6.0p1/dns.c new file mode 100644 index 0000000..131cb3d --- /dev/null +++ b/openssh-6.0p1/dns.c
@@ -0,0 +1,306 @@ +/* $OpenBSD: dns.c,v 1.27 2010/08/31 11:54:45 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. + */ + +#include "includes.h" + +#include <sys/types.h> +#include <sys/socket.h> + +#include <netdb.h> +#include <stdarg.h> +#include <stdio.h> +#include <string.h> + +#include "xmalloc.h" +#include "key.h" +#include "dns.h" +#include "log.h" + +static const char *errset_text[] = { + "success", /* 0 ERRSET_SUCCESS */ + "out of memory", /* 1 ERRSET_NOMEMORY */ + "general failure", /* 2 ERRSET_FAIL */ + "invalid parameter", /* 3 ERRSET_INVAL */ + "name does not exist", /* 4 ERRSET_NONAME */ + "data does not exist", /* 5 ERRSET_NODATA */ +}; + +static const char * +dns_result_totext(unsigned int res) +{ + switch (res) { + case ERRSET_SUCCESS: + return errset_text[ERRSET_SUCCESS]; + case ERRSET_NOMEMORY: + return errset_text[ERRSET_NOMEMORY]; + case ERRSET_FAIL: + return errset_text[ERRSET_FAIL]; + case ERRSET_INVAL: + return errset_text[ERRSET_INVAL]; + case ERRSET_NONAME: + return errset_text[ERRSET_NONAME]; + case ERRSET_NODATA: + return errset_text[ERRSET_NODATA]; + default: + return "unknown error"; + } +} + +/* + * Read SSHFP parameters from key buffer. + */ +static int +dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type, + u_char **digest, u_int *digest_len, Key *key) +{ + int success = 0; + + switch (key->type) { + case KEY_RSA: + *algorithm = SSHFP_KEY_RSA; + break; + case KEY_DSA: + *algorithm = SSHFP_KEY_DSA; + break; + /* XXX KEY_ECDSA */ + default: + *algorithm = SSHFP_KEY_RESERVED; /* 0 */ + } + + if (*algorithm) { + *digest_type = SSHFP_HASH_SHA1; + *digest = key_fingerprint_raw(key, SSH_FP_SHA1, digest_len); + if (*digest == NULL) + fatal("dns_read_key: null from key_fingerprint_raw()"); + success = 1; + } else { + *digest_type = SSHFP_HASH_RESERVED; + *digest = NULL; + *digest_len = 0; + success = 0; + } + + return success; +} + +/* + * Read SSHFP parameters from rdata buffer. + */ +static int +dns_read_rdata(u_int8_t *algorithm, u_int8_t *digest_type, + u_char **digest, u_int *digest_len, u_char *rdata, int rdata_len) +{ + int success = 0; + + *algorithm = SSHFP_KEY_RESERVED; + *digest_type = SSHFP_HASH_RESERVED; + + if (rdata_len >= 2) { + *algorithm = rdata[0]; + *digest_type = rdata[1]; + *digest_len = rdata_len - 2; + + if (*digest_len > 0) { + *digest = (u_char *) xmalloc(*digest_len); + memcpy(*digest, rdata + 2, *digest_len); + } else { + *digest = (u_char *)xstrdup(""); + } + + success = 1; + } + + return success; +} + +/* + * Check if hostname is numerical. + * Returns -1 if hostname is numeric, 0 otherwise + */ +static int +is_numeric_hostname(const char *hostname) +{ + struct addrinfo hints, *ai; + + /* + * 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, + Key *hostkey, int *flags) +{ + u_int counter; + int result; + struct rrsetinfo *fingerprints = NULL; + + u_int8_t hostkey_algorithm; + u_int8_t hostkey_digest_type; + u_char *hostkey_digest; + u_int hostkey_digest_len; + + u_int8_t dnskey_algorithm; + u_int8_t dnskey_digest_type; + u_char *dnskey_digest; + u_int dnskey_digest_len; + + *flags = 0; + + debug3("verify_host_key_dns"); + if (hostkey == NULL) + fatal("No key to look up!"); + + if (is_numeric_hostname(hostname)) { + debug("skipped DNS lookup for numerical hostname"); + return -1; + } + + result = getrrsetbyname(hostname, DNS_RDATACLASS_IN, + DNS_RDATATYPE_SSHFP, 0, &fingerprints); + if (result) { + verbose("DNS lookup error: %s", dns_result_totext(result)); + return -1; + } + + if (fingerprints->rri_flags & RRSET_VALIDATED) { + *flags |= DNS_VERIFY_SECURE; + debug("found %d secure fingerprints in DNS", + fingerprints->rri_nrdatas); + } else { + debug("found %d insecure fingerprints in DNS", + fingerprints->rri_nrdatas); + } + + /* Initialize host key parameters */ + if (!dns_read_key(&hostkey_algorithm, &hostkey_digest_type, + &hostkey_digest, &hostkey_digest_len, hostkey)) { + error("Error calculating host key fingerprint."); + freerrset(fingerprints); + return -1; + } + + if (fingerprints->rri_nrdatas) + *flags |= DNS_VERIFY_FOUND; + + for (counter = 0; counter < fingerprints->rri_nrdatas; counter++) { + /* + * Extract the key from the answer. Ignore any badly + * formatted fingerprints. + */ + if (!dns_read_rdata(&dnskey_algorithm, &dnskey_digest_type, + &dnskey_digest, &dnskey_digest_len, + fingerprints->rri_rdatas[counter].rdi_data, + fingerprints->rri_rdatas[counter].rdi_length)) { + verbose("Error parsing fingerprint from DNS."); + continue; + } + + /* Check if the current key is the same as the given key */ + if (hostkey_algorithm == dnskey_algorithm && + hostkey_digest_type == dnskey_digest_type) { + + if (hostkey_digest_len == dnskey_digest_len && + memcmp(hostkey_digest, dnskey_digest, + hostkey_digest_len) == 0) { + + *flags |= DNS_VERIFY_MATCH; + } + } + xfree(dnskey_digest); + } + + xfree(hostkey_digest); /* from key_fingerprint_raw() */ + freerrset(fingerprints); + + if (*flags & DNS_VERIFY_FOUND) + if (*flags & DNS_VERIFY_MATCH) + debug("matching host key fingerprint found in DNS"); + else + debug("mismatching host key fingerprint found in DNS"); + else + debug("no host key fingerprint found in DNS"); + + return 0; +} + +/* + * Export the fingerprint of a key as a DNS resource record + */ +int +export_dns_rr(const char *hostname, Key *key, FILE *f, int generic) +{ + u_int8_t rdata_pubkey_algorithm = 0; + u_int8_t rdata_digest_type = SSHFP_HASH_SHA1; + u_char *rdata_digest; + u_int rdata_digest_len; + + u_int i; + int success = 0; + + if (dns_read_key(&rdata_pubkey_algorithm, &rdata_digest_type, + &rdata_digest, &rdata_digest_len, key)) { + + if (generic) + fprintf(f, "%s IN TYPE%d \\# %d %02x %02x ", hostname, + DNS_RDATATYPE_SSHFP, 2 + rdata_digest_len, + rdata_pubkey_algorithm, rdata_digest_type); + else + fprintf(f, "%s IN SSHFP %d %d ", hostname, + rdata_pubkey_algorithm, rdata_digest_type); + + for (i = 0; i < rdata_digest_len; i++) + fprintf(f, "%02x", rdata_digest[i]); + fprintf(f, "\n"); + xfree(rdata_digest); /* from key_fingerprint_raw() */ + success = 1; + } else { + error("export_dns_rr: unsupported algorithm"); + } + + return success; +}
diff --git a/openssh-6.0p1/dns.h b/openssh-6.0p1/dns.h new file mode 100644 index 0000000..90cfd7b --- /dev/null +++ b/openssh-6.0p1/dns.h
@@ -0,0 +1,52 @@ +/* $OpenBSD: dns.h,v 1.11 2010/02/26 20:29:54 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, + SSHFP_KEY_RSA, + SSHFP_KEY_DSA +}; + +enum sshfp_hashes { + SSHFP_HASH_RESERVED, + SSHFP_HASH_SHA1 +}; + +#define DNS_RDATACLASS_IN 1 +#define DNS_RDATATYPE_SSHFP 44 + +#define DNS_VERIFY_FOUND 0x00000001 +#define DNS_VERIFY_MATCH 0x00000002 +#define DNS_VERIFY_SECURE 0x00000004 + +int verify_host_key_dns(const char *, struct sockaddr *, Key *, int *); +int export_dns_rr(const char *, Key *, FILE *, int); + +#endif /* DNS_H */
diff --git a/openssh-6.0p1/entropy.c b/openssh-6.0p1/entropy.c new file mode 100644 index 0000000..2d483b3 --- /dev/null +++ b/openssh-6.0p1/entropy.c
@@ -0,0 +1,239 @@ +/* + * 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 <sys/types.h> +#include <sys/socket.h> +#ifdef HAVE_SYS_UN_H +# include <sys/un.h> +#endif + +#include <netinet/in.h> +#include <arpa/inet.h> + +#include <errno.h> +#include <signal.h> +#include <string.h> +#include <unistd.h> +#include <stddef.h> /* for offsetof */ + +#include <openssl/rand.h> +#include <openssl/crypto.h> +#include <openssl/err.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 + /* + * 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. + */ + u_long version_mask = SSLeay() >= 0x1000000f ? ~0xffff0L : ~0xff0L; + if (((SSLeay() ^ OPENSSL_VERSION_NUMBER) & version_mask) || + (SSLeay() >> 12) < (OPENSSL_VERSION_NUMBER >> 12)) + 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"); +}
diff --git a/openssh-6.0p1/entropy.h b/openssh-6.0p1/entropy.h new file mode 100644 index 0000000..c3d78db --- /dev/null +++ b/openssh-6.0p1/entropy.h
@@ -0,0 +1,37 @@ +/* + * Copyright (c) 1999-2000 Damien Miller. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* $Id: entropy.h,v 1.6 2011/09/09 01:29:41 dtucker Exp $ */ + +#ifndef _RANDOMS_H +#define _RANDOMS_H + +#include "buffer.h" + +void seed_rng(void); + +void rexec_send_rng_seed(Buffer *); +void rexec_recv_rng_seed(Buffer *); + +#endif /* _RANDOMS_H */
diff --git a/openssh-6.0p1/fatal.c b/openssh-6.0p1/fatal.c new file mode 100644 index 0000000..5e5aa3f --- /dev/null +++ b/openssh-6.0p1/fatal.c
@@ -0,0 +1,45 @@ +/* $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 <sys/types.h> + +#include <stdarg.h> + +#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); +}
diff --git a/openssh-6.0p1/fixpaths b/openssh-6.0p1/fixpaths new file mode 100755 index 0000000..60a6799 --- /dev/null +++ b/openssh-6.0p1/fixpaths
@@ -0,0 +1,22 @@ +#!/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
diff --git a/openssh-6.0p1/fixprogs b/openssh-6.0p1/fixprogs new file mode 100755 index 0000000..af76ee3 --- /dev/null +++ b/openssh-6.0p1/fixprogs
@@ -0,0 +1,72 @@ +#!/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 <command file>\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=<IN>; + +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 (STDOUT, ">/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);
diff --git a/openssh-6.0p1/groupaccess.c b/openssh-6.0p1/groupaccess.c new file mode 100644 index 0000000..2381aeb --- /dev/null +++ b/openssh-6.0p1/groupaccess.c
@@ -0,0 +1,129 @@ +/* $OpenBSD: groupaccess.c,v 1.13 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. + */ + +#include "includes.h" + +#include <sys/types.h> +#include <sys/param.h> + +#include <grp.h> +#include <unistd.h> +#include <stdarg.h> +#include <string.h> + +#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); + xfree(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; + size_t len = strlen(group_pattern); + + for (i = 0; i < ngroups; i++) { + switch (match_pattern_list(groups_byname[i], + group_pattern, len, 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++) + xfree(groups_byname[i]); + ngroups = 0; + xfree(groups_byname); + } +}
diff --git a/openssh-6.0p1/groupaccess.h b/openssh-6.0p1/groupaccess.h new file mode 100644 index 0000000..000578e --- /dev/null +++ b/openssh-6.0p1/groupaccess.h
@@ -0,0 +1,35 @@ +/* $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
diff --git a/openssh-6.0p1/gss-genr.c b/openssh-6.0p1/gss-genr.c new file mode 100644 index 0000000..842f385 --- /dev/null +++ b/openssh-6.0p1/gss-genr.c
@@ -0,0 +1,281 @@ +/* $OpenBSD: gss-genr.c,v 1.20 2009/06/22 05:39:28 dtucker 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 <sys/types.h> +#include <sys/param.h> + +#include <stdarg.h> +#include <string.h> +#include <unistd.h> + +#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) { + xfree(ctx->oid->elements); + xfree(ctx->oid); + } + ctx->oid = xmalloc(sizeof(gss_OID_desc)); + ctx->oid->length = len; + ctx->oid->elements = xmalloc(len); + memcpy(ctx->oid->elements, data, len); +} + +/* Set the contexts OID */ +void +ssh_gssapi_set_oid(Gssctxt *ctx, gss_OID oid) +{ + ssh_gssapi_set_oid_data(ctx, oid->elements, oid->length); +} + +/* All this effort to report an error ... */ +void +ssh_gssapi_error(Gssctxt *ctxt) +{ + char *s; + + s = ssh_gssapi_last_error(ctxt, NULL, NULL); + debug("%s", s); + xfree(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) { + xfree((*ctx)->oid->elements); + xfree((*ctx)->oid); + (*ctx)->oid = GSS_C_NO_OID; + } + if ((*ctx)->creds != GSS_C_NO_CREDENTIAL) + gss_release_cred(&ms, &(*ctx)->creds); + if ((*ctx)->client != GSS_C_NO_NAME) + gss_release_name(&ms, &(*ctx)->client); + if ((*ctx)->client_creds != GSS_C_NO_CREDENTIAL) + gss_release_cred(&ms, &(*ctx)->client_creds); + + xfree(*ctx); + *ctx = NULL; +} + +/* + * Wrapper to init_sec_context + * Requires that the context contains: + * oid + * server name (from ssh_gssapi_import_name) + */ +OM_uint32 +ssh_gssapi_init_ctx(Gssctxt *ctx, int deleg_creds, gss_buffer_desc *recv_tok, + gss_buffer_desc* send_tok, OM_uint32 *flags) +{ + int deleg_flag = 0; + + if (deleg_creds) { + deleg_flag = GSS_C_DELEG_FLAG; + debug("Delegating credentials"); + } + + ctx->major = gss_init_sec_context(&ctx->minor, + GSS_C_NO_CREDENTIAL, &ctx->context, ctx->name, ctx->oid, + GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | deleg_flag, + 0, NULL, recv_tok, NULL, send_tok, flags, NULL); + + if (GSS_ERROR(ctx->major)) + ssh_gssapi_error(ctx); + + return (ctx->major); +} + +/* Create a service name for the given host */ +OM_uint32 +ssh_gssapi_import_name(Gssctxt *ctx, const char *host) +{ + gss_buffer_desc gssbuf; + 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); + + xfree(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 */
diff --git a/openssh-6.0p1/gss-serv-krb5.c b/openssh-6.0p1/gss-serv-krb5.c new file mode 100644 index 0000000..5a625ac --- /dev/null +++ b/openssh-6.0p1/gss-serv-krb5.c
@@ -0,0 +1,199 @@ +/* $OpenBSD: gss-serv-krb5.c,v 1.7 2006/08/03 03:34:42 deraadt Exp $ */ + +/* + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#ifdef GSSAPI +#ifdef KRB5 + +#include <sys/types.h> + +#include <stdarg.h> +#include <string.h> + +#include "xmalloc.h" +#include "key.h" +#include "hostfile.h" +#include "auth.h" +#include "log.h" +#include "servconf.h" + +#include "buffer.h" +#include "ssh-gss.h" + +extern ServerOptions options; + +#ifdef HEIMDAL +# include <krb5.h> +#else +# ifdef HAVE_GSSAPI_KRB5_H +# include <gssapi_krb5.h> +# elif HAVE_GSSAPI_GSSAPI_KRB5_H +# include <gssapi/gssapi_krb5.h> +# endif +#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; + + if (ssh_gssapi_krb5_init() == 0) + return 0; + + if ((retval = krb5_parse_name(krb_context, client->exportedname.value, + &princ))) { + logit("krb5_parse_name(): %.100s", + krb5_get_err_text(krb_context, retval)); + return 0; + } + if (krb5_kuserok(krb_context, princ, name)) { + retval = 1; + logit("Authorized to %s, krb5 principal %s (krb5_kuserok)", + name, (char *)client->displayname.value); + } else + retval = 0; + + krb5_free_principal(krb_context, princ); + return retval; +} + + +/* This writes out any forwarded credentials from the structure populated + * during userauth. Called after we have setuid to the user */ + +static void +ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client) +{ + krb5_ccache ccache; + krb5_error_code problem; + krb5_principal princ; + OM_uint32 maj_status, min_status; + int len; + + if (client->creds == NULL) { + debug("No credentials stored"); + return; + } + + if (ssh_gssapi_krb5_init() == 0) + return; + +#ifdef HEIMDAL + if ((problem = krb5_cc_gen_new(krb_context, &krb5_fcc_ops, &ccache))) { + logit("krb5_cc_gen_new(): %.100s", + krb5_get_err_text(krb_context, problem)); + return; + } +#else + if ((problem = ssh_krb5_cc_gen(krb_context, &ccache))) { + logit("ssh_krb5_cc_gen(): %.100s", + krb5_get_err_text(krb_context, problem)); + return; + } +#endif /* #ifdef HEIMDAL */ + + if ((problem = krb5_parse_name(krb_context, + client->exportedname.value, &princ))) { + logit("krb5_parse_name(): %.100s", + krb5_get_err_text(krb_context, problem)); + krb5_cc_destroy(krb_context, ccache); + return; + } + + if ((problem = krb5_cc_initialize(krb_context, ccache, princ))) { + logit("krb5_cc_initialize(): %.100s", + krb5_get_err_text(krb_context, problem)); + krb5_free_principal(krb_context, princ); + krb5_cc_destroy(krb_context, ccache); + return; + } + + krb5_free_principal(krb_context, princ); + + if ((maj_status = gss_krb5_copy_ccache(&min_status, + client->creds, ccache))) { + logit("gss_krb5_copy_ccache() failed"); + krb5_cc_destroy(krb_context, ccache); + return; + } + + client->store.filename = xstrdup(krb5_cc_get_name(krb_context, ccache)); + client->store.envvar = "KRB5CCNAME"; + 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 */
diff --git a/openssh-6.0p1/gss-serv.c b/openssh-6.0p1/gss-serv.c new file mode 100644 index 0000000..c719c13 --- /dev/null +++ b/openssh-6.0p1/gss-serv.c
@@ -0,0 +1,367 @@ +/* $OpenBSD: gss-serv.c,v 1.23 2011/08/01 19:18:15 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 <sys/types.h> +#include <sys/param.h> + +#include <stdarg.h> +#include <string.h> +#include <unistd.h> + +#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 "ssh-gss.h" + +static ssh_gssapi_client gssapi_client = + { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, + GSS_C_NO_CREDENTIAL, NULL, {NULL, NULL, NULL}}; + +ssh_gssapi_mech gssapi_null_mech = + { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL}; + +#ifdef KRB5 +extern ssh_gssapi_mech gssapi_kerberos_mech; +#endif + +ssh_gssapi_mech* supported_mechs[]= { +#ifdef KRB5 + &gssapi_kerberos_mech, +#endif + &gssapi_null_mech, +}; + + +/* + * 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[MAXHOSTNAMELEN]; + gss_OID_set oidset; + + gss_create_empty_oid_set(&status, &oidset); + gss_add_oid_set_member(&status, ctx->oid, &oidset); + + if (gethostname(lname, MAXHOSTNAMELEN)) { + 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); +} + +/* 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); + memset(&gssapi_client, 0, 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
diff --git a/openssh-6.0p1/hostfile.c b/openssh-6.0p1/hostfile.c new file mode 100644 index 0000000..b6f924b --- /dev/null +++ b/openssh-6.0p1/hostfile.c
@@ -0,0 +1,488 @@ +/* $OpenBSD: hostfile.c,v 1.50 2010/12/04 13:31:37 djm Exp $ */ +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * Functions for manipulating 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 <sys/types.h> + +#include <netinet/in.h> + +#include <openssl/hmac.h> +#include <openssl/sha.h> + +#include <resolv.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "xmalloc.h" +#include "match.h" +#include "key.h" +#include "hostfile.h" +#include "log.h" +#include "misc.h" + +struct hostkeys { + struct hostkey_entry *entries; + u_int num_entries; +}; + +static int +extract_salt(const char *s, u_int l, 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); + xfree(b64salt); + if (ret == -1) { + debug2("extract_salt: salt decode error"); + return (-1); + } + if (ret != SHA_DIGEST_LENGTH) { + debug2("extract_salt: expected salt len %d, got %d", + SHA_DIGEST_LENGTH, ret); + return (-1); + } + + return (0); +} + +char * +host_hash(const char *host, const char *name_from_hostfile, u_int src_len) +{ + const EVP_MD *md = EVP_sha1(); + HMAC_CTX mac_ctx; + char salt[256], result[256], uu_salt[512], uu_result[512]; + static char encoded[1024]; + u_int i, len; + + len = EVP_MD_size(md); + + if (name_from_hostfile == NULL) { + /* Create new salt */ + for (i = 0; i < len; i++) + salt[i] = arc4random(); + } else { + /* Extract salt from known host entry */ + if (extract_salt(name_from_hostfile, src_len, salt, + sizeof(salt)) == -1) + return (NULL); + } + + HMAC_Init(&mac_ctx, salt, len, md); + HMAC_Update(&mac_ctx, host, strlen(host)); + HMAC_Final(&mac_ctx, result, NULL); + HMAC_cleanup(&mac_ctx); + + if (__b64_ntop(salt, len, uu_salt, sizeof(uu_salt)) == -1 || + __b64_ntop(result, len, uu_result, sizeof(uu_result)) == -1) + fatal("host_hash: __b64_ntop failed"); + + 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, Key *ret) +{ + char *cp; + + /* Skip leading whitespace. */ + for (cp = *cpp; *cp == ' ' || *cp == '\t'; cp++) + ; + + if (key_read(ret, &cp) != 1) + return 0; + + /* Skip trailing whitespace. */ + for (; *cp == ' ' || *cp == '\t'; cp++) + ; + + /* Return results. */ + *cpp = cp; + if (bitsp != NULL) + *bitsp = key_size(ret); + return 1; +} + +static int +hostfile_check_key(int bits, const Key *key, const char *host, + const char *filename, u_long linenum) +{ + if (key == NULL || key->type != KEY_RSA1 || key->rsa == NULL) + return 1; + if (bits != BN_num_bits(key->rsa->n)) { + logit("Warning: %s, line %lu: keysize mismatch for host %s: " + "actual %d vs. announced %d.", + filename, linenum, host, BN_num_bits(key->rsa->n), bits); + logit("Warning: replace %d with %d in %s, line %lu.", + bits, BN_num_bits(key->rsa->n), filename, linenum); + } + 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; +} + +void +load_hostkeys(struct hostkeys *hostkeys, const char *host, const char *path) +{ + FILE *f; + char line[8192]; + u_long linenum = 0, num_loaded = 0; + char *cp, *cp2, *hashed_host; + HostkeyMarker marker; + Key *key; + int kbits; + + if ((f = fopen(path, "r")) == NULL) + return; + debug3("%s: loading entries for host \"%.100s\" from file \"%s\"", + __func__, host, path); + while (read_keyfile_line(f, path, line, sizeof(line), &linenum) == 0) { + cp = line; + + /* Skip any leading whitespace, comments and empty lines. */ + for (; *cp == ' ' || *cp == '\t'; cp++) + ; + if (!*cp || *cp == '#' || *cp == '\n') + continue; + + if ((marker = check_markers(&cp)) == MRK_ERROR) { + verbose("%s: invalid marker at %s:%lu", + __func__, path, linenum); + continue; + } + + /* Find the end of the host name portion. */ + for (cp2 = cp; *cp2 && *cp2 != ' ' && *cp2 != '\t'; cp2++) + ; + + /* Check if the host name matches. */ + if (match_hostname(host, cp, (u_int) (cp2 - cp)) != 1) { + if (*cp != HASH_DELIM) + continue; + hashed_host = host_hash(host, cp, (u_int) (cp2 - cp)); + if (hashed_host == NULL) { + debug("Invalid hashed host line %lu of %s", + linenum, path); + continue; + } + if (strncmp(hashed_host, cp, (u_int) (cp2 - cp)) != 0) + continue; + } + + /* Got a match. Skip host name. */ + cp = cp2; + + /* + * Extract the key from the line. This will skip any leading + * whitespace. Ignore badly formatted lines. + */ + key = key_new(KEY_UNSPEC); + if (!hostfile_read_key(&cp, &kbits, key)) { + key_free(key); + key = key_new(KEY_RSA1); + if (!hostfile_read_key(&cp, &kbits, key)) { + key_free(key); + continue; + } + } + if (!hostfile_check_key(kbits, key, host, path, linenum)) + continue; + + debug3("%s: found %skey type %s in file %s:%lu", __func__, + marker == MRK_NONE ? "" : + (marker == MRK_CA ? "ca " : "revoked "), + key_type(key), path, linenum); + hostkeys->entries = xrealloc(hostkeys->entries, + hostkeys->num_entries + 1, sizeof(*hostkeys->entries)); + hostkeys->entries[hostkeys->num_entries].host = xstrdup(host); + hostkeys->entries[hostkeys->num_entries].file = xstrdup(path); + hostkeys->entries[hostkeys->num_entries].line = linenum; + hostkeys->entries[hostkeys->num_entries].key = key; + hostkeys->entries[hostkeys->num_entries].marker = marker; + hostkeys->num_entries++; + num_loaded++; + } + debug3("%s: loaded %lu keys", __func__, num_loaded); + fclose(f); + return; +} + +void +free_hostkeys(struct hostkeys *hostkeys) +{ + u_int i; + + for (i = 0; i < hostkeys->num_entries; i++) { + xfree(hostkeys->entries[i].host); + xfree(hostkeys->entries[i].file); + key_free(hostkeys->entries[i].key); + bzero(hostkeys->entries + i, sizeof(*hostkeys->entries)); + } + if (hostkeys->entries != NULL) + xfree(hostkeys->entries); + hostkeys->entries = NULL; + hostkeys->num_entries = 0; + xfree(hostkeys); +} + +static int +check_key_not_revoked(struct hostkeys *hostkeys, Key *k) +{ + int is_cert = key_is_cert(k); + u_int i; + + for (i = 0; i < hostkeys->num_entries; i++) { + if (hostkeys->entries[i].marker != MRK_REVOKE) + continue; + if (key_equal_public(k, hostkeys->entries[i].key)) + return -1; + if (is_cert && + key_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, + Key *k, int keytype, const struct hostkey_entry **found) +{ + u_int i; + HostStatus end_return = HOST_NEW; + int want_cert = key_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 (key_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 (key_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, Key *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); +} + +/* + * 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 Key *key, + int store_hash) +{ + FILE *f; + int success = 0; + char *hashed_host = NULL; + + if (key == NULL) + return 1; /* XXX ? */ + f = fopen(filename, "a"); + if (!f) + return 0; + + if (store_hash) { + if ((hashed_host = host_hash(host, NULL, 0)) == NULL) { + error("add_host_to_hostfile: host_hash failed"); + fclose(f); + return 0; + } + } + fprintf(f, "%s ", store_hash ? hashed_host : host); + + if (key_write(key, f)) { + success = 1; + } else { + error("add_host_to_hostfile: saving key in %s failed", filename); + } + fprintf(f, "\n"); + fclose(f); + return success; +}
diff --git a/openssh-6.0p1/hostfile.h b/openssh-6.0p1/hostfile.h new file mode 100644 index 0000000..d84d422 --- /dev/null +++ b/openssh-6.0p1/hostfile.h
@@ -0,0 +1,54 @@ +/* $OpenBSD: hostfile.h,v 1.19 2010/11/29 23:45:51 djm Exp $ */ + +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ +#ifndef 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; + Key *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 *, Key *, + 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 *, Key *); +int add_host_to_hostfile(const char *, const char *, const Key *, int); + +#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); + +#endif
diff --git a/openssh-6.0p1/includes.h b/openssh-6.0p1/includes.h new file mode 100644 index 0000000..b4c53d9 --- /dev/null +++ b/openssh-6.0p1/includes.h
@@ -0,0 +1,175 @@ +/* $OpenBSD: includes.h,v 1.54 2006/07/22 20:48:23 stevesk Exp $ */ + +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, 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" + +#define _GNU_SOURCE /* activate extra prototypes for glibc */ + +#include <sys/types.h> +#include <sys/socket.h> /* For CMSG_* */ + +#ifdef HAVE_LIMITS_H +# include <limits.h> /* For PATH_MAX */ +#endif +#ifdef HAVE_BSTRING_H +# include <bstring.h> +#endif +#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) +# include <glob.h> +#endif +#ifdef HAVE_ENDIAN_H +# include <endian.h> +#endif +#ifdef HAVE_TTYENT_H +# include <ttyent.h> +#endif +#ifdef HAVE_UTIME_H +# include <utime.h> +#endif +#ifdef HAVE_MAILLOCK_H +# include <maillock.h> /* For _PATH_MAILDIR */ +#endif +#ifdef HAVE_NEXT +# include <libc.h> +#endif +#ifdef HAVE_PATHS_H +# include <paths.h> +#endif + +/* + *-*-nto-qnx needs these headers for strcasecmp and LASTLOG_FILE respectively + */ +#ifdef HAVE_STRINGS_H +# include <strings.h> +#endif +#ifdef HAVE_LOGIN_H +# include <login.h> +#endif + +#ifdef HAVE_UTMP_H +# include <utmp.h> +#endif +#ifdef HAVE_UTMPX_H +# include <utmpx.h> +#endif +#ifdef HAVE_LASTLOG_H +# include <lastlog.h> +#endif + +#ifdef HAVE_SYS_SELECT_H +# include <sys/select.h> +#endif +#ifdef HAVE_SYS_BSDTTY_H +# include <sys/bsdtty.h> +#endif +#ifdef HAVE_STDINT_H +# include <stdint.h> +#endif +#include <termios.h> +#ifdef HAVE_SYS_BITYPES_H +# include <sys/bitypes.h> /* For u_intXX_t */ +#endif +#ifdef HAVE_SYS_CDEFS_H +# include <sys/cdefs.h> /* For __P() */ +#endif +#ifdef HAVE_SYS_STAT_H +# include <sys/stat.h> /* For S_* constants and macros */ +#endif +#ifdef HAVE_SYS_SYSMACROS_H +# include <sys/sysmacros.h> /* For MIN, MAX, etc */ +#endif +#ifdef HAVE_SYS_MMAN_H +#include <sys/mman.h> /* for MAP_ANONYMOUS */ +#endif +#ifdef HAVE_SYS_STRTIO_H +#include <sys/strtio.h> /* for TIOCCBRK on HP-UX */ +#endif +#if defined(HAVE_SYS_PTMS_H) && defined(HAVE_DEV_PTMX) +# if defined(HAVE_SYS_STREAM_H) +# include <sys/stream.h> /* reqd for queue_t on Solaris 2.5.1 */ +# endif +#include <sys/ptms.h> /* for grantpt() and friends */ +#endif + +#include <netinet/in.h> +#include <netinet/in_systm.h> /* For typedefs */ +#ifdef HAVE_RPC_TYPES_H +# include <rpc/types.h> /* For INADDR_LOOPBACK */ +#endif +#ifdef USE_PAM +#if defined(HAVE_SECURITY_PAM_APPL_H) +# include <security/pam_appl.h> +#elif defined (HAVE_PAM_PAM_APPL_H) +# include <pam/pam_appl.h> +#endif +#endif +#ifdef HAVE_READPASSPHRASE_H +# include <readpassphrase.h> +#endif + +#ifdef HAVE_IA_H +# include <ia.h> +#endif + +#ifdef HAVE_IAF_H +# include <iaf.h> +#endif + +#ifdef HAVE_TMPDIR_H +# include <tmpdir.h> +#endif + +#ifdef HAVE_LIBUTIL_H +# include <libutil.h> /* Openpty on FreeBSD at least */ +#endif + +#if defined(KRB5) && defined(USE_AFS) +# include <krb5.h> +# include <kafs.h> +#endif + +#if defined(HAVE_SYS_SYSLOG_H) +# include <sys/syslog.h> +#endif + +#include <errno.h> + +/* + * 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 + +#include <openssl/opensslv.h> /* For OPENSSL_VERSION_NUMBER */ + +#include "defines.h" + +#include "platform.h" +#include "openbsd-compat/openbsd-compat.h" +#include "openbsd-compat/bsd-nextstep.h" + +#include "entropy.h" + +#endif /* INCLUDES_H */
diff --git a/openssh-6.0p1/install-sh b/openssh-6.0p1/install-sh new file mode 100755 index 0000000..220abbf --- /dev/null +++ b/openssh-6.0p1/install-sh
@@ -0,0 +1,251 @@ +#!/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
diff --git a/openssh-6.0p1/jpake.c b/openssh-6.0p1/jpake.c new file mode 100644 index 0000000..ac9a4bc --- /dev/null +++ b/openssh-6.0p1/jpake.c
@@ -0,0 +1,456 @@ +/* $OpenBSD: jpake.c,v 1.6 2010/09/20 04:54:07 djm Exp $ */ +/* + * Copyright (c) 2008 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. + */ + +/* + * Shared components of zero-knowledge password auth using J-PAKE protocol + * as described in: + * + * F. Hao, P. Ryan, "Password Authenticated Key Exchange by Juggling", + * 16th Workshop on Security Protocols, Cambridge, April 2008 + * + * http://grouper.ieee.org/groups/1363/Research/contributions/hao-ryan-2008.pdf + */ + +#include "includes.h" + +#include <sys/types.h> + +#include <stdio.h> +#include <string.h> +#include <stdarg.h> + +#include <openssl/bn.h> +#include <openssl/evp.h> + +#include "xmalloc.h" +#include "ssh2.h" +#include "key.h" +#include "hostfile.h" +#include "auth.h" +#include "buffer.h" +#include "packet.h" +#include "dispatch.h" +#include "log.h" +#include "misc.h" + +#include "jpake.h" +#include "schnorr.h" + +#ifdef JPAKE + +/* RFC3526 group 5, 1536 bits */ +#define JPAKE_GROUP_G "2" +#define JPAKE_GROUP_P \ + "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74" \ + "020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437" \ + "4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \ + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05" \ + "98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB" \ + "9ED529077096966D670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF" + +struct modp_group * +jpake_default_group(void) +{ + return modp_group_from_g_and_safe_p(JPAKE_GROUP_G, JPAKE_GROUP_P); +} + +struct jpake_ctx * +jpake_new(void) +{ + struct jpake_ctx *ret; + + ret = xcalloc(1, sizeof(*ret)); + + ret->grp = jpake_default_group(); + + ret->s = ret->k = NULL; + ret->x1 = ret->x2 = ret->x3 = ret->x4 = NULL; + ret->g_x1 = ret->g_x2 = ret->g_x3 = ret->g_x4 = NULL; + ret->a = ret->b = NULL; + + ret->client_id = ret->server_id = NULL; + ret->h_k_cid_sessid = ret->h_k_sid_sessid = NULL; + + debug3("%s: alloc %p", __func__, ret); + + return ret; +} + +void +jpake_free(struct jpake_ctx *pctx) +{ + debug3("%s: free %p", __func__, pctx); + +#define JPAKE_BN_CLEAR_FREE(v) \ + do { \ + if ((v) != NULL) { \ + BN_clear_free(v); \ + (v) = NULL; \ + } \ + } while (0) +#define JPAKE_BUF_CLEAR_FREE(v, l) \ + do { \ + if ((v) != NULL) { \ + bzero((v), (l)); \ + xfree(v); \ + (v) = NULL; \ + (l) = 0; \ + } \ + } while (0) + + JPAKE_BN_CLEAR_FREE(pctx->s); + JPAKE_BN_CLEAR_FREE(pctx->k); + JPAKE_BN_CLEAR_FREE(pctx->x1); + JPAKE_BN_CLEAR_FREE(pctx->x2); + JPAKE_BN_CLEAR_FREE(pctx->x3); + JPAKE_BN_CLEAR_FREE(pctx->x4); + JPAKE_BN_CLEAR_FREE(pctx->g_x1); + JPAKE_BN_CLEAR_FREE(pctx->g_x2); + JPAKE_BN_CLEAR_FREE(pctx->g_x3); + JPAKE_BN_CLEAR_FREE(pctx->g_x4); + JPAKE_BN_CLEAR_FREE(pctx->a); + JPAKE_BN_CLEAR_FREE(pctx->b); + + JPAKE_BUF_CLEAR_FREE(pctx->client_id, pctx->client_id_len); + JPAKE_BUF_CLEAR_FREE(pctx->server_id, pctx->server_id_len); + JPAKE_BUF_CLEAR_FREE(pctx->h_k_cid_sessid, pctx->h_k_cid_sessid_len); + JPAKE_BUF_CLEAR_FREE(pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len); + +#undef JPAKE_BN_CLEAR_FREE +#undef JPAKE_BUF_CLEAR_FREE + + bzero(pctx, sizeof(pctx)); + xfree(pctx); +} + +/* dump entire jpake_ctx. NB. includes private values! */ +void +jpake_dump(struct jpake_ctx *pctx, const char *fmt, ...) +{ + char *out; + va_list args; + + out = NULL; + va_start(args, fmt); + vasprintf(&out, fmt, args); + va_end(args); + if (out == NULL) + fatal("%s: vasprintf failed", __func__); + + debug3("%s: %s (ctx at %p)", __func__, out, pctx); + if (pctx == NULL) { + free(out); + return; + } + +#define JPAKE_DUMP_BN(a) do { \ + if ((a) != NULL) \ + JPAKE_DEBUG_BN(((a), "%s = ", #a)); \ + } while (0) +#define JPAKE_DUMP_BUF(a, b) do { \ + if ((a) != NULL) \ + JPAKE_DEBUG_BUF((a, b, "%s", #a)); \ + } while (0) + + JPAKE_DUMP_BN(pctx->s); + JPAKE_DUMP_BN(pctx->k); + JPAKE_DUMP_BN(pctx->x1); + JPAKE_DUMP_BN(pctx->x2); + JPAKE_DUMP_BN(pctx->x3); + JPAKE_DUMP_BN(pctx->x4); + JPAKE_DUMP_BN(pctx->g_x1); + JPAKE_DUMP_BN(pctx->g_x2); + JPAKE_DUMP_BN(pctx->g_x3); + JPAKE_DUMP_BN(pctx->g_x4); + JPAKE_DUMP_BN(pctx->a); + JPAKE_DUMP_BN(pctx->b); + + JPAKE_DUMP_BUF(pctx->client_id, pctx->client_id_len); + JPAKE_DUMP_BUF(pctx->server_id, pctx->server_id_len); + JPAKE_DUMP_BUF(pctx->h_k_cid_sessid, pctx->h_k_cid_sessid_len); + JPAKE_DUMP_BUF(pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len); + + debug3("%s: %s done", __func__, out); + free(out); +} + +/* Shared parts of step 1 exchange calculation */ +void +jpake_step1(struct modp_group *grp, + u_char **id, u_int *id_len, + BIGNUM **priv1, BIGNUM **priv2, BIGNUM **g_priv1, BIGNUM **g_priv2, + u_char **priv1_proof, u_int *priv1_proof_len, + u_char **priv2_proof, u_int *priv2_proof_len) +{ + BN_CTX *bn_ctx; + + if ((bn_ctx = BN_CTX_new()) == NULL) + fatal("%s: BN_CTX_new", __func__); + + /* Random nonce to prevent replay */ + *id = xmalloc(KZP_ID_LEN); + *id_len = KZP_ID_LEN; + arc4random_buf(*id, *id_len); + + /* + * x1/x3 is a random element of Zq + * x2/x4 is a random element of Z*q + * We also exclude [1] from x1/x3 candidates and [0, 1] from + * x2/x4 candiates to avoid possible degeneracy (i.e. g^0, g^1). + */ + if ((*priv1 = bn_rand_range_gt_one(grp->q)) == NULL || + (*priv2 = bn_rand_range_gt_one(grp->q)) == NULL) + fatal("%s: bn_rand_range_gt_one", __func__); + + /* + * client: g_x1 = g^x1 mod p / server: g_x3 = g^x3 mod p + * client: g_x2 = g^x2 mod p / server: g_x4 = g^x4 mod p + */ + if ((*g_priv1 = BN_new()) == NULL || + (*g_priv2 = BN_new()) == NULL) + fatal("%s: BN_new", __func__); + if (BN_mod_exp(*g_priv1, grp->g, *priv1, grp->p, bn_ctx) == -1) + fatal("%s: BN_mod_exp", __func__); + if (BN_mod_exp(*g_priv2, grp->g, *priv2, grp->p, bn_ctx) == -1) + fatal("%s: BN_mod_exp", __func__); + + /* Generate proofs for holding x1/x3 and x2/x4 */ + if (schnorr_sign_buf(grp->p, grp->q, grp->g, + *priv1, *g_priv1, *id, *id_len, + priv1_proof, priv1_proof_len) != 0) + fatal("%s: schnorr_sign", __func__); + if (schnorr_sign_buf(grp->p, grp->q, grp->g, + *priv2, *g_priv2, *id, *id_len, + priv2_proof, priv2_proof_len) != 0) + fatal("%s: schnorr_sign", __func__); + + BN_CTX_free(bn_ctx); +} + +/* Shared parts of step 2 exchange calculation */ +void +jpake_step2(struct modp_group *grp, BIGNUM *s, + BIGNUM *mypub1, BIGNUM *theirpub1, BIGNUM *theirpub2, BIGNUM *mypriv2, + const u_char *theirid, u_int theirid_len, + const u_char *myid, u_int myid_len, + const u_char *theirpub1_proof, u_int theirpub1_proof_len, + const u_char *theirpub2_proof, u_int theirpub2_proof_len, + BIGNUM **newpub, + u_char **newpub_exponent_proof, u_int *newpub_exponent_proof_len) +{ + BN_CTX *bn_ctx; + BIGNUM *tmp, *exponent; + + /* Validate peer's step 1 values */ + if (BN_cmp(theirpub1, BN_value_one()) <= 0) + fatal("%s: theirpub1 <= 1", __func__); + if (BN_cmp(theirpub1, grp->p) >= 0) + fatal("%s: theirpub1 >= p", __func__); + if (BN_cmp(theirpub2, BN_value_one()) <= 0) + fatal("%s: theirpub2 <= 1", __func__); + if (BN_cmp(theirpub2, grp->p) >= 0) + fatal("%s: theirpub2 >= p", __func__); + + if (schnorr_verify_buf(grp->p, grp->q, grp->g, theirpub1, + theirid, theirid_len, theirpub1_proof, theirpub1_proof_len) != 1) + fatal("%s: schnorr_verify theirpub1 failed", __func__); + if (schnorr_verify_buf(grp->p, grp->q, grp->g, theirpub2, + theirid, theirid_len, theirpub2_proof, theirpub2_proof_len) != 1) + fatal("%s: schnorr_verify theirpub2 failed", __func__); + + if ((bn_ctx = BN_CTX_new()) == NULL) + fatal("%s: BN_CTX_new", __func__); + + if ((*newpub = BN_new()) == NULL || + (tmp = BN_new()) == NULL || + (exponent = BN_new()) == NULL) + fatal("%s: BN_new", __func__); + + /* + * client: exponent = x2 * s mod p + * server: exponent = x4 * s mod p + */ + if (BN_mod_mul(exponent, mypriv2, s, grp->q, bn_ctx) != 1) + fatal("%s: BN_mod_mul (exponent = mypriv2 * s mod p)", + __func__); + + /* + * client: tmp = g^(x1 + x3 + x4) mod p + * server: tmp = g^(x1 + x2 + x3) mod p + */ + if (BN_mod_mul(tmp, mypub1, theirpub1, grp->p, bn_ctx) != 1) + fatal("%s: BN_mod_mul (tmp = mypub1 * theirpub1 mod p)", + __func__); + if (BN_mod_mul(tmp, tmp, theirpub2, grp->p, bn_ctx) != 1) + fatal("%s: BN_mod_mul (tmp = tmp * theirpub2 mod p)", __func__); + + /* + * client: a = tmp^exponent = g^((x1+x3+x4) * x2 * s) mod p + * server: b = tmp^exponent = g^((x1+x2+x3) * x4 * s) mod p + */ + if (BN_mod_exp(*newpub, tmp, exponent, grp->p, bn_ctx) != 1) + fatal("%s: BN_mod_mul (newpub = tmp^exponent mod p)", __func__); + + JPAKE_DEBUG_BN((tmp, "%s: tmp = ", __func__)); + JPAKE_DEBUG_BN((exponent, "%s: exponent = ", __func__)); + + /* Note the generator here is 'tmp', not g */ + if (schnorr_sign_buf(grp->p, grp->q, tmp, exponent, *newpub, + myid, myid_len, + newpub_exponent_proof, newpub_exponent_proof_len) != 0) + fatal("%s: schnorr_sign newpub", __func__); + + BN_clear_free(tmp); /* XXX stash for later use? */ + BN_clear_free(exponent); /* XXX stash for later use? (yes, in conf) */ + + BN_CTX_free(bn_ctx); +} + +/* Confirmation hash calculation */ +void +jpake_confirm_hash(const BIGNUM *k, + const u_char *endpoint_id, u_int endpoint_id_len, + const u_char *sess_id, u_int sess_id_len, + u_char **confirm_hash, u_int *confirm_hash_len) +{ + Buffer b; + + /* + * Calculate confirmation proof: + * client: H(k || client_id || session_id) + * server: H(k || server_id || session_id) + */ + buffer_init(&b); + buffer_put_bignum2(&b, k); + buffer_put_string(&b, endpoint_id, endpoint_id_len); + buffer_put_string(&b, sess_id, sess_id_len); + if (hash_buffer(buffer_ptr(&b), buffer_len(&b), EVP_sha256(), + confirm_hash, confirm_hash_len) != 0) + fatal("%s: hash_buffer", __func__); + buffer_free(&b); +} + +/* Shared parts of key derivation and confirmation calculation */ +void +jpake_key_confirm(struct modp_group *grp, BIGNUM *s, BIGNUM *step2_val, + BIGNUM *mypriv2, BIGNUM *mypub1, BIGNUM *mypub2, + BIGNUM *theirpub1, BIGNUM *theirpub2, + const u_char *my_id, u_int my_id_len, + const u_char *their_id, u_int their_id_len, + const u_char *sess_id, u_int sess_id_len, + const u_char *theirpriv2_s_proof, u_int theirpriv2_s_proof_len, + BIGNUM **k, + u_char **confirm_hash, u_int *confirm_hash_len) +{ + BN_CTX *bn_ctx; + BIGNUM *tmp; + + if ((bn_ctx = BN_CTX_new()) == NULL) + fatal("%s: BN_CTX_new", __func__); + if ((tmp = BN_new()) == NULL || + (*k = BN_new()) == NULL) + fatal("%s: BN_new", __func__); + + /* Validate step 2 values */ + if (BN_cmp(step2_val, BN_value_one()) <= 0) + fatal("%s: step2_val <= 1", __func__); + if (BN_cmp(step2_val, grp->p) >= 0) + fatal("%s: step2_val >= p", __func__); + + /* + * theirpriv2_s_proof is calculated with a different generator: + * tmp = g^(mypriv1+mypriv2+theirpub1) = g^mypub1*g^mypub2*g^theirpub1 + * Calculate it here so we can check the signature. + */ + if (BN_mod_mul(tmp, mypub1, mypub2, grp->p, bn_ctx) != 1) + fatal("%s: BN_mod_mul (tmp = mypub1 * mypub2 mod p)", __func__); + if (BN_mod_mul(tmp, tmp, theirpub1, grp->p, bn_ctx) != 1) + fatal("%s: BN_mod_mul (tmp = tmp * theirpub1 mod p)", __func__); + + JPAKE_DEBUG_BN((tmp, "%s: tmp = ", __func__)); + + if (schnorr_verify_buf(grp->p, grp->q, tmp, step2_val, + their_id, their_id_len, + theirpriv2_s_proof, theirpriv2_s_proof_len) != 1) + fatal("%s: schnorr_verify theirpriv2_s_proof failed", __func__); + + /* + * Derive shared key: + * client: k = (b / g^(x2*x4*s))^x2 = g^((x1+x3)*x2*x4*s) + * server: k = (a / g^(x2*x4*s))^x4 = g^((x1+x3)*x2*x4*s) + * + * Computed as: + * client: k = (g_x4^(q - (x2 * s)) * b)^x2 mod p + * server: k = (g_x2^(q - (x4 * s)) * b)^x4 mod p + */ + if (BN_mul(tmp, mypriv2, s, bn_ctx) != 1) + fatal("%s: BN_mul (tmp = mypriv2 * s)", __func__); + if (BN_mod_sub(tmp, grp->q, tmp, grp->q, bn_ctx) != 1) + fatal("%s: BN_mod_sub (tmp = q - tmp mod q)", __func__); + if (BN_mod_exp(tmp, theirpub2, tmp, grp->p, bn_ctx) != 1) + fatal("%s: BN_mod_exp (tmp = theirpub2^tmp) mod p", __func__); + if (BN_mod_mul(tmp, tmp, step2_val, grp->p, bn_ctx) != 1) + fatal("%s: BN_mod_mul (tmp = tmp * step2_val) mod p", __func__); + if (BN_mod_exp(*k, tmp, mypriv2, grp->p, bn_ctx) != 1) + fatal("%s: BN_mod_exp (k = tmp^mypriv2) mod p", __func__); + + BN_CTX_free(bn_ctx); + BN_clear_free(tmp); + + jpake_confirm_hash(*k, my_id, my_id_len, sess_id, sess_id_len, + confirm_hash, confirm_hash_len); +} + +/* + * Calculate and check confirmation hash from peer. Returns 1 on success + * 0 on failure/mismatch. + */ +int +jpake_check_confirm(const BIGNUM *k, + const u_char *peer_id, u_int peer_id_len, + const u_char *sess_id, u_int sess_id_len, + const u_char *peer_confirm_hash, u_int peer_confirm_hash_len) +{ + u_char *expected_confirm_hash; + u_int expected_confirm_hash_len; + int success = 0; + + /* Calculate and verify expected confirmation hash */ + jpake_confirm_hash(k, peer_id, peer_id_len, sess_id, sess_id_len, + &expected_confirm_hash, &expected_confirm_hash_len); + + JPAKE_DEBUG_BUF((expected_confirm_hash, expected_confirm_hash_len, + "%s: expected confirm hash", __func__)); + JPAKE_DEBUG_BUF((peer_confirm_hash, peer_confirm_hash_len, + "%s: received confirm hash", __func__)); + + if (peer_confirm_hash_len != expected_confirm_hash_len) + error("%s: confirmation length mismatch (my %u them %u)", + __func__, expected_confirm_hash_len, peer_confirm_hash_len); + else if (timingsafe_bcmp(peer_confirm_hash, expected_confirm_hash, + expected_confirm_hash_len) == 0) + success = 1; + bzero(expected_confirm_hash, expected_confirm_hash_len); + xfree(expected_confirm_hash); + debug3("%s: success = %d", __func__, success); + return success; +} + +/* XXX main() function with tests */ + +#endif /* JPAKE */ +
diff --git a/openssh-6.0p1/jpake.h b/openssh-6.0p1/jpake.h new file mode 100644 index 0000000..a3f2cf0 --- /dev/null +++ b/openssh-6.0p1/jpake.h
@@ -0,0 +1,114 @@ +/* $OpenBSD: jpake.h,v 1.2 2009/03/05 07:18:19 djm Exp $ */ +/* + * Copyright (c) 2008 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. + */ + +#ifndef JPAKE_H +#define JPAKE_H + +#include <sys/types.h> + +#include <openssl/bn.h> + +/* Set JPAKE_DEBUG in CFLAGS for privacy-violating debugging */ +#ifndef JPAKE_DEBUG +# define JPAKE_DEBUG_BN(a) +# define JPAKE_DEBUG_BUF(a) +# define JPAKE_DEBUG_CTX(a) +#else +# define JPAKE_DEBUG_BN(a) debug3_bn a +# define JPAKE_DEBUG_BUF(a) debug3_buf a +# define JPAKE_DEBUG_CTX(a) jpake_dump a +#endif /* JPAKE_DEBUG */ + +#define KZP_ID_LEN 16 /* Length of client and server IDs */ + +struct jpake_ctx { + /* Parameters */ + struct modp_group *grp; + + /* Private values shared by client and server */ + BIGNUM *s; /* Secret (salted, crypted password) */ + BIGNUM *k; /* Derived key */ + + /* Client private values (NULL for server) */ + BIGNUM *x1; /* random in Zq */ + BIGNUM *x2; /* random in Z*q */ + + /* Server private values (NULL for server) */ + BIGNUM *x3; /* random in Zq */ + BIGNUM *x4; /* random in Z*q */ + + /* Step 1: C->S */ + u_char *client_id; /* Anti-replay nonce */ + u_int client_id_len; + BIGNUM *g_x1; /* g^x1 */ + BIGNUM *g_x2; /* g^x2 */ + + /* Step 1: S->C */ + u_char *server_id; /* Anti-replay nonce */ + u_int server_id_len; + BIGNUM *g_x3; /* g^x3 */ + BIGNUM *g_x4; /* g^x4 */ + + /* Step 2: C->S */ + BIGNUM *a; /* g^((x1+x3+x4)*x2*s) */ + + /* Step 2: S->C */ + BIGNUM *b; /* g^((x1+x2+x3)*x4*s) */ + + /* Confirmation: C->S */ + u_char *h_k_cid_sessid; /* H(k || client_id || session_id) */ + u_int h_k_cid_sessid_len; + + /* Confirmation: S->C */ + u_char *h_k_sid_sessid; /* H(k || server_id || session_id) */ + u_int h_k_sid_sessid_len; +}; + +/* jpake.c */ +struct modp_group *jpake_default_group(void); +void jpake_dump(struct jpake_ctx *, const char *, ...) + __attribute__((__nonnull__ (2))) + __attribute__((format(printf, 2, 3))); +struct jpake_ctx *jpake_new(void); +void jpake_free(struct jpake_ctx *); + +void jpake_step1(struct modp_group *, u_char **, u_int *, + BIGNUM **, BIGNUM **, BIGNUM **, BIGNUM **, + u_char **, u_int *, u_char **, u_int *); + +void jpake_step2(struct modp_group *, BIGNUM *, + BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, + const u_char *, u_int, const u_char *, u_int, + const u_char *, u_int, const u_char *, u_int, + BIGNUM **, u_char **, u_int *); + +void jpake_confirm_hash(const BIGNUM *, + const u_char *, u_int, + const u_char *, u_int, + u_char **, u_int *); + +void jpake_key_confirm(struct modp_group *, BIGNUM *, BIGNUM *, + BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, + const u_char *, u_int, const u_char *, u_int, + const u_char *, u_int, const u_char *, u_int, + BIGNUM **, u_char **, u_int *); + +int jpake_check_confirm(const BIGNUM *, const u_char *, u_int, + const u_char *, u_int, const u_char *, u_int); + +#endif /* JPAKE_H */ +
diff --git a/openssh-6.0p1/kex.c b/openssh-6.0p1/kex.c new file mode 100644 index 0000000..c65e28f --- /dev/null +++ b/openssh-6.0p1/kex.c
@@ -0,0 +1,610 @@ +/* $OpenBSD: kex.c,v 1.86 2010/09/22 05:01:29 djm Exp $ */ +/* + * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#include <sys/param.h> + +#include <signal.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <openssl/crypto.h> + +#include "xmalloc.h" +#include "ssh2.h" +#include "buffer.h" +#include "packet.h" +#include "compat.h" +#include "cipher.h" +#include "key.h" +#include "kex.h" +#include "log.h" +#include "mac.h" +#include "match.h" +#include "dispatch.h" +#include "monitor.h" +#include "roaming.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 void kex_kexinit_finish(Kex *); +static void kex_choose_conf(Kex *); + +/* Validate KEX method name list */ +int +kex_names_valid(const char *names) +{ + char *s, *cp, *p; + + if (names == NULL || strcmp(names, "") == 0) + return 0; + s = cp = xstrdup(names); + for ((p = strsep(&cp, ",")); p && *p != '\0'; + (p = strsep(&cp, ","))) { + if (strcmp(p, KEX_DHGEX_SHA256) != 0 && + strcmp(p, KEX_DHGEX_SHA1) != 0 && + strcmp(p, KEX_DH14) != 0 && + strcmp(p, KEX_DH1) != 0 && + (strncmp(p, KEX_ECDH_SHA2_STEM, + sizeof(KEX_ECDH_SHA2_STEM) - 1) != 0 || + kex_ecdh_name_to_nid(p) == -1)) { + error("Unsupported KEX algorithm \"%.100s\"", p); + xfree(s); + return 0; + } + } + debug3("kex names ok: [%s]", names); + xfree(s); + return 1; +} + +/* put algorithm proposal into buffer */ +static void +kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX]) +{ + u_int i; + + buffer_clear(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++) + buffer_put_char(b, 0); + for (i = 0; i < PROPOSAL_MAX; i++) + buffer_put_cstring(b, proposal[i]); + buffer_put_char(b, 0); /* first_kex_packet_follows */ + buffer_put_int(b, 0); /* uint32 reserved */ +} + +/* parse buffer and return algorithm proposal */ +static char ** +kex_buf2prop(Buffer *raw, int *first_kex_follows) +{ + Buffer b; + u_int i; + char **proposal; + + proposal = xcalloc(PROPOSAL_MAX, sizeof(char *)); + + buffer_init(&b); + buffer_append(&b, buffer_ptr(raw), buffer_len(raw)); + /* skip cookie */ + for (i = 0; i < KEX_COOKIE_LEN; i++) + buffer_get_char(&b); + /* extract kex init proposal strings */ + for (i = 0; i < PROPOSAL_MAX; i++) { + proposal[i] = buffer_get_cstring(&b,NULL); + debug2("kex_parse_kexinit: %s", proposal[i]); + } + /* first kex follows / reserved */ + i = buffer_get_char(&b); + if (first_kex_follows != NULL) + *first_kex_follows = i; + debug2("kex_parse_kexinit: first_kex_follows %d ", i); + i = buffer_get_int(&b); + debug2("kex_parse_kexinit: reserved %u ", i); + buffer_free(&b); + return proposal; +} + +static void +kex_prop_free(char **proposal) +{ + u_int i; + + for (i = 0; i < PROPOSAL_MAX; i++) + xfree(proposal[i]); + xfree(proposal); +} + +/* ARGSUSED */ +static void +kex_protocol_error(int type, u_int32_t seq, void *ctxt) +{ + error("Hm, kex protocol error: type %d seq %u", type, seq); +} + +static void +kex_reset_dispatch(void) +{ + dispatch_range(SSH2_MSG_TRANSPORT_MIN, + SSH2_MSG_TRANSPORT_MAX, &kex_protocol_error); + dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit); +} + +void +kex_finish(Kex *kex) +{ + kex_reset_dispatch(); + + packet_start(SSH2_MSG_NEWKEYS); + packet_send(); + /* packet_write_wait(); */ + debug("SSH2_MSG_NEWKEYS sent"); + + debug("expecting SSH2_MSG_NEWKEYS"); + packet_read_expect(SSH2_MSG_NEWKEYS); + packet_check_eom(); + debug("SSH2_MSG_NEWKEYS received"); + + kex->done = 1; + buffer_clear(&kex->peer); + /* buffer_clear(&kex->my); */ + kex->flags &= ~KEX_INIT_SENT; + xfree(kex->name); + kex->name = NULL; +} + +void +kex_send_kexinit(Kex *kex) +{ + u_int32_t rnd = 0; + u_char *cookie; + u_int i; + + if (kex == NULL) { + error("kex_send_kexinit: no kex, cannot rekey"); + return; + } + if (kex->flags & KEX_INIT_SENT) { + debug("KEX_INIT_SENT"); + return; + } + kex->done = 0; + + /* generate a random cookie */ + if (buffer_len(&kex->my) < KEX_COOKIE_LEN) + fatal("kex_send_kexinit: kex proposal too short"); + cookie = buffer_ptr(&kex->my); + for (i = 0; i < KEX_COOKIE_LEN; i++) { + if (i % 4 == 0) + rnd = arc4random(); + cookie[i] = rnd; + rnd >>= 8; + } + packet_start(SSH2_MSG_KEXINIT); + packet_put_raw(buffer_ptr(&kex->my), buffer_len(&kex->my)); + packet_send(); + debug("SSH2_MSG_KEXINIT sent"); + kex->flags |= KEX_INIT_SENT; +} + +/* ARGSUSED */ +void +kex_input_kexinit(int type, u_int32_t seq, void *ctxt) +{ + char *ptr; + u_int i, dlen; + Kex *kex = (Kex *)ctxt; + + debug("SSH2_MSG_KEXINIT received"); + if (kex == NULL) + fatal("kex_input_kexinit: no kex, cannot rekey"); + + ptr = packet_get_raw(&dlen); + buffer_append(&kex->peer, ptr, dlen); + + /* discard packet */ + for (i = 0; i < KEX_COOKIE_LEN; i++) + packet_get_char(); + for (i = 0; i < PROPOSAL_MAX; i++) + xfree(packet_get_string(NULL)); + (void) packet_get_char(); + (void) packet_get_int(); + packet_check_eom(); + + kex_kexinit_finish(kex); +} + +Kex * +kex_setup(char *proposal[PROPOSAL_MAX]) +{ + Kex *kex; + + kex = xcalloc(1, sizeof(*kex)); + buffer_init(&kex->peer); + buffer_init(&kex->my); + kex_prop2buf(&kex->my, proposal); + kex->done = 0; + + kex_send_kexinit(kex); /* we start */ + kex_reset_dispatch(); + + return kex; +} + +static void +kex_kexinit_finish(Kex *kex) +{ + if (!(kex->flags & KEX_INIT_SENT)) + kex_send_kexinit(kex); + + kex_choose_conf(kex); + + if (kex->kex_type >= 0 && kex->kex_type < KEX_MAX && + kex->kex[kex->kex_type] != NULL) { + (kex->kex[kex->kex_type])(kex); + } else { + fatal("Unsupported key exchange %d", kex->kex_type); + } +} + +static void +choose_enc(Enc *enc, char *client, char *server) +{ + char *name = match_list(client, server, NULL); + if (name == NULL) + fatal("no matching cipher found: client %s server %s", + client, server); + if ((enc->cipher = cipher_by_name(name)) == NULL) + fatal("matching cipher is not supported: %s", name); + enc->name = name; + enc->enabled = 0; + enc->iv = NULL; + enc->key = NULL; + enc->key_len = cipher_keylen(enc->cipher); + enc->block_size = cipher_blocksize(enc->cipher); +} + +static void +choose_mac(Mac *mac, char *client, char *server) +{ + char *name = match_list(client, server, NULL); + if (name == NULL) + fatal("no matching mac found: client %s server %s", + client, server); + if (mac_setup(mac, name) < 0) + fatal("unsupported mac %s", name); + /* truncate the key */ + if (datafellows & SSH_BUG_HMAC) + mac->key_len = 16; + mac->name = name; + mac->key = NULL; + mac->enabled = 0; +} + +static void +choose_comp(Comp *comp, char *client, char *server) +{ + char *name = match_list(client, server, NULL); + if (name == NULL) + fatal("no matching comp found: client %s server %s", client, server); + 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 { + fatal("unsupported comp %s", name); + } + comp->name = name; +} + +static void +choose_kex(Kex *k, char *client, char *server) +{ + k->name = match_list(client, server, NULL); + if (k->name == NULL) + fatal("Unable to negotiate a key exchange method"); + if (strcmp(k->name, KEX_DH1) == 0) { + k->kex_type = KEX_DH_GRP1_SHA1; + k->evp_md = EVP_sha1(); + } else if (strcmp(k->name, KEX_DH14) == 0) { + k->kex_type = KEX_DH_GRP14_SHA1; + k->evp_md = EVP_sha1(); + } else if (strcmp(k->name, KEX_DHGEX_SHA1) == 0) { + k->kex_type = KEX_DH_GEX_SHA1; + k->evp_md = EVP_sha1(); +#if OPENSSL_VERSION_NUMBER >= 0x00907000L + } else if (strcmp(k->name, KEX_DHGEX_SHA256) == 0) { + k->kex_type = KEX_DH_GEX_SHA256; + k->evp_md = evp_ssh_sha256(); + } else if (strncmp(k->name, KEX_ECDH_SHA2_STEM, + sizeof(KEX_ECDH_SHA2_STEM) - 1) == 0) { + k->kex_type = KEX_ECDH_SHA2; + k->evp_md = kex_ecdh_name_to_evpmd(k->name); +#endif + } else + fatal("bad kex alg %s", k->name); +} + +static void +choose_hostkeyalg(Kex *k, char *client, char *server) +{ + char *hostkeyalg = match_list(client, server, NULL); + if (hostkeyalg == NULL) + fatal("no hostkey alg"); + k->hostkey_type = key_type_from_name(hostkeyalg); + if (k->hostkey_type == KEY_UNSPEC) + fatal("bad hostkey alg '%s'", hostkeyalg); + xfree(hostkeyalg); +} + +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 void +kex_choose_conf(Kex *kex) +{ + Newkeys *newkeys; + char **my, **peer; + char **cprop, **sprop; + int nenc, nmac, ncomp; + u_int mode, ctos, need; + int first_kex_follows, type; + + my = kex_buf2prop(&kex->my, NULL); + peer = kex_buf2prop(&kex->peer, &first_kex_follows); + + if (kex->server) { + cprop=peer; + sprop=my; + } else { + cprop=my; + sprop=peer; + } + + /* Check whether server offers roaming */ + if (!kex->server) { + char *roaming; + roaming = match_list(KEX_RESUME, peer[PROPOSAL_KEX_ALGS], NULL); + if (roaming) { + kex->roaming = 1; + xfree(roaming); + } + } + + /* Algorithm Negotiation */ + for (mode = 0; mode < MODE_MAX; mode++) { + newkeys = xcalloc(1, sizeof(*newkeys)); + 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; + choose_enc (&newkeys->enc, cprop[nenc], sprop[nenc]); + choose_mac (&newkeys->mac, cprop[nmac], sprop[nmac]); + choose_comp(&newkeys->comp, cprop[ncomp], sprop[ncomp]); + debug("kex: %s %s %s %s", + ctos ? "client->server" : "server->client", + newkeys->enc.name, + newkeys->mac.name, + newkeys->comp.name); + } + choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]); + choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS], + sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]); + need = 0; + for (mode = 0; mode < MODE_MAX; mode++) { + newkeys = kex->newkeys[mode]; + if (need < newkeys->enc.key_len) + need = newkeys->enc.key_len; + if (need < newkeys->enc.block_size) + need = newkeys->enc.block_size; + if (need < newkeys->mac.key_len) + need = newkeys->mac.key_len; + } + /* XXX need runden? */ + kex->we_need = need; + + /* ignore the next message if the proposals do not match */ + if (first_kex_follows && !proposals_match(my, peer) && + !(datafellows & SSH_BUG_FIRSTKEX)) { + type = packet_read(); + debug2("skipping next packet (type %u)", type); + } + + kex_prop_free(my); + kex_prop_free(peer); +} + +static u_char * +derive_key(Kex *kex, int id, u_int need, u_char *hash, u_int hashlen, + BIGNUM *shared_secret) +{ + Buffer b; + EVP_MD_CTX md; + char c = id; + u_int have; + int mdsz; + u_char *digest; + + if ((mdsz = EVP_MD_size(kex->evp_md)) <= 0) + fatal("bad kex md size %d", mdsz); + digest = xmalloc(roundup(need, mdsz)); + + buffer_init(&b); + buffer_put_bignum2(&b, shared_secret); + + /* K1 = HASH(K || H || "A" || session_id) */ + EVP_DigestInit(&md, kex->evp_md); + if (!(datafellows & SSH_BUG_DERIVEKEY)) + EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); + EVP_DigestUpdate(&md, hash, hashlen); + EVP_DigestUpdate(&md, &c, 1); + EVP_DigestUpdate(&md, kex->session_id, kex->session_id_len); + EVP_DigestFinal(&md, digest, NULL); + + /* + * expand key: + * Kn = HASH(K || H || K1 || K2 || ... || Kn-1) + * Key = K1 || K2 || ... || Kn + */ + for (have = mdsz; need > have; have += mdsz) { + EVP_DigestInit(&md, kex->evp_md); + if (!(datafellows & SSH_BUG_DERIVEKEY)) + EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); + EVP_DigestUpdate(&md, hash, hashlen); + EVP_DigestUpdate(&md, digest, have); + EVP_DigestFinal(&md, digest + have, NULL); + } + buffer_free(&b); +#ifdef DEBUG_KEX + fprintf(stderr, "key '%c'== ", c); + dump_digest("key", digest, need); +#endif + return digest; +} + +Newkeys *current_keys[MODE_MAX]; + +#define NKEYS 6 +void +kex_derive_keys(Kex *kex, u_char *hash, u_int hashlen, BIGNUM *shared_secret) +{ + u_char *keys[NKEYS]; + u_int i, mode, ctos; + + for (i = 0; i < NKEYS; i++) { + keys[i] = derive_key(kex, 'A'+i, kex->we_need, hash, hashlen, + shared_secret); + } + + debug2("kex_derive_keys"); + for (mode = 0; mode < MODE_MAX; mode++) { + current_keys[mode] = kex->newkeys[mode]; + kex->newkeys[mode] = NULL; + ctos = (!kex->server && mode == MODE_OUT) || + (kex->server && mode == MODE_IN); + current_keys[mode]->enc.iv = keys[ctos ? 0 : 1]; + current_keys[mode]->enc.key = keys[ctos ? 2 : 3]; + current_keys[mode]->mac.key = keys[ctos ? 4 : 5]; + } +} + +Newkeys * +kex_get_newkeys(int mode) +{ + Newkeys *ret; + + ret = current_keys[mode]; + current_keys[mode] = NULL; + return ret; +} + +void +derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus, + u_int8_t cookie[8], u_int8_t id[16]) +{ + const EVP_MD *evp_md = EVP_md5(); + EVP_MD_CTX md; + u_int8_t nbuf[2048], obuf[EVP_MAX_MD_SIZE]; + int len; + + EVP_DigestInit(&md, evp_md); + + len = BN_num_bytes(host_modulus); + if (len < (512 / 8) || (u_int)len > sizeof(nbuf)) + fatal("%s: bad host modulus (len %d)", __func__, len); + BN_bn2bin(host_modulus, nbuf); + EVP_DigestUpdate(&md, nbuf, len); + + len = BN_num_bytes(server_modulus); + if (len < (512 / 8) || (u_int)len > sizeof(nbuf)) + fatal("%s: bad server modulus (len %d)", __func__, len); + BN_bn2bin(server_modulus, nbuf); + EVP_DigestUpdate(&md, nbuf, len); + + EVP_DigestUpdate(&md, cookie, 8); + + EVP_DigestFinal(&md, obuf, NULL); + memcpy(id, obuf, 16); + + memset(nbuf, 0, sizeof(nbuf)); + memset(obuf, 0, sizeof(obuf)); + memset(&md, 0, sizeof(md)); +} + +#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH) +void +dump_digest(char *msg, u_char *digest, int len) +{ + int i; + + fprintf(stderr, "%s\n", msg); + for (i = 0; i < len; i++) { + fprintf(stderr, "%02x", digest[i]); + if (i%32 == 31) + fprintf(stderr, "\n"); + else if (i%8 == 7) + fprintf(stderr, " "); + } + fprintf(stderr, "\n"); +} +#endif
diff --git a/openssh-6.0p1/kex.h b/openssh-6.0p1/kex.h new file mode 100644 index 0000000..7373d3c --- /dev/null +++ b/openssh-6.0p1/kex.h
@@ -0,0 +1,185 @@ +/* $OpenBSD: kex.h,v 1.52 2010/09/22 05:01:29 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 <signal.h> +#include <openssl/evp.h> +#include <openssl/hmac.h> +#ifdef OPENSSL_HAS_ECC +#include <openssl/ec.h> +#endif + +#define KEX_COOKIE_LEN 16 + +#define KEX_DH1 "diffie-hellman-group1-sha1" +#define KEX_DH14 "diffie-hellman-group14-sha1" +#define KEX_DHGEX_SHA1 "diffie-hellman-group-exchange-sha1" +#define KEX_DHGEX_SHA256 "diffie-hellman-group-exchange-sha256" +#define KEX_RESUME "resume@appgate.com" +/* The following represents the family of ECDH methods */ +#define KEX_ECDH_SHA2_STEM "ecdh-sha2-" + +#define COMP_NONE 0 +#define COMP_ZLIB 1 +#define COMP_DELAYED 2 + +enum kex_init_proposals { + PROPOSAL_KEX_ALGS, + PROPOSAL_SERVER_HOST_KEY_ALGS, + PROPOSAL_ENC_ALGS_CTOS, + PROPOSAL_ENC_ALGS_STOC, + PROPOSAL_MAC_ALGS_CTOS, + PROPOSAL_MAC_ALGS_STOC, + PROPOSAL_COMP_ALGS_CTOS, + PROPOSAL_COMP_ALGS_STOC, + PROPOSAL_LANG_CTOS, + PROPOSAL_LANG_STOC, + PROPOSAL_MAX +}; + +enum kex_modes { + MODE_IN, + MODE_OUT, + MODE_MAX +}; + +enum kex_exchange { + KEX_DH_GRP1_SHA1, + KEX_DH_GRP14_SHA1, + KEX_DH_GEX_SHA1, + KEX_DH_GEX_SHA256, + KEX_ECDH_SHA2, + KEX_MAX +}; + +#define KEX_INIT_SENT 0x0001 + +typedef struct Kex Kex; +typedef struct Mac Mac; +typedef struct Comp Comp; +typedef struct Enc Enc; +typedef struct Newkeys Newkeys; + +struct Enc { + char *name; + Cipher *cipher; + int enabled; + u_int key_len; + u_int block_size; + u_char *key; + u_char *iv; +}; +struct Mac { + char *name; + int enabled; + u_int mac_len; + u_char *key; + u_int key_len; + int type; + const EVP_MD *evp_md; + HMAC_CTX evp_ctx; + struct umac_ctx *umac_ctx; +}; +struct Comp { + int type; + int enabled; + char *name; +}; +struct Newkeys { + Enc enc; + Mac mac; + Comp comp; +}; +struct Kex { + u_char *session_id; + u_int session_id_len; + Newkeys *newkeys[MODE_MAX]; + u_int we_need; + int server; + char *name; + int hostkey_type; + int kex_type; + int roaming; + Buffer my; + Buffer peer; + sig_atomic_t done; + int flags; + const EVP_MD *evp_md; + char *client_version_string; + char *server_version_string; + int (*verify_host_key)(Key *); + Key *(*load_host_public_key)(int); + Key *(*load_host_private_key)(int); + int (*host_key_index)(Key *); + void (*kex[KEX_MAX])(Kex *); +}; + +int kex_names_valid(const char *); + +Kex *kex_setup(char *[PROPOSAL_MAX]); +void kex_finish(Kex *); + +void kex_send_kexinit(Kex *); +void kex_input_kexinit(int, u_int32_t, void *); +void kex_derive_keys(Kex *, u_char *, u_int, BIGNUM *); + +Newkeys *kex_get_newkeys(int); + +void kexdh_client(Kex *); +void kexdh_server(Kex *); +void kexgex_client(Kex *); +void kexgex_server(Kex *); +void kexecdh_client(Kex *); +void kexecdh_server(Kex *); + +void +kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int, + BIGNUM *, BIGNUM *, BIGNUM *, u_char **, u_int *); +void +kexgex_hash(const EVP_MD *, char *, char *, char *, int, char *, + int, u_char *, int, int, int, int, BIGNUM *, BIGNUM *, BIGNUM *, + BIGNUM *, BIGNUM *, u_char **, u_int *); +#ifdef OPENSSL_HAS_ECC +void +kex_ecdh_hash(const EVP_MD *, const EC_GROUP *, char *, char *, char *, int, + char *, int, u_char *, int, const EC_POINT *, const EC_POINT *, + const BIGNUM *, u_char **, u_int *); +int kex_ecdh_name_to_nid(const char *); +const EVP_MD *kex_ecdh_name_to_evpmd(const char *); +#else +# define kex_ecdh_name_to_nid(x) (-1) +# define kex_ecdh_name_to_evpmd(x) (NULL) +#endif + +void +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 + +#endif
diff --git a/openssh-6.0p1/kexdh.c b/openssh-6.0p1/kexdh.c new file mode 100644 index 0000000..56e22f5 --- /dev/null +++ b/openssh-6.0p1/kexdh.c
@@ -0,0 +1,88 @@ +/* $OpenBSD: kexdh.c,v 1.23 2006/08/03 03:34:42 deraadt Exp $ */ +/* + * Copyright (c) 2001 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#include <sys/types.h> + +#include <signal.h> + +#include <openssl/evp.h> + +#include "buffer.h" +#include "ssh2.h" +#include "key.h" +#include "cipher.h" +#include "kex.h" + +void +kex_dh_hash( + char *client_version_string, + char *server_version_string, + char *ckexinit, int ckexinitlen, + char *skexinit, int skexinitlen, + u_char *serverhostkeyblob, int sbloblen, + BIGNUM *client_dh_pub, + BIGNUM *server_dh_pub, + BIGNUM *shared_secret, + u_char **hash, u_int *hashlen) +{ + Buffer b; + static u_char digest[EVP_MAX_MD_SIZE]; + const EVP_MD *evp_md = EVP_sha1(); + EVP_MD_CTX md; + + buffer_init(&b); + buffer_put_cstring(&b, client_version_string); + buffer_put_cstring(&b, server_version_string); + + /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ + buffer_put_int(&b, ckexinitlen+1); + buffer_put_char(&b, SSH2_MSG_KEXINIT); + buffer_append(&b, ckexinit, ckexinitlen); + buffer_put_int(&b, skexinitlen+1); + buffer_put_char(&b, SSH2_MSG_KEXINIT); + buffer_append(&b, skexinit, skexinitlen); + + buffer_put_string(&b, serverhostkeyblob, sbloblen); + buffer_put_bignum2(&b, client_dh_pub); + buffer_put_bignum2(&b, server_dh_pub); + buffer_put_bignum2(&b, shared_secret); + +#ifdef DEBUG_KEX + buffer_dump(&b); +#endif + EVP_DigestInit(&md, evp_md); + EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); + EVP_DigestFinal(&md, digest, NULL); + + buffer_free(&b); + +#ifdef DEBUG_KEX + dump_digest("hash", digest, EVP_MD_size(evp_md)); +#endif + *hash = digest; + *hashlen = EVP_MD_size(evp_md); +}
diff --git a/openssh-6.0p1/kexdhc.c b/openssh-6.0p1/kexdhc.c new file mode 100644 index 0000000..76ceb5d --- /dev/null +++ b/openssh-6.0p1/kexdhc.c
@@ -0,0 +1,161 @@ +/* $OpenBSD: kexdhc.c,v 1.12 2010/11/10 01:33:07 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 <sys/types.h> + +#include <openssl/dh.h> + +#include <stdarg.h> +#include <stdio.h> +#include <string.h> +#include <signal.h> + +#include "xmalloc.h" +#include "buffer.h" +#include "key.h" +#include "cipher.h" +#include "kex.h" +#include "log.h" +#include "packet.h" +#include "dh.h" +#include "ssh2.h" + +void +kexdh_client(Kex *kex) +{ + BIGNUM *dh_server_pub = NULL, *shared_secret = NULL; + DH *dh; + Key *server_host_key; + u_char *server_host_key_blob = NULL, *signature = NULL; + u_char *kbuf, *hash; + u_int klen, slen, sbloblen, hashlen; + int kout; + + /* generate and send 'e', client DH public key */ + switch (kex->kex_type) { + case KEX_DH_GRP1_SHA1: + dh = dh_new_group1(); + break; + case KEX_DH_GRP14_SHA1: + dh = dh_new_group14(); + break; + default: + fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); + } + dh_gen_key(dh, kex->we_need * 8); + packet_start(SSH2_MSG_KEXDH_INIT); + packet_put_bignum2(dh->pub_key); + packet_send(); + + debug("sending SSH2_MSG_KEXDH_INIT"); +#ifdef DEBUG_KEXDH + DHparams_print_fp(stderr, dh); + fprintf(stderr, "pub= "); + BN_print_fp(stderr, dh->pub_key); + fprintf(stderr, "\n"); +#endif + + debug("expecting SSH2_MSG_KEXDH_REPLY"); + packet_read_expect(SSH2_MSG_KEXDH_REPLY); + + /* key, cert */ + server_host_key_blob = packet_get_string(&sbloblen); + server_host_key = key_from_blob(server_host_key_blob, sbloblen); + if (server_host_key == NULL) + fatal("cannot decode server_host_key_blob"); + if (server_host_key->type != kex->hostkey_type) + fatal("type mismatch for decoded server_host_key_blob"); + if (kex->verify_host_key == NULL) + fatal("cannot verify server_host_key"); + if (kex->verify_host_key(server_host_key) == -1) + fatal("server_host_key verification failed"); + + /* DH parameter f, server public DH key */ + if ((dh_server_pub = BN_new()) == NULL) + fatal("dh_server_pub == NULL"); + packet_get_bignum2(dh_server_pub); + +#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 + + /* signed H */ + signature = packet_get_string(&slen); + packet_check_eom(); + + if (!dh_pub_is_valid(dh, dh_server_pub)) + packet_disconnect("bad server public DH value"); + + klen = DH_size(dh); + kbuf = xmalloc(klen); + if ((kout = DH_compute_key(kbuf, dh_server_pub, dh)) < 0) + fatal("DH_compute_key: failed"); +#ifdef DEBUG_KEXDH + dump_digest("shared secret", kbuf, kout); +#endif + if ((shared_secret = BN_new()) == NULL) + fatal("kexdh_client: BN_new failed"); + if (BN_bin2bn(kbuf, kout, shared_secret) == NULL) + fatal("kexdh_client: BN_bin2bn failed"); + memset(kbuf, 0, klen); + xfree(kbuf); + + /* calc and verify H */ + kex_dh_hash( + kex->client_version_string, + kex->server_version_string, + buffer_ptr(&kex->my), buffer_len(&kex->my), + buffer_ptr(&kex->peer), buffer_len(&kex->peer), + server_host_key_blob, sbloblen, + dh->pub_key, + dh_server_pub, + shared_secret, + &hash, &hashlen + ); + xfree(server_host_key_blob); + BN_clear_free(dh_server_pub); + DH_free(dh); + + if (key_verify(server_host_key, signature, slen, hash, hashlen) != 1) + fatal("key_verify failed for server_host_key"); + key_free(server_host_key); + xfree(signature); + + /* save session id */ + if (kex->session_id == NULL) { + kex->session_id_len = hashlen; + kex->session_id = xmalloc(kex->session_id_len); + memcpy(kex->session_id, hash, kex->session_id_len); + } + + kex_derive_keys(kex, hash, hashlen, shared_secret); + BN_clear_free(shared_secret); + kex_finish(kex); +}
diff --git a/openssh-6.0p1/kexdhs.c b/openssh-6.0p1/kexdhs.c new file mode 100644 index 0000000..f56e887 --- /dev/null +++ b/openssh-6.0p1/kexdhs.c
@@ -0,0 +1,168 @@ +/* $OpenBSD: kexdhs.c,v 1.12 2010/11/10 01:33:07 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 <sys/types.h> + +#include <stdarg.h> +#include <string.h> +#include <signal.h> + +#include <openssl/dh.h> + +#include "xmalloc.h" +#include "buffer.h" +#include "key.h" +#include "cipher.h" +#include "kex.h" +#include "log.h" +#include "packet.h" +#include "dh.h" +#include "ssh2.h" +#ifdef GSSAPI +#include "ssh-gss.h" +#endif +#include "monitor_wrap.h" + +void +kexdh_server(Kex *kex) +{ + BIGNUM *shared_secret = NULL, *dh_client_pub = NULL; + DH *dh; + Key *server_host_public, *server_host_private; + u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; + u_int sbloblen, klen, hashlen, slen; + int kout; + + /* generate server DH public key */ + switch (kex->kex_type) { + case KEX_DH_GRP1_SHA1: + dh = dh_new_group1(); + break; + case KEX_DH_GRP14_SHA1: + dh = dh_new_group14(); + break; + default: + fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type); + } + dh_gen_key(dh, kex->we_need * 8); + + debug("expecting SSH2_MSG_KEXDH_INIT"); + packet_read_expect(SSH2_MSG_KEXDH_INIT); + + if (kex->load_host_public_key == NULL || + kex->load_host_private_key == NULL) + fatal("Cannot load hostkey"); + server_host_public = kex->load_host_public_key(kex->hostkey_type); + if (server_host_public == NULL) + fatal("Unsupported hostkey type %d", kex->hostkey_type); + server_host_private = kex->load_host_private_key(kex->hostkey_type); + if (server_host_private == NULL) + fatal("Missing private key for hostkey type %d", + kex->hostkey_type); + + /* key, cert */ + if ((dh_client_pub = BN_new()) == NULL) + fatal("dh_client_pub == NULL"); + packet_get_bignum2(dh_client_pub); + packet_check_eom(); + +#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, dh); + fprintf(stderr, "pub= "); + BN_print_fp(stderr, dh->pub_key); + fprintf(stderr, "\n"); +#endif + if (!dh_pub_is_valid(dh, dh_client_pub)) + packet_disconnect("bad client public DH value"); + + klen = DH_size(dh); + kbuf = xmalloc(klen); + if ((kout = DH_compute_key(kbuf, dh_client_pub, dh)) < 0) + fatal("DH_compute_key: failed"); +#ifdef DEBUG_KEXDH + dump_digest("shared secret", kbuf, kout); +#endif + if ((shared_secret = BN_new()) == NULL) + fatal("kexdh_server: BN_new failed"); + if (BN_bin2bn(kbuf, kout, shared_secret) == NULL) + fatal("kexdh_server: BN_bin2bn failed"); + memset(kbuf, 0, klen); + xfree(kbuf); + + key_to_blob(server_host_public, &server_host_key_blob, &sbloblen); + + /* calc H */ + kex_dh_hash( + kex->client_version_string, + kex->server_version_string, + buffer_ptr(&kex->peer), buffer_len(&kex->peer), + buffer_ptr(&kex->my), buffer_len(&kex->my), + server_host_key_blob, sbloblen, + dh_client_pub, + dh->pub_key, + shared_secret, + &hash, &hashlen + ); + BN_clear_free(dh_client_pub); + + /* save session id := H */ + if (kex->session_id == NULL) { + kex->session_id_len = hashlen; + kex->session_id = xmalloc(kex->session_id_len); + memcpy(kex->session_id, hash, kex->session_id_len); + } + + /* sign H */ + if (PRIVSEP(key_sign(server_host_private, &signature, &slen, hash, + hashlen)) < 0) + fatal("kexdh_server: key_sign failed"); + + /* destroy_sensitive_data(); */ + + /* send server hostkey, DH pubkey 'f' and singed H */ + packet_start(SSH2_MSG_KEXDH_REPLY); + packet_put_string(server_host_key_blob, sbloblen); + packet_put_bignum2(dh->pub_key); /* f */ + packet_put_string(signature, slen); + packet_send(); + + xfree(signature); + xfree(server_host_key_blob); + /* have keys, free DH */ + DH_free(dh); + + kex_derive_keys(kex, hash, hashlen, shared_secret); + BN_clear_free(shared_secret); + kex_finish(kex); +}
diff --git a/openssh-6.0p1/kexecdh.c b/openssh-6.0p1/kexecdh.c new file mode 100644 index 0000000..f13f69d --- /dev/null +++ b/openssh-6.0p1/kexecdh.c
@@ -0,0 +1,117 @@ +/* $OpenBSD: kexecdh.c,v 1.3 2010/09/22 05:01:29 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" + +#ifdef OPENSSL_HAS_ECC + +#include <sys/types.h> + +#include <signal.h> +#include <string.h> + +#include <openssl/bn.h> +#include <openssl/evp.h> +#include <openssl/ec.h> +#include <openssl/ecdh.h> + +#include "buffer.h" +#include "ssh2.h" +#include "key.h" +#include "cipher.h" +#include "kex.h" +#include "log.h" + +int +kex_ecdh_name_to_nid(const char *kexname) +{ + if (strlen(kexname) < sizeof(KEX_ECDH_SHA2_STEM) - 1) + fatal("%s: kexname too short \"%s\"", __func__, kexname); + return key_curve_name_to_nid(kexname + sizeof(KEX_ECDH_SHA2_STEM) - 1); +} + +const EVP_MD * +kex_ecdh_name_to_evpmd(const char *kexname) +{ + int nid = kex_ecdh_name_to_nid(kexname); + + if (nid == -1) + fatal("%s: unsupported ECDH curve \"%s\"", __func__, kexname); + return key_ec_nid_to_evpmd(nid); +} + +void +kex_ecdh_hash( + const EVP_MD *evp_md, + const EC_GROUP *ec_group, + char *client_version_string, + char *server_version_string, + char *ckexinit, int ckexinitlen, + char *skexinit, int skexinitlen, + u_char *serverhostkeyblob, int sbloblen, + const EC_POINT *client_dh_pub, + const EC_POINT *server_dh_pub, + const BIGNUM *shared_secret, + u_char **hash, u_int *hashlen) +{ + Buffer b; + EVP_MD_CTX md; + static u_char digest[EVP_MAX_MD_SIZE]; + + buffer_init(&b); + buffer_put_cstring(&b, client_version_string); + buffer_put_cstring(&b, server_version_string); + + /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ + buffer_put_int(&b, ckexinitlen+1); + buffer_put_char(&b, SSH2_MSG_KEXINIT); + buffer_append(&b, ckexinit, ckexinitlen); + buffer_put_int(&b, skexinitlen+1); + buffer_put_char(&b, SSH2_MSG_KEXINIT); + buffer_append(&b, skexinit, skexinitlen); + + buffer_put_string(&b, serverhostkeyblob, sbloblen); + buffer_put_ecpoint(&b, ec_group, client_dh_pub); + buffer_put_ecpoint(&b, ec_group, server_dh_pub); + buffer_put_bignum2(&b, shared_secret); + +#ifdef DEBUG_KEX + buffer_dump(&b); +#endif + EVP_DigestInit(&md, evp_md); + EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); + EVP_DigestFinal(&md, digest, NULL); + + buffer_free(&b); + +#ifdef DEBUG_KEX + dump_digest("hash", digest, EVP_MD_size(evp_md)); +#endif + *hash = digest; + *hashlen = EVP_MD_size(evp_md); +} + +#endif /* OPENSSL_HAS_ECC */
diff --git a/openssh-6.0p1/kexecdhc.c b/openssh-6.0p1/kexecdhc.c new file mode 100644 index 0000000..115d4bf --- /dev/null +++ b/openssh-6.0p1/kexecdhc.c
@@ -0,0 +1,168 @@ +/* $OpenBSD: kexecdhc.c,v 1.2 2010/09/22 05:01:29 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" + +#include <sys/types.h> + +#include <stdio.h> +#include <string.h> +#include <signal.h> + +#include "xmalloc.h" +#include "buffer.h" +#include "key.h" +#include "cipher.h" +#include "kex.h" +#include "log.h" +#include "packet.h" +#include "dh.h" +#include "ssh2.h" + +#ifdef OPENSSL_HAS_ECC + +#include <openssl/ecdh.h> + +void +kexecdh_client(Kex *kex) +{ + EC_KEY *client_key; + EC_POINT *server_public; + const EC_GROUP *group; + BIGNUM *shared_secret; + Key *server_host_key; + u_char *server_host_key_blob = NULL, *signature = NULL; + u_char *kbuf, *hash; + u_int klen, slen, sbloblen, hashlen; + int curve_nid; + + if ((curve_nid = kex_ecdh_name_to_nid(kex->name)) == -1) + fatal("%s: unsupported ECDH curve \"%s\"", __func__, kex->name); + if ((client_key = EC_KEY_new_by_curve_name(curve_nid)) == NULL) + fatal("%s: EC_KEY_new_by_curve_name failed", __func__); + if (EC_KEY_generate_key(client_key) != 1) + fatal("%s: EC_KEY_generate_key failed", __func__); + group = EC_KEY_get0_group(client_key); + + packet_start(SSH2_MSG_KEX_ECDH_INIT); + packet_put_ecpoint(group, EC_KEY_get0_public_key(client_key)); + packet_send(); + debug("sending SSH2_MSG_KEX_ECDH_INIT"); + +#ifdef DEBUG_KEXECDH + fputs("client private key:\n", stderr); + key_dump_ec_key(client_key); +#endif + + debug("expecting SSH2_MSG_KEX_ECDH_REPLY"); + packet_read_expect(SSH2_MSG_KEX_ECDH_REPLY); + + /* hostkey */ + server_host_key_blob = packet_get_string(&sbloblen); + server_host_key = key_from_blob(server_host_key_blob, sbloblen); + if (server_host_key == NULL) + fatal("cannot decode server_host_key_blob"); + if (server_host_key->type != kex->hostkey_type) + fatal("type mismatch for decoded server_host_key_blob"); + if (kex->verify_host_key == NULL) + fatal("cannot verify server_host_key"); + if (kex->verify_host_key(server_host_key) == -1) + fatal("server_host_key verification failed"); + + /* Q_S, server public key */ + if ((server_public = EC_POINT_new(group)) == NULL) + fatal("%s: EC_POINT_new failed", __func__); + packet_get_ecpoint(group, server_public); + + if (key_ec_validate_public(group, server_public) != 0) + fatal("%s: invalid server public key", __func__); + +#ifdef DEBUG_KEXECDH + fputs("server public key:\n", stderr); + key_dump_ec_point(group, server_public); +#endif + + /* signed H */ + signature = packet_get_string(&slen); + packet_check_eom(); + + klen = (EC_GROUP_get_degree(group) + 7) / 8; + kbuf = xmalloc(klen); + if (ECDH_compute_key(kbuf, klen, server_public, + client_key, NULL) != (int)klen) + fatal("%s: ECDH_compute_key failed", __func__); + +#ifdef DEBUG_KEXECDH + dump_digest("shared secret", kbuf, klen); +#endif + if ((shared_secret = BN_new()) == NULL) + fatal("%s: BN_new failed", __func__); + if (BN_bin2bn(kbuf, klen, shared_secret) == NULL) + fatal("%s: BN_bin2bn failed", __func__); + memset(kbuf, 0, klen); + xfree(kbuf); + + /* calc and verify H */ + kex_ecdh_hash( + kex->evp_md, + group, + kex->client_version_string, + kex->server_version_string, + buffer_ptr(&kex->my), buffer_len(&kex->my), + buffer_ptr(&kex->peer), buffer_len(&kex->peer), + server_host_key_blob, sbloblen, + EC_KEY_get0_public_key(client_key), + server_public, + shared_secret, + &hash, &hashlen + ); + xfree(server_host_key_blob); + EC_POINT_clear_free(server_public); + EC_KEY_free(client_key); + + if (key_verify(server_host_key, signature, slen, hash, hashlen) != 1) + fatal("key_verify failed for server_host_key"); + key_free(server_host_key); + xfree(signature); + + /* save session id */ + if (kex->session_id == NULL) { + kex->session_id_len = hashlen; + kex->session_id = xmalloc(kex->session_id_len); + memcpy(kex->session_id, hash, kex->session_id_len); + } + + kex_derive_keys(kex, hash, hashlen, shared_secret); + BN_clear_free(shared_secret); + kex_finish(kex); +} +#else /* OPENSSL_HAS_ECC */ +void +kexecdh_client(Kex *kex) +{ + fatal("ECC support is not enabled"); +} +#endif /* OPENSSL_HAS_ECC */
diff --git a/openssh-6.0p1/kexecdhs.c b/openssh-6.0p1/kexecdhs.c new file mode 100644 index 0000000..8c515df --- /dev/null +++ b/openssh-6.0p1/kexecdhs.c
@@ -0,0 +1,173 @@ +/* $OpenBSD: kexecdhs.c,v 1.2 2010/09/22 05:01:29 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" + +#include <sys/types.h> +#include <string.h> +#include <signal.h> + +#include "xmalloc.h" +#include "buffer.h" +#include "key.h" +#include "cipher.h" +#include "kex.h" +#include "log.h" +#include "packet.h" +#include "dh.h" +#include "ssh2.h" +#ifdef GSSAPI +#include "ssh-gss.h" +#endif +#include "monitor_wrap.h" + +#ifdef OPENSSL_HAS_ECC + +#include <openssl/ecdh.h> + +void +kexecdh_server(Kex *kex) +{ + EC_POINT *client_public; + EC_KEY *server_key; + const EC_GROUP *group; + BIGNUM *shared_secret; + Key *server_host_private, *server_host_public; + u_char *server_host_key_blob = NULL, *signature = NULL; + u_char *kbuf, *hash; + u_int klen, slen, sbloblen, hashlen; + int curve_nid; + + if ((curve_nid = kex_ecdh_name_to_nid(kex->name)) == -1) + fatal("%s: unsupported ECDH curve \"%s\"", __func__, kex->name); + if ((server_key = EC_KEY_new_by_curve_name(curve_nid)) == NULL) + fatal("%s: EC_KEY_new_by_curve_name failed", __func__); + if (EC_KEY_generate_key(server_key) != 1) + fatal("%s: EC_KEY_generate_key failed", __func__); + group = EC_KEY_get0_group(server_key); + +#ifdef DEBUG_KEXECDH + fputs("server private key:\n", stderr); + key_dump_ec_key(server_key); +#endif + + if (kex->load_host_public_key == NULL || + kex->load_host_private_key == NULL) + fatal("Cannot load hostkey"); + server_host_public = kex->load_host_public_key(kex->hostkey_type); + if (server_host_public == NULL) + fatal("Unsupported hostkey type %d", kex->hostkey_type); + server_host_private = kex->load_host_private_key(kex->hostkey_type); + if (server_host_private == NULL) + fatal("Missing private key for hostkey type %d", + kex->hostkey_type); + + debug("expecting SSH2_MSG_KEX_ECDH_INIT"); + packet_read_expect(SSH2_MSG_KEX_ECDH_INIT); + if ((client_public = EC_POINT_new(group)) == NULL) + fatal("%s: EC_POINT_new failed", __func__); + packet_get_ecpoint(group, client_public); + packet_check_eom(); + + if (key_ec_validate_public(group, client_public) != 0) + fatal("%s: invalid client public key", __func__); + +#ifdef DEBUG_KEXECDH + fputs("client public key:\n", stderr); + key_dump_ec_point(group, client_public); +#endif + + /* Calculate shared_secret */ + klen = (EC_GROUP_get_degree(group) + 7) / 8; + kbuf = xmalloc(klen); + if (ECDH_compute_key(kbuf, klen, client_public, + server_key, NULL) != (int)klen) + fatal("%s: ECDH_compute_key failed", __func__); + +#ifdef DEBUG_KEXDH + dump_digest("shared secret", kbuf, klen); +#endif + if ((shared_secret = BN_new()) == NULL) + fatal("%s: BN_new failed", __func__); + if (BN_bin2bn(kbuf, klen, shared_secret) == NULL) + fatal("%s: BN_bin2bn failed", __func__); + memset(kbuf, 0, klen); + xfree(kbuf); + + /* calc H */ + key_to_blob(server_host_public, &server_host_key_blob, &sbloblen); + kex_ecdh_hash( + kex->evp_md, + group, + kex->client_version_string, + kex->server_version_string, + buffer_ptr(&kex->peer), buffer_len(&kex->peer), + buffer_ptr(&kex->my), buffer_len(&kex->my), + server_host_key_blob, sbloblen, + client_public, + EC_KEY_get0_public_key(server_key), + shared_secret, + &hash, &hashlen + ); + EC_POINT_clear_free(client_public); + + /* save session id := H */ + if (kex->session_id == NULL) { + kex->session_id_len = hashlen; + kex->session_id = xmalloc(kex->session_id_len); + memcpy(kex->session_id, hash, kex->session_id_len); + } + + /* sign H */ + if (PRIVSEP(key_sign(server_host_private, &signature, &slen, + hash, hashlen)) < 0) + fatal("kexdh_server: key_sign failed"); + + /* destroy_sensitive_data(); */ + + /* send server hostkey, ECDH pubkey 'Q_S' and signed H */ + packet_start(SSH2_MSG_KEX_ECDH_REPLY); + packet_put_string(server_host_key_blob, sbloblen); + packet_put_ecpoint(group, EC_KEY_get0_public_key(server_key)); + packet_put_string(signature, slen); + packet_send(); + + xfree(signature); + xfree(server_host_key_blob); + /* have keys, free server key */ + EC_KEY_free(server_key); + + kex_derive_keys(kex, hash, hashlen, shared_secret); + BN_clear_free(shared_secret); + kex_finish(kex); +} +#else /* OPENSSL_HAS_ECC */ +void +kexecdh_server(Kex *kex) +{ + fatal("ECC support is not enabled"); +} +#endif /* OPENSSL_HAS_ECC */
diff --git a/openssh-6.0p1/kexgex.c b/openssh-6.0p1/kexgex.c new file mode 100644 index 0000000..b60ab5c --- /dev/null +++ b/openssh-6.0p1/kexgex.c
@@ -0,0 +1,98 @@ +/* $OpenBSD: kexgex.c,v 1.27 2006/08/03 03:34:42 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" + +#include <sys/types.h> + +#include <openssl/evp.h> +#include <signal.h> + +#include "buffer.h" +#include "key.h" +#include "cipher.h" +#include "kex.h" +#include "ssh2.h" + +void +kexgex_hash( + const EVP_MD *evp_md, + char *client_version_string, + char *server_version_string, + char *ckexinit, int ckexinitlen, + char *skexinit, int skexinitlen, + u_char *serverhostkeyblob, int sbloblen, + int min, int wantbits, int max, BIGNUM *prime, BIGNUM *gen, + BIGNUM *client_dh_pub, + BIGNUM *server_dh_pub, + BIGNUM *shared_secret, + u_char **hash, u_int *hashlen) +{ + Buffer b; + static u_char digest[EVP_MAX_MD_SIZE]; + EVP_MD_CTX md; + + buffer_init(&b); + buffer_put_cstring(&b, client_version_string); + buffer_put_cstring(&b, server_version_string); + + /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ + buffer_put_int(&b, ckexinitlen+1); + buffer_put_char(&b, SSH2_MSG_KEXINIT); + buffer_append(&b, ckexinit, ckexinitlen); + buffer_put_int(&b, skexinitlen+1); + buffer_put_char(&b, SSH2_MSG_KEXINIT); + buffer_append(&b, skexinit, skexinitlen); + + buffer_put_string(&b, serverhostkeyblob, sbloblen); + if (min == -1 || max == -1) + buffer_put_int(&b, wantbits); + else { + buffer_put_int(&b, min); + buffer_put_int(&b, wantbits); + buffer_put_int(&b, max); + } + buffer_put_bignum2(&b, prime); + buffer_put_bignum2(&b, gen); + buffer_put_bignum2(&b, client_dh_pub); + buffer_put_bignum2(&b, server_dh_pub); + buffer_put_bignum2(&b, shared_secret); + +#ifdef DEBUG_KEXDH + buffer_dump(&b); +#endif + + EVP_DigestInit(&md, evp_md); + EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); + EVP_DigestFinal(&md, digest, NULL); + + buffer_free(&b); + *hash = digest; + *hashlen = EVP_MD_size(evp_md); +#ifdef DEBUG_KEXDH + dump_digest("hash", digest, *hashlen); +#endif +}
diff --git a/openssh-6.0p1/kexgexc.c b/openssh-6.0p1/kexgexc.c new file mode 100644 index 0000000..79552d7 --- /dev/null +++ b/openssh-6.0p1/kexgexc.c
@@ -0,0 +1,207 @@ +/* $OpenBSD: kexgexc.c,v 1.12 2010/11/10 01:33:07 djm 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" + +#include <sys/types.h> + +#include <openssl/dh.h> + +#include <stdarg.h> +#include <stdio.h> +#include <string.h> +#include <signal.h> + +#include "xmalloc.h" +#include "buffer.h" +#include "key.h" +#include "cipher.h" +#include "kex.h" +#include "log.h" +#include "packet.h" +#include "dh.h" +#include "ssh2.h" +#include "compat.h" + +void +kexgex_client(Kex *kex) +{ + BIGNUM *dh_server_pub = NULL, *shared_secret = NULL; + BIGNUM *p = NULL, *g = NULL; + Key *server_host_key; + u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; + u_int klen, slen, sbloblen, hashlen; + int kout; + int min, max, nbits; + DH *dh; + + nbits = dh_estimate(kex->we_need * 8); + + if (datafellows & SSH_OLD_DHGEX) { + /* Old GEX request */ + packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST_OLD); + packet_put_int(nbits); + min = DH_GRP_MIN; + max = DH_GRP_MAX; + + debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD(%u) sent", nbits); + } else { + /* New GEX request */ + min = DH_GRP_MIN; + max = DH_GRP_MAX; + packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST); + packet_put_int(min); + packet_put_int(nbits); + packet_put_int(max); + + debug("SSH2_MSG_KEX_DH_GEX_REQUEST(%u<%u<%u) sent", + min, nbits, max); + } +#ifdef DEBUG_KEXDH + fprintf(stderr, "\nmin = %d, nbits = %d, max = %d\n", + min, nbits, max); +#endif + packet_send(); + + debug("expecting SSH2_MSG_KEX_DH_GEX_GROUP"); + packet_read_expect(SSH2_MSG_KEX_DH_GEX_GROUP); + + if ((p = BN_new()) == NULL) + fatal("BN_new"); + packet_get_bignum2(p); + if ((g = BN_new()) == NULL) + fatal("BN_new"); + packet_get_bignum2(g); + packet_check_eom(); + + if (BN_num_bits(p) < min || BN_num_bits(p) > max) + fatal("DH_GEX group out of range: %d !< %d !< %d", + min, BN_num_bits(p), max); + + dh = dh_new_group(g, p); + dh_gen_key(dh, kex->we_need * 8); + +#ifdef DEBUG_KEXDH + DHparams_print_fp(stderr, dh); + fprintf(stderr, "pub= "); + BN_print_fp(stderr, dh->pub_key); + fprintf(stderr, "\n"); +#endif + + debug("SSH2_MSG_KEX_DH_GEX_INIT sent"); + /* generate and send 'e', client DH public key */ + packet_start(SSH2_MSG_KEX_DH_GEX_INIT); + packet_put_bignum2(dh->pub_key); + packet_send(); + + debug("expecting SSH2_MSG_KEX_DH_GEX_REPLY"); + packet_read_expect(SSH2_MSG_KEX_DH_GEX_REPLY); + + /* key, cert */ + server_host_key_blob = packet_get_string(&sbloblen); + server_host_key = key_from_blob(server_host_key_blob, sbloblen); + if (server_host_key == NULL) + fatal("cannot decode server_host_key_blob"); + if (server_host_key->type != kex->hostkey_type) + fatal("type mismatch for decoded server_host_key_blob"); + if (kex->verify_host_key == NULL) + fatal("cannot verify server_host_key"); + if (kex->verify_host_key(server_host_key) == -1) + fatal("server_host_key verification failed"); + + /* DH parameter f, server public DH key */ + if ((dh_server_pub = BN_new()) == NULL) + fatal("dh_server_pub == NULL"); + packet_get_bignum2(dh_server_pub); + +#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 + + /* signed H */ + signature = packet_get_string(&slen); + packet_check_eom(); + + if (!dh_pub_is_valid(dh, dh_server_pub)) + packet_disconnect("bad server public DH value"); + + klen = DH_size(dh); + kbuf = xmalloc(klen); + if ((kout = DH_compute_key(kbuf, dh_server_pub, dh)) < 0) + fatal("DH_compute_key: failed"); +#ifdef DEBUG_KEXDH + dump_digest("shared secret", kbuf, kout); +#endif + if ((shared_secret = BN_new()) == NULL) + fatal("kexgex_client: BN_new failed"); + if (BN_bin2bn(kbuf, kout, shared_secret) == NULL) + fatal("kexgex_client: BN_bin2bn failed"); + memset(kbuf, 0, klen); + xfree(kbuf); + + if (datafellows & SSH_OLD_DHGEX) + min = max = -1; + + /* calc and verify H */ + kexgex_hash( + kex->evp_md, + kex->client_version_string, + kex->server_version_string, + buffer_ptr(&kex->my), buffer_len(&kex->my), + buffer_ptr(&kex->peer), buffer_len(&kex->peer), + server_host_key_blob, sbloblen, + min, nbits, max, + dh->p, dh->g, + dh->pub_key, + dh_server_pub, + shared_secret, + &hash, &hashlen + ); + + /* have keys, free DH */ + DH_free(dh); + xfree(server_host_key_blob); + BN_clear_free(dh_server_pub); + + if (key_verify(server_host_key, signature, slen, hash, hashlen) != 1) + fatal("key_verify failed for server_host_key"); + key_free(server_host_key); + xfree(signature); + + /* save session id */ + if (kex->session_id == NULL) { + kex->session_id_len = hashlen; + kex->session_id = xmalloc(kex->session_id_len); + memcpy(kex->session_id, hash, kex->session_id_len); + } + kex_derive_keys(kex, hash, hashlen, shared_secret); + BN_clear_free(shared_secret); + + kex_finish(kex); +}
diff --git a/openssh-6.0p1/kexgexs.c b/openssh-6.0p1/kexgexs.c new file mode 100644 index 0000000..a5e3df7 --- /dev/null +++ b/openssh-6.0p1/kexgexs.c
@@ -0,0 +1,213 @@ +/* $OpenBSD: kexgexs.c,v 1.14 2010/11/10 01:33:07 djm 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" + +#include <sys/param.h> + +#include <stdarg.h> +#include <stdio.h> +#include <string.h> +#include <signal.h> + +#include <openssl/dh.h> + +#include "xmalloc.h" +#include "buffer.h" +#include "key.h" +#include "cipher.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" + +void +kexgex_server(Kex *kex) +{ + BIGNUM *shared_secret = NULL, *dh_client_pub = NULL; + Key *server_host_public, *server_host_private; + DH *dh; + u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; + u_int sbloblen, klen, slen, hashlen; + int omin = -1, min = -1, omax = -1, max = -1, onbits = -1, nbits = -1; + int type, kout; + + if (kex->load_host_public_key == NULL || + kex->load_host_private_key == NULL) + fatal("Cannot load hostkey"); + server_host_public = kex->load_host_public_key(kex->hostkey_type); + if (server_host_public == NULL) + fatal("Unsupported hostkey type %d", kex->hostkey_type); + server_host_private = kex->load_host_private_key(kex->hostkey_type); + if (server_host_private == NULL) + fatal("Missing private key for hostkey type %d", + kex->hostkey_type); + + + type = packet_read(); + switch (type) { + case SSH2_MSG_KEX_DH_GEX_REQUEST: + debug("SSH2_MSG_KEX_DH_GEX_REQUEST received"); + omin = min = packet_get_int(); + onbits = nbits = packet_get_int(); + omax = max = packet_get_int(); + min = MAX(DH_GRP_MIN, min); + max = MIN(DH_GRP_MAX, max); + nbits = MAX(DH_GRP_MIN, nbits); + nbits = MIN(DH_GRP_MAX, nbits); + break; + case SSH2_MSG_KEX_DH_GEX_REQUEST_OLD: + debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD received"); + onbits = nbits = packet_get_int(); + /* unused for old GEX */ + omin = min = DH_GRP_MIN; + omax = max = DH_GRP_MAX; + break; + default: + fatal("protocol error during kex, no DH_GEX_REQUEST: %d", type); + } + packet_check_eom(); + + if (omax < omin || onbits < omin || omax < onbits) + fatal("DH_GEX_REQUEST, bad parameters: %d !< %d !< %d", + omin, onbits, omax); + + /* Contact privileged parent */ + dh = PRIVSEP(choose_dh(min, nbits, max)); + if (dh == NULL) + packet_disconnect("Protocol error: no matching DH grp found"); + + debug("SSH2_MSG_KEX_DH_GEX_GROUP sent"); + packet_start(SSH2_MSG_KEX_DH_GEX_GROUP); + packet_put_bignum2(dh->p); + packet_put_bignum2(dh->g); + packet_send(); + + /* flush */ + packet_write_wait(); + + /* Compute our exchange value in parallel with the client */ + dh_gen_key(dh, kex->we_need * 8); + + debug("expecting SSH2_MSG_KEX_DH_GEX_INIT"); + packet_read_expect(SSH2_MSG_KEX_DH_GEX_INIT); + + /* key, cert */ + if ((dh_client_pub = BN_new()) == NULL) + fatal("dh_client_pub == NULL"); + packet_get_bignum2(dh_client_pub); + packet_check_eom(); + +#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, dh); + fprintf(stderr, "pub= "); + BN_print_fp(stderr, dh->pub_key); + fprintf(stderr, "\n"); +#endif + if (!dh_pub_is_valid(dh, dh_client_pub)) + packet_disconnect("bad client public DH value"); + + klen = DH_size(dh); + kbuf = xmalloc(klen); + if ((kout = DH_compute_key(kbuf, dh_client_pub, dh)) < 0) + fatal("DH_compute_key: failed"); +#ifdef DEBUG_KEXDH + dump_digest("shared secret", kbuf, kout); +#endif + if ((shared_secret = BN_new()) == NULL) + fatal("kexgex_server: BN_new failed"); + if (BN_bin2bn(kbuf, kout, shared_secret) == NULL) + fatal("kexgex_server: BN_bin2bn failed"); + memset(kbuf, 0, klen); + xfree(kbuf); + + key_to_blob(server_host_public, &server_host_key_blob, &sbloblen); + + if (type == SSH2_MSG_KEX_DH_GEX_REQUEST_OLD) + omin = min = omax = max = -1; + + /* calc H */ + kexgex_hash( + kex->evp_md, + kex->client_version_string, + kex->server_version_string, + buffer_ptr(&kex->peer), buffer_len(&kex->peer), + buffer_ptr(&kex->my), buffer_len(&kex->my), + server_host_key_blob, sbloblen, + omin, onbits, omax, + dh->p, dh->g, + dh_client_pub, + dh->pub_key, + shared_secret, + &hash, &hashlen + ); + BN_clear_free(dh_client_pub); + + /* save session id := H */ + if (kex->session_id == NULL) { + kex->session_id_len = hashlen; + kex->session_id = xmalloc(kex->session_id_len); + memcpy(kex->session_id, hash, kex->session_id_len); + } + + /* sign H */ + if (PRIVSEP(key_sign(server_host_private, &signature, &slen, hash, + hashlen)) < 0) + fatal("kexgex_server: key_sign failed"); + + /* destroy_sensitive_data(); */ + + /* send server hostkey, DH pubkey 'f' and singed H */ + debug("SSH2_MSG_KEX_DH_GEX_REPLY sent"); + packet_start(SSH2_MSG_KEX_DH_GEX_REPLY); + packet_put_string(server_host_key_blob, sbloblen); + packet_put_bignum2(dh->pub_key); /* f */ + packet_put_string(signature, slen); + packet_send(); + + xfree(signature); + xfree(server_host_key_blob); + /* have keys, free DH */ + DH_free(dh); + + kex_derive_keys(kex, hash, hashlen, shared_secret); + BN_clear_free(shared_secret); + + kex_finish(kex); +}
diff --git a/openssh-6.0p1/key.c b/openssh-6.0p1/key.c new file mode 100644 index 0000000..5cc4132 --- /dev/null +++ b/openssh-6.0p1/key.c
@@ -0,0 +1,2268 @@ +/* $OpenBSD: key.c,v 1.98 2011/10/18 04:58:26 djm Exp $ */ +/* + * read_bignum(): + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * + * 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. + * Copyright (c) 2008 Alexander von Gernler. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#include <sys/param.h> +#include <sys/types.h> + +#include <openssl/evp.h> +#include <openbsd-compat/openssl-compat.h> + +#include <stdarg.h> +#include <stdio.h> +#include <string.h> + +#include "xmalloc.h" +#include "key.h" +#include "rsa.h" +#include "uuencode.h" +#include "buffer.h" +#include "log.h" +#include "misc.h" +#include "ssh2.h" + +static struct KeyCert * +cert_new(void) +{ + struct KeyCert *cert; + + cert = xcalloc(1, sizeof(*cert)); + buffer_init(&cert->certblob); + buffer_init(&cert->critical); + buffer_init(&cert->extensions); + cert->key_id = NULL; + cert->principals = NULL; + cert->signature_key = NULL; + return cert; +} + +Key * +key_new(int type) +{ + Key *k; + RSA *rsa; + DSA *dsa; + k = xcalloc(1, sizeof(*k)); + k->type = type; + k->ecdsa = NULL; + k->ecdsa_nid = -1; + k->dsa = NULL; + k->rsa = NULL; + k->cert = NULL; + switch (k->type) { + case KEY_RSA1: + case KEY_RSA: + case KEY_RSA_CERT_V00: + case KEY_RSA_CERT: + if ((rsa = RSA_new()) == NULL) + fatal("key_new: RSA_new failed"); + if ((rsa->n = BN_new()) == NULL) + fatal("key_new: BN_new failed"); + if ((rsa->e = BN_new()) == NULL) + fatal("key_new: BN_new failed"); + k->rsa = rsa; + break; + case KEY_DSA: + case KEY_DSA_CERT_V00: + case KEY_DSA_CERT: + if ((dsa = DSA_new()) == NULL) + fatal("key_new: DSA_new failed"); + if ((dsa->p = BN_new()) == NULL) + fatal("key_new: BN_new failed"); + if ((dsa->q = BN_new()) == NULL) + fatal("key_new: BN_new failed"); + if ((dsa->g = BN_new()) == NULL) + fatal("key_new: BN_new failed"); + if ((dsa->pub_key = BN_new()) == NULL) + fatal("key_new: BN_new failed"); + k->dsa = dsa; + break; +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA: + case KEY_ECDSA_CERT: + /* Cannot do anything until we know the group */ + break; +#endif + case KEY_UNSPEC: + break; + default: + fatal("key_new: bad key type %d", k->type); + break; + } + + if (key_is_cert(k)) + k->cert = cert_new(); + + return k; +} + +void +key_add_private(Key *k) +{ + switch (k->type) { + case KEY_RSA1: + case KEY_RSA: + case KEY_RSA_CERT_V00: + case KEY_RSA_CERT: + if ((k->rsa->d = BN_new()) == NULL) + fatal("key_new_private: BN_new failed"); + if ((k->rsa->iqmp = BN_new()) == NULL) + fatal("key_new_private: BN_new failed"); + if ((k->rsa->q = BN_new()) == NULL) + fatal("key_new_private: BN_new failed"); + if ((k->rsa->p = BN_new()) == NULL) + fatal("key_new_private: BN_new failed"); + if ((k->rsa->dmq1 = BN_new()) == NULL) + fatal("key_new_private: BN_new failed"); + if ((k->rsa->dmp1 = BN_new()) == NULL) + fatal("key_new_private: BN_new failed"); + break; + case KEY_DSA: + case KEY_DSA_CERT_V00: + case KEY_DSA_CERT: + if ((k->dsa->priv_key = BN_new()) == NULL) + fatal("key_new_private: BN_new failed"); + break; + case KEY_ECDSA: + case KEY_ECDSA_CERT: + /* Cannot do anything until we know the group */ + break; + case KEY_UNSPEC: + break; + default: + break; + } +} + +Key * +key_new_private(int type) +{ + Key *k = key_new(type); + + key_add_private(k); + return k; +} + +static void +cert_free(struct KeyCert *cert) +{ + u_int i; + + buffer_free(&cert->certblob); + buffer_free(&cert->critical); + buffer_free(&cert->extensions); + if (cert->key_id != NULL) + xfree(cert->key_id); + for (i = 0; i < cert->nprincipals; i++) + xfree(cert->principals[i]); + if (cert->principals != NULL) + xfree(cert->principals); + if (cert->signature_key != NULL) + key_free(cert->signature_key); +} + +void +key_free(Key *k) +{ + if (k == NULL) + fatal("key_free: key is NULL"); + switch (k->type) { + case KEY_RSA1: + case KEY_RSA: + case KEY_RSA_CERT_V00: + case KEY_RSA_CERT: + if (k->rsa != NULL) + RSA_free(k->rsa); + k->rsa = NULL; + break; + case KEY_DSA: + case KEY_DSA_CERT_V00: + 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 + case KEY_UNSPEC: + break; + default: + fatal("key_free: bad key type %d", k->type); + break; + } + if (key_is_cert(k)) { + if (k->cert != NULL) + cert_free(k->cert); + k->cert = NULL; + } + + xfree(k); +} + +static int +cert_compare(struct KeyCert *a, struct KeyCert *b) +{ + if (a == NULL && b == NULL) + return 1; + if (a == NULL || b == NULL) + return 0; + if (buffer_len(&a->certblob) != buffer_len(&b->certblob)) + return 0; + if (timingsafe_bcmp(buffer_ptr(&a->certblob), buffer_ptr(&b->certblob), + buffer_len(&a->certblob)) != 0) + return 0; + return 1; +} + +/* + * Compare public portions of key only, allowing comparisons between + * certificates and plain keys too. + */ +int +key_equal_public(const Key *a, const Key *b) +{ +#ifdef OPENSSL_HAS_ECC + BN_CTX *bnctx; +#endif + + if (a == NULL || b == NULL || + key_type_plain(a->type) != key_type_plain(b->type)) + return 0; + + switch (a->type) { + case KEY_RSA1: + case KEY_RSA_CERT_V00: + 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_V00: + 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) + fatal("%s: BN_CTX_new failed", __func__); + 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 */ + default: + fatal("key_equal: bad key type %d", a->type); + } + /* NOTREACHED */ +} + +int +key_equal(const Key *a, const Key *b) +{ + if (a == NULL || b == NULL || a->type != b->type) + return 0; + if (key_is_cert(a)) { + if (!cert_compare(a->cert, b->cert)) + return 0; + } + return key_equal_public(a, b); +} + +u_char* +key_fingerprint_raw(Key *k, enum fp_type dgst_type, u_int *dgst_raw_length) +{ + const EVP_MD *md = NULL; + EVP_MD_CTX ctx; + u_char *blob = NULL; + u_char *retval = NULL; + u_int len = 0; + int nlen, elen, otype; + + *dgst_raw_length = 0; + + switch (dgst_type) { + case SSH_FP_MD5: + md = EVP_md5(); + break; + case SSH_FP_SHA1: + md = EVP_sha1(); + break; + default: + fatal("key_fingerprint_raw: bad digest type %d", + dgst_type); + } + switch (k->type) { + case KEY_RSA1: + nlen = BN_num_bytes(k->rsa->n); + elen = BN_num_bytes(k->rsa->e); + len = nlen + elen; + blob = xmalloc(len); + BN_bn2bin(k->rsa->n, blob); + BN_bn2bin(k->rsa->e, blob + nlen); + break; + case KEY_DSA: + case KEY_ECDSA: + case KEY_RSA: + key_to_blob(k, &blob, &len); + break; + case KEY_DSA_CERT_V00: + case KEY_RSA_CERT_V00: + case KEY_DSA_CERT: + case KEY_ECDSA_CERT: + case KEY_RSA_CERT: + /* We want a fingerprint of the _key_ not of the cert */ + otype = k->type; + k->type = key_type_plain(k->type); + key_to_blob(k, &blob, &len); + k->type = otype; + break; + case KEY_UNSPEC: + return retval; + default: + fatal("key_fingerprint_raw: bad key type %d", k->type); + break; + } + if (blob != NULL) { + retval = xmalloc(EVP_MAX_MD_SIZE); + EVP_DigestInit(&ctx, md); + EVP_DigestUpdate(&ctx, blob, len); + EVP_DigestFinal(&ctx, retval, dgst_raw_length); + memset(blob, 0, len); + xfree(blob); + } else { + fatal("key_fingerprint_raw: blob is null"); + } + return retval; +} + +static char * +key_fingerprint_hex(u_char *dgst_raw, u_int dgst_raw_len) +{ + char *retval; + u_int i; + + retval = xcalloc(1, dgst_raw_len * 3 + 1); + for (i = 0; i < dgst_raw_len; i++) { + char hex[4]; + snprintf(hex, sizeof(hex), "%02x:", dgst_raw[i]); + strlcat(retval, hex, dgst_raw_len * 3 + 1); + } + + /* Remove the trailing ':' character */ + retval[(dgst_raw_len * 3) - 1] = '\0'; + return retval; +} + +static char * +key_fingerprint_bubblebabble(u_char *dgst_raw, u_int 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; + retval = xcalloc((rounds * 6), sizeof(char)); + 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 * +key_fingerprint_randomart(u_char *dgst_raw, u_int dgst_raw_len, const Key *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; + u_char field[FLDSIZE_X][FLDSIZE_Y]; + u_int i, b; + int x, y; + size_t len = strlen(augmentation_string) - 1; + + retval = xcalloc(1, (FLDSIZE_X + 3) * (FLDSIZE_Y + 2)); + + /* initialize field */ + memset(field, 0, FLDSIZE_X * FLDSIZE_Y * sizeof(char)); + x = FLDSIZE_X / 2; + y = FLDSIZE_Y / 2; + + /* process raw key */ + for (i = 0; i < dgst_raw_len; i++) { + int input; + /* each byte conveys four 2-bit move commands */ + input = dgst_raw[i]; + for (b = 0; b < 4; b++) { + /* evaluate 2 bit, rest is shifted later */ + x += (input & 0x1) ? 1 : -1; + y += (input & 0x2) ? 1 : -1; + + /* assure we are still in bounds */ + x = MAX(x, 0); + y = MAX(y, 0); + x = MIN(x, FLDSIZE_X - 1); + y = MIN(y, FLDSIZE_Y - 1); + + /* augment the field */ + if (field[x][y] < len - 2) + field[x][y]++; + input = input >> 2; + } + } + + /* mark starting point and end point*/ + field[FLDSIZE_X / 2][FLDSIZE_Y / 2] = len - 1; + field[x][y] = len; + + /* fill in retval */ + snprintf(retval, FLDSIZE_X, "+--[%4s %4u]", key_type(k), key_size(k)); + p = strchr(retval, '\0'); + + /* output upper border */ + for (i = p - retval - 1; i < FLDSIZE_X; i++) + *p++ = '-'; + *p++ = '+'; + *p++ = '\n'; + + /* output content */ + for (y = 0; y < FLDSIZE_Y; y++) { + *p++ = '|'; + for (x = 0; x < FLDSIZE_X; x++) + *p++ = augmentation_string[MIN(field[x][y], len)]; + *p++ = '|'; + *p++ = '\n'; + } + + /* output lower border */ + *p++ = '+'; + for (i = 0; i < FLDSIZE_X; i++) + *p++ = '-'; + *p++ = '+'; + + return retval; +} + +char * +key_fingerprint(Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep) +{ + char *retval = NULL; + u_char *dgst_raw; + u_int dgst_raw_len; + + dgst_raw = key_fingerprint_raw(k, dgst_type, &dgst_raw_len); + if (!dgst_raw) + fatal("key_fingerprint: null from key_fingerprint_raw()"); + switch (dgst_rep) { + case SSH_FP_HEX: + retval = key_fingerprint_hex(dgst_raw, dgst_raw_len); + break; + case SSH_FP_BUBBLEBABBLE: + retval = key_fingerprint_bubblebabble(dgst_raw, dgst_raw_len); + break; + case SSH_FP_RANDOMART: + retval = key_fingerprint_randomart(dgst_raw, dgst_raw_len, k); + break; + default: + fatal("key_fingerprint: bad digest representation %d", + dgst_rep); + break; + } + memset(dgst_raw, 0, dgst_raw_len); + xfree(dgst_raw); + return retval; +} + +/* + * 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 (and maybe modified) character. Note that this may modify + * the buffer containing the number. + */ +static int +read_bignum(char **cpp, BIGNUM * value) +{ + char *cp = *cpp; + int old; + + /* Skip any leading whitespace. */ + for (; *cp == ' ' || *cp == '\t'; cp++) + ; + + /* Check that it begins with a decimal digit. */ + if (*cp < '0' || *cp > '9') + return 0; + + /* Save starting position. */ + *cpp = cp; + + /* Move forward until all decimal digits skipped. */ + for (; *cp >= '0' && *cp <= '9'; cp++) + ; + + /* Save the old terminating character, and replace it by \0. */ + old = *cp; + *cp = 0; + + /* Parse the number. */ + if (BN_dec2bn(&value, *cpp) == 0) + return 0; + + /* Restore old terminating character. */ + *cp = old; + + /* Move beyond the number and return success. */ + *cpp = cp; + return 1; +} + +static int +write_bignum(FILE *f, BIGNUM *num) +{ + char *buf = BN_bn2dec(num); + if (buf == NULL) { + error("write_bignum: BN_bn2dec() failed"); + return 0; + } + fprintf(f, " %s", buf); + OPENSSL_free(buf); + return 1; +} + +/* returns 1 ok, -1 error */ +int +key_read(Key *ret, char **cpp) +{ + Key *k; + int success = -1; + char *cp, *space; + int len, n, type; + u_int bits; + u_char *blob; +#ifdef OPENSSL_HAS_ECC + int curve_nid = -1; +#endif + + cp = *cpp; + + switch (ret->type) { + case KEY_RSA1: + /* Get number of bits. */ + if (*cp < '0' || *cp > '9') + return -1; /* Bad bit count... */ + for (bits = 0; *cp >= '0' && *cp <= '9'; cp++) + bits = 10 * bits + *cp - '0'; + if (bits == 0) + return -1; + *cpp = cp; + /* Get public exponent, public modulus. */ + if (!read_bignum(cpp, ret->rsa->e)) + return -1; + if (!read_bignum(cpp, ret->rsa->n)) + return -1; + /* validate the claimed number of bits */ + if ((u_int)BN_num_bits(ret->rsa->n) != bits) { + verbose("key_read: claimed key size %d does not match " + "actual %d", bits, BN_num_bits(ret->rsa->n)); + return -1; + } + success = 1; + break; + case KEY_UNSPEC: + case KEY_RSA: + case KEY_DSA: + case KEY_ECDSA: + case KEY_DSA_CERT_V00: + case KEY_RSA_CERT_V00: + case KEY_DSA_CERT: + case KEY_ECDSA_CERT: + case KEY_RSA_CERT: + space = strchr(cp, ' '); + if (space == NULL) { + debug3("key_read: missing whitespace"); + return -1; + } + *space = '\0'; + type = key_type_from_name(cp); +#ifdef OPENSSL_HAS_ECC + if (key_type_plain(type) == KEY_ECDSA && + (curve_nid = key_ecdsa_nid_from_name(cp)) == -1) { + debug("key_read: invalid curve"); + return -1; + } +#endif + *space = ' '; + if (type == KEY_UNSPEC) { + debug3("key_read: missing keytype"); + return -1; + } + cp = space+1; + if (*cp == '\0') { + debug3("key_read: short string"); + return -1; + } + if (ret->type == KEY_UNSPEC) { + ret->type = type; + } else if (ret->type != type) { + /* is a key, but different type */ + debug3("key_read: type mismatch"); + return -1; + } + len = 2*strlen(cp); + blob = xmalloc(len); + n = uudecode(cp, blob, len); + if (n < 0) { + error("key_read: uudecode %s failed", cp); + xfree(blob); + return -1; + } + k = key_from_blob(blob, (u_int)n); + xfree(blob); + if (k == NULL) { + error("key_read: key_from_blob %s failed", cp); + return -1; + } + if (k->type != type) { + error("key_read: type mismatch: encoding error"); + key_free(k); + return -1; + } +#ifdef OPENSSL_HAS_ECC + if (key_type_plain(type) == KEY_ECDSA && + curve_nid != k->ecdsa_nid) { + error("key_read: type mismatch: EC curve mismatch"); + key_free(k); + return -1; + } +#endif +/*XXXX*/ + if (key_is_cert(ret)) { + if (!key_is_cert(k)) { + error("key_read: loaded key is not a cert"); + key_free(k); + return -1; + } + if (ret->cert != NULL) + cert_free(ret->cert); + ret->cert = k->cert; + k->cert = NULL; + } + if (key_type_plain(ret->type) == 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 + } + if (key_type_plain(ret->type) == 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 + } +#ifdef OPENSSL_HAS_ECC + if (key_type_plain(ret->type) == 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 + key_dump_ec_key(ret->ecdsa); +#endif + } +#endif + success = 1; +/*XXXX*/ + key_free(k); + if (success != 1) + break; + /* advance cp: skip whitespace and data */ + while (*cp == ' ' || *cp == '\t') + cp++; + while (*cp != '\0' && *cp != ' ' && *cp != '\t') + cp++; + *cpp = cp; + break; + default: + fatal("key_read: bad key type: %d", ret->type); + break; + } + return success; +} + +int +key_write(const Key *key, FILE *f) +{ + int n, success = 0; + u_int len, bits = 0; + u_char *blob; + char *uu; + + if (key_is_cert(key)) { + if (key->cert == NULL) { + error("%s: no cert data", __func__); + return 0; + } + if (buffer_len(&key->cert->certblob) == 0) { + error("%s: no signed certificate blob", __func__); + return 0; + } + } + + switch (key->type) { + case KEY_RSA1: + if (key->rsa == NULL) + return 0; + /* size of modulus 'n' */ + bits = BN_num_bits(key->rsa->n); + fprintf(f, "%u", bits); + if (write_bignum(f, key->rsa->e) && + write_bignum(f, key->rsa->n)) + return 1; + error("key_write: failed for RSA key"); + return 0; + case KEY_DSA: + case KEY_DSA_CERT_V00: + case KEY_DSA_CERT: + if (key->dsa == NULL) + return 0; + break; +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA: + case KEY_ECDSA_CERT: + if (key->ecdsa == NULL) + return 0; + break; +#endif + case KEY_RSA: + case KEY_RSA_CERT_V00: + case KEY_RSA_CERT: + if (key->rsa == NULL) + return 0; + break; + default: + return 0; + } + + key_to_blob(key, &blob, &len); + uu = xmalloc(2*len); + n = uuencode(blob, len, uu, 2*len); + if (n > 0) { + fprintf(f, "%s %s", key_ssh_name(key), uu); + success = 1; + } + xfree(blob); + xfree(uu); + + return success; +} + +const char * +key_type(const Key *k) +{ + switch (k->type) { + case KEY_RSA1: + return "RSA1"; + case KEY_RSA: + return "RSA"; + case KEY_DSA: + return "DSA"; +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA: + return "ECDSA"; +#endif + case KEY_RSA_CERT_V00: + return "RSA-CERT-V00"; + case KEY_DSA_CERT_V00: + return "DSA-CERT-V00"; + case KEY_RSA_CERT: + return "RSA-CERT"; + case KEY_DSA_CERT: + return "DSA-CERT"; +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA_CERT: + return "ECDSA-CERT"; +#endif + } + return "unknown"; +} + +const char * +key_cert_type(const Key *k) +{ + switch (k->cert->type) { + case SSH2_CERT_TYPE_USER: + return "user"; + case SSH2_CERT_TYPE_HOST: + return "host"; + default: + return "unknown"; + } +} + +static const char * +key_ssh_name_from_type_nid(int type, int nid) +{ + switch (type) { + case KEY_RSA: + return "ssh-rsa"; + case KEY_DSA: + return "ssh-dss"; + case KEY_RSA_CERT_V00: + return "ssh-rsa-cert-v00@openssh.com"; + case KEY_DSA_CERT_V00: + return "ssh-dss-cert-v00@openssh.com"; + case KEY_RSA_CERT: + return "ssh-rsa-cert-v01@openssh.com"; + case KEY_DSA_CERT: + return "ssh-dss-cert-v01@openssh.com"; +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA: + switch (nid) { + case NID_X9_62_prime256v1: + return "ecdsa-sha2-nistp256"; + case NID_secp384r1: + return "ecdsa-sha2-nistp384"; + case NID_secp521r1: + return "ecdsa-sha2-nistp521"; + default: + break; + } + break; + case KEY_ECDSA_CERT: + switch (nid) { + case NID_X9_62_prime256v1: + return "ecdsa-sha2-nistp256-cert-v01@openssh.com"; + case NID_secp384r1: + return "ecdsa-sha2-nistp384-cert-v01@openssh.com"; + case NID_secp521r1: + return "ecdsa-sha2-nistp521-cert-v01@openssh.com"; + default: + break; + } + break; +#endif /* OPENSSL_HAS_ECC */ + } + return "ssh-unknown"; +} + +const char * +key_ssh_name(const Key *k) +{ + return key_ssh_name_from_type_nid(k->type, k->ecdsa_nid); +} + +const char * +key_ssh_name_plain(const Key *k) +{ + return key_ssh_name_from_type_nid(key_type_plain(k->type), + k->ecdsa_nid); +} + +u_int +key_size(const Key *k) +{ + switch (k->type) { + case KEY_RSA1: + case KEY_RSA: + case KEY_RSA_CERT_V00: + case KEY_RSA_CERT: + return BN_num_bits(k->rsa->n); + case KEY_DSA: + case KEY_DSA_CERT_V00: + case KEY_DSA_CERT: + return BN_num_bits(k->dsa->p); +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA: + case KEY_ECDSA_CERT: + return key_curve_nid_to_bits(k->ecdsa_nid); +#endif + } + return 0; +} + +static RSA * +rsa_generate_private_key(u_int bits) +{ + RSA *private = RSA_new(); + BIGNUM *f4 = BN_new(); + + if (private == NULL) + fatal("%s: RSA_new failed", __func__); + if (f4 == NULL) + fatal("%s: BN_new failed", __func__); + if (!BN_set_word(f4, RSA_F4)) + fatal("%s: BN_new failed", __func__); + if (!RSA_generate_key_ex(private, bits, f4, NULL)) + fatal("%s: key generation failed.", __func__); + BN_free(f4); + return private; +} + +static DSA* +dsa_generate_private_key(u_int bits) +{ + DSA *private = DSA_new(); + + if (private == NULL) + fatal("%s: DSA_new failed", __func__); + if (!DSA_generate_parameters_ex(private, bits, NULL, 0, NULL, + NULL, NULL)) + fatal("%s: DSA_generate_parameters failed", __func__); + if (!DSA_generate_key(private)) + fatal("%s: DSA_generate_key failed.", __func__); + return private; +} + +int +key_ecdsa_bits_to_nid(int bits) +{ + switch (bits) { +#ifdef OPENSSL_HAS_ECC + case 256: + return NID_X9_62_prime256v1; + case 384: + return NID_secp384r1; + case 521: + return NID_secp521r1; +#endif + default: + return -1; + } +} + +#ifdef OPENSSL_HAS_ECC +int +key_ecdsa_key_to_nid(EC_KEY *k) +{ + EC_GROUP *eg; + int nids[] = { + NID_X9_62_prime256v1, + NID_secp384r1, + NID_secp521r1, + -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) + fatal("%s: BN_CTX_new() failed", __func__); + for (i = 0; nids[i] != -1; i++) { + if ((eg = EC_GROUP_new_by_curve_name(nids[i])) == NULL) + fatal("%s: EC_GROUP_new_by_curve_name failed", + __func__); + if (EC_GROUP_cmp(g, eg, bnctx) == 0) + break; + EC_GROUP_free(eg); + } + BN_CTX_free(bnctx); + debug3("%s: nid = %d", __func__, nids[i]); + 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) + fatal("%s: EC_KEY_set_group", __func__); + } + return nids[i]; +} + +static EC_KEY* +ecdsa_generate_private_key(u_int bits, int *nid) +{ + EC_KEY *private; + + if ((*nid = key_ecdsa_bits_to_nid(bits)) == -1) + fatal("%s: invalid key length", __func__); + if ((private = EC_KEY_new_by_curve_name(*nid)) == NULL) + fatal("%s: EC_KEY_new_by_curve_name failed", __func__); + if (EC_KEY_generate_key(private) != 1) + fatal("%s: EC_KEY_generate_key failed", __func__); + EC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE); + return private; +} +#endif /* OPENSSL_HAS_ECC */ + +Key * +key_generate(int type, u_int bits) +{ + Key *k = key_new(KEY_UNSPEC); + switch (type) { + case KEY_DSA: + k->dsa = dsa_generate_private_key(bits); + break; +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA: + k->ecdsa = ecdsa_generate_private_key(bits, &k->ecdsa_nid); + break; +#endif + case KEY_RSA: + case KEY_RSA1: + k->rsa = rsa_generate_private_key(bits); + break; + case KEY_RSA_CERT_V00: + case KEY_DSA_CERT_V00: + case KEY_RSA_CERT: + case KEY_DSA_CERT: + fatal("key_generate: cert keys cannot be generated directly"); + default: + fatal("key_generate: unknown type %d", type); + } + k->type = type; + return k; +} + +void +key_cert_copy(const Key *from_key, struct Key *to_key) +{ + u_int i; + const struct KeyCert *from; + struct KeyCert *to; + + if (to_key->cert != NULL) { + cert_free(to_key->cert); + to_key->cert = NULL; + } + + if ((from = from_key->cert) == NULL) + return; + + to = to_key->cert = cert_new(); + + buffer_append(&to->certblob, buffer_ptr(&from->certblob), + buffer_len(&from->certblob)); + + buffer_append(&to->critical, + buffer_ptr(&from->critical), buffer_len(&from->critical)); + buffer_append(&to->extensions, + buffer_ptr(&from->extensions), buffer_len(&from->extensions)); + + to->serial = from->serial; + to->type = from->type; + to->key_id = from->key_id == NULL ? NULL : xstrdup(from->key_id); + to->valid_after = from->valid_after; + to->valid_before = from->valid_before; + to->signature_key = from->signature_key == NULL ? + NULL : key_from_private(from->signature_key); + + to->nprincipals = from->nprincipals; + if (to->nprincipals > CERT_MAX_PRINCIPALS) + fatal("%s: nprincipals (%u) > CERT_MAX_PRINCIPALS (%u)", + __func__, to->nprincipals, CERT_MAX_PRINCIPALS); + if (to->nprincipals > 0) { + to->principals = xcalloc(from->nprincipals, + sizeof(*to->principals)); + for (i = 0; i < to->nprincipals; i++) + to->principals[i] = xstrdup(from->principals[i]); + } +} + +Key * +key_from_private(const Key *k) +{ + Key *n = NULL; + switch (k->type) { + case KEY_DSA: + case KEY_DSA_CERT_V00: + case KEY_DSA_CERT: + n = key_new(k->type); + 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)) + fatal("key_from_private: BN_copy failed"); + break; +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA: + case KEY_ECDSA_CERT: + n = key_new(k->type); + n->ecdsa_nid = k->ecdsa_nid; + if ((n->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid)) == NULL) + fatal("%s: EC_KEY_new_by_curve_name failed", __func__); + if (EC_KEY_set_public_key(n->ecdsa, + EC_KEY_get0_public_key(k->ecdsa)) != 1) + fatal("%s: EC_KEY_set_public_key failed", __func__); + break; +#endif + case KEY_RSA: + case KEY_RSA1: + case KEY_RSA_CERT_V00: + case KEY_RSA_CERT: + n = key_new(k->type); + if ((BN_copy(n->rsa->n, k->rsa->n) == NULL) || + (BN_copy(n->rsa->e, k->rsa->e) == NULL)) + fatal("key_from_private: BN_copy failed"); + break; + default: + fatal("key_from_private: unknown type %d", k->type); + break; + } + if (key_is_cert(k)) + key_cert_copy(k, n); + return n; +} + +int +key_type_from_name(char *name) +{ + if (strcmp(name, "rsa1") == 0) { + return KEY_RSA1; + } else if (strcmp(name, "rsa") == 0) { + return KEY_RSA; + } else if (strcmp(name, "dsa") == 0) { + return KEY_DSA; + } else if (strcmp(name, "ssh-rsa") == 0) { + return KEY_RSA; + } else if (strcmp(name, "ssh-dss") == 0) { + return KEY_DSA; +#ifdef OPENSSL_HAS_ECC + } else if (strcmp(name, "ecdsa") == 0 || + strcmp(name, "ecdsa-sha2-nistp256") == 0 || + strcmp(name, "ecdsa-sha2-nistp384") == 0 || + strcmp(name, "ecdsa-sha2-nistp521") == 0) { + return KEY_ECDSA; +#endif + } else if (strcmp(name, "ssh-rsa-cert-v00@openssh.com") == 0) { + return KEY_RSA_CERT_V00; + } else if (strcmp(name, "ssh-dss-cert-v00@openssh.com") == 0) { + return KEY_DSA_CERT_V00; + } else if (strcmp(name, "ssh-rsa-cert-v01@openssh.com") == 0) { + return KEY_RSA_CERT; + } else if (strcmp(name, "ssh-dss-cert-v01@openssh.com") == 0) { + return KEY_DSA_CERT; +#ifdef OPENSSL_HAS_ECC + } else if (strcmp(name, "ecdsa-sha2-nistp256-cert-v01@openssh.com") == 0 || + strcmp(name, "ecdsa-sha2-nistp384-cert-v01@openssh.com") == 0 || + strcmp(name, "ecdsa-sha2-nistp521-cert-v01@openssh.com") == 0) { + return KEY_ECDSA_CERT; +#endif + } + + debug2("key_type_from_name: unknown key type '%s'", name); + return KEY_UNSPEC; +} + +int +key_ecdsa_nid_from_name(const char *name) +{ +#ifdef OPENSSL_HAS_ECC + if (strcmp(name, "ecdsa-sha2-nistp256") == 0 || + strcmp(name, "ecdsa-sha2-nistp256-cert-v01@openssh.com") == 0) + return NID_X9_62_prime256v1; + if (strcmp(name, "ecdsa-sha2-nistp384") == 0 || + strcmp(name, "ecdsa-sha2-nistp384-cert-v01@openssh.com") == 0) + return NID_secp384r1; + if (strcmp(name, "ecdsa-sha2-nistp521") == 0 || + strcmp(name, "ecdsa-sha2-nistp521-cert-v01@openssh.com") == 0) + return NID_secp521r1; +#endif /* OPENSSL_HAS_ECC */ + + debug2("%s: unknown/non-ECDSA key type '%s'", __func__, name); + return -1; +} + +int +key_names_valid2(const char *names) +{ + char *s, *cp, *p; + + if (names == NULL || strcmp(names, "") == 0) + return 0; + s = cp = xstrdup(names); + for ((p = strsep(&cp, ",")); p && *p != '\0'; + (p = strsep(&cp, ","))) { + switch (key_type_from_name(p)) { + case KEY_RSA1: + case KEY_UNSPEC: + xfree(s); + return 0; + } + } + debug3("key names ok: [%s]", names); + xfree(s); + return 1; +} + +static int +cert_parse(Buffer *b, Key *key, const u_char *blob, u_int blen) +{ + u_char *principals, *critical, *exts, *sig_key, *sig; + u_int signed_len, plen, clen, sklen, slen, kidlen, elen; + Buffer tmp; + char *principal; + int ret = -1; + int v00 = key->type == KEY_DSA_CERT_V00 || + key->type == KEY_RSA_CERT_V00; + + buffer_init(&tmp); + + /* Copy the entire key blob for verification and later serialisation */ + buffer_append(&key->cert->certblob, blob, blen); + + elen = 0; /* Not touched for v00 certs */ + principals = exts = critical = sig_key = sig = NULL; + if ((!v00 && buffer_get_int64_ret(&key->cert->serial, b) != 0) || + buffer_get_int_ret(&key->cert->type, b) != 0 || + (key->cert->key_id = buffer_get_cstring_ret(b, &kidlen)) == NULL || + (principals = buffer_get_string_ret(b, &plen)) == NULL || + buffer_get_int64_ret(&key->cert->valid_after, b) != 0 || + buffer_get_int64_ret(&key->cert->valid_before, b) != 0 || + (critical = buffer_get_string_ret(b, &clen)) == NULL || + (!v00 && (exts = buffer_get_string_ret(b, &elen)) == NULL) || + (v00 && buffer_get_string_ptr_ret(b, NULL) == NULL) || /* nonce */ + buffer_get_string_ptr_ret(b, NULL) == NULL || /* reserved */ + (sig_key = buffer_get_string_ret(b, &sklen)) == NULL) { + error("%s: parse error", __func__); + goto out; + } + + /* Signature is left in the buffer so we can calculate this length */ + signed_len = buffer_len(&key->cert->certblob) - buffer_len(b); + + if ((sig = buffer_get_string_ret(b, &slen)) == NULL) { + error("%s: parse error", __func__); + goto out; + } + + if (key->cert->type != SSH2_CERT_TYPE_USER && + key->cert->type != SSH2_CERT_TYPE_HOST) { + error("Unknown certificate type %u", key->cert->type); + goto out; + } + + buffer_append(&tmp, principals, plen); + while (buffer_len(&tmp) > 0) { + if (key->cert->nprincipals >= CERT_MAX_PRINCIPALS) { + error("%s: Too many principals", __func__); + goto out; + } + if ((principal = buffer_get_cstring_ret(&tmp, &plen)) == NULL) { + error("%s: Principals data invalid", __func__); + goto out; + } + key->cert->principals = xrealloc(key->cert->principals, + key->cert->nprincipals + 1, sizeof(*key->cert->principals)); + key->cert->principals[key->cert->nprincipals++] = principal; + } + + buffer_clear(&tmp); + + buffer_append(&key->cert->critical, critical, clen); + buffer_append(&tmp, critical, clen); + /* validate structure */ + while (buffer_len(&tmp) != 0) { + if (buffer_get_string_ptr_ret(&tmp, NULL) == NULL || + buffer_get_string_ptr_ret(&tmp, NULL) == NULL) { + error("%s: critical option data invalid", __func__); + goto out; + } + } + buffer_clear(&tmp); + + buffer_append(&key->cert->extensions, exts, elen); + buffer_append(&tmp, exts, elen); + /* validate structure */ + while (buffer_len(&tmp) != 0) { + if (buffer_get_string_ptr_ret(&tmp, NULL) == NULL || + buffer_get_string_ptr_ret(&tmp, NULL) == NULL) { + error("%s: extension data invalid", __func__); + goto out; + } + } + buffer_clear(&tmp); + + if ((key->cert->signature_key = key_from_blob(sig_key, + sklen)) == NULL) { + error("%s: Signature key invalid", __func__); + goto out; + } + if (key->cert->signature_key->type != KEY_RSA && + key->cert->signature_key->type != KEY_DSA && + key->cert->signature_key->type != KEY_ECDSA) { + error("%s: Invalid signature key type %s (%d)", __func__, + key_type(key->cert->signature_key), + key->cert->signature_key->type); + goto out; + } + + switch (key_verify(key->cert->signature_key, sig, slen, + buffer_ptr(&key->cert->certblob), signed_len)) { + case 1: + ret = 0; + break; /* Good signature */ + case 0: + error("%s: Invalid signature on certificate", __func__); + goto out; + case -1: + error("%s: Certificate signature verification failed", + __func__); + goto out; + } + + out: + buffer_free(&tmp); + if (principals != NULL) + xfree(principals); + if (critical != NULL) + xfree(critical); + if (exts != NULL) + xfree(exts); + if (sig_key != NULL) + xfree(sig_key); + if (sig != NULL) + xfree(sig); + return ret; +} + +Key * +key_from_blob(const u_char *blob, u_int blen) +{ + Buffer b; + int rlen, type; + char *ktype = NULL, *curve = NULL; + Key *key = NULL; +#ifdef OPENSSL_HAS_ECC + EC_POINT *q = NULL; + int nid = -1; +#endif + +#ifdef DEBUG_PK + dump_base64(stderr, blob, blen); +#endif + buffer_init(&b); + buffer_append(&b, blob, blen); + if ((ktype = buffer_get_cstring_ret(&b, NULL)) == NULL) { + error("key_from_blob: can't read key type"); + goto out; + } + + type = key_type_from_name(ktype); +#ifdef OPENSSL_HAS_ECC + if (key_type_plain(type) == KEY_ECDSA) + nid = key_ecdsa_nid_from_name(ktype); +#endif + + switch (type) { + case KEY_RSA_CERT: + (void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */ + /* FALLTHROUGH */ + case KEY_RSA: + case KEY_RSA_CERT_V00: + key = key_new(type); + if (buffer_get_bignum2_ret(&b, key->rsa->e) == -1 || + buffer_get_bignum2_ret(&b, key->rsa->n) == -1) { + error("key_from_blob: can't read rsa key"); + badkey: + key_free(key); + key = NULL; + goto out; + } +#ifdef DEBUG_PK + RSA_print_fp(stderr, key->rsa, 8); +#endif + break; + case KEY_DSA_CERT: + (void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */ + /* FALLTHROUGH */ + case KEY_DSA: + case KEY_DSA_CERT_V00: + key = key_new(type); + if (buffer_get_bignum2_ret(&b, key->dsa->p) == -1 || + buffer_get_bignum2_ret(&b, key->dsa->q) == -1 || + buffer_get_bignum2_ret(&b, key->dsa->g) == -1 || + buffer_get_bignum2_ret(&b, key->dsa->pub_key) == -1) { + error("key_from_blob: can't read dsa key"); + goto badkey; + } +#ifdef DEBUG_PK + DSA_print_fp(stderr, key->dsa, 8); +#endif + break; +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA_CERT: + (void)buffer_get_string_ptr_ret(&b, NULL); /* Skip nonce */ + /* FALLTHROUGH */ + case KEY_ECDSA: + key = key_new(type); + key->ecdsa_nid = nid; + if ((curve = buffer_get_string_ret(&b, NULL)) == NULL) { + error("key_from_blob: can't read ecdsa curve"); + goto badkey; + } + if (key->ecdsa_nid != key_curve_name_to_nid(curve)) { + error("key_from_blob: ecdsa curve doesn't match type"); + goto badkey; + } + if (key->ecdsa != NULL) + EC_KEY_free(key->ecdsa); + if ((key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid)) + == NULL) + fatal("key_from_blob: EC_KEY_new_by_curve_name failed"); + if ((q = EC_POINT_new(EC_KEY_get0_group(key->ecdsa))) == NULL) + fatal("key_from_blob: EC_POINT_new failed"); + if (buffer_get_ecpoint_ret(&b, EC_KEY_get0_group(key->ecdsa), + q) == -1) { + error("key_from_blob: can't read ecdsa key point"); + goto badkey; + } + if (key_ec_validate_public(EC_KEY_get0_group(key->ecdsa), + q) != 0) + goto badkey; + if (EC_KEY_set_public_key(key->ecdsa, q) != 1) + fatal("key_from_blob: EC_KEY_set_public_key failed"); +#ifdef DEBUG_PK + key_dump_ec_point(EC_KEY_get0_group(key->ecdsa), q); +#endif + break; +#endif /* OPENSSL_HAS_ECC */ + case KEY_UNSPEC: + key = key_new(type); + break; + default: + error("key_from_blob: cannot handle type %s", ktype); + goto out; + } + if (key_is_cert(key) && cert_parse(&b, key, blob, blen) == -1) { + error("key_from_blob: can't parse cert data"); + goto badkey; + } + rlen = buffer_len(&b); + if (key != NULL && rlen != 0) + error("key_from_blob: remaining bytes in key blob %d", rlen); + out: + if (ktype != NULL) + xfree(ktype); + if (curve != NULL) + xfree(curve); +#ifdef OPENSSL_HAS_ECC + if (q != NULL) + EC_POINT_free(q); +#endif + buffer_free(&b); + return key; +} + +int +key_to_blob(const Key *key, u_char **blobp, u_int *lenp) +{ + Buffer b; + int len; + + if (key == NULL) { + error("key_to_blob: key == NULL"); + return 0; + } + buffer_init(&b); + switch (key->type) { + case KEY_DSA_CERT_V00: + case KEY_RSA_CERT_V00: + case KEY_DSA_CERT: + case KEY_ECDSA_CERT: + case KEY_RSA_CERT: + /* Use the existing blob */ + buffer_append(&b, buffer_ptr(&key->cert->certblob), + buffer_len(&key->cert->certblob)); + break; + case KEY_DSA: + buffer_put_cstring(&b, key_ssh_name(key)); + buffer_put_bignum2(&b, key->dsa->p); + buffer_put_bignum2(&b, key->dsa->q); + buffer_put_bignum2(&b, key->dsa->g); + buffer_put_bignum2(&b, key->dsa->pub_key); + break; +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA: + buffer_put_cstring(&b, key_ssh_name(key)); + buffer_put_cstring(&b, key_curve_nid_to_name(key->ecdsa_nid)); + buffer_put_ecpoint(&b, EC_KEY_get0_group(key->ecdsa), + EC_KEY_get0_public_key(key->ecdsa)); + break; +#endif + case KEY_RSA: + buffer_put_cstring(&b, key_ssh_name(key)); + buffer_put_bignum2(&b, key->rsa->e); + buffer_put_bignum2(&b, key->rsa->n); + break; + default: + error("key_to_blob: unsupported key type %d", key->type); + buffer_free(&b); + return 0; + } + len = buffer_len(&b); + if (lenp != NULL) + *lenp = len; + if (blobp != NULL) { + *blobp = xmalloc(len); + memcpy(*blobp, buffer_ptr(&b), len); + } + memset(buffer_ptr(&b), 0, len); + buffer_free(&b); + return len; +} + +int +key_sign( + const Key *key, + u_char **sigp, u_int *lenp, + const u_char *data, u_int datalen) +{ + switch (key->type) { + case KEY_DSA_CERT_V00: + case KEY_DSA_CERT: + case KEY_DSA: + return ssh_dss_sign(key, sigp, lenp, data, datalen); +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA_CERT: + case KEY_ECDSA: + return ssh_ecdsa_sign(key, sigp, lenp, data, datalen); +#endif + case KEY_RSA_CERT_V00: + case KEY_RSA_CERT: + case KEY_RSA: + return ssh_rsa_sign(key, sigp, lenp, data, datalen); + default: + error("key_sign: invalid key type %d", key->type); + return -1; + } +} + +/* + * key_verify returns 1 for a correct signature, 0 for an incorrect signature + * and -1 on error. + */ +int +key_verify( + const Key *key, + const u_char *signature, u_int signaturelen, + const u_char *data, u_int datalen) +{ + if (signaturelen == 0) + return -1; + + switch (key->type) { + case KEY_DSA_CERT_V00: + case KEY_DSA_CERT: + case KEY_DSA: + return ssh_dss_verify(key, signature, signaturelen, data, datalen); +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA_CERT: + case KEY_ECDSA: + return ssh_ecdsa_verify(key, signature, signaturelen, data, datalen); +#endif + case KEY_RSA_CERT_V00: + case KEY_RSA_CERT: + case KEY_RSA: + return ssh_rsa_verify(key, signature, signaturelen, data, datalen); + default: + error("key_verify: invalid key type %d", key->type); + return -1; + } +} + +/* Converts a private to a public key */ +Key * +key_demote(const Key *k) +{ + Key *pk; + + pk = xcalloc(1, sizeof(*pk)); + pk->type = k->type; + pk->flags = k->flags; + pk->ecdsa_nid = k->ecdsa_nid; + pk->dsa = NULL; + pk->ecdsa = NULL; + pk->rsa = NULL; + + switch (k->type) { + case KEY_RSA_CERT_V00: + case KEY_RSA_CERT: + key_cert_copy(k, pk); + /* FALLTHROUGH */ + case KEY_RSA1: + case KEY_RSA: + if ((pk->rsa = RSA_new()) == NULL) + fatal("key_demote: RSA_new failed"); + if ((pk->rsa->e = BN_dup(k->rsa->e)) == NULL) + fatal("key_demote: BN_dup failed"); + if ((pk->rsa->n = BN_dup(k->rsa->n)) == NULL) + fatal("key_demote: BN_dup failed"); + break; + case KEY_DSA_CERT_V00: + case KEY_DSA_CERT: + key_cert_copy(k, pk); + /* FALLTHROUGH */ + case KEY_DSA: + if ((pk->dsa = DSA_new()) == NULL) + fatal("key_demote: DSA_new failed"); + if ((pk->dsa->p = BN_dup(k->dsa->p)) == NULL) + fatal("key_demote: BN_dup failed"); + if ((pk->dsa->q = BN_dup(k->dsa->q)) == NULL) + fatal("key_demote: BN_dup failed"); + if ((pk->dsa->g = BN_dup(k->dsa->g)) == NULL) + fatal("key_demote: BN_dup failed"); + if ((pk->dsa->pub_key = BN_dup(k->dsa->pub_key)) == NULL) + fatal("key_demote: BN_dup failed"); + break; +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA_CERT: + key_cert_copy(k, pk); + /* FALLTHROUGH */ + case KEY_ECDSA: + if ((pk->ecdsa = EC_KEY_new_by_curve_name(pk->ecdsa_nid)) == NULL) + fatal("key_demote: EC_KEY_new_by_curve_name failed"); + if (EC_KEY_set_public_key(pk->ecdsa, + EC_KEY_get0_public_key(k->ecdsa)) != 1) + fatal("key_demote: EC_KEY_set_public_key failed"); + break; +#endif + default: + fatal("key_free: bad key type %d", k->type); + break; + } + + return (pk); +} + +int +key_is_cert(const Key *k) +{ + if (k == NULL) + return 0; + switch (k->type) { + case KEY_RSA_CERT_V00: + case KEY_DSA_CERT_V00: + case KEY_RSA_CERT: + case KEY_DSA_CERT: + case KEY_ECDSA_CERT: + return 1; + default: + return 0; + } +} + +/* Return the cert-less equivalent to a certified key type */ +int +key_type_plain(int type) +{ + switch (type) { + case KEY_RSA_CERT_V00: + case KEY_RSA_CERT: + return KEY_RSA; + case KEY_DSA_CERT_V00: + case KEY_DSA_CERT: + return KEY_DSA; + case KEY_ECDSA_CERT: + return KEY_ECDSA; + default: + return type; + } +} + +/* Convert a KEY_RSA or KEY_DSA to their _CERT equivalent */ +int +key_to_certified(Key *k, int legacy) +{ + switch (k->type) { + case KEY_RSA: + k->cert = cert_new(); + k->type = legacy ? KEY_RSA_CERT_V00 : KEY_RSA_CERT; + return 0; + case KEY_DSA: + k->cert = cert_new(); + k->type = legacy ? KEY_DSA_CERT_V00 : KEY_DSA_CERT; + return 0; + case KEY_ECDSA: + if (legacy) + fatal("%s: legacy ECDSA certificates are not supported", + __func__); + k->cert = cert_new(); + k->type = KEY_ECDSA_CERT; + return 0; + default: + error("%s: key has incorrect type %s", __func__, key_type(k)); + return -1; + } +} + +/* Convert a KEY_RSA_CERT or KEY_DSA_CERT to their raw key equivalent */ +int +key_drop_cert(Key *k) +{ + switch (k->type) { + case KEY_RSA_CERT_V00: + case KEY_RSA_CERT: + cert_free(k->cert); + k->type = KEY_RSA; + return 0; + case KEY_DSA_CERT_V00: + case KEY_DSA_CERT: + cert_free(k->cert); + k->type = KEY_DSA; + return 0; + case KEY_ECDSA_CERT: + cert_free(k->cert); + k->type = KEY_ECDSA; + return 0; + default: + error("%s: key has incorrect type %s", __func__, key_type(k)); + return -1; + } +} + +/* + * Sign a KEY_RSA_CERT, KEY_DSA_CERT or KEY_ECDSA_CERT, (re-)generating + * the signed certblob + */ +int +key_certify(Key *k, Key *ca) +{ + Buffer principals; + u_char *ca_blob, *sig_blob, nonce[32]; + u_int i, ca_len, sig_len; + + if (k->cert == NULL) { + error("%s: key lacks cert info", __func__); + return -1; + } + + if (!key_is_cert(k)) { + error("%s: certificate has unknown type %d", __func__, + k->cert->type); + return -1; + } + + if (ca->type != KEY_RSA && ca->type != KEY_DSA && + ca->type != KEY_ECDSA) { + error("%s: CA key has unsupported type %s", __func__, + key_type(ca)); + return -1; + } + + key_to_blob(ca, &ca_blob, &ca_len); + + buffer_clear(&k->cert->certblob); + buffer_put_cstring(&k->cert->certblob, key_ssh_name(k)); + + /* -v01 certs put nonce first */ + arc4random_buf(&nonce, sizeof(nonce)); + if (!key_cert_is_legacy(k)) + buffer_put_string(&k->cert->certblob, nonce, sizeof(nonce)); + + switch (k->type) { + case KEY_DSA_CERT_V00: + case KEY_DSA_CERT: + buffer_put_bignum2(&k->cert->certblob, k->dsa->p); + buffer_put_bignum2(&k->cert->certblob, k->dsa->q); + buffer_put_bignum2(&k->cert->certblob, k->dsa->g); + buffer_put_bignum2(&k->cert->certblob, k->dsa->pub_key); + break; +#ifdef OPENSSL_HAS_ECC + case KEY_ECDSA_CERT: + buffer_put_cstring(&k->cert->certblob, + key_curve_nid_to_name(k->ecdsa_nid)); + buffer_put_ecpoint(&k->cert->certblob, + EC_KEY_get0_group(k->ecdsa), + EC_KEY_get0_public_key(k->ecdsa)); + break; +#endif + case KEY_RSA_CERT_V00: + case KEY_RSA_CERT: + buffer_put_bignum2(&k->cert->certblob, k->rsa->e); + buffer_put_bignum2(&k->cert->certblob, k->rsa->n); + break; + default: + error("%s: key has incorrect type %s", __func__, key_type(k)); + buffer_clear(&k->cert->certblob); + xfree(ca_blob); + return -1; + } + + /* -v01 certs have a serial number next */ + if (!key_cert_is_legacy(k)) + buffer_put_int64(&k->cert->certblob, k->cert->serial); + + buffer_put_int(&k->cert->certblob, k->cert->type); + buffer_put_cstring(&k->cert->certblob, k->cert->key_id); + + buffer_init(&principals); + for (i = 0; i < k->cert->nprincipals; i++) + buffer_put_cstring(&principals, k->cert->principals[i]); + buffer_put_string(&k->cert->certblob, buffer_ptr(&principals), + buffer_len(&principals)); + buffer_free(&principals); + + buffer_put_int64(&k->cert->certblob, k->cert->valid_after); + buffer_put_int64(&k->cert->certblob, k->cert->valid_before); + buffer_put_string(&k->cert->certblob, + buffer_ptr(&k->cert->critical), buffer_len(&k->cert->critical)); + + /* -v01 certs have non-critical options here */ + if (!key_cert_is_legacy(k)) { + buffer_put_string(&k->cert->certblob, + buffer_ptr(&k->cert->extensions), + buffer_len(&k->cert->extensions)); + } + + /* -v00 certs put the nonce at the end */ + if (key_cert_is_legacy(k)) + buffer_put_string(&k->cert->certblob, nonce, sizeof(nonce)); + + buffer_put_string(&k->cert->certblob, NULL, 0); /* reserved */ + buffer_put_string(&k->cert->certblob, ca_blob, ca_len); + xfree(ca_blob); + + /* Sign the whole mess */ + if (key_sign(ca, &sig_blob, &sig_len, buffer_ptr(&k->cert->certblob), + buffer_len(&k->cert->certblob)) != 0) { + error("%s: signature operation failed", __func__); + buffer_clear(&k->cert->certblob); + return -1; + } + /* Append signature and we are done */ + buffer_put_string(&k->cert->certblob, sig_blob, sig_len); + xfree(sig_blob); + + return 0; +} + +int +key_cert_check_authority(const Key *k, int want_host, int require_principal, + const char *name, const char **reason) +{ + u_int i, principal_matches; + time_t now = time(NULL); + + if (want_host) { + if (k->cert->type != SSH2_CERT_TYPE_HOST) { + *reason = "Certificate invalid: not a host certificate"; + return -1; + } + } else { + if (k->cert->type != SSH2_CERT_TYPE_USER) { + *reason = "Certificate invalid: not a user certificate"; + return -1; + } + } + if (now < 0) { + error("%s: system clock lies before epoch", __func__); + *reason = "Certificate invalid: not yet valid"; + return -1; + } + if ((u_int64_t)now < k->cert->valid_after) { + *reason = "Certificate invalid: not yet valid"; + return -1; + } + if ((u_int64_t)now >= k->cert->valid_before) { + *reason = "Certificate invalid: expired"; + return -1; + } + if (k->cert->nprincipals == 0) { + if (require_principal) { + *reason = "Certificate lacks principal list"; + return -1; + } + } 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 -1; + } + } + return 0; +} + +int +key_cert_is_legacy(Key *k) +{ + switch (k->type) { + case KEY_DSA_CERT_V00: + case KEY_RSA_CERT_V00: + return 1; + default: + return 0; + } +} + +/* XXX: these are really begging for a table-driven approach */ +int +key_curve_name_to_nid(const char *name) +{ +#ifdef OPENSSL_HAS_ECC + if (strcmp(name, "nistp256") == 0) + return NID_X9_62_prime256v1; + else if (strcmp(name, "nistp384") == 0) + return NID_secp384r1; + else if (strcmp(name, "nistp521") == 0) + return NID_secp521r1; +#endif + + debug("%s: unsupported EC curve name \"%.100s\"", __func__, name); + return -1; +} + +u_int +key_curve_nid_to_bits(int nid) +{ + switch (nid) { +#ifdef OPENSSL_HAS_ECC + case NID_X9_62_prime256v1: + return 256; + case NID_secp384r1: + return 384; + case NID_secp521r1: + return 521; +#endif + default: + error("%s: unsupported EC curve nid %d", __func__, nid); + return 0; + } +} + +const char * +key_curve_nid_to_name(int nid) +{ +#ifdef OPENSSL_HAS_ECC + if (nid == NID_X9_62_prime256v1) + return "nistp256"; + else if (nid == NID_secp384r1) + return "nistp384"; + else if (nid == NID_secp521r1) + return "nistp521"; +#endif + error("%s: unsupported EC curve nid %d", __func__, nid); + return NULL; +} + +#ifdef OPENSSL_HAS_ECC +const EVP_MD * +key_ec_nid_to_evpmd(int nid) +{ + int kbits = key_curve_nid_to_bits(nid); + + if (kbits == 0) + fatal("%s: invalid nid %d", __func__, nid); + /* RFC5656 section 6.2.1 */ + if (kbits <= 256) + return EVP_sha256(); + else if (kbits <= 384) + return EVP_sha384(); + else + return EVP_sha512(); +} + +int +key_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 = -1; + + if ((bnctx = BN_CTX_new()) == NULL) + fatal("%s: BN_CTX_new failed", __func__); + 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) { + error("%s: group is not a prime field", __func__); + goto out; + } + + /* Q != infinity */ + if (EC_POINT_is_at_infinity(group, public)) { + error("%s: received degenerate public key (infinity)", + __func__); + 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) + fatal("%s: BN_CTX_get failed", __func__); + + /* log2(x) > log2(order)/2, log2(y) > log2(order)/2 */ + if (EC_GROUP_get_order(group, order, bnctx) != 1) + fatal("%s: EC_GROUP_get_order failed", __func__); + if (EC_POINT_get_affine_coordinates_GFp(group, public, + x, y, bnctx) != 1) + fatal("%s: EC_POINT_get_affine_coordinates_GFp", __func__); + if (BN_num_bits(x) <= BN_num_bits(order) / 2) { + error("%s: public key x coordinate too small: " + "bits(x) = %d, bits(order)/2 = %d", __func__, + BN_num_bits(x), BN_num_bits(order) / 2); + goto out; + } + if (BN_num_bits(y) <= BN_num_bits(order) / 2) { + error("%s: public key y coordinate too small: " + "bits(y) = %d, bits(order)/2 = %d", __func__, + BN_num_bits(x), BN_num_bits(order) / 2); + goto out; + } + + /* nQ == infinity (n == order of subgroup) */ + if ((nq = EC_POINT_new(group)) == NULL) + fatal("%s: BN_CTX_tmp failed", __func__); + if (EC_POINT_mul(group, nq, NULL, public, order, bnctx) != 1) + fatal("%s: EC_GROUP_mul failed", __func__); + if (EC_POINT_is_at_infinity(group, nq) != 1) { + error("%s: received degenerate public key (nQ != infinity)", + __func__); + goto out; + } + + /* x < order - 1, y < order - 1 */ + if (!BN_sub(tmp, order, BN_value_one())) + fatal("%s: BN_sub failed", __func__); + if (BN_cmp(x, tmp) >= 0) { + error("%s: public key x coordinate >= group order - 1", + __func__); + goto out; + } + if (BN_cmp(y, tmp) >= 0) { + error("%s: public key y coordinate >= group order - 1", + __func__); + goto out; + } + ret = 0; + out: + BN_CTX_free(bnctx); + EC_POINT_free(nq); + return ret; +} + +int +key_ec_validate_private(const EC_KEY *key) +{ + BN_CTX *bnctx; + BIGNUM *order, *tmp; + int ret = -1; + + if ((bnctx = BN_CTX_new()) == NULL) + fatal("%s: BN_CTX_new failed", __func__); + BN_CTX_start(bnctx); + + if ((order = BN_CTX_get(bnctx)) == NULL || + (tmp = BN_CTX_get(bnctx)) == NULL) + fatal("%s: BN_CTX_get failed", __func__); + + /* log2(private) > log2(order)/2 */ + if (EC_GROUP_get_order(EC_KEY_get0_group(key), order, bnctx) != 1) + fatal("%s: EC_GROUP_get_order failed", __func__); + if (BN_num_bits(EC_KEY_get0_private_key(key)) <= + BN_num_bits(order) / 2) { + error("%s: private key too small: " + "bits(y) = %d, bits(order)/2 = %d", __func__, + 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())) + fatal("%s: BN_sub failed", __func__); + if (BN_cmp(EC_KEY_get0_private_key(key), tmp) >= 0) { + error("%s: private key >= group order - 1", __func__); + goto out; + } + ret = 0; + out: + BN_CTX_free(bnctx); + return ret; +} + +#if defined(DEBUG_KEXECDH) || defined(DEBUG_PK) +void +key_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) + fatal("%s: BN_CTX_new failed", __func__); + BN_CTX_start(bnctx); + if ((x = BN_CTX_get(bnctx)) == NULL || (y = BN_CTX_get(bnctx)) == NULL) + fatal("%s: BN_CTX_get failed", __func__); + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != + NID_X9_62_prime_field) + fatal("%s: group is not a prime field", __func__); + if (EC_POINT_get_affine_coordinates_GFp(group, point, x, y, bnctx) != 1) + fatal("%s: EC_POINT_get_affine_coordinates_GFp", __func__); + fputs("x=", stderr); + BN_print_fp(stderr, x); + fputs("\ny=", stderr); + BN_print_fp(stderr, y); + fputs("\n", stderr); + BN_CTX_free(bnctx); +} + +void +key_dump_ec_key(const EC_KEY *key) +{ + const BIGNUM *exponent; + + key_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 /* defined(DEBUG_KEXECDH) || defined(DEBUG_PK) */ +#endif /* OPENSSL_HAS_ECC */
diff --git a/openssh-6.0p1/key.h b/openssh-6.0p1/key.h new file mode 100644 index 0000000..ec5ac5e --- /dev/null +++ b/openssh-6.0p1/key.h
@@ -0,0 +1,151 @@ +/* $OpenBSD: key.h,v 1.33 2010/10/28 11:22:09 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 "buffer.h" +#include <openssl/rsa.h> +#include <openssl/dsa.h> +#ifdef OPENSSL_HAS_ECC +#include <openssl/ec.h> +#endif + +typedef struct Key Key; +enum types { + KEY_RSA1, + KEY_RSA, + KEY_DSA, + KEY_ECDSA, + KEY_RSA_CERT, + KEY_DSA_CERT, + KEY_ECDSA_CERT, + KEY_RSA_CERT_V00, + KEY_DSA_CERT_V00, + KEY_UNSPEC +}; +enum fp_type { + SSH_FP_SHA1, + SSH_FP_MD5 +}; +enum fp_rep { + SSH_FP_HEX, + SSH_FP_BUBBLEBABBLE, + SSH_FP_RANDOMART +}; + +/* key is stored in external hardware */ +#define KEY_FLAG_EXT 0x0001 + +#define CERT_MAX_PRINCIPALS 256 +struct KeyCert { + Buffer 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; + Buffer critical; + Buffer extensions; + Key *signature_key; +}; + +struct Key { + int type; + int flags; + RSA *rsa; + DSA *dsa; + int ecdsa_nid; /* NID of curve */ +#ifdef OPENSSL_HAS_ECC + EC_KEY *ecdsa; +#else + void *ecdsa; +#endif + struct KeyCert *cert; +}; + +Key *key_new(int); +void key_add_private(Key *); +Key *key_new_private(int); +void key_free(Key *); +Key *key_demote(const Key *); +int key_equal_public(const Key *, const Key *); +int key_equal(const Key *, const Key *); +char *key_fingerprint(Key *, enum fp_type, enum fp_rep); +u_char *key_fingerprint_raw(Key *, enum fp_type, u_int *); +const char *key_type(const Key *); +const char *key_cert_type(const Key *); +int key_write(const Key *, FILE *); +int key_read(Key *, char **); +u_int key_size(const Key *); + +Key *key_generate(int, u_int); +Key *key_from_private(const Key *); +int key_type_from_name(char *); +int key_is_cert(const Key *); +int key_type_plain(int); +int key_to_certified(Key *, int); +int key_drop_cert(Key *); +int key_certify(Key *, Key *); +void key_cert_copy(const Key *, struct Key *); +int key_cert_check_authority(const Key *, int, int, const char *, + const char **); +int key_cert_is_legacy(Key *); + +int key_ecdsa_nid_from_name(const char *); +int key_curve_name_to_nid(const char *); +const char * key_curve_nid_to_name(int); +u_int key_curve_nid_to_bits(int); +int key_ecdsa_bits_to_nid(int); +#ifdef OPENSSL_HAS_ECC +int key_ecdsa_key_to_nid(EC_KEY *); +const EVP_MD * key_ec_nid_to_evpmd(int nid); +int key_ec_validate_public(const EC_GROUP *, const EC_POINT *); +int key_ec_validate_private(const EC_KEY *); +#endif + +Key *key_from_blob(const u_char *, u_int); +int key_to_blob(const Key *, u_char **, u_int *); +const char *key_ssh_name(const Key *); +const char *key_ssh_name_plain(const Key *); +int key_names_valid2(const char *); + +int key_sign(const Key *, u_char **, u_int *, const u_char *, u_int); +int key_verify(const Key *, const u_char *, u_int, const u_char *, u_int); + +int ssh_dss_sign(const Key *, u_char **, u_int *, const u_char *, u_int); +int ssh_dss_verify(const Key *, const u_char *, u_int, const u_char *, u_int); +int ssh_ecdsa_sign(const Key *, u_char **, u_int *, const u_char *, u_int); +int ssh_ecdsa_verify(const Key *, const u_char *, u_int, const u_char *, u_int); +int ssh_rsa_sign(const Key *, u_char **, u_int *, const u_char *, u_int); +int ssh_rsa_verify(const Key *, const u_char *, u_int, const u_char *, u_int); + +#if defined(OPENSSL_HAS_ECC) && (defined(DEBUG_KEXECDH) || defined(DEBUG_PK)) +void key_dump_ec_point(const EC_GROUP *, const EC_POINT *); +void key_dump_ec_key(const EC_KEY *); +#endif + +#endif
diff --git a/openssh-6.0p1/log.c b/openssh-6.0p1/log.c new file mode 100644 index 0000000..ad5a10b --- /dev/null +++ b/openssh-6.0p1/log.c
@@ -0,0 +1,430 @@ +/* $OpenBSD: log.c,v 1.42 2011/06/17 21:44:30 djm Exp $ */ +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ +/* + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#include <sys/types.h> + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <syslog.h> +#include <unistd.h> +#include <errno.h> +#if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) +# include <vis.h> +#endif + +#include "xmalloc.h" +#include "log.h" + +static LogLevel log_level = SYSLOG_LEVEL_INFO; +static int log_on_stderr = 1; +static int log_facility = LOG_AUTH; +static char *argv0; +static log_handler_fn *log_handler; +static void *log_handler_ctx; + +extern char *__progname; + +#define LOG_SYSLOG_VIS (VIS_CSTYLE|VIS_NL|VIS_TAB|VIS_OCTAL) +#define LOG_STDERR_VIS (VIS_SAFE|VIS_OCTAL) + +/* textual representation of log-facilities/levels */ + +static struct { + const char *name; + SyslogFacility val; +} log_facilities[] = { + { "DAEMON", SYSLOG_FACILITY_DAEMON }, + { "USER", SYSLOG_FACILITY_USER }, + { "AUTH", SYSLOG_FACILITY_AUTH }, +#ifdef LOG_AUTHPRIV + { "AUTHPRIV", SYSLOG_FACILITY_AUTHPRIV }, +#endif + { "LOCAL0", SYSLOG_FACILITY_LOCAL0 }, + { "LOCAL1", SYSLOG_FACILITY_LOCAL1 }, + { "LOCAL2", SYSLOG_FACILITY_LOCAL2 }, + { "LOCAL3", SYSLOG_FACILITY_LOCAL3 }, + { "LOCAL4", SYSLOG_FACILITY_LOCAL4 }, + { "LOCAL5", SYSLOG_FACILITY_LOCAL5 }, + { "LOCAL6", SYSLOG_FACILITY_LOCAL6 }, + { "LOCAL7", SYSLOG_FACILITY_LOCAL7 }, + { NULL, SYSLOG_FACILITY_NOT_SET } +}; + +static struct { + const char *name; + LogLevel val; +} log_levels[] = +{ + { "QUIET", SYSLOG_LEVEL_QUIET }, + { "FATAL", SYSLOG_LEVEL_FATAL }, + { "ERROR", SYSLOG_LEVEL_ERROR }, + { "INFO", SYSLOG_LEVEL_INFO }, + { "VERBOSE", SYSLOG_LEVEL_VERBOSE }, + { "DEBUG", SYSLOG_LEVEL_DEBUG1 }, + { "DEBUG1", SYSLOG_LEVEL_DEBUG1 }, + { "DEBUG2", SYSLOG_LEVEL_DEBUG2 }, + { "DEBUG3", SYSLOG_LEVEL_DEBUG3 }, + { NULL, SYSLOG_LEVEL_NOT_SET } +}; + +SyslogFacility +log_facility_number(char *name) +{ + int i; + + if (name != NULL) + for (i = 0; log_facilities[i].name; i++) + if (strcasecmp(log_facilities[i].name, name) == 0) + return log_facilities[i].val; + return SYSLOG_FACILITY_NOT_SET; +} + +const char * +log_facility_name(SyslogFacility facility) +{ + u_int i; + + for (i = 0; log_facilities[i].name; i++) + if (log_facilities[i].val == facility) + return log_facilities[i].name; + return NULL; +} + +LogLevel +log_level_number(char *name) +{ + int i; + + if (name != NULL) + for (i = 0; log_levels[i].name; i++) + if (strcasecmp(log_levels[i].name, name) == 0) + return log_levels[i].val; + return SYSLOG_LEVEL_NOT_SET; +} + +const char * +log_level_name(LogLevel level) +{ + u_int i; + + for (i = 0; log_levels[i].name != NULL; i++) + if (log_levels[i].val == level) + return log_levels[i].name; + return NULL; +} + +/* Error messages that should be logged. */ + +void +error(const char *fmt,...) +{ + va_list args; + + va_start(args, fmt); + do_log(SYSLOG_LEVEL_ERROR, fmt, args); + va_end(args); +} + +void +sigdie(const char *fmt,...) +{ +#ifdef DO_LOG_SAFE_IN_SIGHAND + va_list args; + + va_start(args, fmt); + do_log(SYSLOG_LEVEL_FATAL, fmt, args); + va_end(args); +#endif + _exit(1); +} + + +/* Log this message (information that usually should go to the log). */ + +void +logit(const char *fmt,...) +{ + va_list args; + + va_start(args, fmt); + do_log(SYSLOG_LEVEL_INFO, fmt, args); + va_end(args); +} + +/* More detailed messages (information that does not need to go to the log). */ + +void +verbose(const char *fmt,...) +{ + va_list args; + + va_start(args, fmt); + do_log(SYSLOG_LEVEL_VERBOSE, fmt, args); + va_end(args); +} + +/* Debugging messages that should not be logged during normal operation. */ + +void +debug(const char *fmt,...) +{ + va_list args; + + va_start(args, fmt); + do_log(SYSLOG_LEVEL_DEBUG1, fmt, args); + va_end(args); +} + +void +debug2(const char *fmt,...) +{ + va_list args; + + va_start(args, fmt); + do_log(SYSLOG_LEVEL_DEBUG2, fmt, args); + va_end(args); +} + +void +debug3(const char *fmt,...) +{ + va_list args; + + va_start(args, fmt); + do_log(SYSLOG_LEVEL_DEBUG3, fmt, args); + va_end(args); +} + +/* + * Initialize the log. + */ + +void +log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr) +{ +#if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) + struct syslog_data sdata = SYSLOG_DATA_INIT; +#endif + + argv0 = av0; + + switch (level) { + case SYSLOG_LEVEL_QUIET: + case SYSLOG_LEVEL_FATAL: + case SYSLOG_LEVEL_ERROR: + case SYSLOG_LEVEL_INFO: + case SYSLOG_LEVEL_VERBOSE: + case SYSLOG_LEVEL_DEBUG1: + case SYSLOG_LEVEL_DEBUG2: + case SYSLOG_LEVEL_DEBUG3: + log_level = level; + break; + default: + fprintf(stderr, "Unrecognized internal syslog level code %d\n", + (int) level); + exit(1); + } + + log_handler = NULL; + log_handler_ctx = NULL; + + log_on_stderr = on_stderr; + if (on_stderr) + return; + + switch (facility) { + case SYSLOG_FACILITY_DAEMON: + log_facility = LOG_DAEMON; + break; + case SYSLOG_FACILITY_USER: + log_facility = LOG_USER; + break; + case SYSLOG_FACILITY_AUTH: + log_facility = LOG_AUTH; + break; +#ifdef LOG_AUTHPRIV + case SYSLOG_FACILITY_AUTHPRIV: + log_facility = LOG_AUTHPRIV; + break; +#endif + case SYSLOG_FACILITY_LOCAL0: + log_facility = LOG_LOCAL0; + break; + case SYSLOG_FACILITY_LOCAL1: + log_facility = LOG_LOCAL1; + break; + case SYSLOG_FACILITY_LOCAL2: + log_facility = LOG_LOCAL2; + break; + case SYSLOG_FACILITY_LOCAL3: + log_facility = LOG_LOCAL3; + break; + case SYSLOG_FACILITY_LOCAL4: + log_facility = LOG_LOCAL4; + break; + case SYSLOG_FACILITY_LOCAL5: + log_facility = LOG_LOCAL5; + break; + case SYSLOG_FACILITY_LOCAL6: + log_facility = LOG_LOCAL6; + break; + case SYSLOG_FACILITY_LOCAL7: + log_facility = LOG_LOCAL7; + break; + default: + fprintf(stderr, + "Unrecognized internal syslog facility code %d\n", + (int) facility); + exit(1); + } + + /* + * If an external library (eg libwrap) attempts to use syslog + * immediately after reexec, syslog may be pointing to the wrong + * facility, so we force an open/close of syslog here. + */ +#if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) + openlog_r(argv0 ? argv0 : __progname, LOG_PID, log_facility, &sdata); + closelog_r(&sdata); +#else + openlog(argv0 ? argv0 : __progname, LOG_PID, log_facility); + closelog(); +#endif +} + +#define MSGBUFSIZ 1024 + +void +set_log_handler(log_handler_fn *handler, void *ctx) +{ + log_handler = handler; + log_handler_ctx = ctx; +} + +void +do_log2(LogLevel level, const char *fmt,...) +{ + va_list args; + + va_start(args, fmt); + do_log(level, fmt, args); + va_end(args); +} + +void +do_log(LogLevel level, const char *fmt, va_list args) +{ +#if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) + struct syslog_data sdata = SYSLOG_DATA_INIT; +#endif + char msgbuf[MSGBUFSIZ]; + char fmtbuf[MSGBUFSIZ]; + char *txt = NULL; + int pri = LOG_INFO; + int saved_errno = errno; + log_handler_fn *tmp_handler; + + if (level > log_level) + return; + + switch (level) { + case SYSLOG_LEVEL_FATAL: + if (!log_on_stderr) + txt = "fatal"; + pri = LOG_CRIT; + break; + case SYSLOG_LEVEL_ERROR: + if (!log_on_stderr) + txt = "error"; + pri = LOG_ERR; + break; + case SYSLOG_LEVEL_INFO: + pri = LOG_INFO; + break; + case SYSLOG_LEVEL_VERBOSE: + pri = LOG_INFO; + break; + case SYSLOG_LEVEL_DEBUG1: + txt = "debug1"; + pri = LOG_DEBUG; + break; + case SYSLOG_LEVEL_DEBUG2: + txt = "debug2"; + pri = LOG_DEBUG; + break; + case SYSLOG_LEVEL_DEBUG3: + txt = "debug3"; + pri = LOG_DEBUG; + break; + default: + txt = "internal error"; + pri = LOG_ERR; + break; + } + if (txt != NULL && log_handler == NULL) { + snprintf(fmtbuf, sizeof(fmtbuf), "%s: %s", txt, fmt); + vsnprintf(msgbuf, sizeof(msgbuf), fmtbuf, args); + } else { + vsnprintf(msgbuf, sizeof(msgbuf), fmt, args); + } + strnvis(fmtbuf, msgbuf, sizeof(fmtbuf), + log_on_stderr ? LOG_STDERR_VIS : LOG_SYSLOG_VIS); + if (log_handler != NULL) { + /* Avoid recursion */ + tmp_handler = log_handler; + log_handler = NULL; + tmp_handler(level, fmtbuf, log_handler_ctx); + log_handler = tmp_handler; + } else if (log_on_stderr) { + snprintf(msgbuf, sizeof msgbuf, "%s\r\n", fmtbuf); + write(STDERR_FILENO, 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; +}
diff --git a/openssh-6.0p1/log.h b/openssh-6.0p1/log.h new file mode 100644 index 0000000..1b8d214 --- /dev/null +++ b/openssh-6.0p1/log.h
@@ -0,0 +1,75 @@ +/* $OpenBSD: log.h,v 1.18 2011/06/17 21:44:30 djm Exp $ */ + +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ + +#ifndef 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); + +SyslogFacility log_facility_number(char *); +const char * log_facility_name(SyslogFacility); +LogLevel log_level_number(char *); +const char * log_level_name(LogLevel); + +void fatal(const char *, ...) __attribute__((noreturn)) + __attribute__((format(printf, 1, 2))); +void error(const char *, ...) __attribute__((format(printf, 1, 2))); +void sigdie(const char *, ...) __attribute__((noreturn)) + __attribute__((format(printf, 1, 2))); +void logit(const char *, ...) __attribute__((format(printf, 1, 2))); +void verbose(const char *, ...) __attribute__((format(printf, 1, 2))); +void debug(const char *, ...) __attribute__((format(printf, 1, 2))); +void debug2(const char *, ...) __attribute__((format(printf, 1, 2))); +void debug3(const char *, ...) __attribute__((format(printf, 1, 2))); + + +void set_log_handler(log_handler_fn *, void *); +void do_log2(LogLevel, const char *, ...) + __attribute__((format(printf, 2, 3))); +void do_log(LogLevel, const char *, va_list); +void cleanup_exit(int) __attribute__((noreturn)); +#endif
diff --git a/openssh-6.0p1/loginrec.c b/openssh-6.0p1/loginrec.c new file mode 100644 index 0000000..32941c9 --- /dev/null +++ b/openssh-6.0p1/loginrec.c
@@ -0,0 +1,1727 @@ +/* + * 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_<method> or CONF_<method>_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 <sys/types.h> +#include <sys/stat.h> +#include <sys/socket.h> + +#include <netinet/in.h> + +#include <errno.h> +#include <fcntl.h> +#ifdef HAVE_PATHS_H +# include <paths.h> +#endif +#include <pwd.h> +#include <stdarg.h> +#include <string.h> +#include <time.h> +#include <unistd.h> + +#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 <util.h> +#endif + +#ifdef HAVE_LIBUTIL_H +# include <libutil.h> +#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); + + /* No MIN_SIZEOF here - we absolutely *must not* truncate the + * username (XXX - so check for trunc!) */ + strlcpy(li->username, pw->pw_name, sizeof(li->username)); + + 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) +{ + xfree(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 <dstsize> 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(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 +# 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 */
diff --git a/openssh-6.0p1/loginrec.h b/openssh-6.0p1/loginrec.h new file mode 100644 index 0000000..28923e7 --- /dev/null +++ b/openssh-6.0p1/loginrec.h
@@ -0,0 +1,131 @@ +#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_ */
diff --git a/openssh-6.0p1/logintest.c b/openssh-6.0p1/logintest.c new file mode 100644 index 0000000..4897ae0 --- /dev/null +++ b/openssh-6.0p1/logintest.c
@@ -0,0 +1,308 @@ +/* + * 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 <sys/types.h> +#include <sys/wait.h> +#include <sys/socket.h> + +#include <netinet/in.h> + +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <pwd.h> +#include <netdb.h> +#ifdef HAVE_TIME_H +#include <time.h> +#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() */ +
diff --git a/openssh-6.0p1/mac.c b/openssh-6.0p1/mac.c new file mode 100644 index 0000000..332d3c6 --- /dev/null +++ b/openssh-6.0p1/mac.c
@@ -0,0 +1,197 @@ +/* $OpenBSD: mac.c,v 1.17 2011/12/02 00:43:57 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 <sys/types.h> + +#include <openssl/hmac.h> + +#include <stdarg.h> +#include <string.h> +#include <signal.h> + +#include "xmalloc.h" +#include "log.h" +#include "cipher.h" +#include "buffer.h" +#include "key.h" +#include "kex.h" +#include "mac.h" +#include "misc.h" + +#include "umac.h" + +#include "openbsd-compat/openssl-compat.h" + +#define SSH_EVP 1 /* OpenSSL EVP-based MAC */ +#define SSH_UMAC 2 /* UMAC (not integrated with OpenSSL) */ + +struct { + char *name; + int type; + const EVP_MD * (*mdfunc)(void); + int truncatebits; /* truncate digest if != 0 */ + int key_len; /* just for UMAC */ + int len; /* just for UMAC */ +} macs[] = { + { "hmac-sha1", SSH_EVP, EVP_sha1, 0, -1, -1 }, + { "hmac-sha1-96", SSH_EVP, EVP_sha1, 96, -1, -1 }, +#ifdef HAVE_EVP_SHA256 + { "hmac-sha2-256", SSH_EVP, EVP_sha256, 0, -1, -1 }, + { "hmac-sha2-256-96", SSH_EVP, EVP_sha256, 96, -1, -1 }, + { "hmac-sha2-512", SSH_EVP, EVP_sha512, 0, -1, -1 }, + { "hmac-sha2-512-96", SSH_EVP, EVP_sha512, 96, -1, -1 }, +#endif + { "hmac-md5", SSH_EVP, EVP_md5, 0, -1, -1 }, + { "hmac-md5-96", SSH_EVP, EVP_md5, 96, -1, -1 }, + { "hmac-ripemd160", SSH_EVP, EVP_ripemd160, 0, -1, -1 }, + { "hmac-ripemd160@openssh.com", SSH_EVP, EVP_ripemd160, 0, -1, -1 }, + { "umac-64@openssh.com", SSH_UMAC, NULL, 0, 128, 64 }, + { NULL, 0, NULL, 0, -1, -1 } +}; + +static void +mac_setup_by_id(Mac *mac, int which) +{ + int evp_len; + mac->type = macs[which].type; + if (mac->type == SSH_EVP) { + mac->evp_md = (*macs[which].mdfunc)(); + if ((evp_len = EVP_MD_size(mac->evp_md)) <= 0) + fatal("mac %s len %d", mac->name, evp_len); + mac->key_len = mac->mac_len = (u_int)evp_len; + } else { + mac->mac_len = macs[which].len / 8; + mac->key_len = macs[which].key_len / 8; + mac->umac_ctx = NULL; + } + if (macs[which].truncatebits != 0) + mac->mac_len = macs[which].truncatebits / 8; +} + +int +mac_setup(Mac *mac, char *name) +{ + int i; + + for (i = 0; macs[i].name; i++) { + if (strcmp(name, macs[i].name) == 0) { + if (mac != NULL) + mac_setup_by_id(mac, i); + debug2("mac_setup: found %s", name); + return (0); + } + } + debug2("mac_setup: unknown %s", name); + return (-1); +} + +int +mac_init(Mac *mac) +{ + if (mac->key == NULL) + fatal("mac_init: no key"); + switch (mac->type) { + case SSH_EVP: + if (mac->evp_md == NULL) + return -1; + HMAC_CTX_init(&mac->evp_ctx); + HMAC_Init(&mac->evp_ctx, mac->key, mac->key_len, mac->evp_md); + return 0; + case SSH_UMAC: + mac->umac_ctx = umac_new(mac->key); + return 0; + default: + return -1; + } +} + +u_char * +mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen) +{ + static u_char m[EVP_MAX_MD_SIZE]; + u_char b[4], nonce[8]; + + if (mac->mac_len > sizeof(m)) + fatal("mac_compute: mac too long %u %lu", + mac->mac_len, (u_long)sizeof(m)); + + switch (mac->type) { + case SSH_EVP: + put_u32(b, seqno); + /* reset HMAC context */ + HMAC_Init(&mac->evp_ctx, NULL, 0, NULL); + HMAC_Update(&mac->evp_ctx, b, sizeof(b)); + HMAC_Update(&mac->evp_ctx, data, datalen); + HMAC_Final(&mac->evp_ctx, m, NULL); + break; + case SSH_UMAC: + put_u64(nonce, seqno); + umac_update(mac->umac_ctx, data, datalen); + umac_final(mac->umac_ctx, m, nonce); + break; + default: + fatal("mac_compute: unknown MAC type"); + } + return (m); +} + +void +mac_clear(Mac *mac) +{ + if (mac->type == SSH_UMAC) { + if (mac->umac_ctx != NULL) + umac_delete(mac->umac_ctx); + } else if (mac->evp_md != NULL) + HMAC_cleanup(&mac->evp_ctx); + mac->evp_md = 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); + maclist = cp = xstrdup(names); + for ((p = strsep(&cp, MAC_SEP)); p && *p != '\0'; + (p = strsep(&cp, MAC_SEP))) { + if (mac_setup(NULL, p) < 0) { + debug("bad mac %s [%s]", p, names); + xfree(maclist); + return (0); + } else { + debug3("mac ok: %s [%s]", p, names); + } + } + debug3("macs ok: [%s]", names); + xfree(maclist); + return (1); +}
diff --git a/openssh-6.0p1/mac.h b/openssh-6.0p1/mac.h new file mode 100644 index 0000000..39f564d --- /dev/null +++ b/openssh-6.0p1/mac.h
@@ -0,0 +1,30 @@ +/* $OpenBSD: mac.h,v 1.6 2007/06/07 19:37:34 pvalchev 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. + */ + +int mac_valid(const char *); +int mac_setup(Mac *, char *); +int mac_init(Mac *); +u_char *mac_compute(Mac *, u_int32_t, u_char *, int); +void mac_clear(Mac *);
diff --git a/openssh-6.0p1/match.c b/openssh-6.0p1/match.c new file mode 100644 index 0000000..2389477 --- /dev/null +++ b/openssh-6.0p1/match.c
@@ -0,0 +1,278 @@ +/* $OpenBSD: match.c,v 1.27 2008/06/10 23:06:19 djm Exp $ */ +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, 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 <sys/types.h> + +#include <ctype.h> +#include <string.h> + +#include "xmalloc.h" +#include "match.h" + +/* + * Returns true if the given string matches the pattern (which may contain ? + * and * as wildcards), and zero if it does not match. + */ + +int +match_pattern(const char *s, const char *pattern) +{ + for (;;) { + /* If at end of pattern, accept if also at end of string. */ + if (!*pattern) + return !*s; + + if (*pattern == '*') { + /* Skip the asterisk. */ + pattern++; + + /* If at end of pattern, accept immediately. */ + if (!*pattern) + return 1; + + /* If next character in pattern is known, optimize. */ + if (*pattern != '?' && *pattern != '*') { + /* + * Look instances of the next character in + * pattern, and try to match starting from + * those. + */ + for (; *s; s++) + if (*s == *pattern && + match_pattern(s + 1, pattern + 1)) + return 1; + /* Failed. */ + return 0; + } + /* + * Move ahead one character at a time and try to + * match at each position. + */ + for (; *s; s++) + if (match_pattern(s, pattern)) + return 1; + /* Failed. */ + return 0; + } + /* + * There must be at least one more character in the string. + * If we are at the end, fail. + */ + if (!*s) + return 0; + + /* Check if the next character of the string is acceptable. */ + if (*pattern != '?' && *pattern != *s) + return 0; + + /* Move to the next character, both in string and in pattern. */ + s++; + pattern++; + } + /* NOTREACHED */ +} + +/* + * Tries to match the string against the + * comma-separated sequence of subpatterns (each possibly preceded by ! to + * indicate negation). Returns -1 if negation matches, 1 if there is + * a positive match, 0 if there is no match at all. + */ + +int +match_pattern_list(const char *string, const char *pattern, u_int len, + int dolower) +{ + char sub[1024]; + int negated; + int got_positive; + u_int i, subi; + + 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(pattern[i]) ? + (char)tolower(pattern[i]) : pattern[i]; + /* If subpattern too long, return failure (no match). */ + if (subi >= sizeof(sub) - 1) + return 0; + + /* If the subpattern was terminated by a comma, skip the comma. */ + if (i < len && pattern[i] == ',') + i++; + + /* Null-terminate the subpattern. */ + sub[subi] = '\0'; + + /* Try to match the subpattern against the string. */ + if (match_pattern(string, sub)) { + if (negated) + return -1; /* Negative */ + else + got_positive = 1; /* Positive */ + } + } + + /* + * Return success if got a positive match. If there was a negative + * match, we have already returned -1 and never get here. + */ + return got_positive; +} + +/* + * Tries to match the host name (which must be in all lowercase) against the + * comma-separated sequence of subpatterns (each possibly preceded by ! to + * indicate negation). Returns -1 if negation matches, 1 if there is + * a positive match, 0 if there is no match at all. + */ +int +match_hostname(const char *host, const char *pattern, u_int len) +{ + return match_pattern_list(host, pattern, len, 1); +} + +/* + * returns 0 if we get a negative match for the hostname or the ip + * or if we get no match at all. returns -1 on error, or 1 on + * successful match. + */ +int +match_host_and_ip(const char *host, const char *ipaddr, + const char *patterns) +{ + int mhost, mip; + + /* error in ipaddr match */ + if ((mip = addr_match_list(ipaddr, patterns)) == -2) + return -1; + else if (mip == -1) /* negative ip address match */ + return 0; + + /* negative hostname match */ + if ((mhost = match_hostname(host, patterns, strlen(patterns))) == -1) + return 0; + /* no match at all */ + if (mhost == 0 && mip == 0) + return 0; + return 1; +} + +/* + * match user, user@host_or_ip, user@host_or_ip_list against pattern + */ +int +match_user(const char *user, const char *host, const char *ipaddr, + const char *pattern) +{ + char *p, *pat; + int ret; + + if ((p = strchr(pattern,'@')) == NULL) + return match_pattern(user, pattern); + + pat = xstrdup(pattern); + p = strchr(pat, '@'); + *p++ = '\0'; + + if ((ret = match_pattern(user, pat)) == 1) + ret = match_host_and_ip(host, ipaddr, p); + xfree(pat); + + return ret; +} + +/* + * Returns first item from client-list that is also supported by server-list, + * caller must xfree() 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); + xfree(c); + xfree(s); + return ret; + } + } + } + if (next != NULL) + *next = strlen(c); + xfree(c); + xfree(s); + return NULL; +}
diff --git a/openssh-6.0p1/match.h b/openssh-6.0p1/match.h new file mode 100644 index 0000000..3d7f70f --- /dev/null +++ b/openssh-6.0p1/match.h
@@ -0,0 +1,27 @@ +/* $OpenBSD: match.h,v 1.15 2010/02/26 20:29:54 djm Exp $ */ + +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ +#ifndef MATCH_H +#define MATCH_H + +int match_pattern(const char *, const char *); +int match_pattern_list(const char *, const char *, u_int, int); +int match_hostname(const char *, const char *, u_int); +int match_host_and_ip(const char *, const char *, const char *); +int match_user(const char *, const char *, const char *, const char *); +char *match_list(const char *, const char *, u_int *); + +/* addrmatch.c */ +int addr_match_list(const char *, const char *); +int addr_match_cidr_list(const char *, const char *); +#endif
diff --git a/openssh-6.0p1/md-sha256.c b/openssh-6.0p1/md-sha256.c new file mode 100644 index 0000000..8c1b3b9 --- /dev/null +++ b/openssh-6.0p1/md-sha256.c
@@ -0,0 +1,86 @@ +/* $OpenBSD: md-sha256.c,v 1.5 2006/08/03 03:34:42 deraadt Exp $ */ +/* + * Copyright (c) 2005 Damien Miller <djm@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* EVP wrapper for SHA256 */ + +#include "includes.h" + +#include <sys/types.h> +#include <openssl/opensslv.h> + +#if !defined(HAVE_EVP_SHA256) && (OPENSSL_VERSION_NUMBER >= 0x00907000L) + +#include <string.h> +#include <openssl/evp.h> +#ifdef HAVE_SHA256_UPDATE +# ifdef HAVE_SHA2_H +# include <sha2.h> +# elif defined(HAVE_CRYPTO_SHA2_H) +# include <crypto/sha2.h> +# 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) */ +
diff --git a/openssh-6.0p1/md5crypt.c b/openssh-6.0p1/md5crypt.c new file mode 100644 index 0000000..22ef989 --- /dev/null +++ b/openssh-6.0p1/md5crypt.c
@@ -0,0 +1,167 @@ +/* + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * <phk@login.dknet.dk> wrote this file. As long as you retain this + * notice you can do whatever you want with this stuff. If we meet some + * day, and you think this stuff is worth it, you can buy me a beer in + * return. Poul-Henning Kamp + * ---------------------------------------------------------------------------- + */ + +#include "includes.h" + +#if defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) +#include <sys/types.h> + +#include <string.h> + +#include <openssl/md5.h> + +/* 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) */
diff --git a/openssh-6.0p1/md5crypt.h b/openssh-6.0p1/md5crypt.h new file mode 100644 index 0000000..2341e2c --- /dev/null +++ b/openssh-6.0p1/md5crypt.h
@@ -0,0 +1,24 @@ +/* + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp + * ---------------------------------------------------------------------------- + */ + +/* $Id: md5crypt.h,v 1.4 2003/05/18 14:46:46 djm Exp $ */ + +#ifndef _MD5CRYPT_H +#define _MD5CRYPT_H + +#include "config.h" + +#if defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) + +int is_md5_salt(const char *); +char *md5_crypt(const char *, const char *); + +#endif /* defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) */ + +#endif /* MD5CRYPT_H */
diff --git a/openssh-6.0p1/mdoc2man.awk b/openssh-6.0p1/mdoc2man.awk new file mode 100644 index 0000000..80e8d5f --- /dev/null +++ b/openssh-6.0p1/mdoc2man.awk
@@ -0,0 +1,370 @@ +#!/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 <dnelson@allantgroup.com> added .An, .Aq and fixed a typo +# v2, fixed to work on GNU awk --posix and MacOS X +# v1, first attempt, didn't work on MacOS X +# +# Copyright (c) 2003 Peter Stuge <stuge-mdoc2man@cdy.org> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + +BEGIN { + optlist=0 + oldoptlist=0 + nospace=0 + synopsis=0 + reference=0 + block=0 + ext=0 + extopt=0 + literal=0 + prenl=0 + breakw=0 + line="" +} + +function wtail() { + retval="" + while(w<nwords) { + if(length(retval)) + retval=retval OFS + retval=retval words[++w] + } + return retval +} + +function add(str) { + for(;prenl;prenl--) + line=line "\n" + line=line str +} + +! /^\./ { + for(;prenl;prenl--) + print "" + print + if(literal) + print ".br" + next +} + +/^\.\\"/ { next } + +{ + option=0 + parens=0 + angles=0 + sub("^\\.","") + nwords=split($0,words) + for(w=1;w<=nwords;w++) { + skip=0 + if(match(words[w],"^Li|Pf$")) { + skip=1 + } else if(match(words[w],"^Xo$")) { + skip=1 + ext=1 + if(length(line)&&!(match(line," $")||prenl)) + add(OFS) + } else if(match(words[w],"^Xc$")) { + skip=1 + ext=0 + if(!extopt) + prenl++ + w=nwords + } else if(match(words[w],"^Bd$")) { + skip=1 + if(match(words[w+1],"-literal")) { + literal=1 + prenl++ + w=nwords + } + } else if(match(words[w],"^Ed$")) { + skip=1 + literal=0 + } else if(match(words[w],"^Ns$")) { + skip=1 + if(!nospace) + nospace=1 + sub(" $","",line) + } else if(match(words[w],"^No$")) { + skip=1 + sub(" $","",line) + add(words[++w]) + } else if(match(words[w],"^Dq$")) { + skip=1 + add("``") + add(words[++w]) + while(w<nwords&&!match(words[w+1],"^[\\.,]")) + add(OFS words[++w]) + add("''") + if(!nospace&&match(words[w+1],"^[\\.,]")) + nospace=1 + } else if(match(words[w],"^Sq|Ql$")) { + skip=1 + add("`" words[++w] "'") + if(!nospace&&match(words[w+1],"^[\\.,]")) + nospace=1 + } else if(match(words[w],"^Oo$")) { + skip=1 + extopt=1 + if(!nospace) + nospace=1 + add("[") + } else if(match(words[w],"^Oc$")) { + skip=1 + extopt=0 + add("]") + } + if(!skip) { + if(!nospace&&length(line)&&!(match(line," $")||prenl)) + add(OFS) + if(nospace==1) + nospace=0 + } + if(match(words[w],"^Dd$")) { + if(match(words[w+1],"^\\$Mdocdate:")) { + w++; + if(match(words[w+4],"^\\$$")) { + words[w+4] = "" + } + } + date=wtail() + next + } else if(match(words[w],"^Dt$")) { + id=wtail() + next + } else if(match(words[w],"^Ux$")) { + add("UNIX") + skip=1 + } else if(match(words[w],"^Ox$")) { + add("OpenBSD") + skip=1 + } else if(match(words[w],"^Os$")) { + add(".TH " id " \"" date "\" \"" wtail() "\"") + } else if(match(words[w],"^Sh$")) { + add(".SH") + synopsis=match(words[w+1],"SYNOPSIS") + } else if(match(words[w],"^Xr$")) { + add("\\fB" words[++w] "\\fP(" words[++w] ")" words[++w]) + } else if(match(words[w],"^Rs$")) { + split("",refauthors) + nrefauthors=0 + reftitle="" + refissue="" + refdate="" + refopt="" + refreport="" + reference=1 + next + } else if(match(words[w],"^Re$")) { + prenl++ + for(i=nrefauthors-1;i>0;i--) { + add(refauthors[i]) + if(i>1) + add(", ") + } + if(nrefauthors>1) + add(" and ") + 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<nwords&&match(words[w+1],"^[\\.,:;)]")) + add(words[++w]) + } else if(match(words[w],"^Op$")) { + option=1 + if(!nospace) + nospace=1 + add("[") + } else if(match(words[w],"^Pp$")) { + prenl++ + } else if(match(words[w],"^An$")) { + prenl++ + } else if(match(words[w],"^Ss$")) { + add(".SS") + } else if(match(words[w],"^Pa$")&&!option) { + add("\\fI") + w++ + if(match(words[w],"^\\.")) + add("\\&") + add(words[w] "\\fP") + while(w<nwords&&match(words[w+1],"^[\\.,:;)]")) + add(words[++w]) + } else if(match(words[w],"^Dv$")) { + add(".BR") + } else if(match(words[w],"^Em|Ev$")) { + add(".IR") + } else if(match(words[w],"^Pq$")) { + add("(") + nospace=1 + parens=1 + } else if(match(words[w],"^Aq$")) { + add("<") + nospace=1 + angles=1 + } else if(match(words[w],"^S[xy]$")) { + add(".B " wtail()) + } else if(match(words[w],"^Ic$")) { + plain=1 + add("\\fB") + while(w<nwords) { + w++ + if(match(words[w],"^Op$")) { + w++ + add("[") + words[nwords]=words[nwords] "]" + } + if(match(words[w],"^Ar$")) { + add("\\fI" words[++w] "\\fP") + } else if(match(words[w],"^[\\.,]")) { + sub(" $","",line) + if(plain) { + add("\\fP") + plain=0 + } + add(words[w]) + } else { + if(!plain) { + add("\\fB") + plain=1 + } + add(words[w]) + } + if(!nospace) + add(OFS) + } + sub(" $","",line) + if(plain) + add("\\fP") + } else if(match(words[w],"^Bl$")) { + oldoptlist=optlist + if(match(words[w+1],"-bullet")) + optlist=1 + else if(match(words[w+1],"-enum")) { + optlist=2 + enum=0 + } else if(match(words[w+1],"-tag")) + optlist=3 + else if(match(words[w+1],"-item")) + optlist=4 + else if(match(words[w+1],"-bullet")) + optlist=1 + w=nwords + } else if(match(words[w],"^El$")) { + optlist=oldoptlist + } else if(match(words[w],"^Bk$")) { + if(match(words[w+1],"-words")) { + w++ + breakw=1 + } + } else if(match(words[w],"^Ek$")) { + breakw=0 + } else if(match(words[w],"^It$")&&optlist) { + if(optlist==1) + add(".IP \\(bu") + else if(optlist==2) + add(".IP " ++enum ".") + else if(optlist==3) { + add(".TP") + prenl++ + if(match(words[w+1],"^Pa$|^Ev$")) { + add(".B") + w++ + } + } else if(optlist==4) + add(".IP") + } else if(match(words[w],"^Sm$")) { + if(match(words[w+1],"off")) + nospace=2 + else if(match(words[w+1],"on")) + nospace=0 + w++ + } else if(!skip) { + add(words[w]) + } + } + if(match(line,"^\\.[^a-zA-Z]")) + sub("^\\.","",line) + if(parens) + add(")") + if(angles) + add(">") + if(option) + add("]") + if(ext&&!extopt&&!match(line," $")) + add(OFS) + if(!ext&&!extopt&&length(line)) { + print line + prenl=0 + line="" + } +}
diff --git a/openssh-6.0p1/misc.c b/openssh-6.0p1/misc.c new file mode 100644 index 0000000..a7a23dc --- /dev/null +++ b/openssh-6.0p1/misc.c
@@ -0,0 +1,1011 @@ +/* $OpenBSD: misc.c,v 1.86 2011/09/05 05:59:08 djm 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 <sys/types.h> +#include <sys/ioctl.h> +#include <sys/socket.h> +#include <sys/param.h> + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> + +#include <netinet/in.h> +#include <netinet/in_systm.h> +#include <netinet/ip.h> +#include <netinet/tcp.h> + +#include <errno.h> +#include <fcntl.h> +#include <netdb.h> +#ifdef HAVE_PATHS_H +# include <paths.h> +#include <pwd.h> +#endif +#ifdef SSH_TUN_OPENBSD +#include <net/if.h> +#endif + +#include "xmalloc.h" +#include "misc.h" +#include "log.h" +#include "ssh.h" + +/* remove newline at end of string */ +char * +chop(char *s) +{ + char *t = s; + while (*t) { + if (*t == '\n' || *t == '\r') { + *t = '\0'; + return s; + } + t++; + } + return s; + +} + +/* set/unset filedescriptor to non-blocking */ +int +set_nonblock(int fd) +{ + int val; + + val = fcntl(fd, F_GETFL, 0); + if (val < 0) { + error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno)); + return (-1); + } + if (val & O_NONBLOCK) { + debug3("fd %d is O_NONBLOCK", fd); + return (0); + } + debug2("fd %d setting O_NONBLOCK", fd); + val |= O_NONBLOCK; + if (fcntl(fd, F_SETFL, val) == -1) { + debug("fcntl(%d, F_SETFL, O_NONBLOCK): %s", fd, + strerror(errno)); + return (-1); + } + return (0); +} + +int +unset_nonblock(int fd) +{ + int val; + + val = fcntl(fd, F_GETFL, 0); + if (val < 0) { + error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno)); + return (-1); + } + if (!(val & O_NONBLOCK)) { + debug3("fd %d is not O_NONBLOCK", fd); + return (0); + } + debug("fd %d clearing O_NONBLOCK", fd); + val &= ~O_NONBLOCK; + if (fcntl(fd, F_SETFL, val) == -1) { + debug("fcntl(%d, F_SETFL, ~O_NONBLOCK): %s", + fd, strerror(errno)); + return (-1); + } + return (0); +} + +const char * +ssh_gai_strerror(int gaierr) +{ + if (gaierr == EAI_SYSTEM) + 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); + copy->pw_gecos = xstrdup(pw->pw_gecos); + copy->pw_uid = pw->pw_uid; + copy->pw_gid = pw->pw_gid; +#ifdef HAVE_PW_EXPIRE_IN_PASSWD + copy->pw_expire = pw->pw_expire; +#endif +#ifdef HAVE_PW_CHANGE_IN_PASSWD + copy->pw_change = pw->pw_change; +#endif +#ifdef HAVE_PW_CLASS_IN_PASSWD + 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) { + xfree(sp); + return (a2tun(s, NULL)); + } + ep[0] = '\0'; ep++; + *remote = a2tun(ep, NULL); + tun = a2tun(sp, NULL); + xfree(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: + * <none> seconds + * s|S seconds + * m|M minutes + * h|H hours + * d|D days + * w|W weeks + * + * Examples: + * 90m 90 minutes + * 1h30m 90 minutes + * 2d 2 days + * 1w 1 week + * + * Return -1 if time string is invalid. + */ +long +convtime(const char *s) +{ + long total, secs; + const char *p; + char *endp; + + errno = 0; + total = 0; + p = s; + + if (p == NULL || *p == '\0') + return -1; + + while (*p) { + secs = strtol(p, &endp, 10); + if (p == endp || + (errno == ERANGE && (secs == LONG_MIN || secs == LONG_MAX)) || + secs < 0) + return -1; + + switch (*endp++) { + case '\0': + endp--; + break; + case 's': + case 'S': + break; + case 'm': + case 'M': + secs *= MINUTES; + break; + case 'h': + case 'H': + secs *= HOURS; + break; + case 'd': + case 'D': + secs *= DAYS; + break; + case 'w': + case 'W': + secs *= WEEKS; + break; + default: + return -1; + } + total += secs; + if (total < 0) + return -1; + p = endp; + } + + return total; +} + +/* + * Returns a standardized host+port identifier string. + * Caller must free returned string. + */ +char * +put_host_port(const char *host, u_short port) +{ + char *hoststr; + + if (port == 0 || port == SSH_DEFAULT_PORT) + return(xstrdup(host)); + if (asprintf(&hoststr, "[%s]:%d", host, (int)port) < 0) + fatal("put_host_port: asprintf: %s", strerror(errno)); + debug3("put_host_port: %s", hoststr); + return hoststr; +} + +/* + * Search for next delimiter between hostnames/addresses and ports. + * Argument may be modified (for termination). + * Returns *cp if parsing succeeds. + * *cp is set to the start of the next delimiter, if one was found. + * If this is the last field, *cp is set to NULL. + */ +char * +hpdelim(char **cp) +{ + char *s, *old; + + if (cp == NULL || *cp == NULL) + return NULL; + + old = s = *cp; + if (*s == '[') { + if ((s = strchr(s, ']')) == NULL) + return NULL; + else + s++; + } else if ((s = strpbrk(s, ":/")) == NULL) + s = *cp + strlen(*cp); /* skip to end (see first case below) */ + + switch (*s) { + case '\0': + *cp = NULL; /* no more fields*/ + break; + + case ':': + case '/': + *s = '\0'; /* terminate */ + *cp = s + 1; + break; + + default: + return NULL; + } + + return old; +} + +char * +cleanhostname(char *host) +{ + if (*host == '[' && host[strlen(host) - 1] == ']') { + host[strlen(host) - 1] = '\0'; + return (host + 1); + } else + return host; +} + +char * +colon(char *cp) +{ + int flag = 0; + + if (*cp == ':') /* Leading colon is part of file name. */ + return NULL; + if (*cp == '[') + flag = 1; + + for (; *cp; ++cp) { + if (*cp == '@' && *(cp+1) == '[') + flag = 1; + if (*cp == ']' && *(cp+1) == ':' && flag) + return (cp+1); + if (*cp == ':' && !flag) + return (cp); + if (*cp == '/') + return NULL; + } + return NULL; +} + +/* function to assist building execv() arguments */ +void +addargs(arglist *args, char *fmt, ...) +{ + va_list ap; + char *cp; + u_int nalloc; + int r; + + va_start(ap, fmt); + r = vasprintf(&cp, fmt, ap); + va_end(ap); + if (r == -1) + fatal("addargs: argument too long"); + + nalloc = args->nalloc; + if (args->list == NULL) { + nalloc = 32; + args->num = 0; + } else if (args->num+2 >= nalloc) + nalloc *= 2; + + args->list = xrealloc(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); + xfree(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++) + xfree(args->list[i]); + xfree(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; + char user[128], ret[MAXPATHLEN]; + 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); + + if (strlcpy(ret, pw->pw_dir, sizeof(ret)) >= sizeof(ret)) + fatal("tilde_expand_filename: Path too long"); + + /* Make sure directory has a trailing '/' */ + len = strlen(pw->pw_dir); + if ((len == 0 || pw->pw_dir[len - 1] != '/') && + strlcat(ret, "/", sizeof(ret)) >= sizeof(ret)) + fatal("tilde_expand_filename: Path too long"); + + /* Skip leading '/' from specified path */ + if (path != NULL) + filename = path + 1; + if (strlcat(ret, filename, sizeof(ret)) >= sizeof(ret)) + fatal("tilde_expand_filename: Path too long"); + + return (xstrdup(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; + 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; + + /* Open the tunnel device */ + if (tun <= SSH_TUNID_MAX) { + snprintf(name, sizeof(name), "/dev/tun%d", tun); + fd = open(name, O_RDWR); + } else if (tun == SSH_TUNID_ANY) { + for (tun = 100; tun >= 0; tun--) { + snprintf(name, sizeof(name), "/dev/tun%d", 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 failed: %s", __func__, name, strerror(errno)); + return (-1); + } + + 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), "tun%d", tun); + if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) + goto failed; + + if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) + goto failed; + + /* Set interface mode */ + ifr.ifr_flags &= ~IFF_UP; + if (mode == SSH_TUNMODE_ETHERNET) + ifr.ifr_flags |= IFF_LINK0; + else + ifr.ifr_flags &= ~IFF_LINK0; + if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) + goto failed; + + /* Bring interface up */ + 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); +#else + error("Tunnel interfaces are not supported on this platform"); + return (-1); +#endif +} + +void +sanitise_stdfd(void) +{ + int nullfd, dupfd; + + if ((nullfd = dupfd = open(_PATH_DEVNULL, O_RDWR)) == -1) { + fprintf(stderr, "Couldn't open /dev/null: %s\n", + strerror(errno)); + exit(1); + } + while (++dupfd <= 2) { + /* Only clobber closed fds */ + if (fcntl(dupfd, F_GETFL, 0) >= 0) + continue; + if (dup2(nullfd, dupfd) == -1) { + fprintf(stderr, "dup2: %s\n", strerror(errno)); + exit(1); + } + } + if (nullfd > 2) + close(nullfd); +} + +char * +tohex(const void *vp, size_t l) +{ + const u_char *p = (const u_char *)vp; + char b[3], *r; + size_t i, hl; + + if (l > 65536) + return xstrdup("tohex: length > 65536"); + + hl = l * 2 + 1; + r = xcalloc(1, hl); + for (i = 0; i < l; i++) { + snprintf(b, sizeof(b), "%02x", p[i]); + strlcat(r, b, hl); + } + return (r); +} + +u_int64_t +get_u64(const void *vp) +{ + const u_char *p = (const u_char *)vp; + u_int64_t v; + + v = (u_int64_t)p[0] << 56; + v |= (u_int64_t)p[1] << 48; + v |= (u_int64_t)p[2] << 40; + v |= (u_int64_t)p[3] << 32; + v |= (u_int64_t)p[4] << 24; + v |= (u_int64_t)p[5] << 16; + v |= (u_int64_t)p[6] << 8; + v |= (u_int64_t)p[7]; + + return (v); +} + +u_int32_t +get_u32(const void *vp) +{ + const u_char *p = (const u_char *)vp; + u_int32_t v; + + v = (u_int32_t)p[0] << 24; + v |= (u_int32_t)p[1] << 16; + v |= (u_int32_t)p[2] << 8; + v |= (u_int32_t)p[3]; + + return (v); +} + +u_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_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; +} + +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 +sock_set_v6only(int s) +{ +#ifdef IPV6_V6ONLY + 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 +}
diff --git a/openssh-6.0p1/misc.h b/openssh-6.0p1/misc.h new file mode 100644 index 0000000..f3142a9 --- /dev/null +++ b/openssh-6.0p1/misc.h
@@ -0,0 +1,106 @@ +/* $OpenBSD: misc.h,v 1.48 2011/03/29 18:54:17 stevesk Exp $ */ + +/* + * Author: Tatu Ylonen <ylo@cs.hut.fi> + * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland + * All rights reserved + * + * As far as I am concerned, the code I have written for this software + * can be used freely for any purpose. Any derived versions of this + * software must be clearly marked as such, and if the derived work is + * incompatible with the protocol description in the RFC file, it must be + * called by a name other than "ssh" or "Secure Shell". + */ + +#ifndef _MISC_H +#define _MISC_H + +/* misc.c */ + +char *chop(char *); +char *strdelim(char **); +int set_nonblock(int); +int unset_nonblock(int); +void set_nodelay(int); +int a2port(const char *); +int a2tun(const char *, int *); +char *put_host_port(const char *, u_short); +char *hpdelim(char **); +char *cleanhostname(char *); +char *colon(char *); +long convtime(const char *); +char *tilde_expand_filename(const char *, uid_t); +char *percent_expand(const char *, ...) __attribute__((__sentinel__)); +char *tohex(const void *, size_t); +void sanitise_stdfd(void); +void ms_subtract_diff(struct timeval *, int *); +void ms_to_timeval(struct timeval *, int); +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) + +/* 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))); + +struct bwlimit { + size_t buflen; + u_int64_t rate, thresh, lamt; + struct timeval bwstart, bwend; +}; + +void bandwidth_limit_init(struct bwlimit *, u_int64_t, size_t); +void bandwidth_limit(struct bwlimit *, size_t); + +int parse_ipqos(const char *); +const char *iptos2str(int); +void mktemp_proto(char *, size_t); + +/* readpass.c */ + +#define RP_ECHO 0x0001 +#define RP_ALLOW_STDIN 0x0002 +#define RP_ALLOW_EOF 0x0004 +#define RP_USE_ASKPASS 0x0008 + +char *read_passphrase(const char *, int); +int ask_permission(const char *, ...) __attribute__((format(printf, 1, 2))); +int read_keyfile_line(FILE *, const char *, char *, size_t, u_long *); + +#endif /* _MISC_H */
diff --git a/openssh-6.0p1/mkinstalldirs b/openssh-6.0p1/mkinstalldirs new file mode 100755 index 0000000..47d5f43 --- /dev/null +++ b/openssh-6.0p1/mkinstalldirs
@@ -0,0 +1,40 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman <friedman@prep.ai.mit.edu> +# 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
diff --git a/openssh-6.0p1/moduli b/openssh-6.0p1/moduli new file mode 100644 index 0000000..f406ad3 --- /dev/null +++ b/openssh-6.0p1/moduli
@@ -0,0 +1,181 @@ +# $OpenBSD: moduli,v 1.6 2011/11/04 00:09:39 dtucker Exp $ +# Time Type Tests Tries Size Generator Modulus +20111016112852 2 6 100 1023 2 FB9AFEB297524D1A7A34A4B67CEF09332DE1CB05711182210425A05D3576E75BEB3A3D3CC99389609E5434DBC6CFF6ECAD6B54F4351C4D0BAB3BEDD2AE936AFD22226C62254B8C8C0ED8189C0CC54634956F93600351610A3EAF60C0FDBCD61384FB161BE50E0F0BB0F1AC522044E44361870D6A2BC871BC94B529EAC20B3343 +20111016112853 2 6 100 1023 2 FB9AFEB297524D1A7A34A4B67CEF09332DE1CB05711182210425A05D3576E75BEB3A3D3CC99389609E5434DBC6CFF6ECAD6B54F4351C4D0BAB3BEDD2AE936AFD22226C62254B8C8C0ED8189C0CC54634956F93600351610A3EAF60C0FDBCD61384FB161BE50E0F0BB0F1AC522044E44361870D6A2BC871BC94B529EAC20E815B +20111016112857 2 6 100 1023 5 FB9AFEB297524D1A7A34A4B67CEF09332DE1CB05711182210425A05D3576E75BEB3A3D3CC99389609E5434DBC6CFF6ECAD6B54F4351C4D0BAB3BEDD2AE936AFD22226C62254B8C8C0ED8189C0CC54634956F93600351610A3EAF60C0FDBCD61384FB161BE50E0F0BB0F1AC522044E44361870D6A2BC871BC94B529EAC227B937 +20111016112858 2 6 100 1023 5 FB9AFEB297524D1A7A34A4B67CEF09332DE1CB05711182210425A05D3576E75BEB3A3D3CC99389609E5434DBC6CFF6ECAD6B54F4351C4D0BAB3BEDD2AE936AFD22226C62254B8C8C0ED8189C0CC54634956F93600351610A3EAF60C0FDBCD61384FB161BE50E0F0BB0F1AC522044E44361870D6A2BC871BC94B529EAC22951DF +20111016112901 2 6 100 1023 5 FB9AFEB297524D1A7A34A4B67CEF09332DE1CB05711182210425A05D3576E75BEB3A3D3CC99389609E5434DBC6CFF6ECAD6B54F4351C4D0BAB3BEDD2AE936AFD22226C62254B8C8C0ED8189C0CC54634956F93600351610A3EAF60C0FDBCD61384FB161BE50E0F0BB0F1AC522044E44361870D6A2BC871BC94B529EAC232013F +20111016112907 2 6 100 1023 2 FB9AFEB297524D1A7A34A4B67CEF09332DE1CB05711182210425A05D3576E75BEB3A3D3CC99389609E5434DBC6CFF6ECAD6B54F4351C4D0BAB3BEDD2AE936AFD22226C62254B8C8C0ED8189C0CC54634956F93600351610A3EAF60C0FDBCD61384FB161BE50E0F0BB0F1AC522044E44361870D6A2BC871BC94B529EAC25EA68B +20111016112910 2 6 100 1023 2 FB9AFEB297524D1A7A34A4B67CEF09332DE1CB05711182210425A05D3576E75BEB3A3D3CC99389609E5434DBC6CFF6ECAD6B54F4351C4D0BAB3BEDD2AE936AFD22226C62254B8C8C0ED8189C0CC54634956F93600351610A3EAF60C0FDBCD61384FB161BE50E0F0BB0F1AC522044E44361870D6A2BC871BC94B529EAC26E9CA3 +20111016112912 2 6 100 1023 5 FB9AFEB297524D1A7A34A4B67CEF09332DE1CB05711182210425A05D3576E75BEB3A3D3CC99389609E5434DBC6CFF6ECAD6B54F4351C4D0BAB3BEDD2AE936AFD22226C62254B8C8C0ED8189C0CC54634956F93600351610A3EAF60C0FDBCD61384FB161BE50E0F0BB0F1AC522044E44361870D6A2BC871BC94B529EAC26F5C7F +20111016112915 2 6 100 1023 2 FB9AFEB297524D1A7A34A4B67CEF09332DE1CB05711182210425A05D3576E75BEB3A3D3CC99389609E5434DBC6CFF6ECAD6B54F4351C4D0BAB3BEDD2AE936AFD22226C62254B8C8C0ED8189C0CC54634956F93600351610A3EAF60C0FDBCD61384FB161BE50E0F0BB0F1AC522044E44361870D6A2BC871BC94B529EAC27EC0F3 +20111016112918 2 6 100 1023 2 FB9AFEB297524D1A7A34A4B67CEF09332DE1CB05711182210425A05D3576E75BEB3A3D3CC99389609E5434DBC6CFF6ECAD6B54F4351C4D0BAB3BEDD2AE936AFD22226C62254B8C8C0ED8189C0CC54634956F93600351610A3EAF60C0FDBCD61384FB161BE50E0F0BB0F1AC522044E44361870D6A2BC871BC94B529EAC28E4883 +20111016112919 2 6 100 1023 2 FB9AFEB297524D1A7A34A4B67CEF09332DE1CB05711182210425A05D3576E75BEB3A3D3CC99389609E5434DBC6CFF6ECAD6B54F4351C4D0BAB3BEDD2AE936AFD22226C62254B8C8C0ED8189C0CC54634956F93600351610A3EAF60C0FDBCD61384FB161BE50E0F0BB0F1AC522044E44361870D6A2BC871BC94B529EAC293907B +20111016112920 2 6 100 1023 2 FB9AFEB297524D1A7A34A4B67CEF09332DE1CB05711182210425A05D3576E75BEB3A3D3CC99389609E5434DBC6CFF6ECAD6B54F4351C4D0BAB3BEDD2AE936AFD22226C62254B8C8C0ED8189C0CC54634956F93600351610A3EAF60C0FDBCD61384FB161BE50E0F0BB0F1AC522044E44361870D6A2BC871BC94B529EAC293F2D3 +20111016112922 2 6 100 1023 5 FB9AFEB297524D1A7A34A4B67CEF09332DE1CB05711182210425A05D3576E75BEB3A3D3CC99389609E5434DBC6CFF6ECAD6B54F4351C4D0BAB3BEDD2AE936AFD22226C62254B8C8C0ED8189C0CC54634956F93600351610A3EAF60C0FDBCD61384FB161BE50E0F0BB0F1AC522044E44361870D6A2BC871BC94B529EAC29C3C9F +20111016112924 2 6 100 1023 2 FB9AFEB297524D1A7A34A4B67CEF09332DE1CB05711182210425A05D3576E75BEB3A3D3CC99389609E5434DBC6CFF6ECAD6B54F4351C4D0BAB3BEDD2AE936AFD22226C62254B8C8C0ED8189C0CC54634956F93600351610A3EAF60C0FDBCD61384FB161BE50E0F0BB0F1AC522044E44361870D6A2BC871BC94B529EAC2A020F3 +20111016112927 2 6 100 1023 2 FB9AFEB297524D1A7A34A4B67CEF09332DE1CB05711182210425A05D3576E75BEB3A3D3CC99389609E5434DBC6CFF6ECAD6B54F4351C4D0BAB3BEDD2AE936AFD22226C62254B8C8C0ED8189C0CC54634956F93600351610A3EAF60C0FDBCD61384FB161BE50E0F0BB0F1AC522044E44361870D6A2BC871BC94B529EAC2B2E52B +20111016112932 2 6 100 1023 5 FB9AFEB297524D1A7A34A4B67CEF09332DE1CB05711182210425A05D3576E75BEB3A3D3CC99389609E5434DBC6CFF6ECAD6B54F4351C4D0BAB3BEDD2AE936AFD22226C62254B8C8C0ED8189C0CC54634956F93600351610A3EAF60C0FDBCD61384FB161BE50E0F0BB0F1AC522044E44361870D6A2BC871BC94B529EAC2D1F8A7 +20111016112936 2 6 100 1023 5 FB9AFEB297524D1A7A34A4B67CEF09332DE1CB05711182210425A05D3576E75BEB3A3D3CC99389609E5434DBC6CFF6ECAD6B54F4351C4D0BAB3BEDD2AE936AFD22226C62254B8C8C0ED8189C0CC54634956F93600351610A3EAF60C0FDBCD61384FB161BE50E0F0BB0F1AC522044E44361870D6A2BC871BC94B529EAC2E52A8F +20111016112939 2 6 100 1023 5 FB9AFEB297524D1A7A34A4B67CEF09332DE1CB05711182210425A05D3576E75BEB3A3D3CC99389609E5434DBC6CFF6ECAD6B54F4351C4D0BAB3BEDD2AE936AFD22226C62254B8C8C0ED8189C0CC54634956F93600351610A3EAF60C0FDBCD61384FB161BE50E0F0BB0F1AC522044E44361870D6A2BC871BC94B529EAC2F531FF +20111016112940 2 6 100 1023 2 FB9AFEB297524D1A7A34A4B67CEF09332DE1CB05711182210425A05D3576E75BEB3A3D3CC99389609E5434DBC6CFF6ECAD6B54F4351C4D0BAB3BEDD2AE936AFD22226C62254B8C8C0ED8189C0CC54634956F93600351610A3EAF60C0FDBCD61384FB161BE50E0F0BB0F1AC522044E44361870D6A2BC871BC94B529EAC2F8A183 +20111016112942 2 6 100 1023 2 FB9AFEB297524D1A7A34A4B67CEF09332DE1CB05711182210425A05D3576E75BEB3A3D3CC99389609E5434DBC6CFF6ECAD6B54F4351C4D0BAB3BEDD2AE936AFD22226C62254B8C8C0ED8189C0CC54634956F93600351610A3EAF60C0FDBCD61384FB161BE50E0F0BB0F1AC522044E44361870D6A2BC871BC94B529EAC2FAFF83 +20111016112943 2 6 100 1023 5 FB9AFEB297524D1A7A34A4B67CEF09332DE1CB05711182210425A05D3576E75BEB3A3D3CC99389609E5434DBC6CFF6ECAD6B54F4351C4D0BAB3BEDD2AE936AFD22226C62254B8C8C0ED8189C0CC54634956F93600351610A3EAF60C0FDBCD61384FB161BE50E0F0BB0F1AC522044E44361870D6A2BC871BC94B529EAC2FBA567 +20111016112944 2 6 100 1023 5 FB9AFEB297524D1A7A34A4B67CEF09332DE1CB05711182210425A05D3576E75BEB3A3D3CC99389609E5434DBC6CFF6ECAD6B54F4351C4D0BAB3BEDD2AE936AFD22226C62254B8C8C0ED8189C0CC54634956F93600351610A3EAF60C0FDBCD61384FB161BE50E0F0BB0F1AC522044E44361870D6A2BC871BC94B529EAC2FF5EBF +20111016112946 2 6 100 1023 5 FB9AFEB297524D1A7A34A4B67CEF09332DE1CB05711182210425A05D3576E75BEB3A3D3CC99389609E5434DBC6CFF6ECAD6B54F4351C4D0BAB3BEDD2AE936AFD22226C62254B8C8C0ED8189C0CC54634956F93600351610A3EAF60C0FDBCD61384FB161BE50E0F0BB0F1AC522044E44361870D6A2BC871BC94B529EAC30837D7 +20111016112948 2 6 100 1023 2 FB9AFEB297524D1A7A34A4B67CEF09332DE1CB05711182210425A05D3576E75BEB3A3D3CC99389609E5434DBC6CFF6ECAD6B54F4351C4D0BAB3BEDD2AE936AFD22226C62254B8C8C0ED8189C0CC54634956F93600351610A3EAF60C0FDBCD61384FB161BE50E0F0BB0F1AC522044E44361870D6A2BC871BC94B529EAC30F7B9B +20111016112949 2 6 100 1023 2 FB9AFEB297524D1A7A34A4B67CEF09332DE1CB05711182210425A05D3576E75BEB3A3D3CC99389609E5434DBC6CFF6ECAD6B54F4351C4D0BAB3BEDD2AE936AFD22226C62254B8C8C0ED8189C0CC54634956F93600351610A3EAF60C0FDBCD61384FB161BE50E0F0BB0F1AC522044E44361870D6A2BC871BC94B529EAC3107A6B +20111016112956 2 6 100 1023 2 FB9AFEB297524D1A7A34A4B67CEF09332DE1CB05711182210425A05D3576E75BEB3A3D3CC99389609E5434DBC6CFF6ECAD6B54F4351C4D0BAB3BEDD2AE936AFD22226C62254B8C8C0ED8189C0CC54634956F93600351610A3EAF60C0FDBCD61384FB161BE50E0F0BB0F1AC522044E44361870D6A2BC871BC94B529EAC33BD083 +20111016112958 2 6 100 1023 2 FB9AFEB297524D1A7A34A4B67CEF09332DE1CB05711182210425A05D3576E75BEB3A3D3CC99389609E5434DBC6CFF6ECAD6B54F4351C4D0BAB3BEDD2AE936AFD22226C62254B8C8C0ED8189C0CC54634956F93600351610A3EAF60C0FDBCD61384FB161BE50E0F0BB0F1AC522044E44361870D6A2BC871BC94B529EAC33E8433 +20111016113002 2 6 100 1023 2 FB9AFEB297524D1A7A34A4B67CEF09332DE1CB05711182210425A05D3576E75BEB3A3D3CC99389609E5434DBC6CFF6ECAD6B54F4351C4D0BAB3BEDD2AE936AFD22226C62254B8C8C0ED8189C0CC54634956F93600351610A3EAF60C0FDBCD61384FB161BE50E0F0BB0F1AC522044E44361870D6A2BC871BC94B529EAC3531E4B +20111016113005 2 6 100 1023 2 FB9AFEB297524D1A7A34A4B67CEF09332DE1CB05711182210425A05D3576E75BEB3A3D3CC99389609E5434DBC6CFF6ECAD6B54F4351C4D0BAB3BEDD2AE936AFD22226C62254B8C8C0ED8189C0CC54634956F93600351610A3EAF60C0FDBCD61384FB161BE50E0F0BB0F1AC522044E44361870D6A2BC871BC94B529EAC368DF0B +20111016113006 2 6 100 1023 5 FB9AFEB297524D1A7A34A4B67CEF09332DE1CB05711182210425A05D3576E75BEB3A3D3CC99389609E5434DBC6CFF6ECAD6B54F4351C4D0BAB3BEDD2AE936AFD22226C62254B8C8C0ED8189C0CC54634956F93600351610A3EAF60C0FDBCD61384FB161BE50E0F0BB0F1AC522044E44361870D6A2BC871BC94B529EAC369E717 +20111016113009 2 6 100 1023 5 FB9AFEB297524D1A7A34A4B67CEF09332DE1CB05711182210425A05D3576E75BEB3A3D3CC99389609E5434DBC6CFF6ECAD6B54F4351C4D0BAB3BEDD2AE936AFD22226C62254B8C8C0ED8189C0CC54634956F93600351610A3EAF60C0FDBCD61384FB161BE50E0F0BB0F1AC522044E44361870D6A2BC871BC94B529EAC3726167 +20111016113015 2 6 100 1023 2 FB9AFEB297524D1A7A34A4B67CEF09332DE1CB05711182210425A05D3576E75BEB3A3D3CC99389609E5434DBC6CFF6ECAD6B54F4351C4D0BAB3BEDD2AE936AFD22226C62254B8C8C0ED8189C0CC54634956F93600351610A3EAF60C0FDBCD61384FB161BE50E0F0BB0F1AC522044E44361870D6A2BC871BC94B529EAC39FAE6B +20111016113019 2 6 100 1023 2 FB9AFEB297524D1A7A34A4B67CEF09332DE1CB05711182210425A05D3576E75BEB3A3D3CC99389609E5434DBC6CFF6ECAD6B54F4351C4D0BAB3BEDD2AE936AFD22226C62254B8C8C0ED8189C0CC54634956F93600351610A3EAF60C0FDBCD61384FB161BE50E0F0BB0F1AC522044E44361870D6A2BC871BC94B529EAC3B05733 +20111016113023 2 6 100 1023 5 FB9AFEB297524D1A7A34A4B67CEF09332DE1CB05711182210425A05D3576E75BEB3A3D3CC99389609E5434DBC6CFF6ECAD6B54F4351C4D0BAB3BEDD2AE936AFD22226C62254B8C8C0ED8189C0CC54634956F93600351610A3EAF60C0FDBCD61384FB161BE50E0F0BB0F1AC522044E44361870D6A2BC871BC94B529EAC3C8342F +20111016113025 2 6 100 1023 5 FB9AFEB297524D1A7A34A4B67CEF09332DE1CB05711182210425A05D3576E75BEB3A3D3CC99389609E5434DBC6CFF6ECAD6B54F4351C4D0BAB3BEDD2AE936AFD22226C62254B8C8C0ED8189C0CC54634956F93600351610A3EAF60C0FDBCD61384FB161BE50E0F0BB0F1AC522044E44361870D6A2BC871BC94B529EAC3D0A24F +20111016113029 2 6 100 1023 2 FB9AFEB297524D1A7A34A4B67CEF09332DE1CB05711182210425A05D3576E75BEB3A3D3CC99389609E5434DBC6CFF6ECAD6B54F4351C4D0BAB3BEDD2AE936AFD22226C62254B8C8C0ED8189C0CC54634956F93600351610A3EAF60C0FDBCD61384FB161BE50E0F0BB0F1AC522044E44361870D6A2BC871BC94B529EAC3ED114B +20111016113557 2 6 100 1535 2 F62191A170EC6171C620D3B334952F220077AA5C0FA7F1A7FE08C6B7B0C5F865CDB24346E3BE05B99E2D7FCC3582D0D2D637672EB0EB1DBB95BCE1A0CA54DFC83EBF598A24928CA42A5ABC2AE75E9802451B0C9E180D5D52698DAAF79DA3B968F72B48DA1D04246EA07C2FAD367392C458D34FA17DAA04C22975E417ABD18FC6407D0A04300D521A8A867FE850EB9BA6F1AD32084856AAFDE112247F20579F74950EFA36A803A47134BBF024F561DDE90042A5AF2547ED9520BE77AFB1048043 +20111016113618 2 6 100 1535 5 F62191A170EC6171C620D3B334952F220077AA5C0FA7F1A7FE08C6B7B0C5F865CDB24346E3BE05B99E2D7FCC3582D0D2D637672EB0EB1DBB95BCE1A0CA54DFC83EBF598A24928CA42A5ABC2AE75E9802451B0C9E180D5D52698DAAF79DA3B968F72B48DA1D04246EA07C2FAD367392C458D34FA17DAA04C22975E417ABD18FC6407D0A04300D521A8A867FE850EB9BA6F1AD32084856AAFDE112247F20579F74950EFA36A803A47134BBF024F561DDE90042A5AF2547ED9520BE77AFB1338BFF +20111016113627 2 6 100 1535 2 F62191A170EC6171C620D3B334952F220077AA5C0FA7F1A7FE08C6B7B0C5F865CDB24346E3BE05B99E2D7FCC3582D0D2D637672EB0EB1DBB95BCE1A0CA54DFC83EBF598A24928CA42A5ABC2AE75E9802451B0C9E180D5D52698DAAF79DA3B968F72B48DA1D04246EA07C2FAD367392C458D34FA17DAA04C22975E417ABD18FC6407D0A04300D521A8A867FE850EB9BA6F1AD32084856AAFDE112247F20579F74950EFA36A803A47134BBF024F561DDE90042A5AF2547ED9520BE77AFB140EEE3 +20111016113640 2 6 100 1535 5 F62191A170EC6171C620D3B334952F220077AA5C0FA7F1A7FE08C6B7B0C5F865CDB24346E3BE05B99E2D7FCC3582D0D2D637672EB0EB1DBB95BCE1A0CA54DFC83EBF598A24928CA42A5ABC2AE75E9802451B0C9E180D5D52698DAAF79DA3B968F72B48DA1D04246EA07C2FAD367392C458D34FA17DAA04C22975E417ABD18FC6407D0A04300D521A8A867FE850EB9BA6F1AD32084856AAFDE112247F20579F74950EFA36A803A47134BBF024F561DDE90042A5AF2547ED9520BE77AFB15B201F +20111016113645 2 6 100 1535 2 F62191A170EC6171C620D3B334952F220077AA5C0FA7F1A7FE08C6B7B0C5F865CDB24346E3BE05B99E2D7FCC3582D0D2D637672EB0EB1DBB95BCE1A0CA54DFC83EBF598A24928CA42A5ABC2AE75E9802451B0C9E180D5D52698DAAF79DA3B968F72B48DA1D04246EA07C2FAD367392C458D34FA17DAA04C22975E417ABD18FC6407D0A04300D521A8A867FE850EB9BA6F1AD32084856AAFDE112247F20579F74950EFA36A803A47134BBF024F561DDE90042A5AF2547ED9520BE77AFB1605C6B +20111016113651 2 6 100 1535 2 F62191A170EC6171C620D3B334952F220077AA5C0FA7F1A7FE08C6B7B0C5F865CDB24346E3BE05B99E2D7FCC3582D0D2D637672EB0EB1DBB95BCE1A0CA54DFC83EBF598A24928CA42A5ABC2AE75E9802451B0C9E180D5D52698DAAF79DA3B968F72B48DA1D04246EA07C2FAD367392C458D34FA17DAA04C22975E417ABD18FC6407D0A04300D521A8A867FE850EB9BA6F1AD32084856AAFDE112247F20579F74950EFA36A803A47134BBF024F561DDE90042A5AF2547ED9520BE77AFB1670D23 +20111016113700 2 6 100 1535 5 F62191A170EC6171C620D3B334952F220077AA5C0FA7F1A7FE08C6B7B0C5F865CDB24346E3BE05B99E2D7FCC3582D0D2D637672EB0EB1DBB95BCE1A0CA54DFC83EBF598A24928CA42A5ABC2AE75E9802451B0C9E180D5D52698DAAF79DA3B968F72B48DA1D04246EA07C2FAD367392C458D34FA17DAA04C22975E417ABD18FC6407D0A04300D521A8A867FE850EB9BA6F1AD32084856AAFDE112247F20579F74950EFA36A803A47134BBF024F561DDE90042A5AF2547ED9520BE77AFB17783FF +20111016113705 2 6 100 1535 2 F62191A170EC6171C620D3B334952F220077AA5C0FA7F1A7FE08C6B7B0C5F865CDB24346E3BE05B99E2D7FCC3582D0D2D637672EB0EB1DBB95BCE1A0CA54DFC83EBF598A24928CA42A5ABC2AE75E9802451B0C9E180D5D52698DAAF79DA3B968F72B48DA1D04246EA07C2FAD367392C458D34FA17DAA04C22975E417ABD18FC6407D0A04300D521A8A867FE850EB9BA6F1AD32084856AAFDE112247F20579F74950EFA36A803A47134BBF024F561DDE90042A5AF2547ED9520BE77AFB17C11A3 +20111016113709 2 6 100 1535 2 F62191A170EC6171C620D3B334952F220077AA5C0FA7F1A7FE08C6B7B0C5F865CDB24346E3BE05B99E2D7FCC3582D0D2D637672EB0EB1DBB95BCE1A0CA54DFC83EBF598A24928CA42A5ABC2AE75E9802451B0C9E180D5D52698DAAF79DA3B968F72B48DA1D04246EA07C2FAD367392C458D34FA17DAA04C22975E417ABD18FC6407D0A04300D521A8A867FE850EB9BA6F1AD32084856AAFDE112247F20579F74950EFA36A803A47134BBF024F561DDE90042A5AF2547ED9520BE77AFB17DB8BB +20111016113715 2 6 100 1535 2 F62191A170EC6171C620D3B334952F220077AA5C0FA7F1A7FE08C6B7B0C5F865CDB24346E3BE05B99E2D7FCC3582D0D2D637672EB0EB1DBB95BCE1A0CA54DFC83EBF598A24928CA42A5ABC2AE75E9802451B0C9E180D5D52698DAAF79DA3B968F72B48DA1D04246EA07C2FAD367392C458D34FA17DAA04C22975E417ABD18FC6407D0A04300D521A8A867FE850EB9BA6F1AD32084856AAFDE112247F20579F74950EFA36A803A47134BBF024F561DDE90042A5AF2547ED9520BE77AFB18640BB +20111016113801 2 6 100 1535 5 F62191A170EC6171C620D3B334952F220077AA5C0FA7F1A7FE08C6B7B0C5F865CDB24346E3BE05B99E2D7FCC3582D0D2D637672EB0EB1DBB95BCE1A0CA54DFC83EBF598A24928CA42A5ABC2AE75E9802451B0C9E180D5D52698DAAF79DA3B968F72B48DA1D04246EA07C2FAD367392C458D34FA17DAA04C22975E417ABD18FC6407D0A04300D521A8A867FE850EB9BA6F1AD32084856AAFDE112247F20579F74950EFA36A803A47134BBF024F561DDE90042A5AF2547ED9520BE77AFB1F27217 +20111016113812 2 6 100 1535 2 F62191A170EC6171C620D3B334952F220077AA5C0FA7F1A7FE08C6B7B0C5F865CDB24346E3BE05B99E2D7FCC3582D0D2D637672EB0EB1DBB95BCE1A0CA54DFC83EBF598A24928CA42A5ABC2AE75E9802451B0C9E180D5D52698DAAF79DA3B968F72B48DA1D04246EA07C2FAD367392C458D34FA17DAA04C22975E417ABD18FC6407D0A04300D521A8A867FE850EB9BA6F1AD32084856AAFDE112247F20579F74950EFA36A803A47134BBF024F561DDE90042A5AF2547ED9520BE77AFB2057C63 +20111016113819 2 6 100 1535 5 F62191A170EC6171C620D3B334952F220077AA5C0FA7F1A7FE08C6B7B0C5F865CDB24346E3BE05B99E2D7FCC3582D0D2D637672EB0EB1DBB95BCE1A0CA54DFC83EBF598A24928CA42A5ABC2AE75E9802451B0C9E180D5D52698DAAF79DA3B968F72B48DA1D04246EA07C2FAD367392C458D34FA17DAA04C22975E417ABD18FC6407D0A04300D521A8A867FE850EB9BA6F1AD32084856AAFDE112247F20579F74950EFA36A803A47134BBF024F561DDE90042A5AF2547ED9520BE77AFB2122BA7 +20111016113829 2 6 100 1535 2 F62191A170EC6171C620D3B334952F220077AA5C0FA7F1A7FE08C6B7B0C5F865CDB24346E3BE05B99E2D7FCC3582D0D2D637672EB0EB1DBB95BCE1A0CA54DFC83EBF598A24928CA42A5ABC2AE75E9802451B0C9E180D5D52698DAAF79DA3B968F72B48DA1D04246EA07C2FAD367392C458D34FA17DAA04C22975E417ABD18FC6407D0A04300D521A8A867FE850EB9BA6F1AD32084856AAFDE112247F20579F74950EFA36A803A47134BBF024F561DDE90042A5AF2547ED9520BE77AFB2214263 +20111016113904 2 6 100 1535 2 F62191A170EC6171C620D3B334952F220077AA5C0FA7F1A7FE08C6B7B0C5F865CDB24346E3BE05B99E2D7FCC3582D0D2D637672EB0EB1DBB95BCE1A0CA54DFC83EBF598A24928CA42A5ABC2AE75E9802451B0C9E180D5D52698DAAF79DA3B968F72B48DA1D04246EA07C2FAD367392C458D34FA17DAA04C22975E417ABD18FC6407D0A04300D521A8A867FE850EB9BA6F1AD32084856AAFDE112247F20579F74950EFA36A803A47134BBF024F561DDE90042A5AF2547ED9520BE77AFB27621B3 +20111016113912 2 6 100 1535 5 F62191A170EC6171C620D3B334952F220077AA5C0FA7F1A7FE08C6B7B0C5F865CDB24346E3BE05B99E2D7FCC3582D0D2D637672EB0EB1DBB95BCE1A0CA54DFC83EBF598A24928CA42A5ABC2AE75E9802451B0C9E180D5D52698DAAF79DA3B968F72B48DA1D04246EA07C2FAD367392C458D34FA17DAA04C22975E417ABD18FC6407D0A04300D521A8A867FE850EB9BA6F1AD32084856AAFDE112247F20579F74950EFA36A803A47134BBF024F561DDE90042A5AF2547ED9520BE77AFB27F8CE7 +20111016113940 2 6 100 1535 2 F62191A170EC6171C620D3B334952F220077AA5C0FA7F1A7FE08C6B7B0C5F865CDB24346E3BE05B99E2D7FCC3582D0D2D637672EB0EB1DBB95BCE1A0CA54DFC83EBF598A24928CA42A5ABC2AE75E9802451B0C9E180D5D52698DAAF79DA3B968F72B48DA1D04246EA07C2FAD367392C458D34FA17DAA04C22975E417ABD18FC6407D0A04300D521A8A867FE850EB9BA6F1AD32084856AAFDE112247F20579F74950EFA36A803A47134BBF024F561DDE90042A5AF2547ED9520BE77AFB2BFB33B +20111016113948 2 6 100 1535 2 F62191A170EC6171C620D3B334952F220077AA5C0FA7F1A7FE08C6B7B0C5F865CDB24346E3BE05B99E2D7FCC3582D0D2D637672EB0EB1DBB95BCE1A0CA54DFC83EBF598A24928CA42A5ABC2AE75E9802451B0C9E180D5D52698DAAF79DA3B968F72B48DA1D04246EA07C2FAD367392C458D34FA17DAA04C22975E417ABD18FC6407D0A04300D521A8A867FE850EB9BA6F1AD32084856AAFDE112247F20579F74950EFA36A803A47134BBF024F561DDE90042A5AF2547ED9520BE77AFB2CCE95B +20111016114034 2 6 100 1535 5 F62191A170EC6171C620D3B334952F220077AA5C0FA7F1A7FE08C6B7B0C5F865CDB24346E3BE05B99E2D7FCC3582D0D2D637672EB0EB1DBB95BCE1A0CA54DFC83EBF598A24928CA42A5ABC2AE75E9802451B0C9E180D5D52698DAAF79DA3B968F72B48DA1D04246EA07C2FAD367392C458D34FA17DAA04C22975E417ABD18FC6407D0A04300D521A8A867FE850EB9BA6F1AD32084856AAFDE112247F20579F74950EFA36A803A47134BBF024F561DDE90042A5AF2547ED9520BE77AFB33B315F +20111016114053 2 6 100 1535 5 F62191A170EC6171C620D3B334952F220077AA5C0FA7F1A7FE08C6B7B0C5F865CDB24346E3BE05B99E2D7FCC3582D0D2D637672EB0EB1DBB95BCE1A0CA54DFC83EBF598A24928CA42A5ABC2AE75E9802451B0C9E180D5D52698DAAF79DA3B968F72B48DA1D04246EA07C2FAD367392C458D34FA17DAA04C22975E417ABD18FC6407D0A04300D521A8A867FE850EB9BA6F1AD32084856AAFDE112247F20579F74950EFA36A803A47134BBF024F561DDE90042A5AF2547ED9520BE77AFB36263E7 +20111016114057 2 6 100 1535 5 F62191A170EC6171C620D3B334952F220077AA5C0FA7F1A7FE08C6B7B0C5F865CDB24346E3BE05B99E2D7FCC3582D0D2D637672EB0EB1DBB95BCE1A0CA54DFC83EBF598A24928CA42A5ABC2AE75E9802451B0C9E180D5D52698DAAF79DA3B968F72B48DA1D04246EA07C2FAD367392C458D34FA17DAA04C22975E417ABD18FC6407D0A04300D521A8A867FE850EB9BA6F1AD32084856AAFDE112247F20579F74950EFA36A803A47134BBF024F561DDE90042A5AF2547ED9520BE77AFB362E277 +20111016114122 2 6 100 1535 2 F62191A170EC6171C620D3B334952F220077AA5C0FA7F1A7FE08C6B7B0C5F865CDB24346E3BE05B99E2D7FCC3582D0D2D637672EB0EB1DBB95BCE1A0CA54DFC83EBF598A24928CA42A5ABC2AE75E9802451B0C9E180D5D52698DAAF79DA3B968F72B48DA1D04246EA07C2FAD367392C458D34FA17DAA04C22975E417ABD18FC6407D0A04300D521A8A867FE850EB9BA6F1AD32084856AAFDE112247F20579F74950EFA36A803A47134BBF024F561DDE90042A5AF2547ED9520BE77AFB399342B +20111016114127 2 6 100 1535 5 F62191A170EC6171C620D3B334952F220077AA5C0FA7F1A7FE08C6B7B0C5F865CDB24346E3BE05B99E2D7FCC3582D0D2D637672EB0EB1DBB95BCE1A0CA54DFC83EBF598A24928CA42A5ABC2AE75E9802451B0C9E180D5D52698DAAF79DA3B968F72B48DA1D04246EA07C2FAD367392C458D34FA17DAA04C22975E417ABD18FC6407D0A04300D521A8A867FE850EB9BA6F1AD32084856AAFDE112247F20579F74950EFA36A803A47134BBF024F561DDE90042A5AF2547ED9520BE77AFB39F81EF +20111016114131 2 6 100 1535 5 F62191A170EC6171C620D3B334952F220077AA5C0FA7F1A7FE08C6B7B0C5F865CDB24346E3BE05B99E2D7FCC3582D0D2D637672EB0EB1DBB95BCE1A0CA54DFC83EBF598A24928CA42A5ABC2AE75E9802451B0C9E180D5D52698DAAF79DA3B968F72B48DA1D04246EA07C2FAD367392C458D34FA17DAA04C22975E417ABD18FC6407D0A04300D521A8A867FE850EB9BA6F1AD32084856AAFDE112247F20579F74950EFA36A803A47134BBF024F561DDE90042A5AF2547ED9520BE77AFB3A178E7 +20111016114143 2 6 100 1535 5 F62191A170EC6171C620D3B334952F220077AA5C0FA7F1A7FE08C6B7B0C5F865CDB24346E3BE05B99E2D7FCC3582D0D2D637672EB0EB1DBB95BCE1A0CA54DFC83EBF598A24928CA42A5ABC2AE75E9802451B0C9E180D5D52698DAAF79DA3B968F72B48DA1D04246EA07C2FAD367392C458D34FA17DAA04C22975E417ABD18FC6407D0A04300D521A8A867FE850EB9BA6F1AD32084856AAFDE112247F20579F74950EFA36A803A47134BBF024F561DDE90042A5AF2547ED9520BE77AFB3B94617 +20111016114227 2 6 100 1535 5 F62191A170EC6171C620D3B334952F220077AA5C0FA7F1A7FE08C6B7B0C5F865CDB24346E3BE05B99E2D7FCC3582D0D2D637672EB0EB1DBB95BCE1A0CA54DFC83EBF598A24928CA42A5ABC2AE75E9802451B0C9E180D5D52698DAAF79DA3B968F72B48DA1D04246EA07C2FAD367392C458D34FA17DAA04C22975E417ABD18FC6407D0A04300D521A8A867FE850EB9BA6F1AD32084856AAFDE112247F20579F74950EFA36A803A47134BBF024F561DDE90042A5AF2547ED9520BE77AFB42121AF +20111016114234 2 6 100 1535 2 F62191A170EC6171C620D3B334952F220077AA5C0FA7F1A7FE08C6B7B0C5F865CDB24346E3BE05B99E2D7FCC3582D0D2D637672EB0EB1DBB95BCE1A0CA54DFC83EBF598A24928CA42A5ABC2AE75E9802451B0C9E180D5D52698DAAF79DA3B968F72B48DA1D04246EA07C2FAD367392C458D34FA17DAA04C22975E417ABD18FC6407D0A04300D521A8A867FE850EB9BA6F1AD32084856AAFDE112247F20579F74950EFA36A803A47134BBF024F561DDE90042A5AF2547ED9520BE77AFB429B19B +20111016114346 2 6 100 1535 5 F62191A170EC6171C620D3B334952F220077AA5C0FA7F1A7FE08C6B7B0C5F865CDB24346E3BE05B99E2D7FCC3582D0D2D637672EB0EB1DBB95BCE1A0CA54DFC83EBF598A24928CA42A5ABC2AE75E9802451B0C9E180D5D52698DAAF79DA3B968F72B48DA1D04246EA07C2FAD367392C458D34FA17DAA04C22975E417ABD18FC6407D0A04300D521A8A867FE850EB9BA6F1AD32084856AAFDE112247F20579F74950EFA36A803A47134BBF024F561DDE90042A5AF2547ED9520BE77AFB4DDFA1F +20111016114401 2 6 100 1535 5 F62191A170EC6171C620D3B334952F220077AA5C0FA7F1A7FE08C6B7B0C5F865CDB24346E3BE05B99E2D7FCC3582D0D2D637672EB0EB1DBB95BCE1A0CA54DFC83EBF598A24928CA42A5ABC2AE75E9802451B0C9E180D5D52698DAAF79DA3B968F72B48DA1D04246EA07C2FAD367392C458D34FA17DAA04C22975E417ABD18FC6407D0A04300D521A8A867FE850EB9BA6F1AD32084856AAFDE112247F20579F74950EFA36A803A47134BBF024F561DDE90042A5AF2547ED9520BE77AFB4F9E0EF +20111016114414 2 6 100 1535 2 F62191A170EC6171C620D3B334952F220077AA5C0FA7F1A7FE08C6B7B0C5F865CDB24346E3BE05B99E2D7FCC3582D0D2D637672EB0EB1DBB95BCE1A0CA54DFC83EBF598A24928CA42A5ABC2AE75E9802451B0C9E180D5D52698DAAF79DA3B968F72B48DA1D04246EA07C2FAD367392C458D34FA17DAA04C22975E417ABD18FC6407D0A04300D521A8A867FE850EB9BA6F1AD32084856AAFDE112247F20579F74950EFA36A803A47134BBF024F561DDE90042A5AF2547ED9520BE77AFB5154FFB +20111016114440 2 6 100 1535 2 F62191A170EC6171C620D3B334952F220077AA5C0FA7F1A7FE08C6B7B0C5F865CDB24346E3BE05B99E2D7FCC3582D0D2D637672EB0EB1DBB95BCE1A0CA54DFC83EBF598A24928CA42A5ABC2AE75E9802451B0C9E180D5D52698DAAF79DA3B968F72B48DA1D04246EA07C2FAD367392C458D34FA17DAA04C22975E417ABD18FC6407D0A04300D521A8A867FE850EB9BA6F1AD32084856AAFDE112247F20579F74950EFA36A803A47134BBF024F561DDE90042A5AF2547ED9520BE77AFB54FFD8B +20111016114443 2 6 100 1535 2 F62191A170EC6171C620D3B334952F220077AA5C0FA7F1A7FE08C6B7B0C5F865CDB24346E3BE05B99E2D7FCC3582D0D2D637672EB0EB1DBB95BCE1A0CA54DFC83EBF598A24928CA42A5ABC2AE75E9802451B0C9E180D5D52698DAAF79DA3B968F72B48DA1D04246EA07C2FAD367392C458D34FA17DAA04C22975E417ABD18FC6407D0A04300D521A8A867FE850EB9BA6F1AD32084856AAFDE112247F20579F74950EFA36A803A47134BBF024F561DDE90042A5AF2547ED9520BE77AFB550068B +20111016115243 2 6 100 2047 2 F98E7DDB0BB851699D3EA9E04987BACF7A646E98507456A1D7048046D818C6C164F762BDB39510B199F2E85E029F7F0CD378CE912E393CD1602EFCBE68131FBD0F866ED4F1C488D0569D7DCE44D49F4574BB9186C3458DF2D42BEFCACDA8E100337928A9B8D1E6C22BCC33437EBF4571711A4272EDE3F5B6A629D9BD44E9D4C41A2DAAFF5E417A2E0E90FA8438FB7868142F779EA9B1CC53AABDB13AAF2FE2580A55138826CBED8F8A0674A08513110E7C1F1ADF17371789DD766B53E454ADCBCEBDABBD050F469FF2F355841E8B823C0854825424DC87B273446CC70C2FDB828B43E017BEFC9AC6578DA0298C64CC2B6A33A6651CB55E720F193D7B62AF07E3 +20111016115319 2 6 100 2047 2 F98E7DDB0BB851699D3EA9E04987BACF7A646E98507456A1D7048046D818C6C164F762BDB39510B199F2E85E029F7F0CD378CE912E393CD1602EFCBE68131FBD0F866ED4F1C488D0569D7DCE44D49F4574BB9186C3458DF2D42BEFCACDA8E100337928A9B8D1E6C22BCC33437EBF4571711A4272EDE3F5B6A629D9BD44E9D4C41A2DAAFF5E417A2E0E90FA8438FB7868142F779EA9B1CC53AABDB13AAF2FE2580A55138826CBED8F8A0674A08513110E7C1F1ADF17371789DD766B53E454ADCBCEBDABBD050F469FF2F355841E8B823C0854825424DC87B273446CC70C2FDB828B43E017BEFC9AC6578DA0298C64CC2B6A33A6651CB55E720F193D7B62D02043 +20111016115330 2 6 100 2047 2 F98E7DDB0BB851699D3EA9E04987BACF7A646E98507456A1D7048046D818C6C164F762BDB39510B199F2E85E029F7F0CD378CE912E393CD1602EFCBE68131FBD0F866ED4F1C488D0569D7DCE44D49F4574BB9186C3458DF2D42BEFCACDA8E100337928A9B8D1E6C22BCC33437EBF4571711A4272EDE3F5B6A629D9BD44E9D4C41A2DAAFF5E417A2E0E90FA8438FB7868142F779EA9B1CC53AABDB13AAF2FE2580A55138826CBED8F8A0674A08513110E7C1F1ADF17371789DD766B53E454ADCBCEBDABBD050F469FF2F355841E8B823C0854825424DC87B273446CC70C2FDB828B43E017BEFC9AC6578DA0298C64CC2B6A33A6651CB55E720F193D7B62D3C483 +20111016115410 2 6 100 2047 5 F98E7DDB0BB851699D3EA9E04987BACF7A646E98507456A1D7048046D818C6C164F762BDB39510B199F2E85E029F7F0CD378CE912E393CD1602EFCBE68131FBD0F866ED4F1C488D0569D7DCE44D49F4574BB9186C3458DF2D42BEFCACDA8E100337928A9B8D1E6C22BCC33437EBF4571711A4272EDE3F5B6A629D9BD44E9D4C41A2DAAFF5E417A2E0E90FA8438FB7868142F779EA9B1CC53AABDB13AAF2FE2580A55138826CBED8F8A0674A08513110E7C1F1ADF17371789DD766B53E454ADCBCEBDABBD050F469FF2F355841E8B823C0854825424DC87B273446CC70C2FDB828B43E017BEFC9AC6578DA0298C64CC2B6A33A6651CB55E720F193D7B62F6F79F +20111016115857 2 6 100 2047 2 F98E7DDB0BB851699D3EA9E04987BACF7A646E98507456A1D7048046D818C6C164F762BDB39510B199F2E85E029F7F0CD378CE912E393CD1602EFCBE68131FBD0F866ED4F1C488D0569D7DCE44D49F4574BB9186C3458DF2D42BEFCACDA8E100337928A9B8D1E6C22BCC33437EBF4571711A4272EDE3F5B6A629D9BD44E9D4C41A2DAAFF5E417A2E0E90FA8438FB7868142F779EA9B1CC53AABDB13AAF2FE2580A55138826CBED8F8A0674A08513110E7C1F1ADF17371789DD766B53E454ADCBCEBDABBD050F469FF2F355841E8B823C0854825424DC87B273446CC70C2FDB828B43E017BEFC9AC6578DA0298C64CC2B6A33A6651CB55E720F193D7B64365B73 +20111016120019 2 6 100 2047 2 F98E7DDB0BB851699D3EA9E04987BACF7A646E98507456A1D7048046D818C6C164F762BDB39510B199F2E85E029F7F0CD378CE912E393CD1602EFCBE68131FBD0F866ED4F1C488D0569D7DCE44D49F4574BB9186C3458DF2D42BEFCACDA8E100337928A9B8D1E6C22BCC33437EBF4571711A4272EDE3F5B6A629D9BD44E9D4C41A2DAAFF5E417A2E0E90FA8438FB7868142F779EA9B1CC53AABDB13AAF2FE2580A55138826CBED8F8A0674A08513110E7C1F1ADF17371789DD766B53E454ADCBCEBDABBD050F469FF2F355841E8B823C0854825424DC87B273446CC70C2FDB828B43E017BEFC9AC6578DA0298C64CC2B6A33A6651CB55E720F193D7B6487F1EB +20111016120100 2 6 100 2047 2 F98E7DDB0BB851699D3EA9E04987BACF7A646E98507456A1D7048046D818C6C164F762BDB39510B199F2E85E029F7F0CD378CE912E393CD1602EFCBE68131FBD0F866ED4F1C488D0569D7DCE44D49F4574BB9186C3458DF2D42BEFCACDA8E100337928A9B8D1E6C22BCC33437EBF4571711A4272EDE3F5B6A629D9BD44E9D4C41A2DAAFF5E417A2E0E90FA8438FB7868142F779EA9B1CC53AABDB13AAF2FE2580A55138826CBED8F8A0674A08513110E7C1F1ADF17371789DD766B53E454ADCBCEBDABBD050F469FF2F355841E8B823C0854825424DC87B273446CC70C2FDB828B43E017BEFC9AC6578DA0298C64CC2B6A33A6651CB55E720F193D7B64AF2F53 +20111016120108 2 6 100 2047 5 F98E7DDB0BB851699D3EA9E04987BACF7A646E98507456A1D7048046D818C6C164F762BDB39510B199F2E85E029F7F0CD378CE912E393CD1602EFCBE68131FBD0F866ED4F1C488D0569D7DCE44D49F4574BB9186C3458DF2D42BEFCACDA8E100337928A9B8D1E6C22BCC33437EBF4571711A4272EDE3F5B6A629D9BD44E9D4C41A2DAAFF5E417A2E0E90FA8438FB7868142F779EA9B1CC53AABDB13AAF2FE2580A55138826CBED8F8A0674A08513110E7C1F1ADF17371789DD766B53E454ADCBCEBDABBD050F469FF2F355841E8B823C0854825424DC87B273446CC70C2FDB828B43E017BEFC9AC6578DA0298C64CC2B6A33A6651CB55E720F193D7B64B0009F +20111016120211 2 6 100 2047 5 F98E7DDB0BB851699D3EA9E04987BACF7A646E98507456A1D7048046D818C6C164F762BDB39510B199F2E85E029F7F0CD378CE912E393CD1602EFCBE68131FBD0F866ED4F1C488D0569D7DCE44D49F4574BB9186C3458DF2D42BEFCACDA8E100337928A9B8D1E6C22BCC33437EBF4571711A4272EDE3F5B6A629D9BD44E9D4C41A2DAAFF5E417A2E0E90FA8438FB7868142F779EA9B1CC53AABDB13AAF2FE2580A55138826CBED8F8A0674A08513110E7C1F1ADF17371789DD766B53E454ADCBCEBDABBD050F469FF2F355841E8B823C0854825424DC87B273446CC70C2FDB828B43E017BEFC9AC6578DA0298C64CC2B6A33A6651CB55E720F193D7B64EA9647 +20111016120312 2 6 100 2047 5 F98E7DDB0BB851699D3EA9E04987BACF7A646E98507456A1D7048046D818C6C164F762BDB39510B199F2E85E029F7F0CD378CE912E393CD1602EFCBE68131FBD0F866ED4F1C488D0569D7DCE44D49F4574BB9186C3458DF2D42BEFCACDA8E100337928A9B8D1E6C22BCC33437EBF4571711A4272EDE3F5B6A629D9BD44E9D4C41A2DAAFF5E417A2E0E90FA8438FB7868142F779EA9B1CC53AABDB13AAF2FE2580A55138826CBED8F8A0674A08513110E7C1F1ADF17371789DD766B53E454ADCBCEBDABBD050F469FF2F355841E8B823C0854825424DC87B273446CC70C2FDB828B43E017BEFC9AC6578DA0298C64CC2B6A33A6651CB55E720F193D7B65276D57 +20111016120424 2 6 100 2047 5 F98E7DDB0BB851699D3EA9E04987BACF7A646E98507456A1D7048046D818C6C164F762BDB39510B199F2E85E029F7F0CD378CE912E393CD1602EFCBE68131FBD0F866ED4F1C488D0569D7DCE44D49F4574BB9186C3458DF2D42BEFCACDA8E100337928A9B8D1E6C22BCC33437EBF4571711A4272EDE3F5B6A629D9BD44E9D4C41A2DAAFF5E417A2E0E90FA8438FB7868142F779EA9B1CC53AABDB13AAF2FE2580A55138826CBED8F8A0674A08513110E7C1F1ADF17371789DD766B53E454ADCBCEBDABBD050F469FF2F355841E8B823C0854825424DC87B273446CC70C2FDB828B43E017BEFC9AC6578DA0298C64CC2B6A33A6651CB55E720F193D7B656D2937 +20111016120513 2 6 100 2047 5 F98E7DDB0BB851699D3EA9E04987BACF7A646E98507456A1D7048046D818C6C164F762BDB39510B199F2E85E029F7F0CD378CE912E393CD1602EFCBE68131FBD0F866ED4F1C488D0569D7DCE44D49F4574BB9186C3458DF2D42BEFCACDA8E100337928A9B8D1E6C22BCC33437EBF4571711A4272EDE3F5B6A629D9BD44E9D4C41A2DAAFF5E417A2E0E90FA8438FB7868142F779EA9B1CC53AABDB13AAF2FE2580A55138826CBED8F8A0674A08513110E7C1F1ADF17371789DD766B53E454ADCBCEBDABBD050F469FF2F355841E8B823C0854825424DC87B273446CC70C2FDB828B43E017BEFC9AC6578DA0298C64CC2B6A33A6651CB55E720F193D7B659D1C5F +20111016120533 2 6 100 2047 5 F98E7DDB0BB851699D3EA9E04987BACF7A646E98507456A1D7048046D818C6C164F762BDB39510B199F2E85E029F7F0CD378CE912E393CD1602EFCBE68131FBD0F866ED4F1C488D0569D7DCE44D49F4574BB9186C3458DF2D42BEFCACDA8E100337928A9B8D1E6C22BCC33437EBF4571711A4272EDE3F5B6A629D9BD44E9D4C41A2DAAFF5E417A2E0E90FA8438FB7868142F779EA9B1CC53AABDB13AAF2FE2580A55138826CBED8F8A0674A08513110E7C1F1ADF17371789DD766B53E454ADCBCEBDABBD050F469FF2F355841E8B823C0854825424DC87B273446CC70C2FDB828B43E017BEFC9AC6578DA0298C64CC2B6A33A6651CB55E720F193D7B65AC51CF +20111016120631 2 6 100 2047 5 F98E7DDB0BB851699D3EA9E04987BACF7A646E98507456A1D7048046D818C6C164F762BDB39510B199F2E85E029F7F0CD378CE912E393CD1602EFCBE68131FBD0F866ED4F1C488D0569D7DCE44D49F4574BB9186C3458DF2D42BEFCACDA8E100337928A9B8D1E6C22BCC33437EBF4571711A4272EDE3F5B6A629D9BD44E9D4C41A2DAAFF5E417A2E0E90FA8438FB7868142F779EA9B1CC53AABDB13AAF2FE2580A55138826CBED8F8A0674A08513110E7C1F1ADF17371789DD766B53E454ADCBCEBDABBD050F469FF2F355841E8B823C0854825424DC87B273446CC70C2FDB828B43E017BEFC9AC6578DA0298C64CC2B6A33A6651CB55E720F193D7B65E62417 +20111016121024 2 6 100 2047 2 F98E7DDB0BB851699D3EA9E04987BACF7A646E98507456A1D7048046D818C6C164F762BDB39510B199F2E85E029F7F0CD378CE912E393CD1602EFCBE68131FBD0F866ED4F1C488D0569D7DCE44D49F4574BB9186C3458DF2D42BEFCACDA8E100337928A9B8D1E6C22BCC33437EBF4571711A4272EDE3F5B6A629D9BD44E9D4C41A2DAAFF5E417A2E0E90FA8438FB7868142F779EA9B1CC53AABDB13AAF2FE2580A55138826CBED8F8A0674A08513110E7C1F1ADF17371789DD766B53E454ADCBCEBDABBD050F469FF2F355841E8B823C0854825424DC87B273446CC70C2FDB828B43E017BEFC9AC6578DA0298C64CC2B6A33A6651CB55E720F193D7B66E230FB +20111016121123 2 6 100 2047 5 F98E7DDB0BB851699D3EA9E04987BACF7A646E98507456A1D7048046D818C6C164F762BDB39510B199F2E85E029F7F0CD378CE912E393CD1602EFCBE68131FBD0F866ED4F1C488D0569D7DCE44D49F4574BB9186C3458DF2D42BEFCACDA8E100337928A9B8D1E6C22BCC33437EBF4571711A4272EDE3F5B6A629D9BD44E9D4C41A2DAAFF5E417A2E0E90FA8438FB7868142F779EA9B1CC53AABDB13AAF2FE2580A55138826CBED8F8A0674A08513110E7C1F1ADF17371789DD766B53E454ADCBCEBDABBD050F469FF2F355841E8B823C0854825424DC87B273446CC70C2FDB828B43E017BEFC9AC6578DA0298C64CC2B6A33A6651CB55E720F193D7B671AE1CF +20111016121152 2 6 100 2047 2 F98E7DDB0BB851699D3EA9E04987BACF7A646E98507456A1D7048046D818C6C164F762BDB39510B199F2E85E029F7F0CD378CE912E393CD1602EFCBE68131FBD0F866ED4F1C488D0569D7DCE44D49F4574BB9186C3458DF2D42BEFCACDA8E100337928A9B8D1E6C22BCC33437EBF4571711A4272EDE3F5B6A629D9BD44E9D4C41A2DAAFF5E417A2E0E90FA8438FB7868142F779EA9B1CC53AABDB13AAF2FE2580A55138826CBED8F8A0674A08513110E7C1F1ADF17371789DD766B53E454ADCBCEBDABBD050F469FF2F355841E8B823C0854825424DC87B273446CC70C2FDB828B43E017BEFC9AC6578DA0298C64CC2B6A33A6651CB55E720F193D7B6732A9B3 +20111016121256 2 6 100 2047 5 F98E7DDB0BB851699D3EA9E04987BACF7A646E98507456A1D7048046D818C6C164F762BDB39510B199F2E85E029F7F0CD378CE912E393CD1602EFCBE68131FBD0F866ED4F1C488D0569D7DCE44D49F4574BB9186C3458DF2D42BEFCACDA8E100337928A9B8D1E6C22BCC33437EBF4571711A4272EDE3F5B6A629D9BD44E9D4C41A2DAAFF5E417A2E0E90FA8438FB7868142F779EA9B1CC53AABDB13AAF2FE2580A55138826CBED8F8A0674A08513110E7C1F1ADF17371789DD766B53E454ADCBCEBDABBD050F469FF2F355841E8B823C0854825424DC87B273446CC70C2FDB828B43E017BEFC9AC6578DA0298C64CC2B6A33A6651CB55E720F193D7B677372C7 +20111016121308 2 6 100 2047 2 F98E7DDB0BB851699D3EA9E04987BACF7A646E98507456A1D7048046D818C6C164F762BDB39510B199F2E85E029F7F0CD378CE912E393CD1602EFCBE68131FBD0F866ED4F1C488D0569D7DCE44D49F4574BB9186C3458DF2D42BEFCACDA8E100337928A9B8D1E6C22BCC33437EBF4571711A4272EDE3F5B6A629D9BD44E9D4C41A2DAAFF5E417A2E0E90FA8438FB7868142F779EA9B1CC53AABDB13AAF2FE2580A55138826CBED8F8A0674A08513110E7C1F1ADF17371789DD766B53E454ADCBCEBDABBD050F469FF2F355841E8B823C0854825424DC87B273446CC70C2FDB828B43E017BEFC9AC6578DA0298C64CC2B6A33A6651CB55E720F193D7B67792893 +20111016121745 2 6 100 2047 5 F98E7DDB0BB851699D3EA9E04987BACF7A646E98507456A1D7048046D818C6C164F762BDB39510B199F2E85E029F7F0CD378CE912E393CD1602EFCBE68131FBD0F866ED4F1C488D0569D7DCE44D49F4574BB9186C3458DF2D42BEFCACDA8E100337928A9B8D1E6C22BCC33437EBF4571711A4272EDE3F5B6A629D9BD44E9D4C41A2DAAFF5E417A2E0E90FA8438FB7868142F779EA9B1CC53AABDB13AAF2FE2580A55138826CBED8F8A0674A08513110E7C1F1ADF17371789DD766B53E454ADCBCEBDABBD050F469FF2F355841E8B823C0854825424DC87B273446CC70C2FDB828B43E017BEFC9AC6578DA0298C64CC2B6A33A6651CB55E720F193D7B68A8BB57 +20111016121829 2 6 100 2047 2 F98E7DDB0BB851699D3EA9E04987BACF7A646E98507456A1D7048046D818C6C164F762BDB39510B199F2E85E029F7F0CD378CE912E393CD1602EFCBE68131FBD0F866ED4F1C488D0569D7DCE44D49F4574BB9186C3458DF2D42BEFCACDA8E100337928A9B8D1E6C22BCC33437EBF4571711A4272EDE3F5B6A629D9BD44E9D4C41A2DAAFF5E417A2E0E90FA8438FB7868142F779EA9B1CC53AABDB13AAF2FE2580A55138826CBED8F8A0674A08513110E7C1F1ADF17371789DD766B53E454ADCBCEBDABBD050F469FF2F355841E8B823C0854825424DC87B273446CC70C2FDB828B43E017BEFC9AC6578DA0298C64CC2B6A33A6651CB55E720F193D7B68D4DA1B +20111016121844 2 6 100 2047 2 F98E7DDB0BB851699D3EA9E04987BACF7A646E98507456A1D7048046D818C6C164F762BDB39510B199F2E85E029F7F0CD378CE912E393CD1602EFCBE68131FBD0F866ED4F1C488D0569D7DCE44D49F4574BB9186C3458DF2D42BEFCACDA8E100337928A9B8D1E6C22BCC33437EBF4571711A4272EDE3F5B6A629D9BD44E9D4C41A2DAAFF5E417A2E0E90FA8438FB7868142F779EA9B1CC53AABDB13AAF2FE2580A55138826CBED8F8A0674A08513110E7C1F1ADF17371789DD766B53E454ADCBCEBDABBD050F469FF2F355841E8B823C0854825424DC87B273446CC70C2FDB828B43E017BEFC9AC6578DA0298C64CC2B6A33A6651CB55E720F193D7B68DE0CBB +20111016121951 2 6 100 2047 5 F98E7DDB0BB851699D3EA9E04987BACF7A646E98507456A1D7048046D818C6C164F762BDB39510B199F2E85E029F7F0CD378CE912E393CD1602EFCBE68131FBD0F866ED4F1C488D0569D7DCE44D49F4574BB9186C3458DF2D42BEFCACDA8E100337928A9B8D1E6C22BCC33437EBF4571711A4272EDE3F5B6A629D9BD44E9D4C41A2DAAFF5E417A2E0E90FA8438FB7868142F779EA9B1CC53AABDB13AAF2FE2580A55138826CBED8F8A0674A08513110E7C1F1ADF17371789DD766B53E454ADCBCEBDABBD050F469FF2F355841E8B823C0854825424DC87B273446CC70C2FDB828B43E017BEFC9AC6578DA0298C64CC2B6A33A6651CB55E720F193D7B69233E77 +20111016122306 2 6 100 2047 5 F98E7DDB0BB851699D3EA9E04987BACF7A646E98507456A1D7048046D818C6C164F762BDB39510B199F2E85E029F7F0CD378CE912E393CD1602EFCBE68131FBD0F866ED4F1C488D0569D7DCE44D49F4574BB9186C3458DF2D42BEFCACDA8E100337928A9B8D1E6C22BCC33437EBF4571711A4272EDE3F5B6A629D9BD44E9D4C41A2DAAFF5E417A2E0E90FA8438FB7868142F779EA9B1CC53AABDB13AAF2FE2580A55138826CBED8F8A0674A08513110E7C1F1ADF17371789DD766B53E454ADCBCEBDABBD050F469FF2F355841E8B823C0854825424DC87B273446CC70C2FDB828B43E017BEFC9AC6578DA0298C64CC2B6A33A6651CB55E720F193D7B69F6C057 +20111016122320 2 6 100 2047 5 F98E7DDB0BB851699D3EA9E04987BACF7A646E98507456A1D7048046D818C6C164F762BDB39510B199F2E85E029F7F0CD378CE912E393CD1602EFCBE68131FBD0F866ED4F1C488D0569D7DCE44D49F4574BB9186C3458DF2D42BEFCACDA8E100337928A9B8D1E6C22BCC33437EBF4571711A4272EDE3F5B6A629D9BD44E9D4C41A2DAAFF5E417A2E0E90FA8438FB7868142F779EA9B1CC53AABDB13AAF2FE2580A55138826CBED8F8A0674A08513110E7C1F1ADF17371789DD766B53E454ADCBCEBDABBD050F469FF2F355841E8B823C0854825424DC87B273446CC70C2FDB828B43E017BEFC9AC6578DA0298C64CC2B6A33A6651CB55E720F193D7B69FDDA0F +20111016122337 2 6 100 2047 2 F98E7DDB0BB851699D3EA9E04987BACF7A646E98507456A1D7048046D818C6C164F762BDB39510B199F2E85E029F7F0CD378CE912E393CD1602EFCBE68131FBD0F866ED4F1C488D0569D7DCE44D49F4574BB9186C3458DF2D42BEFCACDA8E100337928A9B8D1E6C22BCC33437EBF4571711A4272EDE3F5B6A629D9BD44E9D4C41A2DAAFF5E417A2E0E90FA8438FB7868142F779EA9B1CC53AABDB13AAF2FE2580A55138826CBED8F8A0674A08513110E7C1F1ADF17371789DD766B53E454ADCBCEBDABBD050F469FF2F355841E8B823C0854825424DC87B273446CC70C2FDB828B43E017BEFC9AC6578DA0298C64CC2B6A33A6651CB55E720F193D7B6A08ADEB +20111016122357 2 6 100 2047 5 F98E7DDB0BB851699D3EA9E04987BACF7A646E98507456A1D7048046D818C6C164F762BDB39510B199F2E85E029F7F0CD378CE912E393CD1602EFCBE68131FBD0F866ED4F1C488D0569D7DCE44D49F4574BB9186C3458DF2D42BEFCACDA8E100337928A9B8D1E6C22BCC33437EBF4571711A4272EDE3F5B6A629D9BD44E9D4C41A2DAAFF5E417A2E0E90FA8438FB7868142F779EA9B1CC53AABDB13AAF2FE2580A55138826CBED8F8A0674A08513110E7C1F1ADF17371789DD766B53E454ADCBCEBDABBD050F469FF2F355841E8B823C0854825424DC87B273446CC70C2FDB828B43E017BEFC9AC6578DA0298C64CC2B6A33A6651CB55E720F193D7B6A17777F +20111016122422 2 6 100 2047 2 F98E7DDB0BB851699D3EA9E04987BACF7A646E98507456A1D7048046D818C6C164F762BDB39510B199F2E85E029F7F0CD378CE912E393CD1602EFCBE68131FBD0F866ED4F1C488D0569D7DCE44D49F4574BB9186C3458DF2D42BEFCACDA8E100337928A9B8D1E6C22BCC33437EBF4571711A4272EDE3F5B6A629D9BD44E9D4C41A2DAAFF5E417A2E0E90FA8438FB7868142F779EA9B1CC53AABDB13AAF2FE2580A55138826CBED8F8A0674A08513110E7C1F1ADF17371789DD766B53E454ADCBCEBDABBD050F469FF2F355841E8B823C0854825424DC87B273446CC70C2FDB828B43E017BEFC9AC6578DA0298C64CC2B6A33A6651CB55E720F193D7B6A2C5253 +20111016123841 2 6 100 3071 2 E6846A58148AC762DD0CA90662E5626D0C5647E5C8CE7D6190997846FB17A509767A28E1E7B5F1AD994407661C1225E05F37EE490AA3C4C5AE757129BE9EEC5DEDD6501D26F43C2CC0A1E1FF7D11A55616D02061E20573AC75DAB592D55C781608B8A20CB3DA2EB9C2C4C2FDA0CF1E083B6CFB43772FEFE969FDF56FA96EBCBFB4110384CBF0307F2DB59954BADE376AEB544ABAA269D39DE57EC52E7CEB5E7A5855BA1523CB774D387F4C018E66BFCDC81CCE6E59A2E9BD9D0E788E6DA081B1588173E0C3C7D7BEC6625D62AFB21B9E1228FD2620E3C257DECFB079DEEBD43EEC3FD8B67AF6D41FB7355BD184796D66FFEB384DB41C7D14ECFDDAF59F845B351D55E24AE97CBD3C21B093E58BF51AEE312A561B9B7C532C859547E1E19D539378B8B806B3ECC2AD7C0ADBC628AAB91DEBC5FA329C2E71F678F962BC12305316936D5A5063411610632451C837D83806B98DD038548592A2910C4BF4713FDF8BFD70897697FFF17B7F59FD8AD505103EEAB7A39BE1BDECD2833DB02524EFAF83 +20111016124416 2 6 100 3071 2 E6846A58148AC762DD0CA90662E5626D0C5647E5C8CE7D6190997846FB17A509767A28E1E7B5F1AD994407661C1225E05F37EE490AA3C4C5AE757129BE9EEC5DEDD6501D26F43C2CC0A1E1FF7D11A55616D02061E20573AC75DAB592D55C781608B8A20CB3DA2EB9C2C4C2FDA0CF1E083B6CFB43772FEFE969FDF56FA96EBCBFB4110384CBF0307F2DB59954BADE376AEB544ABAA269D39DE57EC52E7CEB5E7A5855BA1523CB774D387F4C018E66BFCDC81CCE6E59A2E9BD9D0E788E6DA081B1588173E0C3C7D7BEC6625D62AFB21B9E1228FD2620E3C257DECFB079DEEBD43EEC3FD8B67AF6D41FB7355BD184796D66FFEB384DB41C7D14ECFDDAF59F845B351D55E24AE97CBD3C21B093E58BF51AEE312A561B9B7C532C859547E1E19D539378B8B806B3ECC2AD7C0ADBC628AAB91DEBC5FA329C2E71F678F962BC12305316936D5A5063411610632451C837D83806B98DD038548592A2910C4BF4713FDF8BFD70897697FFF17B7F59FD8AD505103EEAB7A39BE1BDECD2833DB025255DD88B +20111016125629 2 6 100 3071 5 E6846A58148AC762DD0CA90662E5626D0C5647E5C8CE7D6190997846FB17A509767A28E1E7B5F1AD994407661C1225E05F37EE490AA3C4C5AE757129BE9EEC5DEDD6501D26F43C2CC0A1E1FF7D11A55616D02061E20573AC75DAB592D55C781608B8A20CB3DA2EB9C2C4C2FDA0CF1E083B6CFB43772FEFE969FDF56FA96EBCBFB4110384CBF0307F2DB59954BADE376AEB544ABAA269D39DE57EC52E7CEB5E7A5855BA1523CB774D387F4C018E66BFCDC81CCE6E59A2E9BD9D0E788E6DA081B1588173E0C3C7D7BEC6625D62AFB21B9E1228FD2620E3C257DECFB079DEEBD43EEC3FD8B67AF6D41FB7355BD184796D66FFEB384DB41C7D14ECFDDAF59F845B351D55E24AE97CBD3C21B093E58BF51AEE312A561B9B7C532C859547E1E19D539378B8B806B3ECC2AD7C0ADBC628AAB91DEBC5FA329C2E71F678F962BC12305316936D5A5063411610632451C837D83806B98DD038548592A2910C4BF4713FDF8BFD70897697FFF17B7F59FD8AD505103EEAB7A39BE1BDECD2833DB0252654738F +20111016130638 2 6 100 3071 2 E6846A58148AC762DD0CA90662E5626D0C5647E5C8CE7D6190997846FB17A509767A28E1E7B5F1AD994407661C1225E05F37EE490AA3C4C5AE757129BE9EEC5DEDD6501D26F43C2CC0A1E1FF7D11A55616D02061E20573AC75DAB592D55C781608B8A20CB3DA2EB9C2C4C2FDA0CF1E083B6CFB43772FEFE969FDF56FA96EBCBFB4110384CBF0307F2DB59954BADE376AEB544ABAA269D39DE57EC52E7CEB5E7A5855BA1523CB774D387F4C018E66BFCDC81CCE6E59A2E9BD9D0E788E6DA081B1588173E0C3C7D7BEC6625D62AFB21B9E1228FD2620E3C257DECFB079DEEBD43EEC3FD8B67AF6D41FB7355BD184796D66FFEB384DB41C7D14ECFDDAF59F845B351D55E24AE97CBD3C21B093E58BF51AEE312A561B9B7C532C859547E1E19D539378B8B806B3ECC2AD7C0ADBC628AAB91DEBC5FA329C2E71F678F962BC12305316936D5A5063411610632451C837D83806B98DD038548592A2910C4BF4713FDF8BFD70897697FFF17B7F59FD8AD505103EEAB7A39BE1BDECD2833DB025271B3D8B +20111016131447 2 6 100 3071 2 E6846A58148AC762DD0CA90662E5626D0C5647E5C8CE7D6190997846FB17A509767A28E1E7B5F1AD994407661C1225E05F37EE490AA3C4C5AE757129BE9EEC5DEDD6501D26F43C2CC0A1E1FF7D11A55616D02061E20573AC75DAB592D55C781608B8A20CB3DA2EB9C2C4C2FDA0CF1E083B6CFB43772FEFE969FDF56FA96EBCBFB4110384CBF0307F2DB59954BADE376AEB544ABAA269D39DE57EC52E7CEB5E7A5855BA1523CB774D387F4C018E66BFCDC81CCE6E59A2E9BD9D0E788E6DA081B1588173E0C3C7D7BEC6625D62AFB21B9E1228FD2620E3C257DECFB079DEEBD43EEC3FD8B67AF6D41FB7355BD184796D66FFEB384DB41C7D14ECFDDAF59F845B351D55E24AE97CBD3C21B093E58BF51AEE312A561B9B7C532C859547E1E19D539378B8B806B3ECC2AD7C0ADBC628AAB91DEBC5FA329C2E71F678F962BC12305316936D5A5063411610632451C837D83806B98DD038548592A2910C4BF4713FDF8BFD70897697FFF17B7F59FD8AD505103EEAB7A39BE1BDECD2833DB02527B1E0AB +20111016131720 2 6 100 3071 2 E6846A58148AC762DD0CA90662E5626D0C5647E5C8CE7D6190997846FB17A509767A28E1E7B5F1AD994407661C1225E05F37EE490AA3C4C5AE757129BE9EEC5DEDD6501D26F43C2CC0A1E1FF7D11A55616D02061E20573AC75DAB592D55C781608B8A20CB3DA2EB9C2C4C2FDA0CF1E083B6CFB43772FEFE969FDF56FA96EBCBFB4110384CBF0307F2DB59954BADE376AEB544ABAA269D39DE57EC52E7CEB5E7A5855BA1523CB774D387F4C018E66BFCDC81CCE6E59A2E9BD9D0E788E6DA081B1588173E0C3C7D7BEC6625D62AFB21B9E1228FD2620E3C257DECFB079DEEBD43EEC3FD8B67AF6D41FB7355BD184796D66FFEB384DB41C7D14ECFDDAF59F845B351D55E24AE97CBD3C21B093E58BF51AEE312A561B9B7C532C859547E1E19D539378B8B806B3ECC2AD7C0ADBC628AAB91DEBC5FA329C2E71F678F962BC12305316936D5A5063411610632451C837D83806B98DD038548592A2910C4BF4713FDF8BFD70897697FFF17B7F59FD8AD505103EEAB7A39BE1BDECD2833DB02527DE4403 +20111016132301 2 6 100 3071 5 E6846A58148AC762DD0CA90662E5626D0C5647E5C8CE7D6190997846FB17A509767A28E1E7B5F1AD994407661C1225E05F37EE490AA3C4C5AE757129BE9EEC5DEDD6501D26F43C2CC0A1E1FF7D11A55616D02061E20573AC75DAB592D55C781608B8A20CB3DA2EB9C2C4C2FDA0CF1E083B6CFB43772FEFE969FDF56FA96EBCBFB4110384CBF0307F2DB59954BADE376AEB544ABAA269D39DE57EC52E7CEB5E7A5855BA1523CB774D387F4C018E66BFCDC81CCE6E59A2E9BD9D0E788E6DA081B1588173E0C3C7D7BEC6625D62AFB21B9E1228FD2620E3C257DECFB079DEEBD43EEC3FD8B67AF6D41FB7355BD184796D66FFEB384DB41C7D14ECFDDAF59F845B351D55E24AE97CBD3C21B093E58BF51AEE312A561B9B7C532C859547E1E19D539378B8B806B3ECC2AD7C0ADBC628AAB91DEBC5FA329C2E71F678F962BC12305316936D5A5063411610632451C837D83806B98DD038548592A2910C4BF4713FDF8BFD70897697FFF17B7F59FD8AD505103EEAB7A39BE1BDECD2833DB0252844EF27 +20111016132443 2 6 100 3071 5 E6846A58148AC762DD0CA90662E5626D0C5647E5C8CE7D6190997846FB17A509767A28E1E7B5F1AD994407661C1225E05F37EE490AA3C4C5AE757129BE9EEC5DEDD6501D26F43C2CC0A1E1FF7D11A55616D02061E20573AC75DAB592D55C781608B8A20CB3DA2EB9C2C4C2FDA0CF1E083B6CFB43772FEFE969FDF56FA96EBCBFB4110384CBF0307F2DB59954BADE376AEB544ABAA269D39DE57EC52E7CEB5E7A5855BA1523CB774D387F4C018E66BFCDC81CCE6E59A2E9BD9D0E788E6DA081B1588173E0C3C7D7BEC6625D62AFB21B9E1228FD2620E3C257DECFB079DEEBD43EEC3FD8B67AF6D41FB7355BD184796D66FFEB384DB41C7D14ECFDDAF59F845B351D55E24AE97CBD3C21B093E58BF51AEE312A561B9B7C532C859547E1E19D539378B8B806B3ECC2AD7C0ADBC628AAB91DEBC5FA329C2E71F678F962BC12305316936D5A5063411610632451C837D83806B98DD038548592A2910C4BF4713FDF8BFD70897697FFF17B7F59FD8AD505103EEAB7A39BE1BDECD2833DB02528601117 +20111016134949 2 6 100 3071 5 E6846A58148AC762DD0CA90662E5626D0C5647E5C8CE7D6190997846FB17A509767A28E1E7B5F1AD994407661C1225E05F37EE490AA3C4C5AE757129BE9EEC5DEDD6501D26F43C2CC0A1E1FF7D11A55616D02061E20573AC75DAB592D55C781608B8A20CB3DA2EB9C2C4C2FDA0CF1E083B6CFB43772FEFE969FDF56FA96EBCBFB4110384CBF0307F2DB59954BADE376AEB544ABAA269D39DE57EC52E7CEB5E7A5855BA1523CB774D387F4C018E66BFCDC81CCE6E59A2E9BD9D0E788E6DA081B1588173E0C3C7D7BEC6625D62AFB21B9E1228FD2620E3C257DECFB079DEEBD43EEC3FD8B67AF6D41FB7355BD184796D66FFEB384DB41C7D14ECFDDAF59F845B351D55E24AE97CBD3C21B093E58BF51AEE312A561B9B7C532C859547E1E19D539378B8B806B3ECC2AD7C0ADBC628AAB91DEBC5FA329C2E71F678F962BC12305316936D5A5063411610632451C837D83806B98DD038548592A2910C4BF4713FDF8BFD70897697FFF17B7F59FD8AD505103EEAB7A39BE1BDECD2833DB0252A6D1DD7 +20111016135208 2 6 100 3071 2 E6846A58148AC762DD0CA90662E5626D0C5647E5C8CE7D6190997846FB17A509767A28E1E7B5F1AD994407661C1225E05F37EE490AA3C4C5AE757129BE9EEC5DEDD6501D26F43C2CC0A1E1FF7D11A55616D02061E20573AC75DAB592D55C781608B8A20CB3DA2EB9C2C4C2FDA0CF1E083B6CFB43772FEFE969FDF56FA96EBCBFB4110384CBF0307F2DB59954BADE376AEB544ABAA269D39DE57EC52E7CEB5E7A5855BA1523CB774D387F4C018E66BFCDC81CCE6E59A2E9BD9D0E788E6DA081B1588173E0C3C7D7BEC6625D62AFB21B9E1228FD2620E3C257DECFB079DEEBD43EEC3FD8B67AF6D41FB7355BD184796D66FFEB384DB41C7D14ECFDDAF59F845B351D55E24AE97CBD3C21B093E58BF51AEE312A561B9B7C532C859547E1E19D539378B8B806B3ECC2AD7C0ADBC628AAB91DEBC5FA329C2E71F678F962BC12305316936D5A5063411610632451C837D83806B98DD038548592A2910C4BF4713FDF8BFD70897697FFF17B7F59FD8AD505103EEAB7A39BE1BDECD2833DB0252A95BBB3 +20111016140013 2 6 100 3071 5 E6846A58148AC762DD0CA90662E5626D0C5647E5C8CE7D6190997846FB17A509767A28E1E7B5F1AD994407661C1225E05F37EE490AA3C4C5AE757129BE9EEC5DEDD6501D26F43C2CC0A1E1FF7D11A55616D02061E20573AC75DAB592D55C781608B8A20CB3DA2EB9C2C4C2FDA0CF1E083B6CFB43772FEFE969FDF56FA96EBCBFB4110384CBF0307F2DB59954BADE376AEB544ABAA269D39DE57EC52E7CEB5E7A5855BA1523CB774D387F4C018E66BFCDC81CCE6E59A2E9BD9D0E788E6DA081B1588173E0C3C7D7BEC6625D62AFB21B9E1228FD2620E3C257DECFB079DEEBD43EEC3FD8B67AF6D41FB7355BD184796D66FFEB384DB41C7D14ECFDDAF59F845B351D55E24AE97CBD3C21B093E58BF51AEE312A561B9B7C532C859547E1E19D539378B8B806B3ECC2AD7C0ADBC628AAB91DEBC5FA329C2E71F678F962BC12305316936D5A5063411610632451C837D83806B98DD038548592A2910C4BF4713FDF8BFD70897697FFF17B7F59FD8AD505103EEAB7A39BE1BDECD2833DB0252B37A53F +20111016140630 2 6 100 3071 2 E6846A58148AC762DD0CA90662E5626D0C5647E5C8CE7D6190997846FB17A509767A28E1E7B5F1AD994407661C1225E05F37EE490AA3C4C5AE757129BE9EEC5DEDD6501D26F43C2CC0A1E1FF7D11A55616D02061E20573AC75DAB592D55C781608B8A20CB3DA2EB9C2C4C2FDA0CF1E083B6CFB43772FEFE969FDF56FA96EBCBFB4110384CBF0307F2DB59954BADE376AEB544ABAA269D39DE57EC52E7CEB5E7A5855BA1523CB774D387F4C018E66BFCDC81CCE6E59A2E9BD9D0E788E6DA081B1588173E0C3C7D7BEC6625D62AFB21B9E1228FD2620E3C257DECFB079DEEBD43EEC3FD8B67AF6D41FB7355BD184796D66FFEB384DB41C7D14ECFDDAF59F845B351D55E24AE97CBD3C21B093E58BF51AEE312A561B9B7C532C859547E1E19D539378B8B806B3ECC2AD7C0ADBC628AAB91DEBC5FA329C2E71F678F962BC12305316936D5A5063411610632451C837D83806B98DD038548592A2910C4BF4713FDF8BFD70897697FFF17B7F59FD8AD505103EEAB7A39BE1BDECD2833DB0252BB1C4DB +20111016140858 2 6 100 3071 5 E6846A58148AC762DD0CA90662E5626D0C5647E5C8CE7D6190997846FB17A509767A28E1E7B5F1AD994407661C1225E05F37EE490AA3C4C5AE757129BE9EEC5DEDD6501D26F43C2CC0A1E1FF7D11A55616D02061E20573AC75DAB592D55C781608B8A20CB3DA2EB9C2C4C2FDA0CF1E083B6CFB43772FEFE969FDF56FA96EBCBFB4110384CBF0307F2DB59954BADE376AEB544ABAA269D39DE57EC52E7CEB5E7A5855BA1523CB774D387F4C018E66BFCDC81CCE6E59A2E9BD9D0E788E6DA081B1588173E0C3C7D7BEC6625D62AFB21B9E1228FD2620E3C257DECFB079DEEBD43EEC3FD8B67AF6D41FB7355BD184796D66FFEB384DB41C7D14ECFDDAF59F845B351D55E24AE97CBD3C21B093E58BF51AEE312A561B9B7C532C859547E1E19D539378B8B806B3ECC2AD7C0ADBC628AAB91DEBC5FA329C2E71F678F962BC12305316936D5A5063411610632451C837D83806B98DD038548592A2910C4BF4713FDF8BFD70897697FFF17B7F59FD8AD505103EEAB7A39BE1BDECD2833DB0252BDB1B07 +20111016141216 2 6 100 3071 5 E6846A58148AC762DD0CA90662E5626D0C5647E5C8CE7D6190997846FB17A509767A28E1E7B5F1AD994407661C1225E05F37EE490AA3C4C5AE757129BE9EEC5DEDD6501D26F43C2CC0A1E1FF7D11A55616D02061E20573AC75DAB592D55C781608B8A20CB3DA2EB9C2C4C2FDA0CF1E083B6CFB43772FEFE969FDF56FA96EBCBFB4110384CBF0307F2DB59954BADE376AEB544ABAA269D39DE57EC52E7CEB5E7A5855BA1523CB774D387F4C018E66BFCDC81CCE6E59A2E9BD9D0E788E6DA081B1588173E0C3C7D7BEC6625D62AFB21B9E1228FD2620E3C257DECFB079DEEBD43EEC3FD8B67AF6D41FB7355BD184796D66FFEB384DB41C7D14ECFDDAF59F845B351D55E24AE97CBD3C21B093E58BF51AEE312A561B9B7C532C859547E1E19D539378B8B806B3ECC2AD7C0ADBC628AAB91DEBC5FA329C2E71F678F962BC12305316936D5A5063411610632451C837D83806B98DD038548592A2910C4BF4713FDF8BFD70897697FFF17B7F59FD8AD505103EEAB7A39BE1BDECD2833DB0252C19DC1F +20111016145709 2 6 100 3071 5 E6846A58148AC762DD0CA90662E5626D0C5647E5C8CE7D6190997846FB17A509767A28E1E7B5F1AD994407661C1225E05F37EE490AA3C4C5AE757129BE9EEC5DEDD6501D26F43C2CC0A1E1FF7D11A55616D02061E20573AC75DAB592D55C781608B8A20CB3DA2EB9C2C4C2FDA0CF1E083B6CFB43772FEFE969FDF56FA96EBCBFB4110384CBF0307F2DB59954BADE376AEB544ABAA269D39DE57EC52E7CEB5E7A5855BA1523CB774D387F4C018E66BFCDC81CCE6E59A2E9BD9D0E788E6DA081B1588173E0C3C7D7BEC6625D62AFB21B9E1228FD2620E3C257DECFB079DEEBD43EEC3FD8B67AF6D41FB7355BD184796D66FFEB384DB41C7D14ECFDDAF59F845B351D55E24AE97CBD3C21B093E58BF51AEE312A561B9B7C532C859547E1E19D539378B8B806B3ECC2AD7C0ADBC628AAB91DEBC5FA329C2E71F678F962BC12305316936D5A5063411610632451C837D83806B98DD038548592A2910C4BF4713FDF8BFD70897697FFF17B7F59FD8AD505103EEAB7A39BE1BDECD2833DB0252EFF7C87 +20111016152316 2 6 100 3071 5 E6846A58148AC762DD0CA90662E5626D0C5647E5C8CE7D6190997846FB17A509767A28E1E7B5F1AD994407661C1225E05F37EE490AA3C4C5AE757129BE9EEC5DEDD6501D26F43C2CC0A1E1FF7D11A55616D02061E20573AC75DAB592D55C781608B8A20CB3DA2EB9C2C4C2FDA0CF1E083B6CFB43772FEFE969FDF56FA96EBCBFB4110384CBF0307F2DB59954BADE376AEB544ABAA269D39DE57EC52E7CEB5E7A5855BA1523CB774D387F4C018E66BFCDC81CCE6E59A2E9BD9D0E788E6DA081B1588173E0C3C7D7BEC6625D62AFB21B9E1228FD2620E3C257DECFB079DEEBD43EEC3FD8B67AF6D41FB7355BD184796D66FFEB384DB41C7D14ECFDDAF59F845B351D55E24AE97CBD3C21B093E58BF51AEE312A561B9B7C532C859547E1E19D539378B8B806B3ECC2AD7C0ADBC628AAB91DEBC5FA329C2E71F678F962BC12305316936D5A5063411610632451C837D83806B98DD038548592A2910C4BF4713FDF8BFD70897697FFF17B7F59FD8AD505103EEAB7A39BE1BDECD2833DB02531269677 +20111016153558 2 6 100 3071 2 E6846A58148AC762DD0CA90662E5626D0C5647E5C8CE7D6190997846FB17A509767A28E1E7B5F1AD994407661C1225E05F37EE490AA3C4C5AE757129BE9EEC5DEDD6501D26F43C2CC0A1E1FF7D11A55616D02061E20573AC75DAB592D55C781608B8A20CB3DA2EB9C2C4C2FDA0CF1E083B6CFB43772FEFE969FDF56FA96EBCBFB4110384CBF0307F2DB59954BADE376AEB544ABAA269D39DE57EC52E7CEB5E7A5855BA1523CB774D387F4C018E66BFCDC81CCE6E59A2E9BD9D0E788E6DA081B1588173E0C3C7D7BEC6625D62AFB21B9E1228FD2620E3C257DECFB079DEEBD43EEC3FD8B67AF6D41FB7355BD184796D66FFEB384DB41C7D14ECFDDAF59F845B351D55E24AE97CBD3C21B093E58BF51AEE312A561B9B7C532C859547E1E19D539378B8B806B3ECC2AD7C0ADBC628AAB91DEBC5FA329C2E71F678F962BC12305316936D5A5063411610632451C837D83806B98DD038548592A2910C4BF4713FDF8BFD70897697FFF17B7F59FD8AD505103EEAB7A39BE1BDECD2833DB025322E1E9B +20111016154232 2 6 100 3071 2 E6846A58148AC762DD0CA90662E5626D0C5647E5C8CE7D6190997846FB17A509767A28E1E7B5F1AD994407661C1225E05F37EE490AA3C4C5AE757129BE9EEC5DEDD6501D26F43C2CC0A1E1FF7D11A55616D02061E20573AC75DAB592D55C781608B8A20CB3DA2EB9C2C4C2FDA0CF1E083B6CFB43772FEFE969FDF56FA96EBCBFB4110384CBF0307F2DB59954BADE376AEB544ABAA269D39DE57EC52E7CEB5E7A5855BA1523CB774D387F4C018E66BFCDC81CCE6E59A2E9BD9D0E788E6DA081B1588173E0C3C7D7BEC6625D62AFB21B9E1228FD2620E3C257DECFB079DEEBD43EEC3FD8B67AF6D41FB7355BD184796D66FFEB384DB41C7D14ECFDDAF59F845B351D55E24AE97CBD3C21B093E58BF51AEE312A561B9B7C532C859547E1E19D539378B8B806B3ECC2AD7C0ADBC628AAB91DEBC5FA329C2E71F678F962BC12305316936D5A5063411610632451C837D83806B98DD038548592A2910C4BF4713FDF8BFD70897697FFF17B7F59FD8AD505103EEAB7A39BE1BDECD2833DB02532B0D1E3 +20111016154831 2 6 100 3071 2 E6846A58148AC762DD0CA90662E5626D0C5647E5C8CE7D6190997846FB17A509767A28E1E7B5F1AD994407661C1225E05F37EE490AA3C4C5AE757129BE9EEC5DEDD6501D26F43C2CC0A1E1FF7D11A55616D02061E20573AC75DAB592D55C781608B8A20CB3DA2EB9C2C4C2FDA0CF1E083B6CFB43772FEFE969FDF56FA96EBCBFB4110384CBF0307F2DB59954BADE376AEB544ABAA269D39DE57EC52E7CEB5E7A5855BA1523CB774D387F4C018E66BFCDC81CCE6E59A2E9BD9D0E788E6DA081B1588173E0C3C7D7BEC6625D62AFB21B9E1228FD2620E3C257DECFB079DEEBD43EEC3FD8B67AF6D41FB7355BD184796D66FFEB384DB41C7D14ECFDDAF59F845B351D55E24AE97CBD3C21B093E58BF51AEE312A561B9B7C532C859547E1E19D539378B8B806B3ECC2AD7C0ADBC628AAB91DEBC5FA329C2E71F678F962BC12305316936D5A5063411610632451C837D83806B98DD038548592A2910C4BF4713FDF8BFD70897697FFF17B7F59FD8AD505103EEAB7A39BE1BDECD2833DB025332903AB +20111016154921 2 6 100 3071 2 E6846A58148AC762DD0CA90662E5626D0C5647E5C8CE7D6190997846FB17A509767A28E1E7B5F1AD994407661C1225E05F37EE490AA3C4C5AE757129BE9EEC5DEDD6501D26F43C2CC0A1E1FF7D11A55616D02061E20573AC75DAB592D55C781608B8A20CB3DA2EB9C2C4C2FDA0CF1E083B6CFB43772FEFE969FDF56FA96EBCBFB4110384CBF0307F2DB59954BADE376AEB544ABAA269D39DE57EC52E7CEB5E7A5855BA1523CB774D387F4C018E66BFCDC81CCE6E59A2E9BD9D0E788E6DA081B1588173E0C3C7D7BEC6625D62AFB21B9E1228FD2620E3C257DECFB079DEEBD43EEC3FD8B67AF6D41FB7355BD184796D66FFEB384DB41C7D14ECFDDAF59F845B351D55E24AE97CBD3C21B093E58BF51AEE312A561B9B7C532C859547E1E19D539378B8B806B3ECC2AD7C0ADBC628AAB91DEBC5FA329C2E71F678F962BC12305316936D5A5063411610632451C837D83806B98DD038548592A2910C4BF4713FDF8BFD70897697FFF17B7F59FD8AD505103EEAB7A39BE1BDECD2833DB02533323CAB +20111016155024 2 6 100 3071 5 E6846A58148AC762DD0CA90662E5626D0C5647E5C8CE7D6190997846FB17A509767A28E1E7B5F1AD994407661C1225E05F37EE490AA3C4C5AE757129BE9EEC5DEDD6501D26F43C2CC0A1E1FF7D11A55616D02061E20573AC75DAB592D55C781608B8A20CB3DA2EB9C2C4C2FDA0CF1E083B6CFB43772FEFE969FDF56FA96EBCBFB4110384CBF0307F2DB59954BADE376AEB544ABAA269D39DE57EC52E7CEB5E7A5855BA1523CB774D387F4C018E66BFCDC81CCE6E59A2E9BD9D0E788E6DA081B1588173E0C3C7D7BEC6625D62AFB21B9E1228FD2620E3C257DECFB079DEEBD43EEC3FD8B67AF6D41FB7355BD184796D66FFEB384DB41C7D14ECFDDAF59F845B351D55E24AE97CBD3C21B093E58BF51AEE312A561B9B7C532C859547E1E19D539378B8B806B3ECC2AD7C0ADBC628AAB91DEBC5FA329C2E71F678F962BC12305316936D5A5063411610632451C837D83806B98DD038548592A2910C4BF4713FDF8BFD70897697FFF17B7F59FD8AD505103EEAB7A39BE1BDECD2833DB025334024C7 +20111016155250 2 6 100 3071 5 E6846A58148AC762DD0CA90662E5626D0C5647E5C8CE7D6190997846FB17A509767A28E1E7B5F1AD994407661C1225E05F37EE490AA3C4C5AE757129BE9EEC5DEDD6501D26F43C2CC0A1E1FF7D11A55616D02061E20573AC75DAB592D55C781608B8A20CB3DA2EB9C2C4C2FDA0CF1E083B6CFB43772FEFE969FDF56FA96EBCBFB4110384CBF0307F2DB59954BADE376AEB544ABAA269D39DE57EC52E7CEB5E7A5855BA1523CB774D387F4C018E66BFCDC81CCE6E59A2E9BD9D0E788E6DA081B1588173E0C3C7D7BEC6625D62AFB21B9E1228FD2620E3C257DECFB079DEEBD43EEC3FD8B67AF6D41FB7355BD184796D66FFEB384DB41C7D14ECFDDAF59F845B351D55E24AE97CBD3C21B093E58BF51AEE312A561B9B7C532C859547E1E19D539378B8B806B3ECC2AD7C0ADBC628AAB91DEBC5FA329C2E71F678F962BC12305316936D5A5063411610632451C837D83806B98DD038548592A2910C4BF4713FDF8BFD70897697FFF17B7F59FD8AD505103EEAB7A39BE1BDECD2833DB025336A6067 +20111016155621 2 6 100 3071 5 E6846A58148AC762DD0CA90662E5626D0C5647E5C8CE7D6190997846FB17A509767A28E1E7B5F1AD994407661C1225E05F37EE490AA3C4C5AE757129BE9EEC5DEDD6501D26F43C2CC0A1E1FF7D11A55616D02061E20573AC75DAB592D55C781608B8A20CB3DA2EB9C2C4C2FDA0CF1E083B6CFB43772FEFE969FDF56FA96EBCBFB4110384CBF0307F2DB59954BADE376AEB544ABAA269D39DE57EC52E7CEB5E7A5855BA1523CB774D387F4C018E66BFCDC81CCE6E59A2E9BD9D0E788E6DA081B1588173E0C3C7D7BEC6625D62AFB21B9E1228FD2620E3C257DECFB079DEEBD43EEC3FD8B67AF6D41FB7355BD184796D66FFEB384DB41C7D14ECFDDAF59F845B351D55E24AE97CBD3C21B093E58BF51AEE312A561B9B7C532C859547E1E19D539378B8B806B3ECC2AD7C0ADBC628AAB91DEBC5FA329C2E71F678F962BC12305316936D5A5063411610632451C837D83806B98DD038548592A2910C4BF4713FDF8BFD70897697FFF17B7F59FD8AD505103EEAB7A39BE1BDECD2833DB02533AF3637 +20111016161525 2 6 100 3071 2 E6846A58148AC762DD0CA90662E5626D0C5647E5C8CE7D6190997846FB17A509767A28E1E7B5F1AD994407661C1225E05F37EE490AA3C4C5AE757129BE9EEC5DEDD6501D26F43C2CC0A1E1FF7D11A55616D02061E20573AC75DAB592D55C781608B8A20CB3DA2EB9C2C4C2FDA0CF1E083B6CFB43772FEFE969FDF56FA96EBCBFB4110384CBF0307F2DB59954BADE376AEB544ABAA269D39DE57EC52E7CEB5E7A5855BA1523CB774D387F4C018E66BFCDC81CCE6E59A2E9BD9D0E788E6DA081B1588173E0C3C7D7BEC6625D62AFB21B9E1228FD2620E3C257DECFB079DEEBD43EEC3FD8B67AF6D41FB7355BD184796D66FFEB384DB41C7D14ECFDDAF59F845B351D55E24AE97CBD3C21B093E58BF51AEE312A561B9B7C532C859547E1E19D539378B8B806B3ECC2AD7C0ADBC628AAB91DEBC5FA329C2E71F678F962BC12305316936D5A5063411610632451C837D83806B98DD038548592A2910C4BF4713FDF8BFD70897697FFF17B7F59FD8AD505103EEAB7A39BE1BDECD2833DB0253536D8F3 +20111016162555 2 6 100 3071 5 E6846A58148AC762DD0CA90662E5626D0C5647E5C8CE7D6190997846FB17A509767A28E1E7B5F1AD994407661C1225E05F37EE490AA3C4C5AE757129BE9EEC5DEDD6501D26F43C2CC0A1E1FF7D11A55616D02061E20573AC75DAB592D55C781608B8A20CB3DA2EB9C2C4C2FDA0CF1E083B6CFB43772FEFE969FDF56FA96EBCBFB4110384CBF0307F2DB59954BADE376AEB544ABAA269D39DE57EC52E7CEB5E7A5855BA1523CB774D387F4C018E66BFCDC81CCE6E59A2E9BD9D0E788E6DA081B1588173E0C3C7D7BEC6625D62AFB21B9E1228FD2620E3C257DECFB079DEEBD43EEC3FD8B67AF6D41FB7355BD184796D66FFEB384DB41C7D14ECFDDAF59F845B351D55E24AE97CBD3C21B093E58BF51AEE312A561B9B7C532C859547E1E19D539378B8B806B3ECC2AD7C0ADBC628AAB91DEBC5FA329C2E71F678F962BC12305316936D5A5063411610632451C837D83806B98DD038548592A2910C4BF4713FDF8BFD70897697FFF17B7F59FD8AD505103EEAB7A39BE1BDECD2833DB025360C11B7 +20111016163016 2 6 100 3071 5 E6846A58148AC762DD0CA90662E5626D0C5647E5C8CE7D6190997846FB17A509767A28E1E7B5F1AD994407661C1225E05F37EE490AA3C4C5AE757129BE9EEC5DEDD6501D26F43C2CC0A1E1FF7D11A55616D02061E20573AC75DAB592D55C781608B8A20CB3DA2EB9C2C4C2FDA0CF1E083B6CFB43772FEFE969FDF56FA96EBCBFB4110384CBF0307F2DB59954BADE376AEB544ABAA269D39DE57EC52E7CEB5E7A5855BA1523CB774D387F4C018E66BFCDC81CCE6E59A2E9BD9D0E788E6DA081B1588173E0C3C7D7BEC6625D62AFB21B9E1228FD2620E3C257DECFB079DEEBD43EEC3FD8B67AF6D41FB7355BD184796D66FFEB384DB41C7D14ECFDDAF59F845B351D55E24AE97CBD3C21B093E58BF51AEE312A561B9B7C532C859547E1E19D539378B8B806B3ECC2AD7C0ADBC628AAB91DEBC5FA329C2E71F678F962BC12305316936D5A5063411610632451C837D83806B98DD038548592A2910C4BF4713FDF8BFD70897697FFF17B7F59FD8AD505103EEAB7A39BE1BDECD2833DB025365EBB6F +20111016174236 2 6 100 4095 5 F5D3849D2092FD427B4EBD838EA4830397A55F80B644626320DBBE51E8F63ED88148D787C94E7E67E4F393F26C565E1992B0CFF8A47A953439462A4D0FFA5763EF60FF908F8EE6C4F6EF9F32B9BA50F01AD56FE7EBE90876A5CF61813A4AD4BA7EC0704303C9BF887D36ABBD6C2AA9545FC2263232927E731060F5C701C96DC34016636DF438CE30973715F121D767CFB98B5D09AE7B86FA36A051AD3C2941A295A68E2F583A56BC69913EC9D25ABEF4FDF1E31EDE827A02620DB058B9F041DA051C8C0F13B132C17CEB893FA7C4CD8D8FEEBD82C5F9120CB221B8E88C5FE4DC17CA020A535484C92C7D4BEE69C7703E1FA9A652D444C80065342C6EC0FAC23C24DE246E3DEE72CA8BC8BECCDADE2B36771EFCC350558268F5352AE53F2F71DB62249AD9AC4FABDD6DFB099C6CFF8C05BDEA894390F9860F011CCA046DFEB2F6EF81094E7980BE526742706D1F3DB920DB107409291BB4C11F9A7DCBFAF26D808E6F9FE636B26B939DE419129E86B1E632C60EC23B65C815723C5D861AF068FD0AC8B37F4C06ECBD5CB2EF069CA8DAAC5CBD67C6182A65FED656D0DFBBB8A430B1DBAC7BD6303BEC8DE078FE69F443A7BC8131A284D25DC2844F096240BFC61B62E91A87802987659B884C094C68741D29AA5CA19B9457E1F9DF61C7DBBB13A61A79E4670B086027F20DA2AF4F5B020725F8828726379F429178926A1A016AFF +20111016180550 2 6 100 4095 2 F5D3849D2092FD427B4EBD838EA4830397A55F80B644626320DBBE51E8F63ED88148D787C94E7E67E4F393F26C565E1992B0CFF8A47A953439462A4D0FFA5763EF60FF908F8EE6C4F6EF9F32B9BA50F01AD56FE7EBE90876A5CF61813A4AD4BA7EC0704303C9BF887D36ABBD6C2AA9545FC2263232927E731060F5C701C96DC34016636DF438CE30973715F121D767CFB98B5D09AE7B86FA36A051AD3C2941A295A68E2F583A56BC69913EC9D25ABEF4FDF1E31EDE827A02620DB058B9F041DA051C8C0F13B132C17CEB893FA7C4CD8D8FEEBD82C5F9120CB221B8E88C5FE4DC17CA020A535484C92C7D4BEE69C7703E1FA9A652D444C80065342C6EC0FAC23C24DE246E3DEE72CA8BC8BECCDADE2B36771EFCC350558268F5352AE53F2F71DB62249AD9AC4FABDD6DFB099C6CFF8C05BDEA894390F9860F011CCA046DFEB2F6EF81094E7980BE526742706D1F3DB920DB107409291BB4C11F9A7DCBFAF26D808E6F9FE636B26B939DE419129E86B1E632C60EC23B65C815723C5D861AF068FD0AC8B37F4C06ECBD5CB2EF069CA8DAAC5CBD67C6182A65FED656D0DFBBB8A430B1DBAC7BD6303BEC8DE078FE69F443A7BC8131A284D25DC2844F096240BFC61B62E91A87802987659B884C094C68741D29AA5CA19B9457E1F9DF61C7DBBB13A61A79E4670B086027F20DA2AF4F5B020725F8828726379F429178926A1AD638E3 +20111016184221 2 6 100 4095 2 F5D3849D2092FD427B4EBD838EA4830397A55F80B644626320DBBE51E8F63ED88148D787C94E7E67E4F393F26C565E1992B0CFF8A47A953439462A4D0FFA5763EF60FF908F8EE6C4F6EF9F32B9BA50F01AD56FE7EBE90876A5CF61813A4AD4BA7EC0704303C9BF887D36ABBD6C2AA9545FC2263232927E731060F5C701C96DC34016636DF438CE30973715F121D767CFB98B5D09AE7B86FA36A051AD3C2941A295A68E2F583A56BC69913EC9D25ABEF4FDF1E31EDE827A02620DB058B9F041DA051C8C0F13B132C17CEB893FA7C4CD8D8FEEBD82C5F9120CB221B8E88C5FE4DC17CA020A535484C92C7D4BEE69C7703E1FA9A652D444C80065342C6EC0FAC23C24DE246E3DEE72CA8BC8BECCDADE2B36771EFCC350558268F5352AE53F2F71DB62249AD9AC4FABDD6DFB099C6CFF8C05BDEA894390F9860F011CCA046DFEB2F6EF81094E7980BE526742706D1F3DB920DB107409291BB4C11F9A7DCBFAF26D808E6F9FE636B26B939DE419129E86B1E632C60EC23B65C815723C5D861AF068FD0AC8B37F4C06ECBD5CB2EF069CA8DAAC5CBD67C6182A65FED656D0DFBBB8A430B1DBAC7BD6303BEC8DE078FE69F443A7BC8131A284D25DC2844F096240BFC61B62E91A87802987659B884C094C68741D29AA5CA19B9457E1F9DF61C7DBBB13A61A79E4670B086027F20DA2AF4F5B020725F8828726379F429178926A1C280E1B +20111016184933 2 6 100 4095 2 F5D3849D2092FD427B4EBD838EA4830397A55F80B644626320DBBE51E8F63ED88148D787C94E7E67E4F393F26C565E1992B0CFF8A47A953439462A4D0FFA5763EF60FF908F8EE6C4F6EF9F32B9BA50F01AD56FE7EBE90876A5CF61813A4AD4BA7EC0704303C9BF887D36ABBD6C2AA9545FC2263232927E731060F5C701C96DC34016636DF438CE30973715F121D767CFB98B5D09AE7B86FA36A051AD3C2941A295A68E2F583A56BC69913EC9D25ABEF4FDF1E31EDE827A02620DB058B9F041DA051C8C0F13B132C17CEB893FA7C4CD8D8FEEBD82C5F9120CB221B8E88C5FE4DC17CA020A535484C92C7D4BEE69C7703E1FA9A652D444C80065342C6EC0FAC23C24DE246E3DEE72CA8BC8BECCDADE2B36771EFCC350558268F5352AE53F2F71DB62249AD9AC4FABDD6DFB099C6CFF8C05BDEA894390F9860F011CCA046DFEB2F6EF81094E7980BE526742706D1F3DB920DB107409291BB4C11F9A7DCBFAF26D808E6F9FE636B26B939DE419129E86B1E632C60EC23B65C815723C5D861AF068FD0AC8B37F4C06ECBD5CB2EF069CA8DAAC5CBD67C6182A65FED656D0DFBBB8A430B1DBAC7BD6303BEC8DE078FE69F443A7BC8131A284D25DC2844F096240BFC61B62E91A87802987659B884C094C68741D29AA5CA19B9457E1F9DF61C7DBBB13A61A79E4670B086027F20DA2AF4F5B020725F8828726379F429178926A1C6693C3 +20111016190136 2 6 100 4095 5 F5D3849D2092FD427B4EBD838EA4830397A55F80B644626320DBBE51E8F63ED88148D787C94E7E67E4F393F26C565E1992B0CFF8A47A953439462A4D0FFA5763EF60FF908F8EE6C4F6EF9F32B9BA50F01AD56FE7EBE90876A5CF61813A4AD4BA7EC0704303C9BF887D36ABBD6C2AA9545FC2263232927E731060F5C701C96DC34016636DF438CE30973715F121D767CFB98B5D09AE7B86FA36A051AD3C2941A295A68E2F583A56BC69913EC9D25ABEF4FDF1E31EDE827A02620DB058B9F041DA051C8C0F13B132C17CEB893FA7C4CD8D8FEEBD82C5F9120CB221B8E88C5FE4DC17CA020A535484C92C7D4BEE69C7703E1FA9A652D444C80065342C6EC0FAC23C24DE246E3DEE72CA8BC8BECCDADE2B36771EFCC350558268F5352AE53F2F71DB62249AD9AC4FABDD6DFB099C6CFF8C05BDEA894390F9860F011CCA046DFEB2F6EF81094E7980BE526742706D1F3DB920DB107409291BB4C11F9A7DCBFAF26D808E6F9FE636B26B939DE419129E86B1E632C60EC23B65C815723C5D861AF068FD0AC8B37F4C06ECBD5CB2EF069CA8DAAC5CBD67C6182A65FED656D0DFBBB8A430B1DBAC7BD6303BEC8DE078FE69F443A7BC8131A284D25DC2844F096240BFC61B62E91A87802987659B884C094C68741D29AA5CA19B9457E1F9DF61C7DBBB13A61A79E4670B086027F20DA2AF4F5B020725F8828726379F429178926A1CD26BDF +20111016192019 2 6 100 4095 2 F5D3849D2092FD427B4EBD838EA4830397A55F80B644626320DBBE51E8F63ED88148D787C94E7E67E4F393F26C565E1992B0CFF8A47A953439462A4D0FFA5763EF60FF908F8EE6C4F6EF9F32B9BA50F01AD56FE7EBE90876A5CF61813A4AD4BA7EC0704303C9BF887D36ABBD6C2AA9545FC2263232927E731060F5C701C96DC34016636DF438CE30973715F121D767CFB98B5D09AE7B86FA36A051AD3C2941A295A68E2F583A56BC69913EC9D25ABEF4FDF1E31EDE827A02620DB058B9F041DA051C8C0F13B132C17CEB893FA7C4CD8D8FEEBD82C5F9120CB221B8E88C5FE4DC17CA020A535484C92C7D4BEE69C7703E1FA9A652D444C80065342C6EC0FAC23C24DE246E3DEE72CA8BC8BECCDADE2B36771EFCC350558268F5352AE53F2F71DB62249AD9AC4FABDD6DFB099C6CFF8C05BDEA894390F9860F011CCA046DFEB2F6EF81094E7980BE526742706D1F3DB920DB107409291BB4C11F9A7DCBFAF26D808E6F9FE636B26B939DE419129E86B1E632C60EC23B65C815723C5D861AF068FD0AC8B37F4C06ECBD5CB2EF069CA8DAAC5CBD67C6182A65FED656D0DFBBB8A430B1DBAC7BD6303BEC8DE078FE69F443A7BC8131A284D25DC2844F096240BFC61B62E91A87802987659B884C094C68741D29AA5CA19B9457E1F9DF61C7DBBB13A61A79E4670B086027F20DA2AF4F5B020725F8828726379F429178926A1D7AF093 +20111016200408 2 6 100 4095 5 F5D3849D2092FD427B4EBD838EA4830397A55F80B644626320DBBE51E8F63ED88148D787C94E7E67E4F393F26C565E1992B0CFF8A47A953439462A4D0FFA5763EF60FF908F8EE6C4F6EF9F32B9BA50F01AD56FE7EBE90876A5CF61813A4AD4BA7EC0704303C9BF887D36ABBD6C2AA9545FC2263232927E731060F5C701C96DC34016636DF438CE30973715F121D767CFB98B5D09AE7B86FA36A051AD3C2941A295A68E2F583A56BC69913EC9D25ABEF4FDF1E31EDE827A02620DB058B9F041DA051C8C0F13B132C17CEB893FA7C4CD8D8FEEBD82C5F9120CB221B8E88C5FE4DC17CA020A535484C92C7D4BEE69C7703E1FA9A652D444C80065342C6EC0FAC23C24DE246E3DEE72CA8BC8BECCDADE2B36771EFCC350558268F5352AE53F2F71DB62249AD9AC4FABDD6DFB099C6CFF8C05BDEA894390F9860F011CCA046DFEB2F6EF81094E7980BE526742706D1F3DB920DB107409291BB4C11F9A7DCBFAF26D808E6F9FE636B26B939DE419129E86B1E632C60EC23B65C815723C5D861AF068FD0AC8B37F4C06ECBD5CB2EF069CA8DAAC5CBD67C6182A65FED656D0DFBBB8A430B1DBAC7BD6303BEC8DE078FE69F443A7BC8131A284D25DC2844F096240BFC61B62E91A87802987659B884C094C68741D29AA5CA19B9457E1F9DF61C7DBBB13A61A79E4670B086027F20DA2AF4F5B020725F8828726379F429178926A1F0EA03F +20111016203816 2 6 100 4095 5 F5D3849D2092FD427B4EBD838EA4830397A55F80B644626320DBBE51E8F63ED88148D787C94E7E67E4F393F26C565E1992B0CFF8A47A953439462A4D0FFA5763EF60FF908F8EE6C4F6EF9F32B9BA50F01AD56FE7EBE90876A5CF61813A4AD4BA7EC0704303C9BF887D36ABBD6C2AA9545FC2263232927E731060F5C701C96DC34016636DF438CE30973715F121D767CFB98B5D09AE7B86FA36A051AD3C2941A295A68E2F583A56BC69913EC9D25ABEF4FDF1E31EDE827A02620DB058B9F041DA051C8C0F13B132C17CEB893FA7C4CD8D8FEEBD82C5F9120CB221B8E88C5FE4DC17CA020A535484C92C7D4BEE69C7703E1FA9A652D444C80065342C6EC0FAC23C24DE246E3DEE72CA8BC8BECCDADE2B36771EFCC350558268F5352AE53F2F71DB62249AD9AC4FABDD6DFB099C6CFF8C05BDEA894390F9860F011CCA046DFEB2F6EF81094E7980BE526742706D1F3DB920DB107409291BB4C11F9A7DCBFAF26D808E6F9FE636B26B939DE419129E86B1E632C60EC23B65C815723C5D861AF068FD0AC8B37F4C06ECBD5CB2EF069CA8DAAC5CBD67C6182A65FED656D0DFBBB8A430B1DBAC7BD6303BEC8DE078FE69F443A7BC8131A284D25DC2844F096240BFC61B62E91A87802987659B884C094C68741D29AA5CA19B9457E1F9DF61C7DBBB13A61A79E4670B086027F20DA2AF4F5B020725F8828726379F429178926A203A2C8F +20111016211011 2 6 100 4095 5 F5D3849D2092FD427B4EBD838EA4830397A55F80B644626320DBBE51E8F63ED88148D787C94E7E67E4F393F26C565E1992B0CFF8A47A953439462A4D0FFA5763EF60FF908F8EE6C4F6EF9F32B9BA50F01AD56FE7EBE90876A5CF61813A4AD4BA7EC0704303C9BF887D36ABBD6C2AA9545FC2263232927E731060F5C701C96DC34016636DF438CE30973715F121D767CFB98B5D09AE7B86FA36A051AD3C2941A295A68E2F583A56BC69913EC9D25ABEF4FDF1E31EDE827A02620DB058B9F041DA051C8C0F13B132C17CEB893FA7C4CD8D8FEEBD82C5F9120CB221B8E88C5FE4DC17CA020A535484C92C7D4BEE69C7703E1FA9A652D444C80065342C6EC0FAC23C24DE246E3DEE72CA8BC8BECCDADE2B36771EFCC350558268F5352AE53F2F71DB62249AD9AC4FABDD6DFB099C6CFF8C05BDEA894390F9860F011CCA046DFEB2F6EF81094E7980BE526742706D1F3DB920DB107409291BB4C11F9A7DCBFAF26D808E6F9FE636B26B939DE419129E86B1E632C60EC23B65C815723C5D861AF068FD0AC8B37F4C06ECBD5CB2EF069CA8DAAC5CBD67C6182A65FED656D0DFBBB8A430B1DBAC7BD6303BEC8DE078FE69F443A7BC8131A284D25DC2844F096240BFC61B62E91A87802987659B884C094C68741D29AA5CA19B9457E1F9DF61C7DBBB13A61A79E4670B086027F20DA2AF4F5B020725F8828726379F429178926A2160E077 +20111016222042 2 6 100 4095 2 F5D3849D2092FD427B4EBD838EA4830397A55F80B644626320DBBE51E8F63ED88148D787C94E7E67E4F393F26C565E1992B0CFF8A47A953439462A4D0FFA5763EF60FF908F8EE6C4F6EF9F32B9BA50F01AD56FE7EBE90876A5CF61813A4AD4BA7EC0704303C9BF887D36ABBD6C2AA9545FC2263232927E731060F5C701C96DC34016636DF438CE30973715F121D767CFB98B5D09AE7B86FA36A051AD3C2941A295A68E2F583A56BC69913EC9D25ABEF4FDF1E31EDE827A02620DB058B9F041DA051C8C0F13B132C17CEB893FA7C4CD8D8FEEBD82C5F9120CB221B8E88C5FE4DC17CA020A535484C92C7D4BEE69C7703E1FA9A652D444C80065342C6EC0FAC23C24DE246E3DEE72CA8BC8BECCDADE2B36771EFCC350558268F5352AE53F2F71DB62249AD9AC4FABDD6DFB099C6CFF8C05BDEA894390F9860F011CCA046DFEB2F6EF81094E7980BE526742706D1F3DB920DB107409291BB4C11F9A7DCBFAF26D808E6F9FE636B26B939DE419129E86B1E632C60EC23B65C815723C5D861AF068FD0AC8B37F4C06ECBD5CB2EF069CA8DAAC5CBD67C6182A65FED656D0DFBBB8A430B1DBAC7BD6303BEC8DE078FE69F443A7BC8131A284D25DC2844F096240BFC61B62E91A87802987659B884C094C68741D29AA5CA19B9457E1F9DF61C7DBBB13A61A79E4670B086027F20DA2AF4F5B020725F8828726379F429178926A23F56DCB +20111016222359 2 6 100 4095 5 F5D3849D2092FD427B4EBD838EA4830397A55F80B644626320DBBE51E8F63ED88148D787C94E7E67E4F393F26C565E1992B0CFF8A47A953439462A4D0FFA5763EF60FF908F8EE6C4F6EF9F32B9BA50F01AD56FE7EBE90876A5CF61813A4AD4BA7EC0704303C9BF887D36ABBD6C2AA9545FC2263232927E731060F5C701C96DC34016636DF438CE30973715F121D767CFB98B5D09AE7B86FA36A051AD3C2941A295A68E2F583A56BC69913EC9D25ABEF4FDF1E31EDE827A02620DB058B9F041DA051C8C0F13B132C17CEB893FA7C4CD8D8FEEBD82C5F9120CB221B8E88C5FE4DC17CA020A535484C92C7D4BEE69C7703E1FA9A652D444C80065342C6EC0FAC23C24DE246E3DEE72CA8BC8BECCDADE2B36771EFCC350558268F5352AE53F2F71DB62249AD9AC4FABDD6DFB099C6CFF8C05BDEA894390F9860F011CCA046DFEB2F6EF81094E7980BE526742706D1F3DB920DB107409291BB4C11F9A7DCBFAF26D808E6F9FE636B26B939DE419129E86B1E632C60EC23B65C815723C5D861AF068FD0AC8B37F4C06ECBD5CB2EF069CA8DAAC5CBD67C6182A65FED656D0DFBBB8A430B1DBAC7BD6303BEC8DE078FE69F443A7BC8131A284D25DC2844F096240BFC61B62E91A87802987659B884C094C68741D29AA5CA19B9457E1F9DF61C7DBBB13A61A79E4670B086027F20DA2AF4F5B020725F8828726379F429178926A240A25EF +20111016222847 2 6 100 4095 2 F5D3849D2092FD427B4EBD838EA4830397A55F80B644626320DBBE51E8F63ED88148D787C94E7E67E4F393F26C565E1992B0CFF8A47A953439462A4D0FFA5763EF60FF908F8EE6C4F6EF9F32B9BA50F01AD56FE7EBE90876A5CF61813A4AD4BA7EC0704303C9BF887D36ABBD6C2AA9545FC2263232927E731060F5C701C96DC34016636DF438CE30973715F121D767CFB98B5D09AE7B86FA36A051AD3C2941A295A68E2F583A56BC69913EC9D25ABEF4FDF1E31EDE827A02620DB058B9F041DA051C8C0F13B132C17CEB893FA7C4CD8D8FEEBD82C5F9120CB221B8E88C5FE4DC17CA020A535484C92C7D4BEE69C7703E1FA9A652D444C80065342C6EC0FAC23C24DE246E3DEE72CA8BC8BECCDADE2B36771EFCC350558268F5352AE53F2F71DB62249AD9AC4FABDD6DFB099C6CFF8C05BDEA894390F9860F011CCA046DFEB2F6EF81094E7980BE526742706D1F3DB920DB107409291BB4C11F9A7DCBFAF26D808E6F9FE636B26B939DE419129E86B1E632C60EC23B65C815723C5D861AF068FD0AC8B37F4C06ECBD5CB2EF069CA8DAAC5CBD67C6182A65FED656D0DFBBB8A430B1DBAC7BD6303BEC8DE078FE69F443A7BC8131A284D25DC2844F096240BFC61B62E91A87802987659B884C094C68741D29AA5CA19B9457E1F9DF61C7DBBB13A61A79E4670B086027F20DA2AF4F5B020725F8828726379F429178926A242BA9FB +20111016223306 2 6 100 4095 5 F5D3849D2092FD427B4EBD838EA4830397A55F80B644626320DBBE51E8F63ED88148D787C94E7E67E4F393F26C565E1992B0CFF8A47A953439462A4D0FFA5763EF60FF908F8EE6C4F6EF9F32B9BA50F01AD56FE7EBE90876A5CF61813A4AD4BA7EC0704303C9BF887D36ABBD6C2AA9545FC2263232927E731060F5C701C96DC34016636DF438CE30973715F121D767CFB98B5D09AE7B86FA36A051AD3C2941A295A68E2F583A56BC69913EC9D25ABEF4FDF1E31EDE827A02620DB058B9F041DA051C8C0F13B132C17CEB893FA7C4CD8D8FEEBD82C5F9120CB221B8E88C5FE4DC17CA020A535484C92C7D4BEE69C7703E1FA9A652D444C80065342C6EC0FAC23C24DE246E3DEE72CA8BC8BECCDADE2B36771EFCC350558268F5352AE53F2F71DB62249AD9AC4FABDD6DFB099C6CFF8C05BDEA894390F9860F011CCA046DFEB2F6EF81094E7980BE526742706D1F3DB920DB107409291BB4C11F9A7DCBFAF26D808E6F9FE636B26B939DE419129E86B1E632C60EC23B65C815723C5D861AF068FD0AC8B37F4C06ECBD5CB2EF069CA8DAAC5CBD67C6182A65FED656D0DFBBB8A430B1DBAC7BD6303BEC8DE078FE69F443A7BC8131A284D25DC2844F096240BFC61B62E91A87802987659B884C094C68741D29AA5CA19B9457E1F9DF61C7DBBB13A61A79E4670B086027F20DA2AF4F5B020725F8828726379F429178926A244B6A0F +20111016225817 2 6 100 4095 5 F5D3849D2092FD427B4EBD838EA4830397A55F80B644626320DBBE51E8F63ED88148D787C94E7E67E4F393F26C565E1992B0CFF8A47A953439462A4D0FFA5763EF60FF908F8EE6C4F6EF9F32B9BA50F01AD56FE7EBE90876A5CF61813A4AD4BA7EC0704303C9BF887D36ABBD6C2AA9545FC2263232927E731060F5C701C96DC34016636DF438CE30973715F121D767CFB98B5D09AE7B86FA36A051AD3C2941A295A68E2F583A56BC69913EC9D25ABEF4FDF1E31EDE827A02620DB058B9F041DA051C8C0F13B132C17CEB893FA7C4CD8D8FEEBD82C5F9120CB221B8E88C5FE4DC17CA020A535484C92C7D4BEE69C7703E1FA9A652D444C80065342C6EC0FAC23C24DE246E3DEE72CA8BC8BECCDADE2B36771EFCC350558268F5352AE53F2F71DB62249AD9AC4FABDD6DFB099C6CFF8C05BDEA894390F9860F011CCA046DFEB2F6EF81094E7980BE526742706D1F3DB920DB107409291BB4C11F9A7DCBFAF26D808E6F9FE636B26B939DE419129E86B1E632C60EC23B65C815723C5D861AF068FD0AC8B37F4C06ECBD5CB2EF069CA8DAAC5CBD67C6182A65FED656D0DFBBB8A430B1DBAC7BD6303BEC8DE078FE69F443A7BC8131A284D25DC2844F096240BFC61B62E91A87802987659B884C094C68741D29AA5CA19B9457E1F9DF61C7DBBB13A61A79E4670B086027F20DA2AF4F5B020725F8828726379F429178926A25319D4F +20111017013900 2 6 100 4095 2 F5D3849D2092FD427B4EBD838EA4830397A55F80B644626320DBBE51E8F63ED88148D787C94E7E67E4F393F26C565E1992B0CFF8A47A953439462A4D0FFA5763EF60FF908F8EE6C4F6EF9F32B9BA50F01AD56FE7EBE90876A5CF61813A4AD4BA7EC0704303C9BF887D36ABBD6C2AA9545FC2263232927E731060F5C701C96DC34016636DF438CE30973715F121D767CFB98B5D09AE7B86FA36A051AD3C2941A295A68E2F583A56BC69913EC9D25ABEF4FDF1E31EDE827A02620DB058B9F041DA051C8C0F13B132C17CEB893FA7C4CD8D8FEEBD82C5F9120CB221B8E88C5FE4DC17CA020A535484C92C7D4BEE69C7703E1FA9A652D444C80065342C6EC0FAC23C24DE246E3DEE72CA8BC8BECCDADE2B36771EFCC350558268F5352AE53F2F71DB62249AD9AC4FABDD6DFB099C6CFF8C05BDEA894390F9860F011CCA046DFEB2F6EF81094E7980BE526742706D1F3DB920DB107409291BB4C11F9A7DCBFAF26D808E6F9FE636B26B939DE419129E86B1E632C60EC23B65C815723C5D861AF068FD0AC8B37F4C06ECBD5CB2EF069CA8DAAC5CBD67C6182A65FED656D0DFBBB8A430B1DBAC7BD6303BEC8DE078FE69F443A7BC8131A284D25DC2844F096240BFC61B62E91A87802987659B884C094C68741D29AA5CA19B9457E1F9DF61C7DBBB13A61A79E4670B086027F20DA2AF4F5B020725F8828726379F429178926A2B06A893 +20111017020339 2 6 100 4095 5 F5D3849D2092FD427B4EBD838EA4830397A55F80B644626320DBBE51E8F63ED88148D787C94E7E67E4F393F26C565E1992B0CFF8A47A953439462A4D0FFA5763EF60FF908F8EE6C4F6EF9F32B9BA50F01AD56FE7EBE90876A5CF61813A4AD4BA7EC0704303C9BF887D36ABBD6C2AA9545FC2263232927E731060F5C701C96DC34016636DF438CE30973715F121D767CFB98B5D09AE7B86FA36A051AD3C2941A295A68E2F583A56BC69913EC9D25ABEF4FDF1E31EDE827A02620DB058B9F041DA051C8C0F13B132C17CEB893FA7C4CD8D8FEEBD82C5F9120CB221B8E88C5FE4DC17CA020A535484C92C7D4BEE69C7703E1FA9A652D444C80065342C6EC0FAC23C24DE246E3DEE72CA8BC8BECCDADE2B36771EFCC350558268F5352AE53F2F71DB62249AD9AC4FABDD6DFB099C6CFF8C05BDEA894390F9860F011CCA046DFEB2F6EF81094E7980BE526742706D1F3DB920DB107409291BB4C11F9A7DCBFAF26D808E6F9FE636B26B939DE419129E86B1E632C60EC23B65C815723C5D861AF068FD0AC8B37F4C06ECBD5CB2EF069CA8DAAC5CBD67C6182A65FED656D0DFBBB8A430B1DBAC7BD6303BEC8DE078FE69F443A7BC8131A284D25DC2844F096240BFC61B62E91A87802987659B884C094C68741D29AA5CA19B9457E1F9DF61C7DBBB13A61A79E4670B086027F20DA2AF4F5B020725F8828726379F429178926A2BE061B7 +20111017021940 2 6 100 4095 5 F5D3849D2092FD427B4EBD838EA4830397A55F80B644626320DBBE51E8F63ED88148D787C94E7E67E4F393F26C565E1992B0CFF8A47A953439462A4D0FFA5763EF60FF908F8EE6C4F6EF9F32B9BA50F01AD56FE7EBE90876A5CF61813A4AD4BA7EC0704303C9BF887D36ABBD6C2AA9545FC2263232927E731060F5C701C96DC34016636DF438CE30973715F121D767CFB98B5D09AE7B86FA36A051AD3C2941A295A68E2F583A56BC69913EC9D25ABEF4FDF1E31EDE827A02620DB058B9F041DA051C8C0F13B132C17CEB893FA7C4CD8D8FEEBD82C5F9120CB221B8E88C5FE4DC17CA020A535484C92C7D4BEE69C7703E1FA9A652D444C80065342C6EC0FAC23C24DE246E3DEE72CA8BC8BECCDADE2B36771EFCC350558268F5352AE53F2F71DB62249AD9AC4FABDD6DFB099C6CFF8C05BDEA894390F9860F011CCA046DFEB2F6EF81094E7980BE526742706D1F3DB920DB107409291BB4C11F9A7DCBFAF26D808E6F9FE636B26B939DE419129E86B1E632C60EC23B65C815723C5D861AF068FD0AC8B37F4C06ECBD5CB2EF069CA8DAAC5CBD67C6182A65FED656D0DFBBB8A430B1DBAC7BD6303BEC8DE078FE69F443A7BC8131A284D25DC2844F096240BFC61B62E91A87802987659B884C094C68741D29AA5CA19B9457E1F9DF61C7DBBB13A61A79E4670B086027F20DA2AF4F5B020725F8828726379F429178926A2C6885BF +20111017022558 2 6 100 4095 2 F5D3849D2092FD427B4EBD838EA4830397A55F80B644626320DBBE51E8F63ED88148D787C94E7E67E4F393F26C565E1992B0CFF8A47A953439462A4D0FFA5763EF60FF908F8EE6C4F6EF9F32B9BA50F01AD56FE7EBE90876A5CF61813A4AD4BA7EC0704303C9BF887D36ABBD6C2AA9545FC2263232927E731060F5C701C96DC34016636DF438CE30973715F121D767CFB98B5D09AE7B86FA36A051AD3C2941A295A68E2F583A56BC69913EC9D25ABEF4FDF1E31EDE827A02620DB058B9F041DA051C8C0F13B132C17CEB893FA7C4CD8D8FEEBD82C5F9120CB221B8E88C5FE4DC17CA020A535484C92C7D4BEE69C7703E1FA9A652D444C80065342C6EC0FAC23C24DE246E3DEE72CA8BC8BECCDADE2B36771EFCC350558268F5352AE53F2F71DB62249AD9AC4FABDD6DFB099C6CFF8C05BDEA894390F9860F011CCA046DFEB2F6EF81094E7980BE526742706D1F3DB920DB107409291BB4C11F9A7DCBFAF26D808E6F9FE636B26B939DE419129E86B1E632C60EC23B65C815723C5D861AF068FD0AC8B37F4C06ECBD5CB2EF069CA8DAAC5CBD67C6182A65FED656D0DFBBB8A430B1DBAC7BD6303BEC8DE078FE69F443A7BC8131A284D25DC2844F096240BFC61B62E91A87802987659B884C094C68741D29AA5CA19B9457E1F9DF61C7DBBB13A61A79E4670B086027F20DA2AF4F5B020725F8828726379F429178926A2C9B19CB +20111017022903 2 6 100 4095 5 F5D3849D2092FD427B4EBD838EA4830397A55F80B644626320DBBE51E8F63ED88148D787C94E7E67E4F393F26C565E1992B0CFF8A47A953439462A4D0FFA5763EF60FF908F8EE6C4F6EF9F32B9BA50F01AD56FE7EBE90876A5CF61813A4AD4BA7EC0704303C9BF887D36ABBD6C2AA9545FC2263232927E731060F5C701C96DC34016636DF438CE30973715F121D767CFB98B5D09AE7B86FA36A051AD3C2941A295A68E2F583A56BC69913EC9D25ABEF4FDF1E31EDE827A02620DB058B9F041DA051C8C0F13B132C17CEB893FA7C4CD8D8FEEBD82C5F9120CB221B8E88C5FE4DC17CA020A535484C92C7D4BEE69C7703E1FA9A652D444C80065342C6EC0FAC23C24DE246E3DEE72CA8BC8BECCDADE2B36771EFCC350558268F5352AE53F2F71DB62249AD9AC4FABDD6DFB099C6CFF8C05BDEA894390F9860F011CCA046DFEB2F6EF81094E7980BE526742706D1F3DB920DB107409291BB4C11F9A7DCBFAF26D808E6F9FE636B26B939DE419129E86B1E632C60EC23B65C815723C5D861AF068FD0AC8B37F4C06ECBD5CB2EF069CA8DAAC5CBD67C6182A65FED656D0DFBBB8A430B1DBAC7BD6303BEC8DE078FE69F443A7BC8131A284D25DC2844F096240BFC61B62E91A87802987659B884C094C68741D29AA5CA19B9457E1F9DF61C7DBBB13A61A79E4670B086027F20DA2AF4F5B020725F8828726379F429178926A2CB034D7 +20111017025209 2 6 100 4095 2 F5D3849D2092FD427B4EBD838EA4830397A55F80B644626320DBBE51E8F63ED88148D787C94E7E67E4F393F26C565E1992B0CFF8A47A953439462A4D0FFA5763EF60FF908F8EE6C4F6EF9F32B9BA50F01AD56FE7EBE90876A5CF61813A4AD4BA7EC0704303C9BF887D36ABBD6C2AA9545FC2263232927E731060F5C701C96DC34016636DF438CE30973715F121D767CFB98B5D09AE7B86FA36A051AD3C2941A295A68E2F583A56BC69913EC9D25ABEF4FDF1E31EDE827A02620DB058B9F041DA051C8C0F13B132C17CEB893FA7C4CD8D8FEEBD82C5F9120CB221B8E88C5FE4DC17CA020A535484C92C7D4BEE69C7703E1FA9A652D444C80065342C6EC0FAC23C24DE246E3DEE72CA8BC8BECCDADE2B36771EFCC350558268F5352AE53F2F71DB62249AD9AC4FABDD6DFB099C6CFF8C05BDEA894390F9860F011CCA046DFEB2F6EF81094E7980BE526742706D1F3DB920DB107409291BB4C11F9A7DCBFAF26D808E6F9FE636B26B939DE419129E86B1E632C60EC23B65C815723C5D861AF068FD0AC8B37F4C06ECBD5CB2EF069CA8DAAC5CBD67C6182A65FED656D0DFBBB8A430B1DBAC7BD6303BEC8DE078FE69F443A7BC8131A284D25DC2844F096240BFC61B62E91A87802987659B884C094C68741D29AA5CA19B9457E1F9DF61C7DBBB13A61A79E4670B086027F20DA2AF4F5B020725F8828726379F429178926A2D7B4DE3 +20111017043945 2 6 100 4095 5 F5D3849D2092FD427B4EBD838EA4830397A55F80B644626320DBBE51E8F63ED88148D787C94E7E67E4F393F26C565E1992B0CFF8A47A953439462A4D0FFA5763EF60FF908F8EE6C4F6EF9F32B9BA50F01AD56FE7EBE90876A5CF61813A4AD4BA7EC0704303C9BF887D36ABBD6C2AA9545FC2263232927E731060F5C701C96DC34016636DF438CE30973715F121D767CFB98B5D09AE7B86FA36A051AD3C2941A295A68E2F583A56BC69913EC9D25ABEF4FDF1E31EDE827A02620DB058B9F041DA051C8C0F13B132C17CEB893FA7C4CD8D8FEEBD82C5F9120CB221B8E88C5FE4DC17CA020A535484C92C7D4BEE69C7703E1FA9A652D444C80065342C6EC0FAC23C24DE246E3DEE72CA8BC8BECCDADE2B36771EFCC350558268F5352AE53F2F71DB62249AD9AC4FABDD6DFB099C6CFF8C05BDEA894390F9860F011CCA046DFEB2F6EF81094E7980BE526742706D1F3DB920DB107409291BB4C11F9A7DCBFAF26D808E6F9FE636B26B939DE419129E86B1E632C60EC23B65C815723C5D861AF068FD0AC8B37F4C06ECBD5CB2EF069CA8DAAC5CBD67C6182A65FED656D0DFBBB8A430B1DBAC7BD6303BEC8DE078FE69F443A7BC8131A284D25DC2844F096240BFC61B62E91A87802987659B884C094C68741D29AA5CA19B9457E1F9DF61C7DBBB13A61A79E4670B086027F20DA2AF4F5B020725F8828726379F429178926A3151F387 +20111017044448 2 6 100 4095 5 F5D3849D2092FD427B4EBD838EA4830397A55F80B644626320DBBE51E8F63ED88148D787C94E7E67E4F393F26C565E1992B0CFF8A47A953439462A4D0FFA5763EF60FF908F8EE6C4F6EF9F32B9BA50F01AD56FE7EBE90876A5CF61813A4AD4BA7EC0704303C9BF887D36ABBD6C2AA9545FC2263232927E731060F5C701C96DC34016636DF438CE30973715F121D767CFB98B5D09AE7B86FA36A051AD3C2941A295A68E2F583A56BC69913EC9D25ABEF4FDF1E31EDE827A02620DB058B9F041DA051C8C0F13B132C17CEB893FA7C4CD8D8FEEBD82C5F9120CB221B8E88C5FE4DC17CA020A535484C92C7D4BEE69C7703E1FA9A652D444C80065342C6EC0FAC23C24DE246E3DEE72CA8BC8BECCDADE2B36771EFCC350558268F5352AE53F2F71DB62249AD9AC4FABDD6DFB099C6CFF8C05BDEA894390F9860F011CCA046DFEB2F6EF81094E7980BE526742706D1F3DB920DB107409291BB4C11F9A7DCBFAF26D808E6F9FE636B26B939DE419129E86B1E632C60EC23B65C815723C5D861AF068FD0AC8B37F4C06ECBD5CB2EF069CA8DAAC5CBD67C6182A65FED656D0DFBBB8A430B1DBAC7BD6303BEC8DE078FE69F443A7BC8131A284D25DC2844F096240BFC61B62E91A87802987659B884C094C68741D29AA5CA19B9457E1F9DF61C7DBBB13A61A79E4670B086027F20DA2AF4F5B020725F8828726379F429178926A317A826F +20111017044959 2 6 100 4095 5 F5D3849D2092FD427B4EBD838EA4830397A55F80B644626320DBBE51E8F63ED88148D787C94E7E67E4F393F26C565E1992B0CFF8A47A953439462A4D0FFA5763EF60FF908F8EE6C4F6EF9F32B9BA50F01AD56FE7EBE90876A5CF61813A4AD4BA7EC0704303C9BF887D36ABBD6C2AA9545FC2263232927E731060F5C701C96DC34016636DF438CE30973715F121D767CFB98B5D09AE7B86FA36A051AD3C2941A295A68E2F583A56BC69913EC9D25ABEF4FDF1E31EDE827A02620DB058B9F041DA051C8C0F13B132C17CEB893FA7C4CD8D8FEEBD82C5F9120CB221B8E88C5FE4DC17CA020A535484C92C7D4BEE69C7703E1FA9A652D444C80065342C6EC0FAC23C24DE246E3DEE72CA8BC8BECCDADE2B36771EFCC350558268F5352AE53F2F71DB62249AD9AC4FABDD6DFB099C6CFF8C05BDEA894390F9860F011CCA046DFEB2F6EF81094E7980BE526742706D1F3DB920DB107409291BB4C11F9A7DCBFAF26D808E6F9FE636B26B939DE419129E86B1E632C60EC23B65C815723C5D861AF068FD0AC8B37F4C06ECBD5CB2EF069CA8DAAC5CBD67C6182A65FED656D0DFBBB8A430B1DBAC7BD6303BEC8DE078FE69F443A7BC8131A284D25DC2844F096240BFC61B62E91A87802987659B884C094C68741D29AA5CA19B9457E1F9DF61C7DBBB13A61A79E4670B086027F20DA2AF4F5B020725F8828726379F429178926A31A26F87 +20111017051520 2 6 100 4095 2 F5D3849D2092FD427B4EBD838EA4830397A55F80B644626320DBBE51E8F63ED88148D787C94E7E67E4F393F26C565E1992B0CFF8A47A953439462A4D0FFA5763EF60FF908F8EE6C4F6EF9F32B9BA50F01AD56FE7EBE90876A5CF61813A4AD4BA7EC0704303C9BF887D36ABBD6C2AA9545FC2263232927E731060F5C701C96DC34016636DF438CE30973715F121D767CFB98B5D09AE7B86FA36A051AD3C2941A295A68E2F583A56BC69913EC9D25ABEF4FDF1E31EDE827A02620DB058B9F041DA051C8C0F13B132C17CEB893FA7C4CD8D8FEEBD82C5F9120CB221B8E88C5FE4DC17CA020A535484C92C7D4BEE69C7703E1FA9A652D444C80065342C6EC0FAC23C24DE246E3DEE72CA8BC8BECCDADE2B36771EFCC350558268F5352AE53F2F71DB62249AD9AC4FABDD6DFB099C6CFF8C05BDEA894390F9860F011CCA046DFEB2F6EF81094E7980BE526742706D1F3DB920DB107409291BB4C11F9A7DCBFAF26D808E6F9FE636B26B939DE419129E86B1E632C60EC23B65C815723C5D861AF068FD0AC8B37F4C06ECBD5CB2EF069CA8DAAC5CBD67C6182A65FED656D0DFBBB8A430B1DBAC7BD6303BEC8DE078FE69F443A7BC8131A284D25DC2844F096240BFC61B62E91A87802987659B884C094C68741D29AA5CA19B9457E1F9DF61C7DBBB13A61A79E4670B086027F20DA2AF4F5B020725F8828726379F429178926A32855A13 +20111017054808 2 6 100 4095 5 F5D3849D2092FD427B4EBD838EA4830397A55F80B644626320DBBE51E8F63ED88148D787C94E7E67E4F393F26C565E1992B0CFF8A47A953439462A4D0FFA5763EF60FF908F8EE6C4F6EF9F32B9BA50F01AD56FE7EBE90876A5CF61813A4AD4BA7EC0704303C9BF887D36ABBD6C2AA9545FC2263232927E731060F5C701C96DC34016636DF438CE30973715F121D767CFB98B5D09AE7B86FA36A051AD3C2941A295A68E2F583A56BC69913EC9D25ABEF4FDF1E31EDE827A02620DB058B9F041DA051C8C0F13B132C17CEB893FA7C4CD8D8FEEBD82C5F9120CB221B8E88C5FE4DC17CA020A535484C92C7D4BEE69C7703E1FA9A652D444C80065342C6EC0FAC23C24DE246E3DEE72CA8BC8BECCDADE2B36771EFCC350558268F5352AE53F2F71DB62249AD9AC4FABDD6DFB099C6CFF8C05BDEA894390F9860F011CCA046DFEB2F6EF81094E7980BE526742706D1F3DB920DB107409291BB4C11F9A7DCBFAF26D808E6F9FE636B26B939DE419129E86B1E632C60EC23B65C815723C5D861AF068FD0AC8B37F4C06ECBD5CB2EF069CA8DAAC5CBD67C6182A65FED656D0DFBBB8A430B1DBAC7BD6303BEC8DE078FE69F443A7BC8131A284D25DC2844F096240BFC61B62E91A87802987659B884C094C68741D29AA5CA19B9457E1F9DF61C7DBBB13A61A79E4670B086027F20DA2AF4F5B020725F8828726379F429178926A33B0E8DF +20111017060238 2 6 100 4095 2 F5D3849D2092FD427B4EBD838EA4830397A55F80B644626320DBBE51E8F63ED88148D787C94E7E67E4F393F26C565E1992B0CFF8A47A953439462A4D0FFA5763EF60FF908F8EE6C4F6EF9F32B9BA50F01AD56FE7EBE90876A5CF61813A4AD4BA7EC0704303C9BF887D36ABBD6C2AA9545FC2263232927E731060F5C701C96DC34016636DF438CE30973715F121D767CFB98B5D09AE7B86FA36A051AD3C2941A295A68E2F583A56BC69913EC9D25ABEF4FDF1E31EDE827A02620DB058B9F041DA051C8C0F13B132C17CEB893FA7C4CD8D8FEEBD82C5F9120CB221B8E88C5FE4DC17CA020A535484C92C7D4BEE69C7703E1FA9A652D444C80065342C6EC0FAC23C24DE246E3DEE72CA8BC8BECCDADE2B36771EFCC350558268F5352AE53F2F71DB62249AD9AC4FABDD6DFB099C6CFF8C05BDEA894390F9860F011CCA046DFEB2F6EF81094E7980BE526742706D1F3DB920DB107409291BB4C11F9A7DCBFAF26D808E6F9FE636B26B939DE419129E86B1E632C60EC23B65C815723C5D861AF068FD0AC8B37F4C06ECBD5CB2EF069CA8DAAC5CBD67C6182A65FED656D0DFBBB8A430B1DBAC7BD6303BEC8DE078FE69F443A7BC8131A284D25DC2844F096240BFC61B62E91A87802987659B884C094C68741D29AA5CA19B9457E1F9DF61C7DBBB13A61A79E4670B086027F20DA2AF4F5B020725F8828726379F429178926A342F248B +20111017065731 2 6 100 4095 2 F5D3849D2092FD427B4EBD838EA4830397A55F80B644626320DBBE51E8F63ED88148D787C94E7E67E4F393F26C565E1992B0CFF8A47A953439462A4D0FFA5763EF60FF908F8EE6C4F6EF9F32B9BA50F01AD56FE7EBE90876A5CF61813A4AD4BA7EC0704303C9BF887D36ABBD6C2AA9545FC2263232927E731060F5C701C96DC34016636DF438CE30973715F121D767CFB98B5D09AE7B86FA36A051AD3C2941A295A68E2F583A56BC69913EC9D25ABEF4FDF1E31EDE827A02620DB058B9F041DA051C8C0F13B132C17CEB893FA7C4CD8D8FEEBD82C5F9120CB221B8E88C5FE4DC17CA020A535484C92C7D4BEE69C7703E1FA9A652D444C80065342C6EC0FAC23C24DE246E3DEE72CA8BC8BECCDADE2B36771EFCC350558268F5352AE53F2F71DB62249AD9AC4FABDD6DFB099C6CFF8C05BDEA894390F9860F011CCA046DFEB2F6EF81094E7980BE526742706D1F3DB920DB107409291BB4C11F9A7DCBFAF26D808E6F9FE636B26B939DE419129E86B1E632C60EC23B65C815723C5D861AF068FD0AC8B37F4C06ECBD5CB2EF069CA8DAAC5CBD67C6182A65FED656D0DFBBB8A430B1DBAC7BD6303BEC8DE078FE69F443A7BC8131A284D25DC2844F096240BFC61B62E91A87802987659B884C094C68741D29AA5CA19B9457E1F9DF61C7DBBB13A61A79E4670B086027F20DA2AF4F5B020725F8828726379F429178926A3625C04B +20111017072929 2 6 100 4095 5 F5D3849D2092FD427B4EBD838EA4830397A55F80B644626320DBBE51E8F63ED88148D787C94E7E67E4F393F26C565E1992B0CFF8A47A953439462A4D0FFA5763EF60FF908F8EE6C4F6EF9F32B9BA50F01AD56FE7EBE90876A5CF61813A4AD4BA7EC0704303C9BF887D36ABBD6C2AA9545FC2263232927E731060F5C701C96DC34016636DF438CE30973715F121D767CFB98B5D09AE7B86FA36A051AD3C2941A295A68E2F583A56BC69913EC9D25ABEF4FDF1E31EDE827A02620DB058B9F041DA051C8C0F13B132C17CEB893FA7C4CD8D8FEEBD82C5F9120CB221B8E88C5FE4DC17CA020A535484C92C7D4BEE69C7703E1FA9A652D444C80065342C6EC0FAC23C24DE246E3DEE72CA8BC8BECCDADE2B36771EFCC350558268F5352AE53F2F71DB62249AD9AC4FABDD6DFB099C6CFF8C05BDEA894390F9860F011CCA046DFEB2F6EF81094E7980BE526742706D1F3DB920DB107409291BB4C11F9A7DCBFAF26D808E6F9FE636B26B939DE419129E86B1E632C60EC23B65C815723C5D861AF068FD0AC8B37F4C06ECBD5CB2EF069CA8DAAC5CBD67C6182A65FED656D0DFBBB8A430B1DBAC7BD6303BEC8DE078FE69F443A7BC8131A284D25DC2844F096240BFC61B62E91A87802987659B884C094C68741D29AA5CA19B9457E1F9DF61C7DBBB13A61A79E4670B086027F20DA2AF4F5B020725F8828726379F429178926A3741BA1F +20111017073730 2 6 100 4095 2 F5D3849D2092FD427B4EBD838EA4830397A55F80B644626320DBBE51E8F63ED88148D787C94E7E67E4F393F26C565E1992B0CFF8A47A953439462A4D0FFA5763EF60FF908F8EE6C4F6EF9F32B9BA50F01AD56FE7EBE90876A5CF61813A4AD4BA7EC0704303C9BF887D36ABBD6C2AA9545FC2263232927E731060F5C701C96DC34016636DF438CE30973715F121D767CFB98B5D09AE7B86FA36A051AD3C2941A295A68E2F583A56BC69913EC9D25ABEF4FDF1E31EDE827A02620DB058B9F041DA051C8C0F13B132C17CEB893FA7C4CD8D8FEEBD82C5F9120CB221B8E88C5FE4DC17CA020A535484C92C7D4BEE69C7703E1FA9A652D444C80065342C6EC0FAC23C24DE246E3DEE72CA8BC8BECCDADE2B36771EFCC350558268F5352AE53F2F71DB62249AD9AC4FABDD6DFB099C6CFF8C05BDEA894390F9860F011CCA046DFEB2F6EF81094E7980BE526742706D1F3DB920DB107409291BB4C11F9A7DCBFAF26D808E6F9FE636B26B939DE419129E86B1E632C60EC23B65C815723C5D861AF068FD0AC8B37F4C06ECBD5CB2EF069CA8DAAC5CBD67C6182A65FED656D0DFBBB8A430B1DBAC7BD6303BEC8DE078FE69F443A7BC8131A284D25DC2844F096240BFC61B62E91A87802987659B884C094C68741D29AA5CA19B9457E1F9DF61C7DBBB13A61A79E4670B086027F20DA2AF4F5B020725F8828726379F429178926A37848973 +20111017073836 2 6 100 4095 5 F5D3849D2092FD427B4EBD838EA4830397A55F80B644626320DBBE51E8F63ED88148D787C94E7E67E4F393F26C565E1992B0CFF8A47A953439462A4D0FFA5763EF60FF908F8EE6C4F6EF9F32B9BA50F01AD56FE7EBE90876A5CF61813A4AD4BA7EC0704303C9BF887D36ABBD6C2AA9545FC2263232927E731060F5C701C96DC34016636DF438CE30973715F121D767CFB98B5D09AE7B86FA36A051AD3C2941A295A68E2F583A56BC69913EC9D25ABEF4FDF1E31EDE827A02620DB058B9F041DA051C8C0F13B132C17CEB893FA7C4CD8D8FEEBD82C5F9120CB221B8E88C5FE4DC17CA020A535484C92C7D4BEE69C7703E1FA9A652D444C80065342C6EC0FAC23C24DE246E3DEE72CA8BC8BECCDADE2B36771EFCC350558268F5352AE53F2F71DB62249AD9AC4FABDD6DFB099C6CFF8C05BDEA894390F9860F011CCA046DFEB2F6EF81094E7980BE526742706D1F3DB920DB107409291BB4C11F9A7DCBFAF26D808E6F9FE636B26B939DE419129E86B1E632C60EC23B65C815723C5D861AF068FD0AC8B37F4C06ECBD5CB2EF069CA8DAAC5CBD67C6182A65FED656D0DFBBB8A430B1DBAC7BD6303BEC8DE078FE69F443A7BC8131A284D25DC2844F096240BFC61B62E91A87802987659B884C094C68741D29AA5CA19B9457E1F9DF61C7DBBB13A61A79E4670B086027F20DA2AF4F5B020725F8828726379F429178926A37862917 +20111017074116 2 6 100 4095 2 F5D3849D2092FD427B4EBD838EA4830397A55F80B644626320DBBE51E8F63ED88148D787C94E7E67E4F393F26C565E1992B0CFF8A47A953439462A4D0FFA5763EF60FF908F8EE6C4F6EF9F32B9BA50F01AD56FE7EBE90876A5CF61813A4AD4BA7EC0704303C9BF887D36ABBD6C2AA9545FC2263232927E731060F5C701C96DC34016636DF438CE30973715F121D767CFB98B5D09AE7B86FA36A051AD3C2941A295A68E2F583A56BC69913EC9D25ABEF4FDF1E31EDE827A02620DB058B9F041DA051C8C0F13B132C17CEB893FA7C4CD8D8FEEBD82C5F9120CB221B8E88C5FE4DC17CA020A535484C92C7D4BEE69C7703E1FA9A652D444C80065342C6EC0FAC23C24DE246E3DEE72CA8BC8BECCDADE2B36771EFCC350558268F5352AE53F2F71DB62249AD9AC4FABDD6DFB099C6CFF8C05BDEA894390F9860F011CCA046DFEB2F6EF81094E7980BE526742706D1F3DB920DB107409291BB4C11F9A7DCBFAF26D808E6F9FE636B26B939DE419129E86B1E632C60EC23B65C815723C5D861AF068FD0AC8B37F4C06ECBD5CB2EF069CA8DAAC5CBD67C6182A65FED656D0DFBBB8A430B1DBAC7BD6303BEC8DE078FE69F443A7BC8131A284D25DC2844F096240BFC61B62E91A87802987659B884C094C68741D29AA5CA19B9457E1F9DF61C7DBBB13A61A79E4670B086027F20DA2AF4F5B020725F8828726379F429178926A3797039B +20111007105655 2 6 100 6143 2 EEECABB15BA767CF1068832B8CA6FB7D86A7B3CD2A23BDBB1D0718A821586412C0A65556B7BE9512DE675D290A8008634E7AFFE1962ED92137ADDF2A5A26D1C980029F732AC12AF544CE2B8E95760E5BE78DDEC7AF5D9120D466A20E48ECAE1A0F852221E35FB3DE98108BF906BB410388964A889D85EC2B0C68A5B8FAB9ECD364594E9B8DF61159A07BFA2589D2AC0879BCAB1EACE52C5CBD0E9F1F399487877AB032C8B4C20AE92D6410D39946828B19B10EEA02F462534E72140AD79E8DBAD531967EACF160CF74ED011988AE5FC17519989CCDF1AD354A3CC2B55B80B84D2FCF6AC81B1DB5435813638ECFC58FDCA058F46B67644C968810557B9873AEAFBBB8FC43D0C91A78ECF8828BC8FA3240D8F9CE5F5759FA36D4A5E80E4EAD83497A5772C0A6225FACB02F932C497426503F4306DC2312A167837FD50EB9D63CC3FDDF10D195CE61842596A85B54BC1A3B0D0459D1A32D2CE1B30161A04B0E9B98F79045E77303A95EC6BC2AAAFEC305826C1DEBEB1015C16F30E07A19C7CAB3D0ADCF2DD4158ADCFE75E1A26033C83C1AEDBEC09D509C301A558179EE7D32ACFFB9826075CBC649F10FB32134375223DB0F5232F1FD7DFB0151E4FF24135A97F331F3B8BD6B0BDF8E1CC56E144B3FE8C9A77F2E5077F15C461F0F3900F91615F84EE3D42078AAEAF60DFF47D79139B6FBB920CF901D66C86D81A360F267BFBACAC6528D0558B1A4388B18C94479AC6F5EB70B148617A90056533149C38311FD4149AD54C5D47607A5D67D30DB70B9F4C4DB59FFC4D765B1866EBCEAD21F0F4C19633F76A33D341E62BD5861C94C24490AAB34FECA441CAF9F2E2979423E061B5FFE5A3E12335204354AE4CE57D882DB502E0EC7AF792F2BBED91CE6D980B810BE44E72BC326A853FD0BB9752278899FF24DFC97ACBA85FDFCDA0CBD8D1D51ABCD71F75BC85A4EDE9989AEAE0EE94D22AB01346FB5B5349CDD0163BD98CE835E44AF09E1EC550950BC0D146D391E353DC70FC995A1435B2B9A0BCF88F1D48822CFFB27AEFA112B8487AD96E84F0FC5F9B032659FBE156E50BCC9553F0B29C5D603 +20111007105938 2 6 100 6143 2 EEECABB15BA767CF1068832B8CA6FB7D86A7B3CD2A23BDBB1D0718A821586412C0A65556B7BE9512DE675D290A8008634E7AFFE1962ED92137ADDF2A5A26D1C980029F732AC12AF544CE2B8E95760E5BE78DDEC7AF5D9120D466A20E48ECAE1A0F852221E35FB3DE98108BF906BB410388964A889D85EC2B0C68A5B8FAB9ECD364594E9B8DF61159A07BFA2589D2AC0879BCAB1EACE52C5CBD0E9F1F399487877AB032C8B4C20AE92D6410D39946828B19B10EEA02F462534E72140AD79E8DBAD531967EACF160CF74ED011988AE5FC17519989CCDF1AD354A3CC2B55B80B84D2FCF6AC81B1DB5435813638ECFC58FDCA058F46B67644C968810557B9873AEAFBBB8FC43D0C91A78ECF8828BC8FA3240D8F9CE5F5759FA36D4A5E80E4EAD83497A5772C0A6225FACB02F932C497426503F4306DC2312A167837FD50EB9D63CC3FDDF10D195CE61842596A85B54BC1A3B0D0459D1A32D2CE1B30161A04B0E9B98F79045E77303A95EC6BC2AAAFEC305826C1DEBEB1015C16F30E07A19C7CAB3D0ADCF2DD4158ADCFE75E1A26033C83C1AEDBEC09D509C301A558179EE7D32ACFFB9826075CBC649F10FB32134375223DB0F5232F1FD7DFB0151E4FF24135A97F331F3B8BD6B0BDF8E1CC56E144B3FE8C9A77F2E5077F15C461F0F3900F91615F84EE3D42078AAEAF60DFF47D79139B6FBB920CF901D66C86D81A360F267BFBACAC6528D0558B1A4388B18C94479AC6F5EB70B148617A90056533149C38311FD4149AD54C5D47607A5D67D30DB70B9F4C4DB59FFC4D765B1866EBCEAD21F0F4C19633F76A33D341E62BD5861C94C24490AAB34FECA441CAF9F2E2979423E061B5FFE5A3E12335204354AE4CE57D882DB502E0EC7AF792F2BBED91CE6D980B810BE44E72BC326A853FD0BB9752278899FF24DFC97ACBA85FDFCDA0CBD8D1D51ABCD71F75BC85A4EDE9989AEAE0EE94D22AB01346FB5B5349CDD0163BD98CE835E44AF09E1EC550950BC0D146D391E353DC70FC995A1435B2B9A0BCF88F1D48822CFFB27AEFA112B8487AD96E84F0FC5F9B032659FBE156E50BCC9553F0B29D7233B +20111007115211 2 6 100 6143 2 EEECABB15BA767CF1068832B8CA6FB7D86A7B3CD2A23BDBB1D0718A821586412C0A65556B7BE9512DE675D290A8008634E7AFFE1962ED92137ADDF2A5A26D1C980029F732AC12AF544CE2B8E95760E5BE78DDEC7AF5D9120D466A20E48ECAE1A0F852221E35FB3DE98108BF906BB410388964A889D85EC2B0C68A5B8FAB9ECD364594E9B8DF61159A07BFA2589D2AC0879BCAB1EACE52C5CBD0E9F1F399487877AB032C8B4C20AE92D6410D39946828B19B10EEA02F462534E72140AD79E8DBAD531967EACF160CF74ED011988AE5FC17519989CCDF1AD354A3CC2B55B80B84D2FCF6AC81B1DB5435813638ECFC58FDCA058F46B67644C968810557B9873AEAFBBB8FC43D0C91A78ECF8828BC8FA3240D8F9CE5F5759FA36D4A5E80E4EAD83497A5772C0A6225FACB02F932C497426503F4306DC2312A167837FD50EB9D63CC3FDDF10D195CE61842596A85B54BC1A3B0D0459D1A32D2CE1B30161A04B0E9B98F79045E77303A95EC6BC2AAAFEC305826C1DEBEB1015C16F30E07A19C7CAB3D0ADCF2DD4158ADCFE75E1A26033C83C1AEDBEC09D509C301A558179EE7D32ACFFB9826075CBC649F10FB32134375223DB0F5232F1FD7DFB0151E4FF24135A97F331F3B8BD6B0BDF8E1CC56E144B3FE8C9A77F2E5077F15C461F0F3900F91615F84EE3D42078AAEAF60DFF47D79139B6FBB920CF901D66C86D81A360F267BFBACAC6528D0558B1A4388B18C94479AC6F5EB70B148617A90056533149C38311FD4149AD54C5D47607A5D67D30DB70B9F4C4DB59FFC4D765B1866EBCEAD21F0F4C19633F76A33D341E62BD5861C94C24490AAB34FECA441CAF9F2E2979423E061B5FFE5A3E12335204354AE4CE57D882DB502E0EC7AF792F2BBED91CE6D980B810BE44E72BC326A853FD0BB9752278899FF24DFC97ACBA85FDFCDA0CBD8D1D51ABCD71F75BC85A4EDE9989AEAE0EE94D22AB01346FB5B5349CDD0163BD98CE835E44AF09E1EC550950BC0D146D391E353DC70FC995A1435B2B9A0BCF88F1D48822CFFB27AEFA112B8487AD96E84F0FC5F9B032659FBE156E50BCC9553F0B2BA2FE0B +20111007125656 2 6 100 6143 2 EEECABB15BA767CF1068832B8CA6FB7D86A7B3CD2A23BDBB1D0718A821586412C0A65556B7BE9512DE675D290A8008634E7AFFE1962ED92137ADDF2A5A26D1C980029F732AC12AF544CE2B8E95760E5BE78DDEC7AF5D9120D466A20E48ECAE1A0F852221E35FB3DE98108BF906BB410388964A889D85EC2B0C68A5B8FAB9ECD364594E9B8DF61159A07BFA2589D2AC0879BCAB1EACE52C5CBD0E9F1F399487877AB032C8B4C20AE92D6410D39946828B19B10EEA02F462534E72140AD79E8DBAD531967EACF160CF74ED011988AE5FC17519989CCDF1AD354A3CC2B55B80B84D2FCF6AC81B1DB5435813638ECFC58FDCA058F46B67644C968810557B9873AEAFBBB8FC43D0C91A78ECF8828BC8FA3240D8F9CE5F5759FA36D4A5E80E4EAD83497A5772C0A6225FACB02F932C497426503F4306DC2312A167837FD50EB9D63CC3FDDF10D195CE61842596A85B54BC1A3B0D0459D1A32D2CE1B30161A04B0E9B98F79045E77303A95EC6BC2AAAFEC305826C1DEBEB1015C16F30E07A19C7CAB3D0ADCF2DD4158ADCFE75E1A26033C83C1AEDBEC09D509C301A558179EE7D32ACFFB9826075CBC649F10FB32134375223DB0F5232F1FD7DFB0151E4FF24135A97F331F3B8BD6B0BDF8E1CC56E144B3FE8C9A77F2E5077F15C461F0F3900F91615F84EE3D42078AAEAF60DFF47D79139B6FBB920CF901D66C86D81A360F267BFBACAC6528D0558B1A4388B18C94479AC6F5EB70B148617A90056533149C38311FD4149AD54C5D47607A5D67D30DB70B9F4C4DB59FFC4D765B1866EBCEAD21F0F4C19633F76A33D341E62BD5861C94C24490AAB34FECA441CAF9F2E2979423E061B5FFE5A3E12335204354AE4CE57D882DB502E0EC7AF792F2BBED91CE6D980B810BE44E72BC326A853FD0BB9752278899FF24DFC97ACBA85FDFCDA0CBD8D1D51ABCD71F75BC85A4EDE9989AEAE0EE94D22AB01346FB5B5349CDD0163BD98CE835E44AF09E1EC550950BC0D146D391E353DC70FC995A1435B2B9A0BCF88F1D48822CFFB27AEFA112B8487AD96E84F0FC5F9B032659FBE156E50BCC9553F0B2DDDBECB +20111007141522 2 6 100 6143 5 EEECABB15BA767CF1068832B8CA6FB7D86A7B3CD2A23BDBB1D0718A821586412C0A65556B7BE9512DE675D290A8008634E7AFFE1962ED92137ADDF2A5A26D1C980029F732AC12AF544CE2B8E95760E5BE78DDEC7AF5D9120D466A20E48ECAE1A0F852221E35FB3DE98108BF906BB410388964A889D85EC2B0C68A5B8FAB9ECD364594E9B8DF61159A07BFA2589D2AC0879BCAB1EACE52C5CBD0E9F1F399487877AB032C8B4C20AE92D6410D39946828B19B10EEA02F462534E72140AD79E8DBAD531967EACF160CF74ED011988AE5FC17519989CCDF1AD354A3CC2B55B80B84D2FCF6AC81B1DB5435813638ECFC58FDCA058F46B67644C968810557B9873AEAFBBB8FC43D0C91A78ECF8828BC8FA3240D8F9CE5F5759FA36D4A5E80E4EAD83497A5772C0A6225FACB02F932C497426503F4306DC2312A167837FD50EB9D63CC3FDDF10D195CE61842596A85B54BC1A3B0D0459D1A32D2CE1B30161A04B0E9B98F79045E77303A95EC6BC2AAAFEC305826C1DEBEB1015C16F30E07A19C7CAB3D0ADCF2DD4158ADCFE75E1A26033C83C1AEDBEC09D509C301A558179EE7D32ACFFB9826075CBC649F10FB32134375223DB0F5232F1FD7DFB0151E4FF24135A97F331F3B8BD6B0BDF8E1CC56E144B3FE8C9A77F2E5077F15C461F0F3900F91615F84EE3D42078AAEAF60DFF47D79139B6FBB920CF901D66C86D81A360F267BFBACAC6528D0558B1A4388B18C94479AC6F5EB70B148617A90056533149C38311FD4149AD54C5D47607A5D67D30DB70B9F4C4DB59FFC4D765B1866EBCEAD21F0F4C19633F76A33D341E62BD5861C94C24490AAB34FECA441CAF9F2E2979423E061B5FFE5A3E12335204354AE4CE57D882DB502E0EC7AF792F2BBED91CE6D980B810BE44E72BC326A853FD0BB9752278899FF24DFC97ACBA85FDFCDA0CBD8D1D51ABCD71F75BC85A4EDE9989AEAE0EE94D22AB01346FB5B5349CDD0163BD98CE835E44AF09E1EC550950BC0D146D391E353DC70FC995A1435B2B9A0BCF88F1D48822CFFB27AEFA112B8487AD96E84F0FC5F9B032659FBE156E50BCC9553F0B308E49CF +20111007160248 2 6 100 6143 5 EEECABB15BA767CF1068832B8CA6FB7D86A7B3CD2A23BDBB1D0718A821586412C0A65556B7BE9512DE675D290A8008634E7AFFE1962ED92137ADDF2A5A26D1C980029F732AC12AF544CE2B8E95760E5BE78DDEC7AF5D9120D466A20E48ECAE1A0F852221E35FB3DE98108BF906BB410388964A889D85EC2B0C68A5B8FAB9ECD364594E9B8DF61159A07BFA2589D2AC0879BCAB1EACE52C5CBD0E9F1F399487877AB032C8B4C20AE92D6410D39946828B19B10EEA02F462534E72140AD79E8DBAD531967EACF160CF74ED011988AE5FC17519989CCDF1AD354A3CC2B55B80B84D2FCF6AC81B1DB5435813638ECFC58FDCA058F46B67644C968810557B9873AEAFBBB8FC43D0C91A78ECF8828BC8FA3240D8F9CE5F5759FA36D4A5E80E4EAD83497A5772C0A6225FACB02F932C497426503F4306DC2312A167837FD50EB9D63CC3FDDF10D195CE61842596A85B54BC1A3B0D0459D1A32D2CE1B30161A04B0E9B98F79045E77303A95EC6BC2AAAFEC305826C1DEBEB1015C16F30E07A19C7CAB3D0ADCF2DD4158ADCFE75E1A26033C83C1AEDBEC09D509C301A558179EE7D32ACFFB9826075CBC649F10FB32134375223DB0F5232F1FD7DFB0151E4FF24135A97F331F3B8BD6B0BDF8E1CC56E144B3FE8C9A77F2E5077F15C461F0F3900F91615F84EE3D42078AAEAF60DFF47D79139B6FBB920CF901D66C86D81A360F267BFBACAC6528D0558B1A4388B18C94479AC6F5EB70B148617A90056533149C38311FD4149AD54C5D47607A5D67D30DB70B9F4C4DB59FFC4D765B1866EBCEAD21F0F4C19633F76A33D341E62BD5861C94C24490AAB34FECA441CAF9F2E2979423E061B5FFE5A3E12335204354AE4CE57D882DB502E0EC7AF792F2BBED91CE6D980B810BE44E72BC326A853FD0BB9752278899FF24DFC97ACBA85FDFCDA0CBD8D1D51ABCD71F75BC85A4EDE9989AEAE0EE94D22AB01346FB5B5349CDD0163BD98CE835E44AF09E1EC550950BC0D146D391E353DC70FC995A1435B2B9A0BCF88F1D48822CFFB27AEFA112B8487AD96E84F0FC5F9B032659FBE156E50BCC9553F0B3440E19F +20111007190634 2 6 100 6143 2 EEECABB15BA767CF1068832B8CA6FB7D86A7B3CD2A23BDBB1D0718A821586412C0A65556B7BE9512DE675D290A8008634E7AFFE1962ED92137ADDF2A5A26D1C980029F732AC12AF544CE2B8E95760E5BE78DDEC7AF5D9120D466A20E48ECAE1A0F852221E35FB3DE98108BF906BB410388964A889D85EC2B0C68A5B8FAB9ECD364594E9B8DF61159A07BFA2589D2AC0879BCAB1EACE52C5CBD0E9F1F399487877AB032C8B4C20AE92D6410D39946828B19B10EEA02F462534E72140AD79E8DBAD531967EACF160CF74ED011988AE5FC17519989CCDF1AD354A3CC2B55B80B84D2FCF6AC81B1DB5435813638ECFC58FDCA058F46B67644C968810557B9873AEAFBBB8FC43D0C91A78ECF8828BC8FA3240D8F9CE5F5759FA36D4A5E80E4EAD83497A5772C0A6225FACB02F932C497426503F4306DC2312A167837FD50EB9D63CC3FDDF10D195CE61842596A85B54BC1A3B0D0459D1A32D2CE1B30161A04B0E9B98F79045E77303A95EC6BC2AAAFEC305826C1DEBEB1015C16F30E07A19C7CAB3D0ADCF2DD4158ADCFE75E1A26033C83C1AEDBEC09D509C301A558179EE7D32ACFFB9826075CBC649F10FB32134375223DB0F5232F1FD7DFB0151E4FF24135A97F331F3B8BD6B0BDF8E1CC56E144B3FE8C9A77F2E5077F15C461F0F3900F91615F84EE3D42078AAEAF60DFF47D79139B6FBB920CF901D66C86D81A360F267BFBACAC6528D0558B1A4388B18C94479AC6F5EB70B148617A90056533149C38311FD4149AD54C5D47607A5D67D30DB70B9F4C4DB59FFC4D765B1866EBCEAD21F0F4C19633F76A33D341E62BD5861C94C24490AAB34FECA441CAF9F2E2979423E061B5FFE5A3E12335204354AE4CE57D882DB502E0EC7AF792F2BBED91CE6D980B810BE44E72BC326A853FD0BB9752278899FF24DFC97ACBA85FDFCDA0CBD8D1D51ABCD71F75BC85A4EDE9989AEAE0EE94D22AB01346FB5B5349CDD0163BD98CE835E44AF09E1EC550950BC0D146D391E353DC70FC995A1435B2B9A0BCF88F1D48822CFFB27AEFA112B8487AD96E84F0FC5F9B032659FBE156E50BCC9553F0B3A94CB43 +20111007194444 2 6 100 6143 5 EEECABB15BA767CF1068832B8CA6FB7D86A7B3CD2A23BDBB1D0718A821586412C0A65556B7BE9512DE675D290A8008634E7AFFE1962ED92137ADDF2A5A26D1C980029F732AC12AF544CE2B8E95760E5BE78DDEC7AF5D9120D466A20E48ECAE1A0F852221E35FB3DE98108BF906BB410388964A889D85EC2B0C68A5B8FAB9ECD364594E9B8DF61159A07BFA2589D2AC0879BCAB1EACE52C5CBD0E9F1F399487877AB032C8B4C20AE92D6410D39946828B19B10EEA02F462534E72140AD79E8DBAD531967EACF160CF74ED011988AE5FC17519989CCDF1AD354A3CC2B55B80B84D2FCF6AC81B1DB5435813638ECFC58FDCA058F46B67644C968810557B9873AEAFBBB8FC43D0C91A78ECF8828BC8FA3240D8F9CE5F5759FA36D4A5E80E4EAD83497A5772C0A6225FACB02F932C497426503F4306DC2312A167837FD50EB9D63CC3FDDF10D195CE61842596A85B54BC1A3B0D0459D1A32D2CE1B30161A04B0E9B98F79045E77303A95EC6BC2AAAFEC305826C1DEBEB1015C16F30E07A19C7CAB3D0ADCF2DD4158ADCFE75E1A26033C83C1AEDBEC09D509C301A558179EE7D32ACFFB9826075CBC649F10FB32134375223DB0F5232F1FD7DFB0151E4FF24135A97F331F3B8BD6B0BDF8E1CC56E144B3FE8C9A77F2E5077F15C461F0F3900F91615F84EE3D42078AAEAF60DFF47D79139B6FBB920CF901D66C86D81A360F267BFBACAC6528D0558B1A4388B18C94479AC6F5EB70B148617A90056533149C38311FD4149AD54C5D47607A5D67D30DB70B9F4C4DB59FFC4D765B1866EBCEAD21F0F4C19633F76A33D341E62BD5861C94C24490AAB34FECA441CAF9F2E2979423E061B5FFE5A3E12335204354AE4CE57D882DB502E0EC7AF792F2BBED91CE6D980B810BE44E72BC326A853FD0BB9752278899FF24DFC97ACBA85FDFCDA0CBD8D1D51ABCD71F75BC85A4EDE9989AEAE0EE94D22AB01346FB5B5349CDD0163BD98CE835E44AF09E1EC550950BC0D146D391E353DC70FC995A1435B2B9A0BCF88F1D48822CFFB27AEFA112B8487AD96E84F0FC5F9B032659FBE156E50BCC9553F0B3BDA256F +20111007200841 2 6 100 6143 2 EEECABB15BA767CF1068832B8CA6FB7D86A7B3CD2A23BDBB1D0718A821586412C0A65556B7BE9512DE675D290A8008634E7AFFE1962ED92137ADDF2A5A26D1C980029F732AC12AF544CE2B8E95760E5BE78DDEC7AF5D9120D466A20E48ECAE1A0F852221E35FB3DE98108BF906BB410388964A889D85EC2B0C68A5B8FAB9ECD364594E9B8DF61159A07BFA2589D2AC0879BCAB1EACE52C5CBD0E9F1F399487877AB032C8B4C20AE92D6410D39946828B19B10EEA02F462534E72140AD79E8DBAD531967EACF160CF74ED011988AE5FC17519989CCDF1AD354A3CC2B55B80B84D2FCF6AC81B1DB5435813638ECFC58FDCA058F46B67644C968810557B9873AEAFBBB8FC43D0C91A78ECF8828BC8FA3240D8F9CE5F5759FA36D4A5E80E4EAD83497A5772C0A6225FACB02F932C497426503F4306DC2312A167837FD50EB9D63CC3FDDF10D195CE61842596A85B54BC1A3B0D0459D1A32D2CE1B30161A04B0E9B98F79045E77303A95EC6BC2AAAFEC305826C1DEBEB1015C16F30E07A19C7CAB3D0ADCF2DD4158ADCFE75E1A26033C83C1AEDBEC09D509C301A558179EE7D32ACFFB9826075CBC649F10FB32134375223DB0F5232F1FD7DFB0151E4FF24135A97F331F3B8BD6B0BDF8E1CC56E144B3FE8C9A77F2E5077F15C461F0F3900F91615F84EE3D42078AAEAF60DFF47D79139B6FBB920CF901D66C86D81A360F267BFBACAC6528D0558B1A4388B18C94479AC6F5EB70B148617A90056533149C38311FD4149AD54C5D47607A5D67D30DB70B9F4C4DB59FFC4D765B1866EBCEAD21F0F4C19633F76A33D341E62BD5861C94C24490AAB34FECA441CAF9F2E2979423E061B5FFE5A3E12335204354AE4CE57D882DB502E0EC7AF792F2BBED91CE6D980B810BE44E72BC326A853FD0BB9752278899FF24DFC97ACBA85FDFCDA0CBD8D1D51ABCD71F75BC85A4EDE9989AEAE0EE94D22AB01346FB5B5349CDD0163BD98CE835E44AF09E1EC550950BC0D146D391E353DC70FC995A1435B2B9A0BCF88F1D48822CFFB27AEFA112B8487AD96E84F0FC5F9B032659FBE156E50BCC9553F0B3CA3812B +20111007202834 2 6 100 6143 2 EEECABB15BA767CF1068832B8CA6FB7D86A7B3CD2A23BDBB1D0718A821586412C0A65556B7BE9512DE675D290A8008634E7AFFE1962ED92137ADDF2A5A26D1C980029F732AC12AF544CE2B8E95760E5BE78DDEC7AF5D9120D466A20E48ECAE1A0F852221E35FB3DE98108BF906BB410388964A889D85EC2B0C68A5B8FAB9ECD364594E9B8DF61159A07BFA2589D2AC0879BCAB1EACE52C5CBD0E9F1F399487877AB032C8B4C20AE92D6410D39946828B19B10EEA02F462534E72140AD79E8DBAD531967EACF160CF74ED011988AE5FC17519989CCDF1AD354A3CC2B55B80B84D2FCF6AC81B1DB5435813638ECFC58FDCA058F46B67644C968810557B9873AEAFBBB8FC43D0C91A78ECF8828BC8FA3240D8F9CE5F5759FA36D4A5E80E4EAD83497A5772C0A6225FACB02F932C497426503F4306DC2312A167837FD50EB9D63CC3FDDF10D195CE61842596A85B54BC1A3B0D0459D1A32D2CE1B30161A04B0E9B98F79045E77303A95EC6BC2AAAFEC305826C1DEBEB1015C16F30E07A19C7CAB3D0ADCF2DD4158ADCFE75E1A26033C83C1AEDBEC09D509C301A558179EE7D32ACFFB9826075CBC649F10FB32134375223DB0F5232F1FD7DFB0151E4FF24135A97F331F3B8BD6B0BDF8E1CC56E144B3FE8C9A77F2E5077F15C461F0F3900F91615F84EE3D42078AAEAF60DFF47D79139B6FBB920CF901D66C86D81A360F267BFBACAC6528D0558B1A4388B18C94479AC6F5EB70B148617A90056533149C38311FD4149AD54C5D47607A5D67D30DB70B9F4C4DB59FFC4D765B1866EBCEAD21F0F4C19633F76A33D341E62BD5861C94C24490AAB34FECA441CAF9F2E2979423E061B5FFE5A3E12335204354AE4CE57D882DB502E0EC7AF792F2BBED91CE6D980B810BE44E72BC326A853FD0BB9752278899FF24DFC97ACBA85FDFCDA0CBD8D1D51ABCD71F75BC85A4EDE9989AEAE0EE94D22AB01346FB5B5349CDD0163BD98CE835E44AF09E1EC550950BC0D146D391E353DC70FC995A1435B2B9A0BCF88F1D48822CFFB27AEFA112B8487AD96E84F0FC5F9B032659FBE156E50BCC9553F0B3D47F0CB +20111007210544 2 6 100 6143 2 EEECABB15BA767CF1068832B8CA6FB7D86A7B3CD2A23BDBB1D0718A821586412C0A65556B7BE9512DE675D290A8008634E7AFFE1962ED92137ADDF2A5A26D1C980029F732AC12AF544CE2B8E95760E5BE78DDEC7AF5D9120D466A20E48ECAE1A0F852221E35FB3DE98108BF906BB410388964A889D85EC2B0C68A5B8FAB9ECD364594E9B8DF61159A07BFA2589D2AC0879BCAB1EACE52C5CBD0E9F1F399487877AB032C8B4C20AE92D6410D39946828B19B10EEA02F462534E72140AD79E8DBAD531967EACF160CF74ED011988AE5FC17519989CCDF1AD354A3CC2B55B80B84D2FCF6AC81B1DB5435813638ECFC58FDCA058F46B67644C968810557B9873AEAFBBB8FC43D0C91A78ECF8828BC8FA3240D8F9CE5F5759FA36D4A5E80E4EAD83497A5772C0A6225FACB02F932C497426503F4306DC2312A167837FD50EB9D63CC3FDDF10D195CE61842596A85B54BC1A3B0D0459D1A32D2CE1B30161A04B0E9B98F79045E77303A95EC6BC2AAAFEC305826C1DEBEB1015C16F30E07A19C7CAB3D0ADCF2DD4158ADCFE75E1A26033C83C1AEDBEC09D509C301A558179EE7D32ACFFB9826075CBC649F10FB32134375223DB0F5232F1FD7DFB0151E4FF24135A97F331F3B8BD6B0BDF8E1CC56E144B3FE8C9A77F2E5077F15C461F0F3900F91615F84EE3D42078AAEAF60DFF47D79139B6FBB920CF901D66C86D81A360F267BFBACAC6528D0558B1A4388B18C94479AC6F5EB70B148617A90056533149C38311FD4149AD54C5D47607A5D67D30DB70B9F4C4DB59FFC4D765B1866EBCEAD21F0F4C19633F76A33D341E62BD5861C94C24490AAB34FECA441CAF9F2E2979423E061B5FFE5A3E12335204354AE4CE57D882DB502E0EC7AF792F2BBED91CE6D980B810BE44E72BC326A853FD0BB9752278899FF24DFC97ACBA85FDFCDA0CBD8D1D51ABCD71F75BC85A4EDE9989AEAE0EE94D22AB01346FB5B5349CDD0163BD98CE835E44AF09E1EC550950BC0D146D391E353DC70FC995A1435B2B9A0BCF88F1D48822CFFB27AEFA112B8487AD96E84F0FC5F9B032659FBE156E50BCC9553F0B3E7E62A3 +20111007211239 2 6 100 6143 5 EEECABB15BA767CF1068832B8CA6FB7D86A7B3CD2A23BDBB1D0718A821586412C0A65556B7BE9512DE675D290A8008634E7AFFE1962ED92137ADDF2A5A26D1C980029F732AC12AF544CE2B8E95760E5BE78DDEC7AF5D9120D466A20E48ECAE1A0F852221E35FB3DE98108BF906BB410388964A889D85EC2B0C68A5B8FAB9ECD364594E9B8DF61159A07BFA2589D2AC0879BCAB1EACE52C5CBD0E9F1F399487877AB032C8B4C20AE92D6410D39946828B19B10EEA02F462534E72140AD79E8DBAD531967EACF160CF74ED011988AE5FC17519989CCDF1AD354A3CC2B55B80B84D2FCF6AC81B1DB5435813638ECFC58FDCA058F46B67644C968810557B9873AEAFBBB8FC43D0C91A78ECF8828BC8FA3240D8F9CE5F5759FA36D4A5E80E4EAD83497A5772C0A6225FACB02F932C497426503F4306DC2312A167837FD50EB9D63CC3FDDF10D195CE61842596A85B54BC1A3B0D0459D1A32D2CE1B30161A04B0E9B98F79045E77303A95EC6BC2AAAFEC305826C1DEBEB1015C16F30E07A19C7CAB3D0ADCF2DD4158ADCFE75E1A26033C83C1AEDBEC09D509C301A558179EE7D32ACFFB9826075CBC649F10FB32134375223DB0F5232F1FD7DFB0151E4FF24135A97F331F3B8BD6B0BDF8E1CC56E144B3FE8C9A77F2E5077F15C461F0F3900F91615F84EE3D42078AAEAF60DFF47D79139B6FBB920CF901D66C86D81A360F267BFBACAC6528D0558B1A4388B18C94479AC6F5EB70B148617A90056533149C38311FD4149AD54C5D47607A5D67D30DB70B9F4C4DB59FFC4D765B1866EBCEAD21F0F4C19633F76A33D341E62BD5861C94C24490AAB34FECA441CAF9F2E2979423E061B5FFE5A3E12335204354AE4CE57D882DB502E0EC7AF792F2BBED91CE6D980B810BE44E72BC326A853FD0BB9752278899FF24DFC97ACBA85FDFCDA0CBD8D1D51ABCD71F75BC85A4EDE9989AEAE0EE94D22AB01346FB5B5349CDD0163BD98CE835E44AF09E1EC550950BC0D146D391E353DC70FC995A1435B2B9A0BCF88F1D48822CFFB27AEFA112B8487AD96E84F0FC5F9B032659FBE156E50BCC9553F0B3EAFE99F +20111007211555 2 6 100 6143 2 EEECABB15BA767CF1068832B8CA6FB7D86A7B3CD2A23BDBB1D0718A821586412C0A65556B7BE9512DE675D290A8008634E7AFFE1962ED92137ADDF2A5A26D1C980029F732AC12AF544CE2B8E95760E5BE78DDEC7AF5D9120D466A20E48ECAE1A0F852221E35FB3DE98108BF906BB410388964A889D85EC2B0C68A5B8FAB9ECD364594E9B8DF61159A07BFA2589D2AC0879BCAB1EACE52C5CBD0E9F1F399487877AB032C8B4C20AE92D6410D39946828B19B10EEA02F462534E72140AD79E8DBAD531967EACF160CF74ED011988AE5FC17519989CCDF1AD354A3CC2B55B80B84D2FCF6AC81B1DB5435813638ECFC58FDCA058F46B67644C968810557B9873AEAFBBB8FC43D0C91A78ECF8828BC8FA3240D8F9CE5F5759FA36D4A5E80E4EAD83497A5772C0A6225FACB02F932C497426503F4306DC2312A167837FD50EB9D63CC3FDDF10D195CE61842596A85B54BC1A3B0D0459D1A32D2CE1B30161A04B0E9B98F79045E77303A95EC6BC2AAAFEC305826C1DEBEB1015C16F30E07A19C7CAB3D0ADCF2DD4158ADCFE75E1A26033C83C1AEDBEC09D509C301A558179EE7D32ACFFB9826075CBC649F10FB32134375223DB0F5232F1FD7DFB0151E4FF24135A97F331F3B8BD6B0BDF8E1CC56E144B3FE8C9A77F2E5077F15C461F0F3900F91615F84EE3D42078AAEAF60DFF47D79139B6FBB920CF901D66C86D81A360F267BFBACAC6528D0558B1A4388B18C94479AC6F5EB70B148617A90056533149C38311FD4149AD54C5D47607A5D67D30DB70B9F4C4DB59FFC4D765B1866EBCEAD21F0F4C19633F76A33D341E62BD5861C94C24490AAB34FECA441CAF9F2E2979423E061B5FFE5A3E12335204354AE4CE57D882DB502E0EC7AF792F2BBED91CE6D980B810BE44E72BC326A853FD0BB9752278899FF24DFC97ACBA85FDFCDA0CBD8D1D51ABCD71F75BC85A4EDE9989AEAE0EE94D22AB01346FB5B5349CDD0163BD98CE835E44AF09E1EC550950BC0D146D391E353DC70FC995A1435B2B9A0BCF88F1D48822CFFB27AEFA112B8487AD96E84F0FC5F9B032659FBE156E50BCC9553F0B3EC3E0A3 +20111007215259 2 6 100 6143 2 EEECABB15BA767CF1068832B8CA6FB7D86A7B3CD2A23BDBB1D0718A821586412C0A65556B7BE9512DE675D290A8008634E7AFFE1962ED92137ADDF2A5A26D1C980029F732AC12AF544CE2B8E95760E5BE78DDEC7AF5D9120D466A20E48ECAE1A0F852221E35FB3DE98108BF906BB410388964A889D85EC2B0C68A5B8FAB9ECD364594E9B8DF61159A07BFA2589D2AC0879BCAB1EACE52C5CBD0E9F1F399487877AB032C8B4C20AE92D6410D39946828B19B10EEA02F462534E72140AD79E8DBAD531967EACF160CF74ED011988AE5FC17519989CCDF1AD354A3CC2B55B80B84D2FCF6AC81B1DB5435813638ECFC58FDCA058F46B67644C968810557B9873AEAFBBB8FC43D0C91A78ECF8828BC8FA3240D8F9CE5F5759FA36D4A5E80E4EAD83497A5772C0A6225FACB02F932C497426503F4306DC2312A167837FD50EB9D63CC3FDDF10D195CE61842596A85B54BC1A3B0D0459D1A32D2CE1B30161A04B0E9B98F79045E77303A95EC6BC2AAAFEC305826C1DEBEB1015C16F30E07A19C7CAB3D0ADCF2DD4158ADCFE75E1A26033C83C1AEDBEC09D509C301A558179EE7D32ACFFB9826075CBC649F10FB32134375223DB0F5232F1FD7DFB0151E4FF24135A97F331F3B8BD6B0BDF8E1CC56E144B3FE8C9A77F2E5077F15C461F0F3900F91615F84EE3D42078AAEAF60DFF47D79139B6FBB920CF901D66C86D81A360F267BFBACAC6528D0558B1A4388B18C94479AC6F5EB70B148617A90056533149C38311FD4149AD54C5D47607A5D67D30DB70B9F4C4DB59FFC4D765B1866EBCEAD21F0F4C19633F76A33D341E62BD5861C94C24490AAB34FECA441CAF9F2E2979423E061B5FFE5A3E12335204354AE4CE57D882DB502E0EC7AF792F2BBED91CE6D980B810BE44E72BC326A853FD0BB9752278899FF24DFC97ACBA85FDFCDA0CBD8D1D51ABCD71F75BC85A4EDE9989AEAE0EE94D22AB01346FB5B5349CDD0163BD98CE835E44AF09E1EC550950BC0D146D391E353DC70FC995A1435B2B9A0BCF88F1D48822CFFB27AEFA112B8487AD96E84F0FC5F9B032659FBE156E50BCC9553F0B3FFF795B +20111007222210 2 6 100 6143 5 EEECABB15BA767CF1068832B8CA6FB7D86A7B3CD2A23BDBB1D0718A821586412C0A65556B7BE9512DE675D290A8008634E7AFFE1962ED92137ADDF2A5A26D1C980029F732AC12AF544CE2B8E95760E5BE78DDEC7AF5D9120D466A20E48ECAE1A0F852221E35FB3DE98108BF906BB410388964A889D85EC2B0C68A5B8FAB9ECD364594E9B8DF61159A07BFA2589D2AC0879BCAB1EACE52C5CBD0E9F1F399487877AB032C8B4C20AE92D6410D39946828B19B10EEA02F462534E72140AD79E8DBAD531967EACF160CF74ED011988AE5FC17519989CCDF1AD354A3CC2B55B80B84D2FCF6AC81B1DB5435813638ECFC58FDCA058F46B67644C968810557B9873AEAFBBB8FC43D0C91A78ECF8828BC8FA3240D8F9CE5F5759FA36D4A5E80E4EAD83497A5772C0A6225FACB02F932C497426503F4306DC2312A167837FD50EB9D63CC3FDDF10D195CE61842596A85B54BC1A3B0D0459D1A32D2CE1B30161A04B0E9B98F79045E77303A95EC6BC2AAAFEC305826C1DEBEB1015C16F30E07A19C7CAB3D0ADCF2DD4158ADCFE75E1A26033C83C1AEDBEC09D509C301A558179EE7D32ACFFB9826075CBC649F10FB32134375223DB0F5232F1FD7DFB0151E4FF24135A97F331F3B8BD6B0BDF8E1CC56E144B3FE8C9A77F2E5077F15C461F0F3900F91615F84EE3D42078AAEAF60DFF47D79139B6FBB920CF901D66C86D81A360F267BFBACAC6528D0558B1A4388B18C94479AC6F5EB70B148617A90056533149C38311FD4149AD54C5D47607A5D67D30DB70B9F4C4DB59FFC4D765B1866EBCEAD21F0F4C19633F76A33D341E62BD5861C94C24490AAB34FECA441CAF9F2E2979423E061B5FFE5A3E12335204354AE4CE57D882DB502E0EC7AF792F2BBED91CE6D980B810BE44E72BC326A853FD0BB9752278899FF24DFC97ACBA85FDFCDA0CBD8D1D51ABCD71F75BC85A4EDE9989AEAE0EE94D22AB01346FB5B5349CDD0163BD98CE835E44AF09E1EC550950BC0D146D391E353DC70FC995A1435B2B9A0BCF88F1D48822CFFB27AEFA112B8487AD96E84F0FC5F9B032659FBE156E50BCC9553F0B40FAAAAF +20111007230624 2 6 100 6143 5 EEECABB15BA767CF1068832B8CA6FB7D86A7B3CD2A23BDBB1D0718A821586412C0A65556B7BE9512DE675D290A8008634E7AFFE1962ED92137ADDF2A5A26D1C980029F732AC12AF544CE2B8E95760E5BE78DDEC7AF5D9120D466A20E48ECAE1A0F852221E35FB3DE98108BF906BB410388964A889D85EC2B0C68A5B8FAB9ECD364594E9B8DF61159A07BFA2589D2AC0879BCAB1EACE52C5CBD0E9F1F399487877AB032C8B4C20AE92D6410D39946828B19B10EEA02F462534E72140AD79E8DBAD531967EACF160CF74ED011988AE5FC17519989CCDF1AD354A3CC2B55B80B84D2FCF6AC81B1DB5435813638ECFC58FDCA058F46B67644C968810557B9873AEAFBBB8FC43D0C91A78ECF8828BC8FA3240D8F9CE5F5759FA36D4A5E80E4EAD83497A5772C0A6225FACB02F932C497426503F4306DC2312A167837FD50EB9D63CC3FDDF10D195CE61842596A85B54BC1A3B0D0459D1A32D2CE1B30161A04B0E9B98F79045E77303A95EC6BC2AAAFEC305826C1DEBEB1015C16F30E07A19C7CAB3D0ADCF2DD4158ADCFE75E1A26033C83C1AEDBEC09D509C301A558179EE7D32ACFFB9826075CBC649F10FB32134375223DB0F5232F1FD7DFB0151E4FF24135A97F331F3B8BD6B0BDF8E1CC56E144B3FE8C9A77F2E5077F15C461F0F3900F91615F84EE3D42078AAEAF60DFF47D79139B6FBB920CF901D66C86D81A360F267BFBACAC6528D0558B1A4388B18C94479AC6F5EB70B148617A90056533149C38311FD4149AD54C5D47607A5D67D30DB70B9F4C4DB59FFC4D765B1866EBCEAD21F0F4C19633F76A33D341E62BD5861C94C24490AAB34FECA441CAF9F2E2979423E061B5FFE5A3E12335204354AE4CE57D882DB502E0EC7AF792F2BBED91CE6D980B810BE44E72BC326A853FD0BB9752278899FF24DFC97ACBA85FDFCDA0CBD8D1D51ABCD71F75BC85A4EDE9989AEAE0EE94D22AB01346FB5B5349CDD0163BD98CE835E44AF09E1EC550950BC0D146D391E353DC70FC995A1435B2B9A0BCF88F1D48822CFFB27AEFA112B8487AD96E84F0FC5F9B032659FBE156E50BCC9553F0B42759A07 +20111007232634 2 6 100 6143 2 EEECABB15BA767CF1068832B8CA6FB7D86A7B3CD2A23BDBB1D0718A821586412C0A65556B7BE9512DE675D290A8008634E7AFFE1962ED92137ADDF2A5A26D1C980029F732AC12AF544CE2B8E95760E5BE78DDEC7AF5D9120D466A20E48ECAE1A0F852221E35FB3DE98108BF906BB410388964A889D85EC2B0C68A5B8FAB9ECD364594E9B8DF61159A07BFA2589D2AC0879BCAB1EACE52C5CBD0E9F1F399487877AB032C8B4C20AE92D6410D39946828B19B10EEA02F462534E72140AD79E8DBAD531967EACF160CF74ED011988AE5FC17519989CCDF1AD354A3CC2B55B80B84D2FCF6AC81B1DB5435813638ECFC58FDCA058F46B67644C968810557B9873AEAFBBB8FC43D0C91A78ECF8828BC8FA3240D8F9CE5F5759FA36D4A5E80E4EAD83497A5772C0A6225FACB02F932C497426503F4306DC2312A167837FD50EB9D63CC3FDDF10D195CE61842596A85B54BC1A3B0D0459D1A32D2CE1B30161A04B0E9B98F79045E77303A95EC6BC2AAAFEC305826C1DEBEB1015C16F30E07A19C7CAB3D0ADCF2DD4158ADCFE75E1A26033C83C1AEDBEC09D509C301A558179EE7D32ACFFB9826075CBC649F10FB32134375223DB0F5232F1FD7DFB0151E4FF24135A97F331F3B8BD6B0BDF8E1CC56E144B3FE8C9A77F2E5077F15C461F0F3900F91615F84EE3D42078AAEAF60DFF47D79139B6FBB920CF901D66C86D81A360F267BFBACAC6528D0558B1A4388B18C94479AC6F5EB70B148617A90056533149C38311FD4149AD54C5D47607A5D67D30DB70B9F4C4DB59FFC4D765B1866EBCEAD21F0F4C19633F76A33D341E62BD5861C94C24490AAB34FECA441CAF9F2E2979423E061B5FFE5A3E12335204354AE4CE57D882DB502E0EC7AF792F2BBED91CE6D980B810BE44E72BC326A853FD0BB9752278899FF24DFC97ACBA85FDFCDA0CBD8D1D51ABCD71F75BC85A4EDE9989AEAE0EE94D22AB01346FB5B5349CDD0163BD98CE835E44AF09E1EC550950BC0D146D391E353DC70FC995A1435B2B9A0BCF88F1D48822CFFB27AEFA112B8487AD96E84F0FC5F9B032659FBE156E50BCC9553F0B431EFA63 +20111007233708 2 6 100 6143 5 EEECABB15BA767CF1068832B8CA6FB7D86A7B3CD2A23BDBB1D0718A821586412C0A65556B7BE9512DE675D290A8008634E7AFFE1962ED92137ADDF2A5A26D1C980029F732AC12AF544CE2B8E95760E5BE78DDEC7AF5D9120D466A20E48ECAE1A0F852221E35FB3DE98108BF906BB410388964A889D85EC2B0C68A5B8FAB9ECD364594E9B8DF61159A07BFA2589D2AC0879BCAB1EACE52C5CBD0E9F1F399487877AB032C8B4C20AE92D6410D39946828B19B10EEA02F462534E72140AD79E8DBAD531967EACF160CF74ED011988AE5FC17519989CCDF1AD354A3CC2B55B80B84D2FCF6AC81B1DB5435813638ECFC58FDCA058F46B67644C968810557B9873AEAFBBB8FC43D0C91A78ECF8828BC8FA3240D8F9CE5F5759FA36D4A5E80E4EAD83497A5772C0A6225FACB02F932C497426503F4306DC2312A167837FD50EB9D63CC3FDDF10D195CE61842596A85B54BC1A3B0D0459D1A32D2CE1B30161A04B0E9B98F79045E77303A95EC6BC2AAAFEC305826C1DEBEB1015C16F30E07A19C7CAB3D0ADCF2DD4158ADCFE75E1A26033C83C1AEDBEC09D509C301A558179EE7D32ACFFB9826075CBC649F10FB32134375223DB0F5232F1FD7DFB0151E4FF24135A97F331F3B8BD6B0BDF8E1CC56E144B3FE8C9A77F2E5077F15C461F0F3900F91615F84EE3D42078AAEAF60DFF47D79139B6FBB920CF901D66C86D81A360F267BFBACAC6528D0558B1A4388B18C94479AC6F5EB70B148617A90056533149C38311FD4149AD54C5D47607A5D67D30DB70B9F4C4DB59FFC4D765B1866EBCEAD21F0F4C19633F76A33D341E62BD5861C94C24490AAB34FECA441CAF9F2E2979423E061B5FFE5A3E12335204354AE4CE57D882DB502E0EC7AF792F2BBED91CE6D980B810BE44E72BC326A853FD0BB9752278899FF24DFC97ACBA85FDFCDA0CBD8D1D51ABCD71F75BC85A4EDE9989AEAE0EE94D22AB01346FB5B5349CDD0163BD98CE835E44AF09E1EC550950BC0D146D391E353DC70FC995A1435B2B9A0BCF88F1D48822CFFB27AEFA112B8487AD96E84F0FC5F9B032659FBE156E50BCC9553F0B436E7997 +20111008000107 2 6 100 6143 5 EEECABB15BA767CF1068832B8CA6FB7D86A7B3CD2A23BDBB1D0718A821586412C0A65556B7BE9512DE675D290A8008634E7AFFE1962ED92137ADDF2A5A26D1C980029F732AC12AF544CE2B8E95760E5BE78DDEC7AF5D9120D466A20E48ECAE1A0F852221E35FB3DE98108BF906BB410388964A889D85EC2B0C68A5B8FAB9ECD364594E9B8DF61159A07BFA2589D2AC0879BCAB1EACE52C5CBD0E9F1F399487877AB032C8B4C20AE92D6410D39946828B19B10EEA02F462534E72140AD79E8DBAD531967EACF160CF74ED011988AE5FC17519989CCDF1AD354A3CC2B55B80B84D2FCF6AC81B1DB5435813638ECFC58FDCA058F46B67644C968810557B9873AEAFBBB8FC43D0C91A78ECF8828BC8FA3240D8F9CE5F5759FA36D4A5E80E4EAD83497A5772C0A6225FACB02F932C497426503F4306DC2312A167837FD50EB9D63CC3FDDF10D195CE61842596A85B54BC1A3B0D0459D1A32D2CE1B30161A04B0E9B98F79045E77303A95EC6BC2AAAFEC305826C1DEBEB1015C16F30E07A19C7CAB3D0ADCF2DD4158ADCFE75E1A26033C83C1AEDBEC09D509C301A558179EE7D32ACFFB9826075CBC649F10FB32134375223DB0F5232F1FD7DFB0151E4FF24135A97F331F3B8BD6B0BDF8E1CC56E144B3FE8C9A77F2E5077F15C461F0F3900F91615F84EE3D42078AAEAF60DFF47D79139B6FBB920CF901D66C86D81A360F267BFBACAC6528D0558B1A4388B18C94479AC6F5EB70B148617A90056533149C38311FD4149AD54C5D47607A5D67D30DB70B9F4C4DB59FFC4D765B1866EBCEAD21F0F4C19633F76A33D341E62BD5861C94C24490AAB34FECA441CAF9F2E2979423E061B5FFE5A3E12335204354AE4CE57D882DB502E0EC7AF792F2BBED91CE6D980B810BE44E72BC326A853FD0BB9752278899FF24DFC97ACBA85FDFCDA0CBD8D1D51ABCD71F75BC85A4EDE9989AEAE0EE94D22AB01346FB5B5349CDD0163BD98CE835E44AF09E1EC550950BC0D146D391E353DC70FC995A1435B2B9A0BCF88F1D48822CFFB27AEFA112B8487AD96E84F0FC5F9B032659FBE156E50BCC9553F0B443671AF +20111008001457 2 6 100 6143 2 EEECABB15BA767CF1068832B8CA6FB7D86A7B3CD2A23BDBB1D0718A821586412C0A65556B7BE9512DE675D290A8008634E7AFFE1962ED92137ADDF2A5A26D1C980029F732AC12AF544CE2B8E95760E5BE78DDEC7AF5D9120D466A20E48ECAE1A0F852221E35FB3DE98108BF906BB410388964A889D85EC2B0C68A5B8FAB9ECD364594E9B8DF61159A07BFA2589D2AC0879BCAB1EACE52C5CBD0E9F1F399487877AB032C8B4C20AE92D6410D39946828B19B10EEA02F462534E72140AD79E8DBAD531967EACF160CF74ED011988AE5FC17519989CCDF1AD354A3CC2B55B80B84D2FCF6AC81B1DB5435813638ECFC58FDCA058F46B67644C968810557B9873AEAFBBB8FC43D0C91A78ECF8828BC8FA3240D8F9CE5F5759FA36D4A5E80E4EAD83497A5772C0A6225FACB02F932C497426503F4306DC2312A167837FD50EB9D63CC3FDDF10D195CE61842596A85B54BC1A3B0D0459D1A32D2CE1B30161A04B0E9B98F79045E77303A95EC6BC2AAAFEC305826C1DEBEB1015C16F30E07A19C7CAB3D0ADCF2DD4158ADCFE75E1A26033C83C1AEDBEC09D509C301A558179EE7D32ACFFB9826075CBC649F10FB32134375223DB0F5232F1FD7DFB0151E4FF24135A97F331F3B8BD6B0BDF8E1CC56E144B3FE8C9A77F2E5077F15C461F0F3900F91615F84EE3D42078AAEAF60DFF47D79139B6FBB920CF901D66C86D81A360F267BFBACAC6528D0558B1A4388B18C94479AC6F5EB70B148617A90056533149C38311FD4149AD54C5D47607A5D67D30DB70B9F4C4DB59FFC4D765B1866EBCEAD21F0F4C19633F76A33D341E62BD5861C94C24490AAB34FECA441CAF9F2E2979423E061B5FFE5A3E12335204354AE4CE57D882DB502E0EC7AF792F2BBED91CE6D980B810BE44E72BC326A853FD0BB9752278899FF24DFC97ACBA85FDFCDA0CBD8D1D51ABCD71F75BC85A4EDE9989AEAE0EE94D22AB01346FB5B5349CDD0163BD98CE835E44AF09E1EC550950BC0D146D391E353DC70FC995A1435B2B9A0BCF88F1D48822CFFB27AEFA112B8487AD96E84F0FC5F9B032659FBE156E50BCC9553F0B44A69D2B +20111006035941 2 6 100 8191 2 DC1D85A42DE4C80C1455C33938AC46F508FDBE197DF8FE8BDF59E1C8A231B1624DEDB6646D1DC4261826F11473EF3339E6B5B0303106815477E91C136E9B3EBC68397ED71BF54892DE86E5F72D23EACCB5C3D16565453F58D3DCFA28A812D11A540D1B38C29DA6531CC43F08F655E067A16248391F7AE8C506E02AF15754DAB728C250C13EAD01CFEBFAFF7480D7BF4ACC079244346B781DE51F864C830647165532155A85DA9A3AAE48EA9EF5287208F249E4C54EEF46522F2762EB44CAC8D58929DB658AB4BD9C69EEDAFF63CD7808D59DF9018779240959A43FC2FC40D55C2E12C60CFCA55DD4502BC7E3F799DBDB199CC5DC3B39825A443F33A0CFDBE157251978A986CE9208369360C26E99631E740805A73E24B0B95CFB3F7794E1D874C031FEAC1D5993FD260148BA9CFC24640A4AD34A5AB89838B24D7205E1C595618ED497BACBB4B3278454F04525AFF3FD9FC838851F50B819AF80CDF922255F86F480F9D3F37AD1196446F37801E9B98507228C649D5FF908292CFE5D0392A4E98BB77012C9D13D2CB6B94122526C4BA893A94F0D60ADBE4EDA7117AB65CDE8B3A0ED3E19301C1BA65CEF6B4080E86696F729C876CCDC403B7ED070B1BD11CD114B6FD05FA7FC7323DC5EB03AEF10CD74D9DF3548E8E7895DF418C10E97BA6D08A28EF05BFA9086F35B0A131F91B6B905C01E2CFBB6917694DF3996E4417391127BB032EB2490589B5ACFE46D689C84CAD47A0C4FD47CDAF7174B284AF05518A930E60E95DF7B07F40545EC5DF700587A42493A3BDCDB23AC834A762122C91B1E9EB303EA372D6FCA20A4BA33514B245D109805A00575E60AAA5269F6ED9B32D5794D45127D5273F4CCE7469724ED8DBAD208B501F39A2941C4F487356C6131D3C4EF02DA616F0BF39D114C92054C98FC5AE5AFEE146BBD1466E90BF81352D6B28F40E4411A7AA22D49D824A0972E3F202EDDE7AEAB34D7271CED7529E123A810CED480EAA077CD45AE6F4BBEE477CC78C5D8B54ED2531E60C9516DCB84ABD210277D2E6A1CB2F70914447ED7BE54B7081CB3A0B9FD50BDE2396DACEF196AB03D0FB6A73C0C106630E82E5F58BE2F1A94236A3B3BC1F2704CF4B59D08D1C4CDEA9A3F4C9A4856349A7AA8146F25A1AA335C60F798007FCCA3C53DCC88090B28BAEAAA9E232625A3DEE44E4DE7E0B262B02CAD4C7C03CD866F78A60798037EA9463CDEFB58F85547AF9D9D38D7B5E265F9B111BDC579E352699B766135CC148E054A8F1D22974414B86B31DF58D55AEF1780FF911154ED5B6CA0E16B2764D4E00C3A2489381953649EBCEC78541DC62663E1B38EB3B6CF791B6393137D91F4C5FE6625DFB9630C2198D78477C2A7C07C5DD8320BC8EB7C1FDD4C2D65BF3F3059FF9194EA87892C311EA1B1CF9345DF144D82EFF4A3C62EDA8E977535B83D6C86CB +20111006044651 2 6 100 8191 5 DC1D85A42DE4C80C1455C33938AC46F508FDBE197DF8FE8BDF59E1C8A231B1624DEDB6646D1DC4261826F11473EF3339E6B5B0303106815477E91C136E9B3EBC68397ED71BF54892DE86E5F72D23EACCB5C3D16565453F58D3DCFA28A812D11A540D1B38C29DA6531CC43F08F655E067A16248391F7AE8C506E02AF15754DAB728C250C13EAD01CFEBFAFF7480D7BF4ACC079244346B781DE51F864C830647165532155A85DA9A3AAE48EA9EF5287208F249E4C54EEF46522F2762EB44CAC8D58929DB658AB4BD9C69EEDAFF63CD7808D59DF9018779240959A43FC2FC40D55C2E12C60CFCA55DD4502BC7E3F799DBDB199CC5DC3B39825A443F33A0CFDBE157251978A986CE9208369360C26E99631E740805A73E24B0B95CFB3F7794E1D874C031FEAC1D5993FD260148BA9CFC24640A4AD34A5AB89838B24D7205E1C595618ED497BACBB4B3278454F04525AFF3FD9FC838851F50B819AF80CDF922255F86F480F9D3F37AD1196446F37801E9B98507228C649D5FF908292CFE5D0392A4E98BB77012C9D13D2CB6B94122526C4BA893A94F0D60ADBE4EDA7117AB65CDE8B3A0ED3E19301C1BA65CEF6B4080E86696F729C876CCDC403B7ED070B1BD11CD114B6FD05FA7FC7323DC5EB03AEF10CD74D9DF3548E8E7895DF418C10E97BA6D08A28EF05BFA9086F35B0A131F91B6B905C01E2CFBB6917694DF3996E4417391127BB032EB2490589B5ACFE46D689C84CAD47A0C4FD47CDAF7174B284AF05518A930E60E95DF7B07F40545EC5DF700587A42493A3BDCDB23AC834A762122C91B1E9EB303EA372D6FCA20A4BA33514B245D109805A00575E60AAA5269F6ED9B32D5794D45127D5273F4CCE7469724ED8DBAD208B501F39A2941C4F487356C6131D3C4EF02DA616F0BF39D114C92054C98FC5AE5AFEE146BBD1466E90BF81352D6B28F40E4411A7AA22D49D824A0972E3F202EDDE7AEAB34D7271CED7529E123A810CED480EAA077CD45AE6F4BBEE477CC78C5D8B54ED2531E60C9516DCB84ABD210277D2E6A1CB2F70914447ED7BE54B7081CB3A0B9FD50BDE2396DACEF196AB03D0FB6A73C0C106630E82E5F58BE2F1A94236A3B3BC1F2704CF4B59D08D1C4CDEA9A3F4C9A4856349A7AA8146F25A1AA335C60F798007FCCA3C53DCC88090B28BAEAAA9E232625A3DEE44E4DE7E0B262B02CAD4C7C03CD866F78A60798037EA9463CDEFB58F85547AF9D9D38D7B5E265F9B111BDC579E352699B766135CC148E054A8F1D22974414B86B31DF58D55AEF1780FF911154ED5B6CA0E16B2764D4E00C3A2489381953649EBCEC78541DC62663E1B38EB3B6CF791B6393137D91F4C5FE6625DFB9630C2198D78477C2A7C07C5DD8320BC8EB7C1FDD4C2D65BF3F3059FF9194EA87892C311EA1B1CF9345DF144D82EFF4A3C62EDA8E977535B83E2EC20F +20111006062727 2 6 100 8191 2 DC1D85A42DE4C80C1455C33938AC46F508FDBE197DF8FE8BDF59E1C8A231B1624DEDB6646D1DC4261826F11473EF3339E6B5B0303106815477E91C136E9B3EBC68397ED71BF54892DE86E5F72D23EACCB5C3D16565453F58D3DCFA28A812D11A540D1B38C29DA6531CC43F08F655E067A16248391F7AE8C506E02AF15754DAB728C250C13EAD01CFEBFAFF7480D7BF4ACC079244346B781DE51F864C830647165532155A85DA9A3AAE48EA9EF5287208F249E4C54EEF46522F2762EB44CAC8D58929DB658AB4BD9C69EEDAFF63CD7808D59DF9018779240959A43FC2FC40D55C2E12C60CFCA55DD4502BC7E3F799DBDB199CC5DC3B39825A443F33A0CFDBE157251978A986CE9208369360C26E99631E740805A73E24B0B95CFB3F7794E1D874C031FEAC1D5993FD260148BA9CFC24640A4AD34A5AB89838B24D7205E1C595618ED497BACBB4B3278454F04525AFF3FD9FC838851F50B819AF80CDF922255F86F480F9D3F37AD1196446F37801E9B98507228C649D5FF908292CFE5D0392A4E98BB77012C9D13D2CB6B94122526C4BA893A94F0D60ADBE4EDA7117AB65CDE8B3A0ED3E19301C1BA65CEF6B4080E86696F729C876CCDC403B7ED070B1BD11CD114B6FD05FA7FC7323DC5EB03AEF10CD74D9DF3548E8E7895DF418C10E97BA6D08A28EF05BFA9086F35B0A131F91B6B905C01E2CFBB6917694DF3996E4417391127BB032EB2490589B5ACFE46D689C84CAD47A0C4FD47CDAF7174B284AF05518A930E60E95DF7B07F40545EC5DF700587A42493A3BDCDB23AC834A762122C91B1E9EB303EA372D6FCA20A4BA33514B245D109805A00575E60AAA5269F6ED9B32D5794D45127D5273F4CCE7469724ED8DBAD208B501F39A2941C4F487356C6131D3C4EF02DA616F0BF39D114C92054C98FC5AE5AFEE146BBD1466E90BF81352D6B28F40E4411A7AA22D49D824A0972E3F202EDDE7AEAB34D7271CED7529E123A810CED480EAA077CD45AE6F4BBEE477CC78C5D8B54ED2531E60C9516DCB84ABD210277D2E6A1CB2F70914447ED7BE54B7081CB3A0B9FD50BDE2396DACEF196AB03D0FB6A73C0C106630E82E5F58BE2F1A94236A3B3BC1F2704CF4B59D08D1C4CDEA9A3F4C9A4856349A7AA8146F25A1AA335C60F798007FCCA3C53DCC88090B28BAEAAA9E232625A3DEE44E4DE7E0B262B02CAD4C7C03CD866F78A60798037EA9463CDEFB58F85547AF9D9D38D7B5E265F9B111BDC579E352699B766135CC148E054A8F1D22974414B86B31DF58D55AEF1780FF911154ED5B6CA0E16B2764D4E00C3A2489381953649EBCEC78541DC62663E1B38EB3B6CF791B6393137D91F4C5FE6625DFB9630C2198D78477C2A7C07C5DD8320BC8EB7C1FDD4C2D65BF3F3059FF9194EA87892C311EA1B1CF9345DF144D82EFF4A3C62EDA8E977535B83FD87D93 +20111006134408 2 6 100 8191 2 DC1D85A42DE4C80C1455C33938AC46F508FDBE197DF8FE8BDF59E1C8A231B1624DEDB6646D1DC4261826F11473EF3339E6B5B0303106815477E91C136E9B3EBC68397ED71BF54892DE86E5F72D23EACCB5C3D16565453F58D3DCFA28A812D11A540D1B38C29DA6531CC43F08F655E067A16248391F7AE8C506E02AF15754DAB728C250C13EAD01CFEBFAFF7480D7BF4ACC079244346B781DE51F864C830647165532155A85DA9A3AAE48EA9EF5287208F249E4C54EEF46522F2762EB44CAC8D58929DB658AB4BD9C69EEDAFF63CD7808D59DF9018779240959A43FC2FC40D55C2E12C60CFCA55DD4502BC7E3F799DBDB199CC5DC3B39825A443F33A0CFDBE157251978A986CE9208369360C26E99631E740805A73E24B0B95CFB3F7794E1D874C031FEAC1D5993FD260148BA9CFC24640A4AD34A5AB89838B24D7205E1C595618ED497BACBB4B3278454F04525AFF3FD9FC838851F50B819AF80CDF922255F86F480F9D3F37AD1196446F37801E9B98507228C649D5FF908292CFE5D0392A4E98BB77012C9D13D2CB6B94122526C4BA893A94F0D60ADBE4EDA7117AB65CDE8B3A0ED3E19301C1BA65CEF6B4080E86696F729C876CCDC403B7ED070B1BD11CD114B6FD05FA7FC7323DC5EB03AEF10CD74D9DF3548E8E7895DF418C10E97BA6D08A28EF05BFA9086F35B0A131F91B6B905C01E2CFBB6917694DF3996E4417391127BB032EB2490589B5ACFE46D689C84CAD47A0C4FD47CDAF7174B284AF05518A930E60E95DF7B07F40545EC5DF700587A42493A3BDCDB23AC834A762122C91B1E9EB303EA372D6FCA20A4BA33514B245D109805A00575E60AAA5269F6ED9B32D5794D45127D5273F4CCE7469724ED8DBAD208B501F39A2941C4F487356C6131D3C4EF02DA616F0BF39D114C92054C98FC5AE5AFEE146BBD1466E90BF81352D6B28F40E4411A7AA22D49D824A0972E3F202EDDE7AEAB34D7271CED7529E123A810CED480EAA077CD45AE6F4BBEE477CC78C5D8B54ED2531E60C9516DCB84ABD210277D2E6A1CB2F70914447ED7BE54B7081CB3A0B9FD50BDE2396DACEF196AB03D0FB6A73C0C106630E82E5F58BE2F1A94236A3B3BC1F2704CF4B59D08D1C4CDEA9A3F4C9A4856349A7AA8146F25A1AA335C60F798007FCCA3C53DCC88090B28BAEAAA9E232625A3DEE44E4DE7E0B262B02CAD4C7C03CD866F78A60798037EA9463CDEFB58F85547AF9D9D38D7B5E265F9B111BDC579E352699B766135CC148E054A8F1D22974414B86B31DF58D55AEF1780FF911154ED5B6CA0E16B2764D4E00C3A2489381953649EBCEC78541DC62663E1B38EB3B6CF791B6393137D91F4C5FE6625DFB9630C2198D78477C2A7C07C5DD8320BC8EB7C1FDD4C2D65BF3F3059FF9194EA87892C311EA1B1CF9345DF144D82EFF4A3C62EDA8E977535B8472BC33B +20111006170514 2 6 100 8191 2 DC1D85A42DE4C80C1455C33938AC46F508FDBE197DF8FE8BDF59E1C8A231B1624DEDB6646D1DC4261826F11473EF3339E6B5B0303106815477E91C136E9B3EBC68397ED71BF54892DE86E5F72D23EACCB5C3D16565453F58D3DCFA28A812D11A540D1B38C29DA6531CC43F08F655E067A16248391F7AE8C506E02AF15754DAB728C250C13EAD01CFEBFAFF7480D7BF4ACC079244346B781DE51F864C830647165532155A85DA9A3AAE48EA9EF5287208F249E4C54EEF46522F2762EB44CAC8D58929DB658AB4BD9C69EEDAFF63CD7808D59DF9018779240959A43FC2FC40D55C2E12C60CFCA55DD4502BC7E3F799DBDB199CC5DC3B39825A443F33A0CFDBE157251978A986CE9208369360C26E99631E740805A73E24B0B95CFB3F7794E1D874C031FEAC1D5993FD260148BA9CFC24640A4AD34A5AB89838B24D7205E1C595618ED497BACBB4B3278454F04525AFF3FD9FC838851F50B819AF80CDF922255F86F480F9D3F37AD1196446F37801E9B98507228C649D5FF908292CFE5D0392A4E98BB77012C9D13D2CB6B94122526C4BA893A94F0D60ADBE4EDA7117AB65CDE8B3A0ED3E19301C1BA65CEF6B4080E86696F729C876CCDC403B7ED070B1BD11CD114B6FD05FA7FC7323DC5EB03AEF10CD74D9DF3548E8E7895DF418C10E97BA6D08A28EF05BFA9086F35B0A131F91B6B905C01E2CFBB6917694DF3996E4417391127BB032EB2490589B5ACFE46D689C84CAD47A0C4FD47CDAF7174B284AF05518A930E60E95DF7B07F40545EC5DF700587A42493A3BDCDB23AC834A762122C91B1E9EB303EA372D6FCA20A4BA33514B245D109805A00575E60AAA5269F6ED9B32D5794D45127D5273F4CCE7469724ED8DBAD208B501F39A2941C4F487356C6131D3C4EF02DA616F0BF39D114C92054C98FC5AE5AFEE146BBD1466E90BF81352D6B28F40E4411A7AA22D49D824A0972E3F202EDDE7AEAB34D7271CED7529E123A810CED480EAA077CD45AE6F4BBEE477CC78C5D8B54ED2531E60C9516DCB84ABD210277D2E6A1CB2F70914447ED7BE54B7081CB3A0B9FD50BDE2396DACEF196AB03D0FB6A73C0C106630E82E5F58BE2F1A94236A3B3BC1F2704CF4B59D08D1C4CDEA9A3F4C9A4856349A7AA8146F25A1AA335C60F798007FCCA3C53DCC88090B28BAEAAA9E232625A3DEE44E4DE7E0B262B02CAD4C7C03CD866F78A60798037EA9463CDEFB58F85547AF9D9D38D7B5E265F9B111BDC579E352699B766135CC148E054A8F1D22974414B86B31DF58D55AEF1780FF911154ED5B6CA0E16B2764D4E00C3A2489381953649EBCEC78541DC62663E1B38EB3B6CF791B6393137D91F4C5FE6625DFB9630C2198D78477C2A7C07C5DD8320BC8EB7C1FDD4C2D65BF3F3059FF9194EA87892C311EA1B1CF9345DF144D82EFF4A3C62EDA8E977535B84A83002B +20111006194118 2 6 100 8191 2 DC1D85A42DE4C80C1455C33938AC46F508FDBE197DF8FE8BDF59E1C8A231B1624DEDB6646D1DC4261826F11473EF3339E6B5B0303106815477E91C136E9B3EBC68397ED71BF54892DE86E5F72D23EACCB5C3D16565453F58D3DCFA28A812D11A540D1B38C29DA6531CC43F08F655E067A16248391F7AE8C506E02AF15754DAB728C250C13EAD01CFEBFAFF7480D7BF4ACC079244346B781DE51F864C830647165532155A85DA9A3AAE48EA9EF5287208F249E4C54EEF46522F2762EB44CAC8D58929DB658AB4BD9C69EEDAFF63CD7808D59DF9018779240959A43FC2FC40D55C2E12C60CFCA55DD4502BC7E3F799DBDB199CC5DC3B39825A443F33A0CFDBE157251978A986CE9208369360C26E99631E740805A73E24B0B95CFB3F7794E1D874C031FEAC1D5993FD260148BA9CFC24640A4AD34A5AB89838B24D7205E1C595618ED497BACBB4B3278454F04525AFF3FD9FC838851F50B819AF80CDF922255F86F480F9D3F37AD1196446F37801E9B98507228C649D5FF908292CFE5D0392A4E98BB77012C9D13D2CB6B94122526C4BA893A94F0D60ADBE4EDA7117AB65CDE8B3A0ED3E19301C1BA65CEF6B4080E86696F729C876CCDC403B7ED070B1BD11CD114B6FD05FA7FC7323DC5EB03AEF10CD74D9DF3548E8E7895DF418C10E97BA6D08A28EF05BFA9086F35B0A131F91B6B905C01E2CFBB6917694DF3996E4417391127BB032EB2490589B5ACFE46D689C84CAD47A0C4FD47CDAF7174B284AF05518A930E60E95DF7B07F40545EC5DF700587A42493A3BDCDB23AC834A762122C91B1E9EB303EA372D6FCA20A4BA33514B245D109805A00575E60AAA5269F6ED9B32D5794D45127D5273F4CCE7469724ED8DBAD208B501F39A2941C4F487356C6131D3C4EF02DA616F0BF39D114C92054C98FC5AE5AFEE146BBD1466E90BF81352D6B28F40E4411A7AA22D49D824A0972E3F202EDDE7AEAB34D7271CED7529E123A810CED480EAA077CD45AE6F4BBEE477CC78C5D8B54ED2531E60C9516DCB84ABD210277D2E6A1CB2F70914447ED7BE54B7081CB3A0B9FD50BDE2396DACEF196AB03D0FB6A73C0C106630E82E5F58BE2F1A94236A3B3BC1F2704CF4B59D08D1C4CDEA9A3F4C9A4856349A7AA8146F25A1AA335C60F798007FCCA3C53DCC88090B28BAEAAA9E232625A3DEE44E4DE7E0B262B02CAD4C7C03CD866F78A60798037EA9463CDEFB58F85547AF9D9D38D7B5E265F9B111BDC579E352699B766135CC148E054A8F1D22974414B86B31DF58D55AEF1780FF911154ED5B6CA0E16B2764D4E00C3A2489381953649EBCEC78541DC62663E1B38EB3B6CF791B6393137D91F4C5FE6625DFB9630C2198D78477C2A7C07C5DD8320BC8EB7C1FDD4C2D65BF3F3059FF9194EA87892C311EA1B1CF9345DF144D82EFF4A3C62EDA8E977535B84D0AC8C3
diff --git a/openssh-6.0p1/moduli.0 b/openssh-6.0p1/moduli.0 new file mode 100644 index 0000000..c529488 --- /dev/null +++ b/openssh-6.0p1/moduli.0
@@ -0,0 +1,72 @@ +MODULI(5) OpenBSD Programmer's Manual MODULI(5) + +NAME + moduli - 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; (p+1)*2 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 - 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) + + Diffie-Hellman Group Exchange for the Secure Shell (SSH) Transport Layer + Protocol, RFC 4419, 2006. + +OpenBSD 5.0 October 14, 2010 OpenBSD 5.0
diff --git a/openssh-6.0p1/moduli.5 b/openssh-6.0p1/moduli.5 new file mode 100644 index 0000000..0e01b94 --- /dev/null +++ b/openssh-6.0p1/moduli.5
@@ -0,0 +1,122 @@ +.\" $OpenBSD: moduli.5,v 1.15 2010/10/14 20:41:28 jmc Exp $ +.\" +.\" Copyright (c) 2008 Damien Miller <djm@mindrot.org> +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.Dd $Mdocdate: October 14 2010 $ +.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; (p+1)*2 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 +.Rs +.%R RFC 4419 +.%T "Diffie-Hellman Group Exchange for the Secure Shell (SSH) Transport Layer Protocol" +.%D 2006 +.Re
diff --git a/openssh-6.0p1/moduli.c b/openssh-6.0p1/moduli.c new file mode 100644 index 0000000..973ee62 --- /dev/null +++ b/openssh-6.0p1/moduli.c
@@ -0,0 +1,717 @@ +/* $OpenBSD: moduli.c,v 1.25 2011/10/19 00:06:10 djm Exp $ */ +/* + * Copyright 1994 Phil Karn <karn@qualcomm.com> + * Copyright 1996-1998, 2003 William Allen Simpson <wsimpson@greendragon.com> + * Copyright 2000 Niels Provos <provos@citi.umich.edu> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Two-step process to generate safe primes for DHGEX + * + * Sieve candidates for "safe" primes, + * suitable for use as Diffie-Hellman moduli; + * that is, where q = (p-1)/2 is also prime. + * + * First step: generate candidate primes (memory intensive) + * Second step: test primes' safety (processor intensive) + */ + +#include "includes.h" + +#include <sys/param.h> +#include <sys/types.h> + +#include <openssl/bn.h> +#include <openssl/dh.h> + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> +#include <time.h> +#include <unistd.h> + +#include "xmalloc.h" +#include "dh.h" +#include "log.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 *); + +/* + * 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); + + xfree(LargeSieve); + xfree(SmallSieve); + xfree(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[MAXPATHLEN]; + int r; + + r = snprintf(tmp, sizeof(tmp), "%s.XXXXXXXXXX", cpfile); + if (r == -1 || r >= MAXPATHLEN) { + 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)); + 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; +} + +/* + * 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) +{ + 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; + time_t time_start, time_stop; + int res; + + if (trials < TRIAL_MINIMUM) { + error("Minimum primality trials is %d", TRIAL_MINIMUM); + return (-1); + } + + 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); + + res = 0; + lp = xmalloc(QLINESIZE + 1); + while (fgets(lp, QLINESIZE + 1, in) != NULL) { + count_in++; + if (checkpoint_file != NULL) { + if (count_in <= last_processed) { + debug3("skipping line %u, before checkpoint", + count_in); + continue; + } + write_checkpoint(checkpoint_file, count_in); + } + 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); + xfree(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); +}
diff --git a/openssh-6.0p1/monitor.c b/openssh-6.0p1/monitor.c new file mode 100644 index 0000000..e7abf24 --- /dev/null +++ b/openssh-6.0p1/monitor.c
@@ -0,0 +1,2309 @@ +/* $OpenBSD: monitor.c,v 1.116 2012/01/05 00:16:56 djm Exp $ */ +/* + * Copyright 2002 Niels Provos <provos@citi.umich.edu> + * Copyright 2002 Markus Friedl <markus@openbsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/socket.h> +#include "openbsd-compat/sys-tree.h" +#include <sys/wait.h> + +#include <errno.h> +#include <fcntl.h> +#ifdef HAVE_PATHS_H +#include <paths.h> +#endif +#include <pwd.h> +#include <signal.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#ifdef HAVE_POLL_H +#include <poll.h> +#else +# ifdef HAVE_SYS_POLL_H +# include <sys/poll.h> +# endif +#endif + +#ifdef SKEY +#include <skey.h> +#endif + +#include <openssl/dh.h> + +#include "openbsd-compat/sys-queue.h" +#include "atomicio.h" +#include "xmalloc.h" +#include "ssh.h" +#include "key.h" +#include "buffer.h" +#include "hostfile.h" +#include "auth.h" +#include "cipher.h" +#include "kex.h" +#include "dh.h" +#ifdef TARGET_OS_MAC /* XXX Broken krb5 headers on Mac */ +#undef TARGET_OS_MAC +#include "zlib.h" +#define TARGET_OS_MAC 1 +#else +#include "zlib.h" +#endif +#include "packet.h" +#include "auth-options.h" +#include "sshpty.h" +#include "channels.h" +#include "session.h" +#include "sshlogin.h" +#include "canohost.h" +#include "log.h" +#include "servconf.h" +#include "monitor.h" +#include "monitor_mm.h" +#ifdef GSSAPI +#include "ssh-gss.h" +#endif +#include "monitor_wrap.h" +#include "monitor_fdpass.h" +#include "misc.h" +#include "compat.h" +#include "ssh2.h" +#include "jpake.h" +#include "roaming.h" + +#ifdef GSSAPI +static Gssctxt *gsscontext = NULL; +#endif + +/* Imports */ +extern ServerOptions options; +extern u_int utmp_len; +extern Newkeys *current_keys[]; +extern z_stream incoming_stream; +extern z_stream outgoing_stream; +extern u_char session_id[]; +extern Buffer auth_debug; +extern int auth_debug_init; +extern Buffer loginmsg; + +/* State exported from the child */ + +struct { + z_stream incoming; + z_stream outgoing; + u_char *keyin; + u_int keyinlen; + u_char *keyout; + u_int keyoutlen; + u_char *ivin; + u_int ivinlen; + u_char *ivout; + u_int ivoutlen; + u_char *ssh1key; + u_int ssh1keylen; + int ssh1cipher; + int ssh1protoflags; + u_char *input; + u_int ilen; + u_char *output; + u_int olen; + u_int64_t sent_bytes; + u_int64_t recv_bytes; +} 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 *); +int mm_answer_jpake_get_pwdata(int, Buffer *); +int mm_answer_jpake_step1(int, Buffer *); +int mm_answer_jpake_step2(int, Buffer *); +int mm_answer_jpake_key_confirm(int, Buffer *); +int mm_answer_jpake_check_confirm(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; +static BIGNUM *ssh1_challenge = NULL; /* used for ssh1 rsa auth */ + +/* 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 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[] = { + {MONITOR_REQ_MODULI, MON_ONCE, mm_answer_moduli}, + {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, + {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, + {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, + {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, + {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, +#ifdef USE_PAM + {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start}, + {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, + {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx}, + {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query}, + {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond}, + {MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx}, +#endif +#ifdef SSH_AUDIT_EVENTS + {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, +#endif +#ifdef BSD_AUTH + {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery}, + {MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH, mm_answer_bsdauthrespond}, +#endif +#ifdef SKEY + {MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery}, + {MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond}, +#endif + {MONITOR_REQ_KEYALLOWED, MON_ISAUTH, mm_answer_keyallowed}, + {MONITOR_REQ_KEYVERIFY, MON_AUTH, mm_answer_keyverify}, +#ifdef GSSAPI + {MONITOR_REQ_GSSSETUP, MON_ISAUTH, mm_answer_gss_setup_ctx}, + {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx}, + {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok}, + {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic}, +#endif +#ifdef JPAKE + {MONITOR_REQ_JPAKE_GET_PWDATA, MON_ONCE, mm_answer_jpake_get_pwdata}, + {MONITOR_REQ_JPAKE_STEP1, MON_ISAUTH, mm_answer_jpake_step1}, + {MONITOR_REQ_JPAKE_STEP2, MON_ONCE, mm_answer_jpake_step2}, + {MONITOR_REQ_JPAKE_KEY_CONFIRM, MON_ONCE, mm_answer_jpake_key_confirm}, + {MONITOR_REQ_JPAKE_CHECK_CONFIRM, MON_AUTH, mm_answer_jpake_check_confirm}, +#endif + {0, 0, NULL} +}; + +struct mon_table mon_dispatch_postauth20[] = { + {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, + {MONITOR_REQ_SIGN, 0, mm_answer_sign}, + {MONITOR_REQ_PTY, 0, mm_answer_pty}, + {MONITOR_REQ_PTYCLEANUP, 0, mm_answer_pty_cleanup}, + {MONITOR_REQ_TERM, 0, mm_answer_term}, +#ifdef SSH_AUDIT_EVENTS + {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, + {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT, mm_answer_audit_command}, +#endif + {0, 0, NULL} +}; + +struct mon_table mon_dispatch_proto15[] = { + {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, + {MONITOR_REQ_SESSKEY, MON_ONCE, mm_answer_sesskey}, + {MONITOR_REQ_SESSID, MON_ONCE, mm_answer_sessid}, + {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, + {MONITOR_REQ_RSAKEYALLOWED, MON_ISAUTH|MON_ALOG, mm_answer_rsa_keyallowed}, + {MONITOR_REQ_KEYALLOWED, MON_ISAUTH|MON_ALOG, mm_answer_keyallowed}, + {MONITOR_REQ_RSACHALLENGE, MON_ONCE, mm_answer_rsa_challenge}, + {MONITOR_REQ_RSARESPONSE, MON_ONCE|MON_AUTHDECIDE, mm_answer_rsa_response}, +#ifdef BSD_AUTH + {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery}, + {MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH, mm_answer_bsdauthrespond}, +#endif +#ifdef SKEY + {MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery}, + {MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond}, +#endif +#ifdef USE_PAM + {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start}, + {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, + {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx}, + {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query}, + {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond}, + {MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx}, +#endif +#ifdef SSH_AUDIT_EVENTS + {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, +#endif + {0, 0, NULL} +}; + +struct mon_table mon_dispatch_postauth15[] = { + {MONITOR_REQ_PTY, MON_ONCE, mm_answer_pty}, + {MONITOR_REQ_PTYCLEANUP, MON_ONCE, mm_answer_pty_cleanup}, + {MONITOR_REQ_TERM, 0, mm_answer_term}, +#ifdef SSH_AUDIT_EVENTS + {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event}, + {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT|MON_ONCE, mm_answer_audit_command}, +#endif + {0, 0, NULL} +}; + +struct mon_table *mon_dispatch; + +/* Specifies if a certain message is allowed at the moment */ + +static void +monitor_permit(struct mon_table *ent, enum monitor_reqtype type, int permit) +{ + while (ent->f != NULL) { + if (ent->type == type) { + ent->flags &= ~MON_PERMIT; + ent->flags |= permit ? MON_PERMIT : 0; + return; + } + ent++; + } +} + +static void +monitor_permit_authentications(int permit) +{ + struct mon_table *ent = mon_dispatch; + + while (ent->f != NULL) { + if (ent->flags & MON_AUTH) { + ent->flags &= ~MON_PERMIT; + ent->flags |= permit ? MON_PERMIT : 0; + } + ent++; + } +} + +void +monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) +{ + struct mon_table *ent; + int authenticated = 0; + + debug3("preauth child monitor started"); + + close(pmonitor->m_recvfd); + close(pmonitor->m_log_sendfd); + pmonitor->m_log_sendfd = pmonitor->m_recvfd = -1; + + authctxt = _authctxt; + memset(authctxt, 0, sizeof(*authctxt)); + + authctxt->loginmsg = &loginmsg; + + if (compat20) { + mon_dispatch = mon_dispatch_proto20; + + /* Permit requests for moduli and signatures */ + monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); + monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); + } else { + mon_dispatch = mon_dispatch_proto15; + + monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 1); + } + + /* The first few requests do not require asynchronous access */ + while (!authenticated) { + auth_method = "unknown"; + authenticated = (monitor_read(pmonitor, mon_dispatch, &ent) == 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, auth_method, + compat20 ? " ssh2" : ""); + if (!authenticated) + authctxt->failures++; + } +#ifdef JPAKE + /* Cleanup JPAKE context after authentication */ + if (ent->flags & MON_AUTHDECIDE) { + if (authctxt->jpake_ctx != NULL) { + jpake_free(authctxt->jpake_ctx); + authctxt->jpake_ctx = NULL; + } + } +#endif + } + + /* Drain any buffered messages from the child */ + while (pmonitor->m_log_recvfd != -1 && monitor_read_log(pmonitor) == 0) + ; + + if (!authctxt->valid) + fatal("%s: authenticated invalid user", __func__); + if (strcmp(auth_method, "unknown") == 0) + fatal("%s: authentication method name unknown", __func__); + + debug("%s: %s has been authenticated by privileged process", + __func__, authctxt->user); + + mm_get_keystate(pmonitor); + + 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); + + if (compat20) { + mon_dispatch = mon_dispatch_postauth20; + + /* Permit requests for moduli and signatures */ + monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); + monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); + monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); + } else { + mon_dispatch = mon_dispatch_postauth15; + monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); + } + if (!no_pty_flag) { + monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); + monitor_permit(mon_dispatch, MONITOR_REQ_PTYCLEANUP, 1); + } + + for (;;) + monitor_read(pmonitor, mon_dispatch, NULL); + + close(pmonitor->m_sendfd); + pmonitor->m_sendfd = -1; +} + +void +monitor_sync(struct monitor *pmonitor) +{ + if (options.compression) { + /* The member allocation is not visible, so sync it */ + mm_share_sync(&pmonitor->m_zlib, &pmonitor->m_zback); + } +} + +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); + xfree(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 (;;) { + bzero(&pfd, 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 */ + if (key_blob != NULL) + xfree(key_blob); + if (hostbased_cuser != NULL) + xfree(hostbased_cuser); + if (hostbased_chost != NULL) + xfree(hostbased_chost); + key_blob = NULL; + key_bloblen = 0; + key_blobtype = MM_NOKEY; + hostbased_cuser = NULL; + hostbased_chost = NULL; +} + +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); +} + +int +mm_answer_sign(int sock, Buffer *m) +{ + Key *key; + u_char *p; + u_char *signature; + u_int siglen, datlen; + int keyid; + + debug3("%s", __func__); + + keyid = buffer_get_int(m); + p = buffer_get_string(m, &datlen); + + /* + * Supported KEX types use SHA1 (20 bytes), SHA256 (32 bytes), + * SHA384 (48 bytes) and SHA512 (64 bytes). + */ + if (datlen != 20 && datlen != 32 && datlen != 48 && datlen != 64) + fatal("%s: data length incorrect: %u", __func__, datlen); + + /* 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) + fatal("%s: no hostkey from index %d", __func__, keyid); + if (key_sign(key, &signature, &siglen, p, datlen) < 0) + fatal("%s: key_sign failed", __func__); + + debug3("%s: signature %p(%u)", __func__, signature, siglen); + + buffer_clear(m); + buffer_put_string(m, signature, siglen); + + xfree(p); + xfree(signature); + + mm_request_send(sock, MONITOR_ANS_SIGN, m); + + /* Turn on permissions for getpwnam */ + monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1); + + return (0); +} + +/* Retrieves the password entry and also checks if the user is permitted */ + +int +mm_answer_pwnamallow(int sock, Buffer *m) +{ + char *username; + struct passwd *pwent; + int allowed = 0; + u_int i; + + debug3("%s", __func__); + + if (authctxt->attempt++ != 0) + fatal("%s: multiple attempts for getpwnam", __func__); + + username = buffer_get_string(m, NULL); + + pwent = getpwnamallow(username); + + authctxt->user = xstrdup(username); + setproctitle("%s [priv]", pwent ? username : "unknown"); + xfree(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, "*"); + buffer_put_cstring(m, pwent->pw_gecos); +#ifdef HAVE_PW_CLASS_IN_PASSWD + buffer_put_cstring(m, pwent->pw_class); +#endif + buffer_put_cstring(m, pwent->pw_dir); + buffer_put_cstring(m, pwent->pw_shell); + + out: + buffer_put_string(m, &options, sizeof(options)); + +#define M_CP_STROPT(x) do { \ + if (options.x != NULL) \ + buffer_put_cstring(m, options.x); \ + } while (0) +#define M_CP_STRARRAYOPT(x, nx) do { \ + for (i = 0; i < options.nx; i++) \ + buffer_put_cstring(m, options.x[i]); \ + } while (0) + /* See comment in servconf.h */ + COPY_MATCH_STRING_OPTS(); +#undef M_CP_STROPT +#undef M_CP_STRARRAYOPT + + debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed); + mm_request_send(sock, MONITOR_ANS_PWNAM, m); + + /* For SSHv1 allow authentication now */ + if (!compat20) + monitor_permit_authentications(1); + else { + /* Allow service/style information on the auth context */ + monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); + monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); + } +#ifdef USE_PAM + if (options.use_pam) + monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1); +#endif + + return (0); +} + +int mm_answer_auth2_read_banner(int sock, Buffer *m) +{ + char *banner; + + buffer_clear(m); + banner = auth2_read_banner(); + buffer_put_cstring(m, banner != NULL ? banner : ""); + mm_request_send(sock, MONITOR_ANS_AUTH2_READ_BANNER, m); + + if (banner != NULL) + xfree(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) { + xfree(authctxt->style); + authctxt->style = NULL; + } + + return (0); +} + +int +mm_answer_authpassword(int sock, Buffer *m) +{ + static int call_count; + char *passwd; + int authenticated; + u_int plen; + + passwd = buffer_get_string(m, &plen); + /* Only authenticate if the context is valid */ + authenticated = options.password_authentication && + auth_password(authctxt, passwd); + memset(passwd, 0, strlen(passwd)); + xfree(passwd); + + buffer_clear(m); + buffer_put_int(m, authenticated); + + debug3("%s: sending result %d", __func__, authenticated); + mm_request_send(sock, MONITOR_ANS_AUTHPASSWORD, m); + + call_count++; + if (plen == 0 && call_count == 1) + auth_method = "none"; + else + auth_method = "password"; + + /* Causes monitor loop to terminate if authenticated */ + return (authenticated); +} + +#ifdef BSD_AUTH +int +mm_answer_bsdauthquery(int sock, Buffer *m) +{ + char *name, *infotxt; + u_int numprompts; + u_int *echo_on; + char **prompts; + u_int success; + + success = bsdauth_query(authctxt, &name, &infotxt, &numprompts, + &prompts, &echo_on) < 0 ? 0 : 1; + + buffer_clear(m); + buffer_put_int(m, success); + if (success) + buffer_put_cstring(m, prompts[0]); + + debug3("%s: sending challenge success: %u", __func__, success); + mm_request_send(sock, MONITOR_ANS_BSDAUTHQUERY, m); + + if (success) { + xfree(name); + xfree(infotxt); + xfree(prompts); + xfree(echo_on); + } + + return (0); +} + +int +mm_answer_bsdauthrespond(int sock, Buffer *m) +{ + char *response; + int authok; + + if (authctxt->as == 0) + 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); + xfree(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 = "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); + + xfree(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 = "skey"; + + return (authok != 0); +} +#endif + +#ifdef USE_PAM +int +mm_answer_pam_start(int sock, Buffer *m) +{ + if (!options.use_pam) + fatal("UsePAM not set, but ended up in %s anyway", __func__); + + start_pam(authctxt); + + monitor_permit(mon_dispatch, MONITOR_REQ_PAM_ACCOUNT, 1); + + return (0); +} + +int +mm_answer_pam_account(int sock, Buffer *m) +{ + u_int ret; + + if (!options.use_pam) + fatal("UsePAM not set, but ended up in %s anyway", __func__); + + ret = do_pam_account(); + + buffer_put_int(m, ret); + buffer_put_string(m, buffer_ptr(&loginmsg), buffer_len(&loginmsg)); + + mm_request_send(sock, MONITOR_ANS_PAM_ACCOUNT, m); + + return (ret); +} + +static void *sshpam_ctxt, *sshpam_authok; +extern KbdintDevice sshpam_device; + +int +mm_answer_pam_init_ctx(int sock, Buffer *m) +{ + + debug3("%s", __func__); + authctxt->user = buffer_get_string(m, NULL); + sshpam_ctxt = (sshpam_device.init_ctx)(authctxt); + sshpam_authok = NULL; + buffer_clear(m); + if (sshpam_ctxt != NULL) { + monitor_permit(mon_dispatch, MONITOR_REQ_PAM_FREE_CTX, 1); + buffer_put_int(m, 1); + } else { + buffer_put_int(m, 0); + } + mm_request_send(sock, MONITOR_ANS_PAM_INIT_CTX, m); + return (0); +} + +int +mm_answer_pam_query(int sock, Buffer *m) +{ + char *name = NULL, *info = NULL, **prompts = NULL; + u_int i, num = 0, *echo_on = 0; + int ret; + + debug3("%s", __func__); + sshpam_authok = NULL; + ret = (sshpam_device.query)(sshpam_ctxt, &name, &info, &num, &prompts, &echo_on); + if (ret == 0 && num == 0) + sshpam_authok = sshpam_ctxt; + if (num > 1 || name == NULL || info == NULL) + ret = -1; + buffer_clear(m); + buffer_put_int(m, ret); + buffer_put_cstring(m, name); + xfree(name); + buffer_put_cstring(m, info); + xfree(info); + buffer_put_int(m, num); + for (i = 0; i < num; ++i) { + buffer_put_cstring(m, prompts[i]); + xfree(prompts[i]); + buffer_put_int(m, echo_on[i]); + } + if (prompts != NULL) + xfree(prompts); + if (echo_on != NULL) + xfree(echo_on); + auth_method = "keyboard-interactive/pam"; + mm_request_send(sock, MONITOR_ANS_PAM_QUERY, m); + return (0); +} + +int +mm_answer_pam_respond(int sock, Buffer *m) +{ + char **resp; + u_int i, num; + int ret; + + debug3("%s", __func__); + sshpam_authok = NULL; + num = buffer_get_int(m); + if (num > 0) { + resp = xcalloc(num, sizeof(char *)); + for (i = 0; i < num; ++i) + resp[i] = buffer_get_string(m, NULL); + ret = (sshpam_device.respond)(sshpam_ctxt, num, resp); + for (i = 0; i < num; ++i) + xfree(resp[i]); + xfree(resp); + } else { + ret = (sshpam_device.respond)(sshpam_ctxt, num, NULL); + } + buffer_clear(m); + buffer_put_int(m, ret); + mm_request_send(sock, MONITOR_ANS_PAM_RESPOND, m); + auth_method = "keyboard-interactive/pam"; + if (ret == 0) + sshpam_authok = sshpam_ctxt; + return (0); +} + +int +mm_answer_pam_free_ctx(int sock, Buffer *m) +{ + + debug3("%s", __func__); + (sshpam_device.free_ctx)(sshpam_ctxt); + buffer_clear(m); + mm_request_send(sock, MONITOR_ANS_PAM_FREE_CTX, m); + auth_method = "keyboard-interactive/pam"; + return (sshpam_authok == sshpam_ctxt); +} +#endif + +int +mm_answer_keyallowed(int sock, Buffer *m) +{ + Key *key; + char *cuser, *chost; + u_char *blob; + u_int bloblen; + 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); + + key = key_from_blob(blob, bloblen); + + if ((compat20 && type == MM_RSAHOSTKEY) || + (!compat20 && type != MM_RSAHOSTKEY)) + fatal("%s: key type and protocol mismatch", __func__); + + debug3("%s: key_from_blob: %p", __func__, key); + + if (key != NULL && authctxt->valid) { + switch (type) { + case MM_USERKEY: + allowed = options.pubkey_authentication && + user_key_allowed(authctxt->pw, key); + auth_method = "publickey"; + if (options.pubkey_authentication && allowed != 1) + auth_clear_options(); + break; + case MM_HOSTKEY: + allowed = options.hostbased_authentication && + hostbased_key_allowed(authctxt->pw, + cuser, chost, key); + auth_method = "hostbased"; + break; + case MM_RSAHOSTKEY: + key->type = KEY_RSA1; /* XXX */ + allowed = options.rhosts_rsa_authentication && + auth_rhosts_rsa_key_allowed(authctxt->pw, + cuser, chost, key); + if (options.rhosts_rsa_authentication && allowed != 1) + auth_clear_options(); + auth_method = "rsa"; + break; + default: + fatal("%s: unknown key type %d", __func__, type); + break; + } + } + if (key != NULL) + key_free(key); + + /* clear temporarily storage (used by verify) */ + monitor_reset_key_state(); + + if (allowed) { + /* Save temporarily for comparison in verify */ + key_blob = blob; + key_bloblen = bloblen; + key_blobtype = type; + hostbased_cuser = cuser; + hostbased_chost = chost; + } else { + /* Log failed attempt */ + auth_log(authctxt, 0, auth_method, compat20 ? " ssh2" : ""); + xfree(blob); + xfree(cuser); + xfree(chost); + } + + debug3("%s: key %p is %s", + __func__, key, allowed ? "allowed" : "not allowed"); + + buffer_clear(m); + buffer_put_int(m, allowed); + buffer_put_int(m, forced_command != NULL); + + mm_request_send(sock, MONITOR_ANS_KEYALLOWED, m); + + if (type == MM_RSAHOSTKEY) + monitor_permit(mon_dispatch, MONITOR_REQ_RSACHALLENGE, allowed); + + return (0); +} + +static int +monitor_valid_userblob(u_char *data, u_int datalen) +{ + Buffer b; + char *p; + 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++; + xfree(p); + } + if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) + fail++; + p = buffer_get_string(&b, NULL); + if (strcmp(authctxt->user, p) != 0) { + logit("wrong user name passed to monitor: expected %s != %.100s", + authctxt->user, p); + fail++; + } + xfree(p); + buffer_skip_string(&b); + if (datafellows & SSH_BUG_PKAUTH) { + if (!buffer_get_char(&b)) + fail++; + } else { + p = buffer_get_string(&b, NULL); + if (strcmp("publickey", p) != 0) + fail++; + xfree(p); + if (!buffer_get_char(&b)) + fail++; + buffer_skip_string(&b); + } + buffer_skip_string(&b); + if (buffer_len(&b) != 0) + fail++; + buffer_free(&b); + return (fail == 0); +} + +static int +monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser, + char *chost) +{ + Buffer b; + char *p; + 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++; + xfree(p); + + if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) + fail++; + p = buffer_get_string(&b, NULL); + if (strcmp(authctxt->user, p) != 0) { + logit("wrong user name passed to monitor: expected %s != %.100s", + authctxt->user, p); + fail++; + } + xfree(p); + buffer_skip_string(&b); /* service */ + p = buffer_get_string(&b, NULL); + if (strcmp(p, "hostbased") != 0) + fail++; + xfree(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++; + xfree(p); + + /* verify client user */ + p = buffer_get_string(&b, NULL); + if (strcmp(p, cuser) != 0) + fail++; + xfree(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"); + + key_free(key); + xfree(blob); + xfree(signature); + xfree(data); + + auth_method = key_blobtype == MM_USERKEY ? "publickey" : "hostbased"; + + monitor_reset_key_state(); + + buffer_clear(m); + buffer_put_int(m, verified); + mm_request_send(sock, MONITOR_ANS_KEYVERIFY, m); + + return (verified == 1); +} + +static void +mm_record_login(Session *s, struct passwd *pw) +{ + socklen_t fromlen; + struct sockaddr_storage from; + + /* + * Get IP address of client. If the connection is not a socket, let + * the address be 0.0.0.0. + */ + memset(&from, 0, sizeof(from)); + fromlen = sizeof(from); + if (packet_connection_is_on_socket()) { + if (getpeername(packet_get_connection_in(), + (struct sockaddr *)&from, &fromlen) < 0) { + debug("getpeername: %.100s", strerror(errno)); + cleanup_exit(255); + } + } + /* Record that there was a login on that tty from the remote host. */ + record_login(s->pid, s->tty, pw->pw_name, pw->pw_uid, + get_remote_name_or_ip(utmp_len, options.use_dns), + (struct sockaddr *)&from, fromlen); +} + +static void +mm_session_close(Session *s) +{ + debug3("%s: session %d pid %ld", __func__, s->self, (long)s->pid); + if (s->ttyfd != -1) { + debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd); + session_pty_cleanup2(s); + } + session_unused(s->self); +} + +int +mm_answer_pty(int sock, Buffer *m) +{ + extern struct monitor *pmonitor; + Session *s; + int res, fd0; + + debug3("%s entering", __func__); + + buffer_clear(m); + s = session_new(); + if (s == NULL) + goto error; + s->authctxt = authctxt; + s->pw = authctxt->pw; + s->pid = pmonitor->m_pid; + res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)); + if (res == 0) + goto error; + pty_setowner(authctxt->pw, s->tty); + + buffer_put_int(m, 1); + buffer_put_cstring(m, s->tty); + + /* We need to trick ttyslot */ + if (dup2(s->ttyfd, 0) == -1) + fatal("%s: dup2", __func__); + + mm_record_login(s, authctxt->pw); + + /* Now we can close the file descriptor again */ + close(0); + + /* send messages generated by record_login */ + buffer_put_string(m, buffer_ptr(&loginmsg), buffer_len(&loginmsg)); + buffer_clear(&loginmsg); + + mm_request_send(sock, MONITOR_ANS_PTY, m); + + if (mm_send_fd(sock, s->ptyfd) == -1 || + mm_send_fd(sock, s->ttyfd) == -1) + fatal("%s: send fds failed", __func__); + + /* make sure nothing uses fd 0 */ + if ((fd0 = open(_PATH_DEVNULL, O_RDONLY)) < 0) + fatal("%s: open(/dev/null): %s", __func__, strerror(errno)); + if (fd0 != 0) + error("%s: fd0 %d != 0", __func__, fd0); + + /* slave is not needed */ + close(s->ttyfd); + s->ttyfd = s->ptyfd; + /* no need to dup() because nobody closes ptyfd */ + s->ptymaster = s->ptyfd; + + debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ttyfd); + + return (0); + + error: + if (s != NULL) + mm_session_close(s); + buffer_put_int(m, 0); + mm_request_send(sock, MONITOR_ANS_PTY, m); + return (0); +} + +int +mm_answer_pty_cleanup(int sock, Buffer *m) +{ + Session *s; + char *tty; + + debug3("%s entering", __func__); + + tty = buffer_get_string(m, NULL); + if ((s = session_by_tty(tty)) != NULL) + mm_session_close(s); + buffer_clear(m); + xfree(tty); + return (0); +} + +int +mm_answer_sesskey(int sock, Buffer *m) +{ + BIGNUM *p; + int rsafail; + + /* Turn off permissions */ + monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 0); + + if ((p = BN_new()) == NULL) + fatal("%s: BN_new", __func__); + + buffer_get_bignum2(m, p); + + rsafail = ssh1_session_key(p); + + buffer_clear(m); + buffer_put_int(m, rsafail); + buffer_put_bignum2(m, p); + + BN_clear_free(p); + + mm_request_send(sock, MONITOR_ANS_SESSKEY, m); + + /* Turn on permissions for sessid passing */ + monitor_permit(mon_dispatch, MONITOR_REQ_SESSID, 1); + + return (0); +} + +int +mm_answer_sessid(int sock, Buffer *m) +{ + int i; + + debug3("%s entering", __func__); + + if (buffer_len(m) != 16) + fatal("%s: bad ssh1 session id", __func__); + for (i = 0; i < 16; i++) + session_id[i] = buffer_get_char(m); + + /* Turn on permissions for getpwnam */ + monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1); + + return (0); +} + +int +mm_answer_rsa_keyallowed(int sock, Buffer *m) +{ + BIGNUM *client_n; + Key *key = NULL; + u_char *blob = NULL; + u_int blen = 0; + int allowed = 0; + + debug3("%s entering", __func__); + + auth_method = "rsa"; + if (options.rsa_authentication && authctxt->valid) { + if ((client_n = BN_new()) == NULL) + fatal("%s: BN_new", __func__); + buffer_get_bignum2(m, client_n); + allowed = auth_rsa_key_allowed(authctxt->pw, client_n, &key); + BN_clear_free(client_n); + } + buffer_clear(m); + buffer_put_int(m, allowed); + buffer_put_int(m, forced_command != NULL); + + /* clear temporarily storage (used by generate challenge) */ + monitor_reset_key_state(); + + if (allowed && key != NULL) { + key->type = KEY_RSA; /* cheat for key_to_blob */ + if (key_to_blob(key, &blob, &blen) == 0) + fatal("%s: key_to_blob failed", __func__); + buffer_put_string(m, blob, blen); + + /* Save temporarily for comparison in verify */ + key_blob = blob; + key_bloblen = blen; + key_blobtype = MM_RSAUSERKEY; + } + if (key != NULL) + key_free(key); + + mm_request_send(sock, MONITOR_ANS_RSAKEYALLOWED, m); + + monitor_permit(mon_dispatch, MONITOR_REQ_RSACHALLENGE, allowed); + monitor_permit(mon_dispatch, MONITOR_REQ_RSARESPONSE, 0); + return (0); +} + +int +mm_answer_rsa_challenge(int sock, Buffer *m) +{ + Key *key = NULL; + u_char *blob; + u_int blen; + + debug3("%s entering", __func__); + + if (!authctxt->valid) + fatal("%s: authctxt not valid", __func__); + blob = buffer_get_string(m, &blen); + if (!monitor_allowed_key(blob, blen)) + fatal("%s: bad key, not previously allowed", __func__); + if (key_blobtype != MM_RSAUSERKEY && key_blobtype != MM_RSAHOSTKEY) + fatal("%s: key type mismatch", __func__); + if ((key = key_from_blob(blob, blen)) == NULL) + fatal("%s: received bad key", __func__); + if (key->type != KEY_RSA) + fatal("%s: received bad key type %d", __func__, key->type); + key->type = KEY_RSA1; + if (ssh1_challenge) + BN_clear_free(ssh1_challenge); + ssh1_challenge = auth_rsa_generate_challenge(key); + + buffer_clear(m); + buffer_put_bignum2(m, ssh1_challenge); + + debug3("%s sending reply", __func__); + mm_request_send(sock, MONITOR_ANS_RSACHALLENGE, m); + + monitor_permit(mon_dispatch, MONITOR_REQ_RSARESPONSE, 1); + + xfree(blob); + key_free(key); + return (0); +} + +int +mm_answer_rsa_response(int sock, Buffer *m) +{ + Key *key = NULL; + u_char *blob, *response; + u_int blen, len; + int success; + + debug3("%s entering", __func__); + + if (!authctxt->valid) + fatal("%s: authctxt not valid", __func__); + if (ssh1_challenge == NULL) + fatal("%s: no ssh1_challenge", __func__); + + blob = buffer_get_string(m, &blen); + if (!monitor_allowed_key(blob, blen)) + fatal("%s: bad key, not previously allowed", __func__); + if (key_blobtype != MM_RSAUSERKEY && key_blobtype != MM_RSAHOSTKEY) + fatal("%s: key type mismatch: %d", __func__, key_blobtype); + if ((key = key_from_blob(blob, blen)) == NULL) + fatal("%s: received bad key", __func__); + response = buffer_get_string(m, &len); + if (len != 16) + fatal("%s: received bad response to challenge", __func__); + success = auth_rsa_verify_response(key, ssh1_challenge, response); + + xfree(blob); + key_free(key); + xfree(response); + + auth_method = key_blobtype == MM_RSAUSERKEY ? "rsa" : "rhosts-rsa"; + + /* reset state */ + BN_clear_free(ssh1_challenge); + ssh1_challenge = NULL; + monitor_reset_key_state(); + + buffer_clear(m); + buffer_put_int(m, success); + mm_request_send(sock, MONITOR_ANS_RSARESPONSE, m); + + return (success); +} + +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); + xfree(cmd); + return (0); +} +#endif /* SSH_AUDIT_EVENTS */ + +void +monitor_apply_keystate(struct monitor *pmonitor) +{ + if (compat20) { + set_newkeys(MODE_IN); + set_newkeys(MODE_OUT); + } else { + packet_set_protocol_flags(child_state.ssh1protoflags); + packet_set_encryption_key(child_state.ssh1key, + child_state.ssh1keylen, child_state.ssh1cipher); + xfree(child_state.ssh1key); + } + + /* for rc4 and other stateful ciphers */ + packet_set_keycontext(MODE_OUT, child_state.keyout); + xfree(child_state.keyout); + packet_set_keycontext(MODE_IN, child_state.keyin); + xfree(child_state.keyin); + + if (!compat20) { + packet_set_iv(MODE_OUT, child_state.ivout); + xfree(child_state.ivout); + packet_set_iv(MODE_IN, child_state.ivin); + xfree(child_state.ivin); + } + + memcpy(&incoming_stream, &child_state.incoming, + sizeof(incoming_stream)); + memcpy(&outgoing_stream, &child_state.outgoing, + sizeof(outgoing_stream)); + + /* Update with new address */ + if (options.compression) + mm_init_compression(pmonitor->m_zlib); + + /* Network I/O buffers */ + /* XXX inefficient for large buffers, need: buffer_init_from_string */ + buffer_clear(packet_get_input()); + buffer_append(packet_get_input(), child_state.input, child_state.ilen); + memset(child_state.input, 0, child_state.ilen); + xfree(child_state.input); + + buffer_clear(packet_get_output()); + buffer_append(packet_get_output(), child_state.output, + child_state.olen); + memset(child_state.output, 0, child_state.olen); + xfree(child_state.output); + + /* Roaming */ + if (compat20) + roam_set_bytes(child_state.sent_bytes, child_state.recv_bytes); +} + +static Kex * +mm_get_kex(Buffer *m) +{ + Kex *kex; + void *blob; + u_int bloblen; + + kex = xcalloc(1, sizeof(*kex)); + kex->session_id = buffer_get_string(m, &kex->session_id_len); + if (session_id2 == NULL || + kex->session_id_len != session_id2_len || + timingsafe_bcmp(kex->session_id, session_id2, session_id2_len) != 0) + fatal("mm_get_get: internal error: bad session id"); + kex->we_need = buffer_get_int(m); + kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; + kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server; + kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; + kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; + kex->kex[KEX_ECDH_SHA2] = kexecdh_server; + kex->server = 1; + kex->hostkey_type = buffer_get_int(m); + kex->kex_type = buffer_get_int(m); + blob = buffer_get_string(m, &bloblen); + buffer_init(&kex->my); + buffer_append(&kex->my, blob, bloblen); + xfree(blob); + blob = buffer_get_string(m, &bloblen); + buffer_init(&kex->peer); + buffer_append(&kex->peer, blob, bloblen); + xfree(blob); + kex->done = 1; + kex->flags = buffer_get_int(m); + kex->client_version_string = buffer_get_string(m, NULL); + kex->server_version_string = buffer_get_string(m, NULL); + 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; + + return (kex); +} + +/* This function requries careful sanity checking */ + +void +mm_get_keystate(struct monitor *pmonitor) +{ + Buffer m; + u_char *blob, *p; + u_int bloblen, plen; + u_int32_t seqnr, packets; + u_int64_t blocks, bytes; + + debug3("%s: Waiting for new keys", __func__); + + buffer_init(&m); + mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT, &m); + if (!compat20) { + child_state.ssh1protoflags = buffer_get_int(&m); + child_state.ssh1cipher = buffer_get_int(&m); + child_state.ssh1key = buffer_get_string(&m, + &child_state.ssh1keylen); + child_state.ivout = buffer_get_string(&m, + &child_state.ivoutlen); + child_state.ivin = buffer_get_string(&m, &child_state.ivinlen); + goto skip; + } else { + /* Get the Kex for rekeying */ + *pmonitor->m_pkex = mm_get_kex(&m); + } + + blob = buffer_get_string(&m, &bloblen); + current_keys[MODE_OUT] = mm_newkeys_from_blob(blob, bloblen); + xfree(blob); + + debug3("%s: Waiting for second key", __func__); + blob = buffer_get_string(&m, &bloblen); + current_keys[MODE_IN] = mm_newkeys_from_blob(blob, bloblen); + xfree(blob); + + /* Now get sequence numbers for the packets */ + seqnr = buffer_get_int(&m); + blocks = buffer_get_int64(&m); + packets = buffer_get_int(&m); + bytes = buffer_get_int64(&m); + packet_set_state(MODE_OUT, seqnr, blocks, packets, bytes); + seqnr = buffer_get_int(&m); + blocks = buffer_get_int64(&m); + packets = buffer_get_int(&m); + bytes = buffer_get_int64(&m); + packet_set_state(MODE_IN, seqnr, blocks, packets, bytes); + + skip: + /* Get the key context */ + child_state.keyout = buffer_get_string(&m, &child_state.keyoutlen); + child_state.keyin = buffer_get_string(&m, &child_state.keyinlen); + + debug3("%s: Getting compression state", __func__); + /* Get compression state */ + p = buffer_get_string(&m, &plen); + if (plen != sizeof(child_state.outgoing)) + fatal("%s: bad request size", __func__); + memcpy(&child_state.outgoing, p, sizeof(child_state.outgoing)); + xfree(p); + + p = buffer_get_string(&m, &plen); + if (plen != sizeof(child_state.incoming)) + fatal("%s: bad request size", __func__); + memcpy(&child_state.incoming, p, sizeof(child_state.incoming)); + xfree(p); + + /* Network I/O buffers */ + debug3("%s: Getting Network I/O buffers", __func__); + child_state.input = buffer_get_string(&m, &child_state.ilen); + child_state.output = buffer_get_string(&m, &child_state.olen); + + /* Roaming */ + if (compat20) { + child_state.sent_bytes = buffer_get_int64(&m); + child_state.recv_bytes = buffer_get_int64(&m); + } + + buffer_free(&m); +} + + +/* Allocation functions for zlib */ +void * +mm_zalloc(struct mm_master *mm, u_int ncount, u_int size) +{ + size_t len = (size_t) size * ncount; + void *address; + + if (len == 0 || ncount > SIZE_T_MAX / size) + fatal("%s: mm_zalloc(%u, %u)", __func__, ncount, size); + + address = mm_malloc(mm, len); + + return (address); +} + +void +mm_zfree(struct mm_master *mm, void *address) +{ + mm_free(mm, address); +} + +void +mm_init_compression(struct mm_master *mm) +{ + outgoing_stream.zalloc = (alloc_func)mm_zalloc; + outgoing_stream.zfree = (free_func)mm_zfree; + outgoing_stream.opaque = mm; + + incoming_stream.zalloc = (alloc_func)mm_zalloc; + incoming_stream.zfree = (free_func)mm_zfree; + incoming_stream.opaque = mm; +} + +/* 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); + + /* Used to share zlib space across processes */ + if (options.compression) { + mon->m_zback = mm_create(NULL, MM_MEMSIZE); + mon->m_zlib = mm_create(mon->m_zback, 20 * MM_MEMSIZE); + + /* Compression needs to share state across borders */ + mm_init_compression(mon->m_zlib); + } + + return mon; +} + +void +monitor_reinit(struct monitor *mon) +{ + monitor_openfds(mon, 0); +} + +#ifdef GSSAPI +int +mm_answer_gss_setup_ctx(int sock, Buffer *m) +{ + gss_OID_desc goid; + OM_uint32 major; + u_int len; + + goid.elements = buffer_get_string(m, &len); + goid.length = len; + + major = ssh_gssapi_server_ctx(&gsscontext, &goid); + + xfree(goid.elements); + + buffer_clear(m); + buffer_put_int(m, major); + + mm_request_send(sock, MONITOR_ANS_GSSSETUP, m); + + /* Now we have a context, enable the step */ + monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 1); + + return (0); +} + +int +mm_answer_gss_accept_ctx(int sock, Buffer *m) +{ + gss_buffer_desc in; + gss_buffer_desc out = GSS_C_EMPTY_BUFFER; + OM_uint32 major, minor; + OM_uint32 flags = 0; /* GSI needs this */ + u_int len; + + in.value = buffer_get_string(m, &len); + in.length = len; + major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags); + xfree(in.value); + + buffer_clear(m); + buffer_put_int(m, major); + buffer_put_string(m, out.value, out.length); + buffer_put_int(m, flags); + mm_request_send(sock, MONITOR_ANS_GSSSTEP, m); + + gss_release_buffer(&minor, &out); + + if (major == GSS_S_COMPLETE) { + monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); + monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); + monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); + } + return (0); +} + +int +mm_answer_gss_checkmic(int sock, Buffer *m) +{ + gss_buffer_desc gssbuf, mic; + OM_uint32 ret; + u_int len; + + gssbuf.value = buffer_get_string(m, &len); + gssbuf.length = len; + mic.value = buffer_get_string(m, &len); + mic.length = len; + + ret = ssh_gssapi_checkmic(gsscontext, &gssbuf, &mic); + + xfree(gssbuf.value); + xfree(mic.value); + + buffer_clear(m); + buffer_put_int(m, ret); + + mm_request_send(sock, MONITOR_ANS_GSSCHECKMIC, m); + + if (!GSS_ERROR(ret)) + monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); + + return (0); +} + +int +mm_answer_gss_userok(int sock, Buffer *m) +{ + int authenticated; + + authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); + + buffer_clear(m); + buffer_put_int(m, authenticated); + + debug3("%s: sending result %d", __func__, authenticated); + mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); + + auth_method = "gssapi-with-mic"; + + /* Monitor loop will terminate if authenticated */ + return (authenticated); +} +#endif /* GSSAPI */ + +#ifdef JPAKE +int +mm_answer_jpake_step1(int sock, Buffer *m) +{ + struct jpake_ctx *pctx; + u_char *x3_proof, *x4_proof; + u_int x3_proof_len, x4_proof_len; + + if (!options.zero_knowledge_password_authentication) + fatal("zero_knowledge_password_authentication disabled"); + + if (authctxt->jpake_ctx != NULL) + fatal("%s: authctxt->jpake_ctx already set (%p)", + __func__, authctxt->jpake_ctx); + authctxt->jpake_ctx = pctx = jpake_new(); + + jpake_step1(pctx->grp, + &pctx->server_id, &pctx->server_id_len, + &pctx->x3, &pctx->x4, &pctx->g_x3, &pctx->g_x4, + &x3_proof, &x3_proof_len, + &x4_proof, &x4_proof_len); + + JPAKE_DEBUG_CTX((pctx, "step1 done in %s", __func__)); + + buffer_clear(m); + + buffer_put_string(m, pctx->server_id, pctx->server_id_len); + buffer_put_bignum2(m, pctx->g_x3); + buffer_put_bignum2(m, pctx->g_x4); + buffer_put_string(m, x3_proof, x3_proof_len); + buffer_put_string(m, x4_proof, x4_proof_len); + + debug3("%s: sending step1", __func__); + mm_request_send(sock, MONITOR_ANS_JPAKE_STEP1, m); + + bzero(x3_proof, x3_proof_len); + bzero(x4_proof, x4_proof_len); + xfree(x3_proof); + xfree(x4_proof); + + monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_GET_PWDATA, 1); + monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP1, 0); + + return 0; +} + +int +mm_answer_jpake_get_pwdata(int sock, Buffer *m) +{ + struct jpake_ctx *pctx = authctxt->jpake_ctx; + char *hash_scheme, *salt; + + if (pctx == NULL) + fatal("%s: pctx == NULL", __func__); + + auth2_jpake_get_pwdata(authctxt, &pctx->s, &hash_scheme, &salt); + + buffer_clear(m); + /* pctx->s is sensitive, not returned to slave */ + buffer_put_cstring(m, hash_scheme); + buffer_put_cstring(m, salt); + + debug3("%s: sending pwdata", __func__); + mm_request_send(sock, MONITOR_ANS_JPAKE_GET_PWDATA, m); + + bzero(hash_scheme, strlen(hash_scheme)); + bzero(salt, strlen(salt)); + xfree(hash_scheme); + xfree(salt); + + monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP2, 1); + + return 0; +} + +int +mm_answer_jpake_step2(int sock, Buffer *m) +{ + struct jpake_ctx *pctx = authctxt->jpake_ctx; + u_char *x1_proof, *x2_proof, *x4_s_proof; + u_int x1_proof_len, x2_proof_len, x4_s_proof_len; + + if (pctx == NULL) + fatal("%s: pctx == NULL", __func__); + + if ((pctx->g_x1 = BN_new()) == NULL || + (pctx->g_x2 = BN_new()) == NULL) + fatal("%s: BN_new", __func__); + buffer_get_bignum2(m, pctx->g_x1); + buffer_get_bignum2(m, pctx->g_x2); + pctx->client_id = buffer_get_string(m, &pctx->client_id_len); + x1_proof = buffer_get_string(m, &x1_proof_len); + x2_proof = buffer_get_string(m, &x2_proof_len); + + jpake_step2(pctx->grp, pctx->s, pctx->g_x3, + pctx->g_x1, pctx->g_x2, pctx->x4, + pctx->client_id, pctx->client_id_len, + pctx->server_id, pctx->server_id_len, + x1_proof, x1_proof_len, + x2_proof, x2_proof_len, + &pctx->b, + &x4_s_proof, &x4_s_proof_len); + + JPAKE_DEBUG_CTX((pctx, "step2 done in %s", __func__)); + + bzero(x1_proof, x1_proof_len); + bzero(x2_proof, x2_proof_len); + xfree(x1_proof); + xfree(x2_proof); + + buffer_clear(m); + + buffer_put_bignum2(m, pctx->b); + buffer_put_string(m, x4_s_proof, x4_s_proof_len); + + debug3("%s: sending step2", __func__); + mm_request_send(sock, MONITOR_ANS_JPAKE_STEP2, m); + + bzero(x4_s_proof, x4_s_proof_len); + xfree(x4_s_proof); + + monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_KEY_CONFIRM, 1); + + return 0; +} + +int +mm_answer_jpake_key_confirm(int sock, Buffer *m) +{ + struct jpake_ctx *pctx = authctxt->jpake_ctx; + u_char *x2_s_proof; + u_int x2_s_proof_len; + + if (pctx == NULL) + fatal("%s: pctx == NULL", __func__); + + if ((pctx->a = BN_new()) == NULL) + fatal("%s: BN_new", __func__); + buffer_get_bignum2(m, pctx->a); + x2_s_proof = buffer_get_string(m, &x2_s_proof_len); + + jpake_key_confirm(pctx->grp, pctx->s, pctx->a, + pctx->x4, pctx->g_x3, pctx->g_x4, pctx->g_x1, pctx->g_x2, + pctx->server_id, pctx->server_id_len, + pctx->client_id, pctx->client_id_len, + session_id2, session_id2_len, + x2_s_proof, x2_s_proof_len, + &pctx->k, + &pctx->h_k_sid_sessid, &pctx->h_k_sid_sessid_len); + + JPAKE_DEBUG_CTX((pctx, "key_confirm done in %s", __func__)); + + bzero(x2_s_proof, x2_s_proof_len); + buffer_clear(m); + + /* pctx->k is sensitive, not sent */ + buffer_put_string(m, pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len); + + debug3("%s: sending confirmation hash", __func__); + mm_request_send(sock, MONITOR_ANS_JPAKE_KEY_CONFIRM, m); + + monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_CHECK_CONFIRM, 1); + + return 0; +} + +int +mm_answer_jpake_check_confirm(int sock, Buffer *m) +{ + int authenticated = 0; + u_char *peer_confirm_hash; + u_int peer_confirm_hash_len; + struct jpake_ctx *pctx = authctxt->jpake_ctx; + + if (pctx == NULL) + fatal("%s: pctx == NULL", __func__); + + peer_confirm_hash = buffer_get_string(m, &peer_confirm_hash_len); + + authenticated = jpake_check_confirm(pctx->k, + pctx->client_id, pctx->client_id_len, + session_id2, session_id2_len, + peer_confirm_hash, peer_confirm_hash_len) && authctxt->valid; + + JPAKE_DEBUG_CTX((pctx, "check_confirm done in %s", __func__)); + + bzero(peer_confirm_hash, peer_confirm_hash_len); + xfree(peer_confirm_hash); + + buffer_clear(m); + buffer_put_int(m, authenticated); + + debug3("%s: sending result %d", __func__, authenticated); + mm_request_send(sock, MONITOR_ANS_JPAKE_CHECK_CONFIRM, m); + + monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP1, 1); + + auth_method = "jpake-01@openssh.com"; + return authenticated; +} + +#endif /* JPAKE */
diff --git a/openssh-6.0p1/monitor.h b/openssh-6.0p1/monitor.h new file mode 100644 index 0000000..5e7d552 --- /dev/null +++ b/openssh-6.0p1/monitor.h
@@ -0,0 +1,99 @@ +/* $OpenBSD: monitor.h,v 1.16 2011/06/17 21:44:31 djm Exp $ */ + +/* + * Copyright 2002 Niels Provos <provos@citi.umich.edu> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _MONITOR_H_ +#define _MONITOR_H_ + +enum monitor_reqtype { + MONITOR_REQ_MODULI, MONITOR_ANS_MODULI, + MONITOR_REQ_FREE, MONITOR_REQ_AUTHSERV, + MONITOR_REQ_SIGN, MONITOR_ANS_SIGN, + MONITOR_REQ_PWNAM, MONITOR_ANS_PWNAM, + MONITOR_REQ_AUTH2_READ_BANNER, MONITOR_ANS_AUTH2_READ_BANNER, + MONITOR_REQ_AUTHPASSWORD, MONITOR_ANS_AUTHPASSWORD, + MONITOR_REQ_BSDAUTHQUERY, MONITOR_ANS_BSDAUTHQUERY, + MONITOR_REQ_BSDAUTHRESPOND, MONITOR_ANS_BSDAUTHRESPOND, + MONITOR_REQ_SKEYQUERY, MONITOR_ANS_SKEYQUERY, + MONITOR_REQ_SKEYRESPOND, MONITOR_ANS_SKEYRESPOND, + MONITOR_REQ_KEYALLOWED, MONITOR_ANS_KEYALLOWED, + MONITOR_REQ_KEYVERIFY, MONITOR_ANS_KEYVERIFY, + MONITOR_REQ_KEYEXPORT, + MONITOR_REQ_PTY, MONITOR_ANS_PTY, + MONITOR_REQ_PTYCLEANUP, + MONITOR_REQ_SESSKEY, MONITOR_ANS_SESSKEY, + MONITOR_REQ_SESSID, + MONITOR_REQ_RSAKEYALLOWED, MONITOR_ANS_RSAKEYALLOWED, + MONITOR_REQ_RSACHALLENGE, MONITOR_ANS_RSACHALLENGE, + MONITOR_REQ_RSARESPONSE, MONITOR_ANS_RSARESPONSE, + MONITOR_REQ_GSSSETUP, MONITOR_ANS_GSSSETUP, + MONITOR_REQ_GSSSTEP, MONITOR_ANS_GSSSTEP, + MONITOR_REQ_GSSUSEROK, MONITOR_ANS_GSSUSEROK, + MONITOR_REQ_GSSCHECKMIC, MONITOR_ANS_GSSCHECKMIC, + MONITOR_REQ_PAM_START, + MONITOR_REQ_PAM_ACCOUNT, MONITOR_ANS_PAM_ACCOUNT, + MONITOR_REQ_PAM_INIT_CTX, MONITOR_ANS_PAM_INIT_CTX, + MONITOR_REQ_PAM_QUERY, MONITOR_ANS_PAM_QUERY, + MONITOR_REQ_PAM_RESPOND, MONITOR_ANS_PAM_RESPOND, + MONITOR_REQ_PAM_FREE_CTX, MONITOR_ANS_PAM_FREE_CTX, + MONITOR_REQ_AUDIT_EVENT, MONITOR_REQ_AUDIT_COMMAND, + MONITOR_REQ_TERM, + MONITOR_REQ_JPAKE_STEP1, MONITOR_ANS_JPAKE_STEP1, + MONITOR_REQ_JPAKE_GET_PWDATA, MONITOR_ANS_JPAKE_GET_PWDATA, + MONITOR_REQ_JPAKE_STEP2, MONITOR_ANS_JPAKE_STEP2, + MONITOR_REQ_JPAKE_KEY_CONFIRM, MONITOR_ANS_JPAKE_KEY_CONFIRM, + MONITOR_REQ_JPAKE_CHECK_CONFIRM, MONITOR_ANS_JPAKE_CHECK_CONFIRM, +}; + +struct mm_master; +struct monitor { + int m_recvfd; + int m_sendfd; + int m_log_recvfd; + int m_log_sendfd; + struct mm_master *m_zback; + struct mm_master *m_zlib; + struct Kex **m_pkex; + pid_t m_pid; +}; + +struct monitor *monitor_init(void); +void monitor_reinit(struct monitor *); +void monitor_sync(struct monitor *); + +struct Authctxt; +void monitor_child_preauth(struct Authctxt *, struct monitor *); +void monitor_child_postauth(struct monitor *); + +struct mon_table; +int monitor_read(struct monitor*, struct mon_table *, struct mon_table **); + +/* Prototypes for request sending and receiving */ +void mm_request_send(int, enum monitor_reqtype, Buffer *); +void mm_request_receive(int, Buffer *); +void mm_request_receive_expect(int, enum monitor_reqtype, Buffer *); + +#endif /* _MONITOR_H_ */
diff --git a/openssh-6.0p1/monitor_fdpass.c b/openssh-6.0p1/monitor_fdpass.c new file mode 100644 index 0000000..7eb6f5c --- /dev/null +++ b/openssh-6.0p1/monitor_fdpass.c
@@ -0,0 +1,182 @@ +/* $OpenBSD: monitor_fdpass.c,v 1.19 2010/01/12 00:58:25 djm Exp $ */ +/* + * Copyright 2001 Niels Provos <provos@citi.umich.edu> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/uio.h> +#ifdef HAVE_SYS_UN_H +#include <sys/un.h> +#endif + +#include <errno.h> +#ifdef HAVE_POLL_H +#include <poll.h> +#endif +#include <string.h> +#include <stdarg.h> + +#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 + msg.msg_control = (caddr_t)&cmsgbuf.buf; + msg.msg_controllen = sizeof(cmsgbuf.buf); + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_len = CMSG_LEN(sizeof(int)); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + *(int *)CMSG_DATA(cmsg) = fd; +#endif + + vec.iov_base = &ch; + vec.iov_len = 1; + msg.msg_iov = &vec; + msg.msg_iovlen = 1; + + pfd.fd = sock; + pfd.events = POLLOUT; + while ((n = sendmsg(sock, &msg, 0)) == -1 && + (errno == EAGAIN || errno == EINTR)) { + debug3("%s: sendmsg(%d): %s", __func__, fd, strerror(errno)); + (void)poll(&pfd, 1, -1); + } + if (n == -1) { + error("%s: sendmsg(%d): %s", __func__, fd, + strerror(errno)); + return -1; + } + + if (n != 1) { + error("%s: sendmsg: expected sent 1 got %ld", + __func__, (long)n); + return -1; + } + return 0; +#else + error("%s: file descriptor passing not supported", __func__); + return -1; +#endif +} + +int +mm_receive_fd(int sock) +{ +#if defined(HAVE_RECVMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR)) + struct msghdr msg; +#ifndef HAVE_ACCRIGHTS_IN_MSGHDR + union { + struct cmsghdr hdr; + char buf[CMSG_SPACE(sizeof(int))]; + } cmsgbuf; + struct cmsghdr *cmsg; +#endif + struct iovec vec; + ssize_t n; + char ch; + int fd; + struct pollfd pfd; + + memset(&msg, 0, sizeof(msg)); + vec.iov_base = &ch; + vec.iov_len = 1; + msg.msg_iov = &vec; + msg.msg_iovlen = 1; +#ifdef HAVE_ACCRIGHTS_IN_MSGHDR + msg.msg_accrights = (caddr_t)&fd; + msg.msg_accrightslen = sizeof(fd); +#else + msg.msg_control = &cmsgbuf.buf; + msg.msg_controllen = sizeof(cmsgbuf.buf); +#endif + + pfd.fd = sock; + pfd.events = POLLIN; + while ((n = recvmsg(sock, &msg, 0)) == -1 && + (errno == EAGAIN || errno == EINTR)) { + debug3("%s: recvmsg: %s", __func__, strerror(errno)); + (void)poll(&pfd, 1, -1); + } + if (n == -1) { + error("%s: recvmsg: %s", __func__, strerror(errno)); + return -1; + } + + if (n != 1) { + error("%s: recvmsg: expected received 1 got %ld", + __func__, (long)n); + return -1; + } + +#ifdef HAVE_ACCRIGHTS_IN_MSGHDR + if (msg.msg_accrightslen != sizeof(fd)) { + error("%s: no fd", __func__); + return -1; + } +#else + cmsg = CMSG_FIRSTHDR(&msg); + if (cmsg == NULL) { + error("%s: no message header", __func__); + return -1; + } + +#ifndef BROKEN_CMSG_TYPE + if (cmsg->cmsg_type != SCM_RIGHTS) { + error("%s: expected type %d got %d", __func__, + SCM_RIGHTS, cmsg->cmsg_type); + return -1; + } +#endif + fd = (*(int *)CMSG_DATA(cmsg)); +#endif + return fd; +#else + error("%s: file descriptor passing not supported", __func__); + return -1; +#endif +}
diff --git a/openssh-6.0p1/monitor_fdpass.h b/openssh-6.0p1/monitor_fdpass.h new file mode 100644 index 0000000..a4b1f63 --- /dev/null +++ b/openssh-6.0p1/monitor_fdpass.h
@@ -0,0 +1,34 @@ +/* $OpenBSD: monitor_fdpass.h,v 1.4 2007/09/04 03:21:03 djm Exp $ */ + +/* + * Copyright 2002 Niels Provos <provos@citi.umich.edu> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _MM_FDPASS_H_ +#define _MM_FDPASS_H_ + +int mm_send_fd(int, int); +int mm_receive_fd(int); + +#endif /* _MM_FDPASS_H_ */
diff --git a/openssh-6.0p1/monitor_mm.c b/openssh-6.0p1/monitor_mm.c new file mode 100644 index 0000000..faf9f3d --- /dev/null +++ b/openssh-6.0p1/monitor_mm.c
@@ -0,0 +1,352 @@ +/* $OpenBSD: monitor_mm.c,v 1.16 2009/06/22 05:39:28 dtucker Exp $ */ +/* + * Copyright 2002 Niels Provos <provos@citi.umich.edu> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#include <sys/types.h> +#ifdef HAVE_SYS_MMAN_H +#include <sys/mman.h> +#endif +#include <sys/param.h> +#include "openbsd-compat/sys-tree.h" + +#include <errno.h> +#include <stdarg.h> +#include <string.h> + +#include "xmalloc.h" +#include "ssh.h" +#include "log.h" +#include "monitor_mm.h" + +static int +mm_compare(struct mm_share *a, struct mm_share *b) +{ + long diff = (char *)a->address - (char *)b->address; + + if (diff == 0) + return (0); + else if (diff < 0) + return (-1); + else + return (1); +} + +RB_GENERATE(mmtree, mm_share, next, mm_compare) + +static struct mm_share * +mm_make_entry(struct mm_master *mm, struct mmtree *head, + void *address, size_t size) +{ + struct mm_share *tmp, *tmp2; + + if (mm->mmalloc == NULL) + tmp = xmalloc(sizeof(struct mm_share)); + else + tmp = mm_xmalloc(mm->mmalloc, sizeof(struct mm_share)); + tmp->address = address; + tmp->size = size; + + tmp2 = RB_INSERT(mmtree, head, tmp); + if (tmp2 != NULL) + fatal("mm_make_entry(%p): double address %p->%p(%lu)", + mm, tmp2, address, (u_long)size); + + return (tmp); +} + +/* Creates a shared memory area of a certain size */ + +struct mm_master * +mm_create(struct mm_master *mmalloc, size_t size) +{ + void *address; + struct mm_master *mm; + + if (mmalloc == NULL) + mm = xmalloc(sizeof(struct mm_master)); + else + mm = mm_xmalloc(mmalloc, sizeof(struct mm_master)); + + /* + * If the memory map has a mm_master it can be completely + * shared including authentication between the child + * and the client. + */ + mm->mmalloc = mmalloc; + + address = xmmap(size); + if (address == (void *)MAP_FAILED) + fatal("mmap(%lu): %s", (u_long)size, strerror(errno)); + + mm->address = address; + mm->size = size; + + RB_INIT(&mm->rb_free); + RB_INIT(&mm->rb_allocated); + + mm_make_entry(mm, &mm->rb_free, address, size); + + return (mm); +} + +/* Frees either the allocated or the free list */ + +static void +mm_freelist(struct mm_master *mmalloc, struct mmtree *head) +{ + struct mm_share *mms, *next; + + for (mms = RB_ROOT(head); mms; mms = next) { + next = RB_NEXT(mmtree, head, mms); + RB_REMOVE(mmtree, head, mms); + if (mmalloc == NULL) + xfree(mms); + else + mm_free(mmalloc, mms); + } +} + +/* Destroys a memory mapped area */ + +void +mm_destroy(struct mm_master *mm) +{ + mm_freelist(mm->mmalloc, &mm->rb_free); + mm_freelist(mm->mmalloc, &mm->rb_allocated); + +#ifdef HAVE_MMAP + if (munmap(mm->address, mm->size) == -1) + fatal("munmap(%p, %lu): %s", mm->address, (u_long)mm->size, + strerror(errno)); +#else + fatal("%s: UsePrivilegeSeparation=yes and Compression=yes not supported", + __func__); +#endif + if (mm->mmalloc == NULL) + xfree(mm); + else + mm_free(mm->mmalloc, mm); +} + +void * +mm_xmalloc(struct mm_master *mm, size_t size) +{ + void *address; + + address = mm_malloc(mm, size); + if (address == NULL) + fatal("%s: mm_malloc(%lu)", __func__, (u_long)size); + return (address); +} + + +/* Allocates data from a memory mapped area */ + +void * +mm_malloc(struct mm_master *mm, size_t size) +{ + struct mm_share *mms, *tmp; + + if (size == 0) + fatal("mm_malloc: try to allocate 0 space"); + if (size > SIZE_T_MAX - MM_MINSIZE + 1) + fatal("mm_malloc: size too big"); + + size = ((size + (MM_MINSIZE - 1)) / MM_MINSIZE) * MM_MINSIZE; + + RB_FOREACH(mms, mmtree, &mm->rb_free) { + if (mms->size >= size) + break; + } + + if (mms == NULL) + return (NULL); + + /* Debug */ + memset(mms->address, 0xd0, size); + + tmp = mm_make_entry(mm, &mm->rb_allocated, mms->address, size); + + /* Does not change order in RB tree */ + mms->size -= size; + mms->address = (u_char *)mms->address + size; + + if (mms->size == 0) { + RB_REMOVE(mmtree, &mm->rb_free, mms); + if (mm->mmalloc == NULL) + xfree(mms); + else + mm_free(mm->mmalloc, mms); + } + + return (tmp->address); +} + +/* Frees memory in a memory mapped area */ + +void +mm_free(struct mm_master *mm, void *address) +{ + struct mm_share *mms, *prev, tmp; + + tmp.address = address; + mms = RB_FIND(mmtree, &mm->rb_allocated, &tmp); + if (mms == NULL) + fatal("mm_free(%p): can not find %p", mm, address); + + /* Debug */ + memset(mms->address, 0xd0, mms->size); + + /* Remove from allocated list and insert in free list */ + RB_REMOVE(mmtree, &mm->rb_allocated, mms); + if (RB_INSERT(mmtree, &mm->rb_free, mms) != NULL) + fatal("mm_free(%p): double address %p", mm, address); + + /* Find previous entry */ + prev = mms; + if (RB_LEFT(prev, next)) { + prev = RB_LEFT(prev, next); + while (RB_RIGHT(prev, next)) + prev = RB_RIGHT(prev, next); + } else { + if (RB_PARENT(prev, next) && + (prev == RB_RIGHT(RB_PARENT(prev, next), next))) + prev = RB_PARENT(prev, next); + else { + while (RB_PARENT(prev, next) && + (prev == RB_LEFT(RB_PARENT(prev, next), next))) + prev = RB_PARENT(prev, next); + prev = RB_PARENT(prev, next); + } + } + + /* Check if range does not overlap */ + if (prev != NULL && MM_ADDRESS_END(prev) > address) + fatal("mm_free: memory corruption: %p(%lu) > %p", + prev->address, (u_long)prev->size, address); + + /* See if we can merge backwards */ + if (prev != NULL && MM_ADDRESS_END(prev) == address) { + prev->size += mms->size; + RB_REMOVE(mmtree, &mm->rb_free, mms); + if (mm->mmalloc == NULL) + xfree(mms); + else + mm_free(mm->mmalloc, mms); + } else + prev = mms; + + if (prev == NULL) + return; + + /* Check if we can merge forwards */ + mms = RB_NEXT(mmtree, &mm->rb_free, prev); + if (mms == NULL) + return; + + if (MM_ADDRESS_END(prev) > mms->address) + fatal("mm_free: memory corruption: %p < %p(%lu)", + mms->address, prev->address, (u_long)prev->size); + if (MM_ADDRESS_END(prev) != mms->address) + return; + + prev->size += mms->size; + RB_REMOVE(mmtree, &mm->rb_free, mms); + + if (mm->mmalloc == NULL) + xfree(mms); + else + mm_free(mm->mmalloc, mms); +} + +static void +mm_sync_list(struct mmtree *oldtree, struct mmtree *newtree, + struct mm_master *mm, struct mm_master *mmold) +{ + struct mm_master *mmalloc = mm->mmalloc; + struct mm_share *mms, *new; + + /* Sync free list */ + RB_FOREACH(mms, mmtree, oldtree) { + /* Check the values */ + mm_memvalid(mmold, mms, sizeof(struct mm_share)); + mm_memvalid(mm, mms->address, mms->size); + + new = mm_xmalloc(mmalloc, sizeof(struct mm_share)); + memcpy(new, mms, sizeof(struct mm_share)); + RB_INSERT(mmtree, newtree, new); + } +} + +void +mm_share_sync(struct mm_master **pmm, struct mm_master **pmmalloc) +{ + struct mm_master *mm; + struct mm_master *mmalloc; + struct mm_master *mmold; + struct mmtree rb_free, rb_allocated; + + debug3("%s: Share sync", __func__); + + mm = *pmm; + mmold = mm->mmalloc; + mm_memvalid(mmold, mm, sizeof(*mm)); + + mmalloc = mm_create(NULL, mm->size); + mm = mm_xmalloc(mmalloc, sizeof(struct mm_master)); + memcpy(mm, *pmm, sizeof(struct mm_master)); + mm->mmalloc = mmalloc; + + rb_free = mm->rb_free; + rb_allocated = mm->rb_allocated; + + RB_INIT(&mm->rb_free); + RB_INIT(&mm->rb_allocated); + + mm_sync_list(&rb_free, &mm->rb_free, mm, mmold); + mm_sync_list(&rb_allocated, &mm->rb_allocated, mm, mmold); + + mm_destroy(mmold); + + *pmm = mm; + *pmmalloc = mmalloc; + + debug3("%s: Share sync end", __func__); +} + +void +mm_memvalid(struct mm_master *mm, void *address, size_t size) +{ + void *end = (u_char *)address + size; + + if (address < mm->address) + fatal("mm_memvalid: address too small: %p", address); + if (end < address) + fatal("mm_memvalid: end < address: %p < %p", end, address); + if (end > (void *)((u_char *)mm->address + mm->size)) + fatal("mm_memvalid: address too large: %p", address); +}
diff --git a/openssh-6.0p1/monitor_mm.h b/openssh-6.0p1/monitor_mm.h new file mode 100644 index 0000000..c890f77 --- /dev/null +++ b/openssh-6.0p1/monitor_mm.h
@@ -0,0 +1,62 @@ +/* $OpenBSD: monitor_mm.h,v 1.5 2008/04/29 11:20:31 otto Exp $ */ + +/* + * Copyright 2002 Niels Provos <provos@citi.umich.edu> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _MM_H_ +#define _MM_H_ + +struct mm_share { + RB_ENTRY(mm_share) next; + void *address; + size_t size; +}; + +struct mm_master { + RB_HEAD(mmtree, mm_share) rb_free; + struct mmtree rb_allocated; + void *address; + size_t size; + + struct mm_master *mmalloc; /* Used to completely share */ +}; + +RB_PROTOTYPE(mmtree, mm_share, next, mm_compare) + +#define MM_MINSIZE 128 + +#define MM_ADDRESS_END(x) (void *)((u_char *)(x)->address + (x)->size) + +struct mm_master *mm_create(struct mm_master *, size_t); +void mm_destroy(struct mm_master *); + +void mm_share_sync(struct mm_master **, struct mm_master **); + +void *mm_malloc(struct mm_master *, size_t); +void *mm_xmalloc(struct mm_master *, size_t); +void mm_free(struct mm_master *, void *); + +void mm_memvalid(struct mm_master *, void *, size_t); +#endif /* _MM_H_ */
diff --git a/openssh-6.0p1/monitor_wrap.c b/openssh-6.0p1/monitor_wrap.c new file mode 100644 index 0000000..1f60658 --- /dev/null +++ b/openssh-6.0p1/monitor_wrap.c
@@ -0,0 +1,1452 @@ +/* $OpenBSD: monitor_wrap.c,v 1.73 2011/06/17 21:44:31 djm Exp $ */ +/* + * Copyright 2002 Niels Provos <provos@citi.umich.edu> + * Copyright 2002 Markus Friedl <markus@openbsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#include <sys/types.h> +#include <sys/uio.h> + +#include <errno.h> +#include <pwd.h> +#include <signal.h> +#include <stdarg.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +#include <openssl/bn.h> +#include <openssl/dh.h> +#include <openssl/evp.h> + +#include "openbsd-compat/sys-queue.h" +#include "xmalloc.h" +#include "ssh.h" +#include "dh.h" +#include "buffer.h" +#include "key.h" +#include "cipher.h" +#include "kex.h" +#include "hostfile.h" +#include "auth.h" +#include "auth-options.h" +#include "packet.h" +#include "mac.h" +#include "log.h" +#ifdef TARGET_OS_MAC /* XXX Broken krb5 headers on Mac */ +#undef TARGET_OS_MAC +#include "zlib.h" +#define TARGET_OS_MAC 1 +#else +#include "zlib.h" +#endif +#include "monitor.h" +#ifdef GSSAPI +#include "ssh-gss.h" +#endif +#include "monitor_wrap.h" +#include "atomicio.h" +#include "monitor_fdpass.h" +#include "misc.h" +#include "schnorr.h" +#include "jpake.h" +#include "uuencode.h" + +#include "channels.h" +#include "session.h" +#include "servconf.h" +#include "roaming.h" + +/* Imports */ +extern int compat20; +extern z_stream incoming_stream; +extern z_stream outgoing_stream; +extern struct monitor *pmonitor; +extern Buffer loginmsg; +extern ServerOptions options; + +void +mm_log_handler(LogLevel level, const char *msg, void *ctx) +{ + Buffer log_msg; + struct monitor *mon = (struct monitor *)ctx; + + if (mon->m_log_sendfd == -1) + fatal("%s: no log channel", __func__); + + buffer_init(&log_msg); + /* + * Placeholder for packet length. Will be filled in with the actual + * packet length once the packet has been constucted. This saves + * fragile math. + */ + buffer_put_int(&log_msg, 0); + + buffer_put_int(&log_msg, level); + buffer_put_cstring(&log_msg, msg); + put_u32(buffer_ptr(&log_msg), buffer_len(&log_msg) - 4); + if (atomicio(vwrite, mon->m_log_sendfd, buffer_ptr(&log_msg), + buffer_len(&log_msg)) != buffer_len(&log_msg)) + fatal("%s: write: %s", __func__, strerror(errno)); + buffer_free(&log_msg); +} + +int +mm_is_monitor(void) +{ + /* + * m_pid is only set in the privileged part, and + * points to the unprivileged child. + */ + return (pmonitor && pmonitor->m_pid > 0); +} + +void +mm_request_send(int sock, enum monitor_reqtype type, Buffer *m) +{ + u_int mlen = buffer_len(m); + u_char buf[5]; + + debug3("%s entering: type %d", __func__, type); + + put_u32(buf, mlen + 1); + buf[4] = (u_char) type; /* 1st byte of payload is mesg-type */ + if (atomicio(vwrite, sock, buf, sizeof(buf)) != sizeof(buf)) + fatal("%s: write: %s", __func__, strerror(errno)); + if (atomicio(vwrite, sock, buffer_ptr(m), mlen) != mlen) + fatal("%s: write: %s", __func__, strerror(errno)); +} + +void +mm_request_receive(int sock, Buffer *m) +{ + u_char buf[4]; + u_int msg_len; + + debug3("%s entering", __func__); + + if (atomicio(read, sock, buf, sizeof(buf)) != sizeof(buf)) { + if (errno == EPIPE) + cleanup_exit(255); + fatal("%s: read: %s", __func__, strerror(errno)); + } + msg_len = get_u32(buf); + if (msg_len > 256 * 1024) + fatal("%s: read: bad msg_len %d", __func__, msg_len); + buffer_clear(m); + buffer_append_space(m, msg_len); + if (atomicio(read, sock, buffer_ptr(m), msg_len) != msg_len) + fatal("%s: read: %s", __func__, strerror(errno)); +} + +void +mm_request_receive_expect(int sock, enum monitor_reqtype type, Buffer *m) +{ + u_char rtype; + + debug3("%s entering: type %d", __func__, type); + + mm_request_receive(sock, m); + rtype = buffer_get_char(m); + if (rtype != type) + fatal("%s: read: rtype %d != type %d", __func__, + rtype, type); +} + +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)); +} + +int +mm_key_sign(Key *key, u_char **sigp, u_int *lenp, u_char *data, u_int datalen) +{ + Kex *kex = *pmonitor->m_pkex; + Buffer m; + + debug3("%s entering", __func__); + + buffer_init(&m); + buffer_put_int(&m, kex->host_key_index(key)); + buffer_put_string(&m, data, datalen); + + 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 *<