diff -ruN --exclude CVS ssh-openbsd-2003091600/acconfig.h openssh-3.7p1/acconfig.h --- ssh-openbsd-2003091600/acconfig.h 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/acconfig.h 2003-09-16 11:52:19.000000000 +1000 @@ -0,0 +1,431 @@ +/* $Id: acconfig.h,v 1.166 2003/09/16 01:52:19 dtucker Exp $ */ + +/* + * 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 _CONFIG_H +#define _CONFIG_H + +/* Generated automatically from acconfig.h by autoheader. */ +/* Please make your changes there */ + +@TOP@ + +/* Define if your platform breaks doing a seteuid before a setuid */ +#undef SETEUID_BREAKS_SETUID + +/* Define if your setreuid() is broken */ +#undef BROKEN_SETREUID + +/* Define if your setregid() is broken */ +#undef BROKEN_SETREGID + +/* Define to a Set Process Title type if your system is */ +/* supported by bsd-setproctitle.c */ +#undef SPT_TYPE +#undef SPT_PADCHAR + +/* setgroups() NOOP allowed */ +#undef SETGROUPS_NOOP + +/* SCO workaround */ +#undef BROKEN_SYS_TERMIO_H + +/* Define if you have SecureWare-based protected password database */ +#undef HAVE_SECUREWARE + +/* If your header files don't define LOGIN_PROGRAM, then use this (detected) */ +/* from environment and PATH */ +#undef LOGIN_PROGRAM_FALLBACK + +/* 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 if your password has a pw_change field */ +#undef HAVE_PW_CHANGE_IN_PASSWD + +/* Define if your system uses access rights style file descriptor passing */ +#undef HAVE_ACCRIGHTS_IN_MSGHDR + +/* Define if your system uses ancillary data style file descriptor passing */ +#undef HAVE_CONTROL_IN_MSGHDR + +/* Define if you system's inet_ntoa is busted (e.g. Irix gcc issue) */ +#undef BROKEN_INET_NTOA + +/* Define if your system defines sys_errlist[] */ +#undef HAVE_SYS_ERRLIST + +/* Define if your system defines sys_nerr */ +#undef HAVE_SYS_NERR + +/* Define if your system choked on IP TOS setting */ +#undef IP_TOS_IS_BROKEN + +/* Define if you have the getuserattr function. */ +#undef HAVE_GETUSERATTR + +/* Work around problematic Linux PAM modules handling of PAM_TTY */ +#undef PAM_TTY_KLUDGE + +/* Use PIPES instead of a socketpair() */ +#undef USE_PIPES + +/* Define if your snprintf is busted */ +#undef BROKEN_SNPRINTF + +/* Define if you are on Cygwin */ +#undef HAVE_CYGWIN + +/* Define if you have a broken realpath. */ +#undef BROKEN_REALPATH + +/* Define if you are on NeXT */ +#undef HAVE_NEXT + +/* Define if you are on NEWS-OS */ +#undef HAVE_NEWS4 + +/* Define if you want to enable PAM support */ +#undef USE_PAM + +/* Define if you want to enable AIX4's authenticate function */ +#undef WITH_AIXAUTHENTICATE + +/* Define if your AIX loginfailed() function takes 4 arguments (AIX >= 5.2) */ +#undef AIX_LOGINFAILED_4ARG + +/* Define if you have/want arrays (cluster-wide session managment, not C arrays) */ +#undef WITH_IRIX_ARRAY + +/* Define if you want IRIX project management */ +#undef WITH_IRIX_PROJECT + +/* Define if you want IRIX audit trails */ +#undef WITH_IRIX_AUDIT + +/* Define if you want IRIX kernel jobs */ +#undef WITH_IRIX_JOBS + +/* Location of PRNGD/EGD random number socket */ +#undef PRNGD_SOCKET + +/* Port number of PRNGD/EGD random number socket */ +#undef PRNGD_PORT + +/* Builtin PRNG command timeout */ +#undef ENTROPY_TIMEOUT_MSEC + +/* non-privileged user for privilege separation */ +#undef SSH_PRIVSEP_USER + +/* Define if you want to install preformatted manpages.*/ +#undef MANTYPE + +/* Define if your ssl headers are included with #include */ +#undef HAVE_OPENSSL + +/* Define if you are linking against RSAref. Used only to print the right + * message at run-time. */ +#undef RSAREF + +/* struct timeval */ +#undef HAVE_STRUCT_TIMEVAL + +/* struct utmp and struct utmpx fields */ +#undef HAVE_HOST_IN_UTMP +#undef HAVE_HOST_IN_UTMPX +#undef HAVE_ADDR_IN_UTMP +#undef HAVE_ADDR_IN_UTMPX +#undef HAVE_ADDR_V6_IN_UTMP +#undef HAVE_ADDR_V6_IN_UTMPX +#undef HAVE_SYSLEN_IN_UTMPX +#undef HAVE_PID_IN_UTMP +#undef HAVE_TYPE_IN_UTMP +#undef HAVE_TYPE_IN_UTMPX +#undef HAVE_TV_IN_UTMP +#undef HAVE_TV_IN_UTMPX +#undef HAVE_ID_IN_UTMP +#undef HAVE_ID_IN_UTMPX +#undef HAVE_EXIT_IN_UTMP +#undef HAVE_TIME_IN_UTMP +#undef HAVE_TIME_IN_UTMPX + +/* 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 don't want to use lastlog */ +#undef DISABLE_LASTLOG + +/* Define if you don't want to use lastlog in session.c */ +#undef NO_SSH_LASTLOG + +/* 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 + +/* Some systems need a utmpx entry for /bin/login to work */ +#undef LOGIN_NEEDS_UTMPX + +/* Some versions of /bin/login need the TERM supplied on the commandline */ +#undef LOGIN_NEEDS_TERM + +/* Define if your login program cannot handle end of options ("--") */ +#undef LOGIN_NO_ENDOPT + +/* 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 wtmp file */ +#undef CONF_WTMP_FILE + +/* Define if you want to specify the path to your utmpx file */ +#undef CONF_UTMPX_FILE + +/* Define if you want to specify the path to your wtmpx file */ +#undef CONF_WTMPX_FILE + +/* Define if you want external askpass support */ +#undef USE_EXTERNAL_ASKPASS + +/* Define if libc defines __progname */ +#undef HAVE___PROGNAME + +/* Define if compiler implements __FUNCTION__ */ +#undef HAVE___FUNCTION__ + +/* Define if compiler implements __func__ */ +#undef HAVE___func__ + +/* Define this is you want GSSAPI support in the version 2 protocol */ +#undef GSSAPI + +/* Define if you want Kerberos 5 support */ +#undef KRB5 + +/* Define this if you are using the Heimdal version of Kerberos V5 */ +#undef HEIMDAL + +/* Define if you want S/Key support */ +#undef SKEY + +/* Define if you want TCP Wrappers support */ +#undef LIBWRAP + +/* Define if your libraries define login() */ +#undef HAVE_LOGIN + +/* Define if your libraries define daemon() */ +#undef HAVE_DAEMON + +/* Define if your libraries define getpagesize() */ +#undef HAVE_GETPAGESIZE + +/* Define if xauth is found in your path */ +#undef XAUTH_PATH + +/* Define if you want to allow MD5 passwords */ +#undef HAVE_MD5_PASSWORDS + +/* Define if you want to disable shadow passwords */ +#undef DISABLE_SHADOW + +/* Define if you want to use shadow password expire field */ +#undef HAS_SHADOW_EXPIRE + +/* Define if you have Digital Unix Security Integration Architecture */ +#undef HAVE_OSF_SIA + +/* Define if you have getpwanam(3) [SunOS 4.x] */ +#undef HAVE_GETPWANAM + +/* Define if you have an old version of PAM which takes only one argument */ +/* to pam_strerror */ +#undef HAVE_OLD_PAM + +/* 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 + +/* Set this to your mail directory if you don't have maillock.h */ +#undef MAIL_DIRECTORY + +/* Data types */ +#undef HAVE_U_INT +#undef HAVE_INTXX_T +#undef HAVE_U_INTXX_T +#undef HAVE_UINTXX_T +#undef HAVE_INT64_T +#undef HAVE_U_INT64_T +#undef HAVE_U_CHAR +#undef HAVE_SIZE_T +#undef HAVE_SSIZE_T +#undef HAVE_CLOCK_T +#undef HAVE_MODE_T +#undef HAVE_PID_T +#undef HAVE_SA_FAMILY_T +#undef HAVE_STRUCT_SOCKADDR_STORAGE +#undef HAVE_STRUCT_ADDRINFO +#undef HAVE_STRUCT_IN6_ADDR +#undef HAVE_STRUCT_SOCKADDR_IN6 + +/* Fields in struct sockaddr_storage */ +#undef HAVE_SS_FAMILY_IN_SS +#undef HAVE___SS_FAMILY_IN_SS + +/* Define if you have /dev/ptmx */ +#undef HAVE_DEV_PTMX + +/* Define if you have /dev/ptc */ +#undef HAVE_DEV_PTS_AND_PTC + +/* Define if you need to use IP address instead of hostname in $DISPLAY */ +#undef IPADDR_IN_DISPLAY + +/* Specify default $PATH */ +#undef USER_PATH + +/* Specify location of ssh.pid */ +#undef _PATH_SSH_PIDDIR + +/* getaddrinfo is broken (if present) */ +#undef BROKEN_GETADDRINFO + +/* Workaround more Linux IPv6 quirks */ +#undef DONT_TRY_OTHER_AF + +/* Detect IPv4 in IPv6 mapped addresses and treat as IPv4 */ +#undef IPV4_IN_IPV6 + +/* Define if you have BSD auth support */ +#undef BSD_AUTH + +/* Define if X11 doesn't support AF_UNIX sockets on that system */ +#undef NO_X11_UNIX_SOCKETS + +/* Define if the concept of ports only accessible to superusers isn't known */ +#undef NO_IPPORT_RESERVED_CONCEPT + +/* Needed for SCO and NeXT */ +#undef BROKEN_SAVED_UIDS + +/* 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 in your struct dirent expects you to allocate extra space for d_name */ +#undef BROKEN_ONE_BYTE_DIRENT_D_NAME + +/* Define if your system has /etc/default/login */ +#undef HAVE_ETC_DEFAULT_LOGIN + +/* Define if your getopt(3) defines and uses optreset */ +#undef HAVE_GETOPT_OPTRESET + +/* Define on *nto-qnx systems */ +#undef MISSING_NFDBITS + +/* Define on *nto-qnx systems */ +#undef MISSING_HOWMANY + +/* Define on *nto-qnx systems */ +#undef MISSING_FD_MASK + +/* Define if you want smartcard support */ +#undef SMARTCARD + +/* Define if you want smartcard support using sectok */ +#undef USE_SECTOK + +/* Define if you want smartcard support using OpenSC */ +#undef USE_OPENSC + +/* Define if you want to use OpenSSL's internally seeded PRNG only */ +#undef OPENSSL_PRNG_ONLY + +/* Define if you shouldn't strip 'tty' from your ttyname in [uw]tmp */ +#undef WITH_ABBREV_NO_TTY + +/* Define if you want a different $PATH for the superuser */ +#undef SUPERUSER_PATH + +/* Path that unprivileged child will chroot() to in privep mode */ +#undef PRIVSEP_PATH + +/* Define if your platform needs to skip post auth file descriptor passing */ +#undef DISABLE_FD_PASSING + +/* Silly mkstemp() */ +#undef HAVE_STRICT_MKSTEMP + +/* Some systems put this outside of libc */ +#undef HAVE_NANOSLEEP + +/* Define if sshd somehow reacquires a controlling TTY after setsid() */ +#undef SSHD_ACQUIRES_CTTY + +/* Define if cmsg_type is not passed correctly */ +#undef BROKEN_CMSG_TYPE + +/* Strings used in /etc/passwd to denote locked account */ +#undef LOCKED_PASSWD_STRING +#undef LOCKED_PASSWD_PREFIX +#undef LOCKED_PASSWD_SUBSTR + +/* Define if DNS support is to be activated */ +#undef DNS + +/* Define if getrrsetbyname() exists */ +#undef HAVE_GETRRSETBYNAME + +/* Define if HEADER.ad exists in arpa/nameser.h */ +#undef HAVE_HEADER_AD + +@BOTTOM@ + +/* ******************* Shouldn't need to edit below this line ************** */ + +#endif /* _CONFIG_H */ diff -ruN --exclude CVS ssh-openbsd-2003091600/aclocal.m4 openssh-3.7p1/aclocal.m4 --- ssh-openbsd-2003091600/aclocal.m4 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/aclocal.m4 2001-10-22 10:53:59.000000000 +1000 @@ -0,0 +1,86 @@ +dnl $Id: aclocal.m4,v 1.5 2001/10/22 00:53:59 tim Exp $ +dnl +dnl OpenSSH-specific autoconf macros +dnl + + +dnl OSSH_CHECK_HEADER_FOR_FIELD(field, header, symbol) +dnl Does AC_EGREP_HEADER on 'header' for the string 'field' +dnl If found, set 'symbol' to be defined. Cache the result. +dnl TODO: This is not foolproof, better to compile and read from there +AC_DEFUN(OSSH_CHECK_HEADER_FOR_FIELD, [ +# look for field '$1' in header '$2' + dnl This strips characters illegal to m4 from the header filename + ossh_safe=`echo "$2" | sed 'y%./+-%__p_%'` + dnl + ossh_varname="ossh_cv_$ossh_safe""_has_"$1 + AC_MSG_CHECKING(for $1 field in $2) + AC_CACHE_VAL($ossh_varname, [ + AC_EGREP_HEADER($1, $2, [ dnl + eval "$ossh_varname=yes" dnl + ], [ dnl + eval "$ossh_varname=no" dnl + ]) dnl + ]) + ossh_result=`eval 'echo $'"$ossh_varname"` + if test -n "`echo $ossh_varname`"; then + AC_MSG_RESULT($ossh_result) + if test "x$ossh_result" = "xyes"; then + AC_DEFINE($3) + fi + else + AC_MSG_RESULT(no) + fi +]) + +dnl OSSH_PATH_ENTROPY_PROG(variablename, command): +dnl Tidiness function, sets 'undef' if not found, and does the AC_SUBST +AC_DEFUN(OSSH_PATH_ENTROPY_PROG, [ + AC_PATH_PROG($1, $2) + if test -z "[$]$1" ; then + $1="undef" + fi + AC_SUBST($1) +]) + +dnl Check for socklen_t: historically on BSD it is an int, and in +dnl POSIX 1g it is a type of its own, but some platforms use different +dnl types for the argument to getsockopt, getpeername, etc. So we +dnl have to test to find something that will work. +AC_DEFUN([TYPE_SOCKLEN_T], +[ + AC_CHECK_TYPE([socklen_t], ,[ + AC_MSG_CHECKING([for socklen_t equivalent]) + AC_CACHE_VAL([curl_cv_socklen_t_equiv], + [ + # Systems have either "struct sockaddr *" or + # "void *" as the second argument to getpeername + curl_cv_socklen_t_equiv= + for arg2 in "struct sockaddr" void; do + for t in int size_t unsigned long "unsigned long"; do + AC_TRY_COMPILE([ + #include + #include + + int getpeername (int, $arg2 *, $t *); + ],[ + $t len; + getpeername(0,0,&len); + ],[ + curl_cv_socklen_t_equiv="$t" + break + ]) + done + done + + if test "x$curl_cv_socklen_t_equiv" = x; then + AC_MSG_ERROR([Cannot find a type to use in place of socklen_t]) + fi + ]) + AC_MSG_RESULT($curl_cv_socklen_t_equiv) + AC_DEFINE_UNQUOTED(socklen_t, $curl_cv_socklen_t_equiv, + [type to use in place of socklen_t if not defined])], + [#include +#include ]) +]) + diff -ruN --exclude CVS ssh-openbsd-2003091600/atomicio.c openssh-3.7p1/atomicio.c --- ssh-openbsd-2003091600/atomicio.c 2003-09-03 12:07:14.000000000 +1000 +++ openssh-3.7p1/atomicio.c 2003-08-03 00:05:59.000000000 +1000 @@ -45,7 +45,11 @@ res = (f) (fd, s + pos, n - pos); switch (res) { case -1: +#ifdef EWOULDBLOCK + if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) +#else if (errno == EINTR || errno == EAGAIN) +#endif continue; case 0: return (res); diff -ruN --exclude CVS ssh-openbsd-2003091600/auth1.c openssh-3.7p1/auth1.c --- ssh-openbsd-2003091600/auth1.c 2003-09-03 12:07:14.000000000 +1000 +++ openssh-3.7p1/auth1.c 2003-09-03 07:32:46.000000000 +1000 @@ -69,7 +69,7 @@ char info[1024]; u_int dlen; u_int ulen; - int type = 0; + int prev, type = 0; struct passwd *pw = authctxt->pw; debug("Attempting authentication for %s%.100s.", @@ -90,6 +90,8 @@ packet_send(); packet_write_wait(); + client_user = NULL; + for (;;) { /* default to fail */ authenticated = 0; @@ -97,8 +99,20 @@ info[0] = '\0'; /* Get a packet from the client. */ + prev = type; type = packet_read(); + /* + * If we started challenge-response authentication but the + * next packet is not a response to our challenge, release + * the resources allocated by get_challenge() (which would + * normally have been released by verify_response() had we + * received such a response) + */ + if (prev == SSH_CMSG_AUTH_TIS && + type != SSH_CMSG_AUTH_TIS_RESPONSE) + abandon_challenge_response(authctxt); + /* Process the packet. */ switch (type) { case SSH_CMSG_AUTH_RHOSTS_RSA: @@ -130,7 +144,6 @@ key_free(client_host_key); snprintf(info, sizeof info, " ruser %.100s", client_user); - xfree(client_user); break; case SSH_CMSG_AUTH_RSA: @@ -211,14 +224,41 @@ fatal("INTERNAL ERROR: authenticated invalid user %s", authctxt->user); +#ifdef _UNICOS + if (authenticated && cray_access_denied(authctxt->user)) { + authenticated = 0; + fatal("Access denied for user %s.",authctxt->user); + } +#endif /* _UNICOS */ + +#ifdef HAVE_CYGWIN + if (authenticated && + !check_nt_auth(type == SSH_CMSG_AUTH_PASSWORD, pw)) { + packet_disconnect("Authentication rejected for uid %d.", + pw == NULL ? -1 : pw->pw_uid); + authenticated = 0; + } +#else /* Special handling for root */ if (authenticated && authctxt->pw->pw_uid == 0 && !auth_root_allowed(get_authname(type))) authenticated = 0; +#endif + +#ifdef USE_PAM + if (options.use_pam && authenticated && + !PRIVSEP(do_pam_account())) + authenticated = 0; +#endif /* Log before sending the reply */ auth_log(authctxt, authenticated, get_authname(type), info); + if (client_user != NULL) { + xfree(client_user); + client_user = NULL; + } + if (authenticated) return; @@ -267,13 +307,20 @@ setproctitle("%s%s", authctxt->pw ? user : "unknown", use_privsep ? " [net]" : ""); +#ifdef USE_PAM + if (options.use_pam) + PRIVSEP(start_pam(user)); +#endif + /* * If we are not running as root, the user must have the same uid as - * the server. + * the server. (Unless you are running Windows) */ +#ifndef HAVE_CYGWIN if (!use_privsep && getuid() != 0 && authctxt->pw && authctxt->pw->pw_uid != getuid()) packet_disconnect("Cannot change user when server not running as root."); +#endif /* * Loop until the user has been authenticated or the connection is diff -ruN --exclude CVS ssh-openbsd-2003091600/auth2.c openssh-3.7p1/auth2.c --- ssh-openbsd-2003091600/auth2.c 2003-09-03 12:07:14.000000000 +1000 +++ openssh-3.7p1/auth2.c 2003-09-03 07:32:46.000000000 +1000 @@ -162,9 +162,17 @@ if (authctxt->pw && strcmp(service, "ssh-connection")==0) { authctxt->valid = 1; debug2("input_userauth_request: setting up authctxt for %s", user); +#ifdef USE_PAM + if (options.use_pam) + PRIVSEP(start_pam(authctxt->pw->pw_name)); +#endif } else { logit("input_userauth_request: illegal user %s", user); authctxt->pw = fakepw(); +#ifdef USE_PAM + if (options.use_pam) + PRIVSEP(start_pam(user)); +#endif } setproctitle("%s%s", authctxt->pw ? user : "unknown", use_privsep ? " [net]" : ""); @@ -216,6 +224,18 @@ !auth_root_allowed(method)) authenticated = 0; +#ifdef USE_PAM + if (options.use_pam && authenticated && !PRIVSEP(do_pam_account())) + authenticated = 0; +#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"); diff -ruN --exclude CVS ssh-openbsd-2003091600/auth2-chall.c openssh-3.7p1/auth2-chall.c --- ssh-openbsd-2003091600/auth2-chall.c 2003-03-26 16:04:02.000000000 +1100 +++ openssh-3.7p1/auth2-chall.c 2003-05-26 21:36:13.000000000 +1000 @@ -41,6 +41,9 @@ #ifdef BSD_AUTH extern KbdintDevice bsdauth_device; #else +#ifdef USE_PAM +extern KbdintDevice sshpam_device; +#endif #ifdef SKEY extern KbdintDevice skey_device; #endif @@ -50,6 +53,9 @@ #ifdef BSD_AUTH &bsdauth_device, #else +#ifdef USE_PAM + &sshpam_device, +#endif #ifdef SKEY &skey_device, #endif @@ -320,18 +326,27 @@ 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 - /* As long as SSHv1 has devices[0] hard coded this is fine */ + #ifdef BSD_AUTH - devices[0] = &mm_bsdauth_device; + devices[n++] = &mm_bsdauth_device; #else +#ifdef USE_PAM + devices[n++] = &mm_sshpam_device; +#endif #ifdef SKEY - devices[0] = &mm_skey_device; + devices[n++] = &mm_skey_device; #endif #endif } diff -ruN --exclude CVS ssh-openbsd-2003091600/auth2-kbdint.c openssh-3.7p1/auth2-kbdint.c --- ssh-openbsd-2003091600/auth2-kbdint.c 2003-03-26 16:04:02.000000000 +1100 +++ openssh-3.7p1/auth2-kbdint.c 2003-05-10 19:28:02.000000000 +1000 @@ -51,6 +51,10 @@ xfree(devs); xfree(lang); +#ifdef HAVE_CYGWIN + if (check_nt_auth(0, authctxt->pw) == 0) + return(0); +#endif return authenticated; } diff -ruN --exclude CVS ssh-openbsd-2003091600/auth2-none.c openssh-3.7p1/auth2-none.c --- ssh-openbsd-2003091600/auth2-none.c 2003-09-03 12:07:14.000000000 +1000 +++ openssh-3.7p1/auth2-none.c 2003-09-03 07:32:46.000000000 +1000 @@ -96,6 +96,10 @@ none_enabled = 0; packet_check_eom(); userauth_banner(); +#ifdef HAVE_CYGWIN + if (check_nt_auth(1, authctxt->pw) == 0) + return(0); +#endif if (options.password_authentication) return (PRIVSEP(auth_password(authctxt, ""))); return (0); diff -ruN --exclude CVS ssh-openbsd-2003091600/auth2-passwd.c openssh-3.7p1/auth2-passwd.c --- ssh-openbsd-2003091600/auth2-passwd.c 2003-09-03 12:07:14.000000000 +1000 +++ openssh-3.7p1/auth2-passwd.c 2003-09-03 07:32:46.000000000 +1000 @@ -47,7 +47,11 @@ logit("password change not supported"); password = packet_get_string(&len); packet_check_eom(); - if (PRIVSEP(auth_password(authctxt, password)) == 1) + if (PRIVSEP(auth_password(authctxt, password)) == 1 +#ifdef HAVE_CYGWIN + && check_nt_auth(1, authctxt->pw) +#endif + ) authenticated = 1; memset(password, 0, len); xfree(password); diff -ruN --exclude CVS ssh-openbsd-2003091600/.#auth2-passwd.c.1.2 openssh-3.7p1/.#auth2-passwd.c.1.2 --- ssh-openbsd-2003091600/.#auth2-passwd.c.1.2 2003-04-29 19:36:42.000000000 +1000 +++ openssh-3.7p1/.#auth2-passwd.c.1.2 1970-01-01 10:00:00.000000000 +1000 @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2000 Markus Friedl. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "includes.h" -RCSID("$OpenBSD: auth2-passwd.c,v 1.2 2002/05/31 11:35:15 markus Exp $"); - -#include "xmalloc.h" -#include "packet.h" -#include "log.h" -#include "auth.h" -#include "monitor_wrap.h" -#include "servconf.h" - -/* import */ -extern ServerOptions options; - -static int -userauth_passwd(Authctxt *authctxt) -{ - char *password; - int authenticated = 0; - int change; - u_int len; - change = packet_get_char(); - if (change) - log("password change not supported"); - password = packet_get_string(&len); - packet_check_eom(); - if (PRIVSEP(auth_password(authctxt, password)) == 1 && authctxt->valid) - authenticated = 1; - memset(password, 0, len); - xfree(password); - return authenticated; -} - -Authmethod method_passwd = { - "password", - userauth_passwd, - &options.password_authentication -}; diff -ruN --exclude CVS ssh-openbsd-2003091600/.#auth2-passwd.c.1.3 openssh-3.7p1/.#auth2-passwd.c.1.3 --- ssh-openbsd-2003091600/.#auth2-passwd.c.1.3 2003-04-29 08:54:17.000000000 +1000 +++ openssh-3.7p1/.#auth2-passwd.c.1.3 1970-01-01 10:00:00.000000000 +1000 @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2000 Markus Friedl. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "includes.h" -RCSID("$OpenBSD: auth2-passwd.c,v 1.3 2003/04/08 20:21:28 itojun Exp $"); - -#include "xmalloc.h" -#include "packet.h" -#include "log.h" -#include "auth.h" -#include "monitor_wrap.h" -#include "servconf.h" - -/* import */ -extern ServerOptions options; - -static int -userauth_passwd(Authctxt *authctxt) -{ - char *password; - int authenticated = 0; - int change; - u_int len; - change = packet_get_char(); - if (change) - logit("password change not supported"); - password = packet_get_string(&len); - packet_check_eom(); - if (PRIVSEP(auth_password(authctxt, password)) == 1 && authctxt->valid) - authenticated = 1; - memset(password, 0, len); - xfree(password); - return authenticated; -} - -Authmethod method_passwd = { - "password", - userauth_passwd, - &options.password_authentication -}; diff -ruN --exclude CVS ssh-openbsd-2003091600/auth2-pubkey.c openssh-3.7p1/auth2-pubkey.c --- ssh-openbsd-2003091600/auth2-pubkey.c 2003-06-28 11:22:37.000000000 +1000 +++ openssh-3.7p1/auth2-pubkey.c 2003-06-28 12:38:02.000000000 +1000 @@ -156,6 +156,10 @@ key_free(key); xfree(pkalg); xfree(pkblob); +#ifdef HAVE_CYGWIN + if (check_nt_auth(0, authctxt->pw) == 0) + return(0); +#endif return authenticated; } diff -ruN --exclude CVS ssh-openbsd-2003091600/auth.c openssh-3.7p1/auth.c --- ssh-openbsd-2003091600/auth.c 2003-09-03 12:07:14.000000000 +1000 +++ openssh-3.7p1/auth.c 2003-09-03 07:32:46.000000000 +1000 @@ -25,7 +25,16 @@ #include "includes.h" RCSID("$OpenBSD: auth.c,v 1.49 2003/08/26 09:58:43 markus Exp $"); +#ifdef HAVE_LOGIN_H +#include +#endif +#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) +#include +#endif /* defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) */ + +#ifdef HAVE_LIBGEN_H #include +#endif #include "xmalloc.h" #include "match.h" @@ -45,6 +54,7 @@ /* import */ extern ServerOptions options; +extern Buffer loginmsg; /* Debugging messages */ Buffer auth_debug; @@ -63,14 +73,87 @@ allowed_user(struct passwd * pw) { struct stat st; - const char *hostname = NULL, *ipaddr = NULL; + const char *hostname = NULL, *ipaddr = NULL, *passwd = NULL; char *shell; int i; +#if defined(HAVE_SHADOW_H) && !defined(DISABLE_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; +#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) + if (!options.use_pam) + spw = getspnam(pw->pw_name); +#ifdef HAS_SHADOW_EXPIRE +#define DAY (24L * 60 * 60) /* 1 day in seconds */ + if (!options.use_pam && spw != NULL) { + time_t today; + + today = time(NULL) / DAY; + debug3("allowed_user: today %d sp_expire %d sp_lstchg %d" + " sp_max %d", (int)today, (int)spw->sp_expire, + (int)spw->sp_lstchg, (int)spw->sp_max); + + /* + * We assume account and password expiration occurs the + * day after the day specified. + */ + if (spw->sp_expire != -1 && today > spw->sp_expire) { + logit("Account %.100s has expired", pw->pw_name); + return 0; + } + + if (spw->sp_lstchg == 0) { + logit("User %.100s password has expired (root forced)", + pw->pw_name); + return 0; + } + + if (spw->sp_max != -1 && + today > spw->sp_lstchg + spw->sp_max) { + logit("User %.100s password has expired (password aged)", + pw->pw_name); + return 0; + } + } +#endif /* HAS_SHADOW_EXPIRE */ +#endif /* defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) */ + + /* grab passwd field for locked account check */ +#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) + if (spw != NULL) + passwd = spw->sp_pwdp; +#else + passwd = pw->pw_passwd; +#endif + + /* check for locked account */ + if (!options.use_pam && passwd && *passwd) { + int locked = 0; + +#ifdef LOCKED_PASSWD_STRING + if (strcmp(passwd, LOCKED_PASSWD_STRING) == 0) + locked = 1; +#endif +#ifdef LOCKED_PASSWD_PREFIX + if (strncmp(passwd, LOCKED_PASSWD_PREFIX, + strlen(LOCKED_PASSWD_PREFIX)) == 0) + locked = 1; +#endif +#ifdef LOCKED_PASSWD_SUBSTR + if (strstr(passwd, LOCKED_PASSWD_SUBSTR)) + locked = 1; +#endif + if (locked) { + logit("User %.100s not allowed because account is locked", + pw->pw_name); + return 0; + } + } + /* * Get the shell from the password data. An empty shell field is * legal, and means /bin/sh. @@ -149,6 +232,33 @@ } ga_free(); } + +#ifdef WITH_AIXAUTHENTICATE + /* + * Don't check loginrestrictions() for root account (use + * PermitRootLogin to control logins via ssh), or if running as + * non-root user (since loginrestrictions will always fail). + */ + if ((pw->pw_uid != 0) && (geteuid() == 0)) { + char *msg; + + if (loginrestrictions(pw->pw_name, S_RLOGIN, NULL, &msg) != 0) { + int loginrestrict_errno = errno; + + if (msg && *msg) { + buffer_append(&loginmsg, msg, strlen(msg)); + aix_remove_embedded_newlines(msg); + logit("Login restricted for %s: %.100s", + pw->pw_name, msg); + } + /* Don't fail if /etc/nologin set */ + if (!(loginrestrict_errno == EPERM && + stat(_PATH_NOLOGIN, &st) == 0)) + return 0; + } + } +#endif /* WITH_AIXAUTHENTICATE */ + /* We found no reason not to let this user try to log on... */ return 1; } @@ -187,6 +297,11 @@ get_remote_ipaddr(), get_remote_port(), info); + +#ifdef CUSTOM_FAILED_LOGIN + if (authenticated == 0 && strcmp(method, "password") == 0) + record_failed_login(authctxt->user, "ssh"); +#endif } /* @@ -408,6 +523,9 @@ if (pw == NULL) { logit("Illegal user %.100s from %.100s", user, get_remote_ipaddr()); +#ifdef CUSTOM_FAILED_LOGIN + record_failed_login(user, "ssh"); +#endif return (NULL); } if (!allowed_user(pw)) @@ -484,7 +602,9 @@ fake.pw_gecos = "NOUSER"; fake.pw_uid = -1; fake.pw_gid = -1; +#ifdef HAVE_PW_CLASS_IN_PASSWD fake.pw_class = ""; +#endif fake.pw_dir = "/nonexist"; fake.pw_shell = "/nonexist"; diff -ruN --exclude CVS ssh-openbsd-2003091600/auth-chall.c openssh-3.7p1/auth-chall.c --- ssh-openbsd-2003091600/auth-chall.c 2003-03-26 16:04:01.000000000 +1100 +++ openssh-3.7p1/auth-chall.c 2003-05-10 19:28:02.000000000 +1000 @@ -76,7 +76,33 @@ return 0; resp[0] = (char *)response; res = device->respond(authctxt->kbdintctxt, 1, resp); + if (res == 1) { + /* postponed - send a null query just in case */ + char *name, *info, **prompts; + u_int i, numprompts, *echo_on; + + res = device->query(authctxt->kbdintctxt, &name, &info, + &numprompts, &prompts, &echo_on); + if (res == 0) { + for (i = 0; i < numprompts; i++) + xfree(prompts[i]); + xfree(prompts); + xfree(name); + xfree(echo_on); + xfree(info); + } + /* if we received more prompts, we're screwed */ + res = (numprompts != 0); + } device->free_ctx(authctxt->kbdintctxt); authctxt->kbdintctxt = NULL; return res ? 0 : 1; } +void +abandon_challenge_response(Authctxt *authctxt) +{ + if (authctxt->kbdintctxt != NULL) { + device->free_ctx(authctxt->kbdintctxt); + authctxt->kbdintctxt = NULL; + } +} diff -ruN --exclude CVS ssh-openbsd-2003091600/authfile.c openssh-3.7p1/authfile.c --- ssh-openbsd-2003091600/authfile.c 2003-05-25 14:26:29.000000000 +1000 +++ openssh-3.7p1/authfile.c 2003-05-25 14:38:33.000000000 +1000 @@ -506,6 +506,9 @@ * 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! @"); diff -ruN --exclude CVS ssh-openbsd-2003091600/auth.h openssh-3.7p1/auth.h --- ssh-openbsd-2003091600/auth.h 2003-09-03 12:07:14.000000000 +1000 +++ openssh-3.7p1/auth.h 2003-09-03 12:11:30.000000000 +1000 @@ -121,6 +121,8 @@ void krb5_cleanup_proc(void *authctxt); #endif /* KRB5 */ +#include "auth-pam.h" + Authctxt *do_authentication(void); Authctxt *do_authentication2(void); @@ -145,6 +147,7 @@ char *get_challenge(Authctxt *); int verify_response(Authctxt *, const char *); +void abandon_challenge_response(Authctxt *); struct passwd * auth_get_user(void); diff -ruN --exclude CVS ssh-openbsd-2003091600/auth-krb5.c openssh-3.7p1/auth-krb5.c --- ssh-openbsd-2003091600/auth-krb5.c 2003-09-03 12:07:14.000000000 +1000 +++ openssh-3.7p1/auth-krb5.c 2003-09-02 22:51:17.000000000 +1000 @@ -40,6 +40,7 @@ #include "auth.h" #ifdef KRB5 + #include extern ServerOptions options; @@ -67,6 +68,12 @@ int auth_krb5_password(Authctxt *authctxt, const char *password) { +#ifndef HEIMDAL + krb5_creds creds; + krb5_principal server; + char ccname[40]; + int tmpfd; +#endif krb5_error_code problem; krb5_ccache ccache = NULL; @@ -84,26 +91,26 @@ 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, + 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, + problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_fcc_ops, &authctxt->krb5_fwd_ccache); if (problem) goto out; @@ -115,8 +122,63 @@ if (problem) goto out; - authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, - authctxt->krb5_fwd_ccache); +#else + problem = krb5_get_init_creds_password(authctxt->krb5_ctx, &creds, + authctxt->krb5_user, (char *)password, NULL, NULL, 0, NULL, NULL); + if (problem) + goto out; + + problem = krb5_sname_to_principal(authctxt->krb5_ctx, NULL, NULL, + KRB5_NT_SRV_HST, &server); + if (problem) + goto out; + + restore_uid(); + problem = krb5_verify_init_creds(authctxt->krb5_ctx, &creds, server, + NULL, NULL, NULL); + krb5_free_principal(authctxt->krb5_ctx, server); + temporarily_use_uid(authctxt->pw); + if (problem) + goto out; + + if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user, + authctxt->pw->pw_name)) { + problem = -1; + goto out; + } + + snprintf(ccname,sizeof(ccname),"FILE:/tmp/krb5cc_%d_XXXXXX",geteuid()); + + if ((tmpfd = mkstemp(ccname+strlen("FILE:")))==-1) { + logit("mkstemp(): %.100s", strerror(errno)); + problem = errno; + goto out; + } + + if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) { + logit("fchmod(): %.100s", strerror(errno)); + close(tmpfd); + problem = errno; + goto out; + } + close(tmpfd); + + problem = krb5_cc_resolve(authctxt->krb5_ctx, ccname, &authctxt->krb5_fwd_ccache); + if (problem) + goto out; + + problem = krb5_cc_initialize(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache, + authctxt->krb5_user); + if (problem) + goto out; + + problem= krb5_cc_store_cred(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache, + &creds); + if (problem) + goto out; +#endif + + authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache); out: restore_uid(); @@ -125,7 +187,7 @@ if (ccache) krb5_cc_destroy(authctxt->krb5_ctx, ccache); - if (authctxt->krb5_ctx != NULL) + if (authctxt->krb5_ctx != NULL && problem!=-1) debug("Kerberos password authentication failed: %s", krb5_get_err_text(authctxt->krb5_ctx, problem)); else diff -ruN --exclude CVS ssh-openbsd-2003091600/auth-pam.c openssh-3.7p1/auth-pam.c --- ssh-openbsd-2003091600/auth-pam.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/auth-pam.c 2003-09-16 16:00:52.000000000 +1000 @@ -0,0 +1,721 @@ +/*- + * 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. + */ + +/* Based on $FreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des Exp $ */ +#include "includes.h" +RCSID("$Id: auth-pam.c,v 1.72.2.1 2003/09/16 06:00:52 djm Exp $"); + +#ifdef USE_PAM +#include + +#include "auth.h" +#include "auth-pam.h" +#include "buffer.h" +#include "bufaux.h" +#include "canohost.h" +#include "log.h" +#include "monitor_wrap.h" +#include "msg.h" +#include "packet.h" +#include "readpass.h" +#include "servconf.h" +#include "ssh2.h" +#include "xmalloc.h" +#include "auth-options.h" + +extern ServerOptions options; + +#define __unused + +#ifdef USE_POSIX_THREADS +#include +/* + * Avoid namespace clash when *not* using pthreads for systems *with* + * pthreads, which unconditionally define pthread_t via sys/types.h + * (e.g. Linux) + */ +typedef pthread_t sp_pthread_t; +#else +/* + * Simulate threads with processes. + */ +typedef pid_t sp_pthread_t; + +static void +pthread_exit(void *value __unused) +{ + _exit(0); +} + +static int +pthread_create(sp_pthread_t *thread, const void *attr __unused, + void *(*thread_start)(void *), void *arg) +{ + pid_t pid; + + switch ((pid = fork())) { + case -1: + error("fork(): %s", strerror(errno)); + return (-1); + case 0: + thread_start(arg); + _exit(1); + default: + *thread = pid; + return (0); + } +} + +static int +pthread_cancel(sp_pthread_t thread) +{ + return (kill(thread, SIGTERM)); +} + +static int +pthread_join(sp_pthread_t thread, void **value __unused) +{ + int status; + + waitpid(thread, &status, 0); + return (status); +} +#endif + + +static pam_handle_t *sshpam_handle; +static int sshpam_err; +static int sshpam_authenticated; +static int sshpam_new_authtok_reqd; +static int sshpam_session_open; +static int sshpam_cred_established; + +struct pam_ctxt { + sp_pthread_t pam_thread; + int pam_psock; + int pam_csock; + int pam_done; +}; + +static void sshpam_free_ctx(void *); + +/* + * Conversation function for authentication thread. + */ +static int +sshpam_thread_conv(int n, const struct pam_message **msg, + struct pam_response **resp, void *data) +{ + Buffer buffer; + struct pam_ctxt *ctxt; + int i; + + ctxt = data; + if (n <= 0 || n > PAM_MAX_NUM_MSG) + return (PAM_CONV_ERR); + *resp = xmalloc(n * sizeof **resp); + buffer_init(&buffer); + for (i = 0; i < n; ++i) { + resp[i]->resp_retcode = 0; + resp[i]->resp = NULL; + switch (PAM_MSG_MEMBER(msg, i, msg_style)) { + case PAM_PROMPT_ECHO_OFF: + buffer_put_cstring(&buffer, PAM_MSG_MEMBER(msg, i, msg)); + ssh_msg_send(ctxt->pam_csock, + PAM_MSG_MEMBER(msg, i, msg_style), &buffer); + ssh_msg_recv(ctxt->pam_csock, &buffer); + if (buffer_get_char(&buffer) != PAM_AUTHTOK) + goto fail; + resp[i]->resp = buffer_get_string(&buffer, NULL); + break; + case PAM_PROMPT_ECHO_ON: + buffer_put_cstring(&buffer, PAM_MSG_MEMBER(msg, i, msg)); + ssh_msg_send(ctxt->pam_csock, + PAM_MSG_MEMBER(msg, i, msg_style), &buffer); + ssh_msg_recv(ctxt->pam_csock, &buffer); + if (buffer_get_char(&buffer) != PAM_AUTHTOK) + goto fail; + resp[i]->resp = buffer_get_string(&buffer, NULL); + break; + case PAM_ERROR_MSG: + buffer_put_cstring(&buffer, PAM_MSG_MEMBER(msg, i, msg)); + ssh_msg_send(ctxt->pam_csock, + PAM_MSG_MEMBER(msg, i, msg_style), &buffer); + break; + case PAM_TEXT_INFO: + buffer_put_cstring(&buffer, PAM_MSG_MEMBER(msg, i, msg)); + ssh_msg_send(ctxt->pam_csock, + PAM_MSG_MEMBER(msg, i, msg_style), &buffer); + break; + default: + goto fail; + } + buffer_clear(&buffer); + } + buffer_free(&buffer); + return (PAM_SUCCESS); + fail: + while (i) + xfree(resp[--i]); + xfree(*resp); + *resp = NULL; + 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; +#ifndef USE_POSIX_THREADS + const char *pam_user; + + pam_get_item(sshpam_handle, PAM_USER, (const void **)&pam_user); + setproctitle("%s [pam]", pam_user); +#endif + + sshpam_conv.conv = sshpam_thread_conv; + sshpam_conv.appdata_ptr = ctxt; + + 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, 0); + if (sshpam_err != PAM_SUCCESS) + goto auth_fail; + buffer_put_cstring(&buffer, "OK"); + 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)); + ssh_msg_send(ctxt->pam_csock, PAM_AUTH_ERR, &buffer); + buffer_free(&buffer); + pthread_exit(NULL); + + return (NULL); /* Avoid warning for non-pthread case */ +} + +static void +sshpam_thread_cleanup(void *ctxtp) +{ + struct pam_ctxt *ctxt = ctxtp; + + pthread_cancel(ctxt->pam_thread); + pthread_join(ctxt->pam_thread, NULL); + close(ctxt->pam_psock); + close(ctxt->pam_csock); +} + +static int +sshpam_null_conv(int n, const struct pam_message **msg, + struct pam_response **resp, void *data) +{ + return (PAM_CONV_ERR); +} + +static struct pam_conv null_conv = { sshpam_null_conv, NULL }; + +static void +sshpam_cleanup(void *arg) +{ + (void)arg; + debug("PAM: cleanup"); + pam_set_item(sshpam_handle, PAM_CONV, (const void *)&null_conv); + if (sshpam_cred_established) { + pam_setcred(sshpam_handle, PAM_DELETE_CRED); + sshpam_cred_established = 0; + } + if (sshpam_session_open) { + pam_close_session(sshpam_handle, PAM_SILENT); + sshpam_session_open = 0; + } + sshpam_authenticated = sshpam_new_authtok_reqd = 0; + pam_end(sshpam_handle, sshpam_err); + sshpam_handle = NULL; +} + +static int +sshpam_init(const char *user) +{ + extern u_int utmp_len; + extern char *__progname; + const char *pam_rhost, *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, (const void **)&pam_user); + if (sshpam_err == PAM_SUCCESS && strcmp(user, pam_user) == 0) + return (0); + fatal_remove_cleanup(sshpam_cleanup, NULL); + pam_end(sshpam_handle, sshpam_err); + sshpam_handle = NULL; + } + debug("PAM: initializing for \"%s\"", user); + sshpam_err = + pam_start(SSHD_PAM_SERVICE, user, &null_conv, &sshpam_handle); + 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 + fatal_add_cleanup(sshpam_cleanup, NULL); + return (0); +} + +static void * +sshpam_init_ctx(Authctxt *authctxt) +{ + struct pam_ctxt *ctxt; + int socks[2]; + + /* Refuse to start if we don't have PAM enabled */ + if (!options.use_pam) + return NULL; + + /* Initialize PAM */ + if (sshpam_init(authctxt->user) == -1) { + error("PAM: initialization failed"); + return (NULL); + } + + ctxt = xmalloc(sizeof *ctxt); + ctxt->pam_done = 0; + + /* 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); + } + fatal_add_cleanup(sshpam_thread_cleanup, 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; + + 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); + switch (type) { + case PAM_PROMPT_ECHO_ON: + case PAM_PROMPT_ECHO_OFF: + *num = 1; + len = plen + strlen(msg) + 1; + **prompts = xrealloc(**prompts, len); + plen += snprintf(**prompts + plen, len, "%s", msg); + **echo_on = (type == PAM_PROMPT_ECHO_ON); + xfree(msg); + return (0); + case PAM_ERROR_MSG: + case PAM_TEXT_INFO: + /* accumulate messages */ + len = plen + strlen(msg) + 1; + **prompts = xrealloc(**prompts, len); + plen += snprintf(**prompts + plen, len, "%s", msg); + xfree(msg); + break; + case PAM_SUCCESS: + case PAM_AUTH_ERR: + if (**prompts != NULL) { + /* drain any accumulated messages */ +#if 0 /* XXX - not compatible with privsep */ + packet_start(SSH2_MSG_USERAUTH_BANNER); + packet_put_cstring(**prompts); + packet_put_cstring(""); + packet_send(); + packet_write_wait(); +#endif + xfree(**prompts); + **prompts = NULL; + } + if (type == PAM_SUCCESS) { + *num = 0; + **echo_on = 0; + ctxt->pam_done = 1; + xfree(msg); + return (0); + } + error("PAM: %s", msg); + 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", __func__); + 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); + buffer_put_cstring(&buffer, *resp); + ssh_msg_send(ctxt->pam_psock, PAM_AUTHTOK, &buffer); + buffer_free(&buffer); + return (1); +} + +static void +sshpam_free_ctx(void *ctxtp) +{ + struct pam_ctxt *ctxt = ctxtp; + + fatal_remove_cleanup(sshpam_thread_cleanup, ctxt); + sshpam_thread_cleanup(ctxtp); + 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(const char *user) +{ + if (!options.use_pam) + fatal("PAM: initialisation requested when UsePAM=no"); + + if (sshpam_init(user) == -1) + fatal("PAM: initialisation failed"); +} + +void +finish_pam(void) +{ + fatal_remove_cleanup(sshpam_cleanup, NULL); + sshpam_cleanup(NULL); +} + +u_int +do_pam_account(void) +{ + sshpam_err = pam_acct_mgmt(sshpam_handle, 0); + debug3("%s: pam_acct_mgmt = %d", __func__, sshpam_err); + + if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) + return (0); + + if (sshpam_err == PAM_NEW_AUTHTOK_REQD) { + sshpam_new_authtok_reqd = 1; + + /* Prevent forwardings until password changed */ + no_port_forwarding_flag |= 2; + no_agent_forwarding_flag |= 2; + no_x11_forwarding_flag |= 2; + } + + return (1); +} + +void +do_pam_session(void) +{ + sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, + (const void *)&null_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) + fatal("PAM: pam_open_session(): %s", + pam_strerror(sshpam_handle, sshpam_err)); + sshpam_session_open = 1; +} + +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 *)&null_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)); +} + +int +is_pam_password_change_required(void) +{ + return (sshpam_new_authtok_reqd); +} + +static int +pam_chauthtok_conv(int n, const struct pam_message **msg, + struct pam_response **resp, void *data) +{ + char input[PAM_MAX_MSG_SIZE]; + int i; + + if (n <= 0 || n > PAM_MAX_NUM_MSG) + return (PAM_CONV_ERR); + *resp = xmalloc(n * sizeof **resp); + for (i = 0; i < n; ++i) { + switch (PAM_MSG_MEMBER(msg, i, msg_style)) { + case PAM_PROMPT_ECHO_OFF: + resp[i]->resp = + read_passphrase(PAM_MSG_MEMBER(msg, i, msg), + RP_ALLOW_STDIN); + resp[i]->resp_retcode = PAM_SUCCESS; + break; + case PAM_PROMPT_ECHO_ON: + fputs(PAM_MSG_MEMBER(msg, i, msg), stderr); + fgets(input, sizeof input, stdin); + resp[i]->resp = xstrdup(input); + resp[i]->resp_retcode = PAM_SUCCESS; + break; + case PAM_ERROR_MSG: + case PAM_TEXT_INFO: + fputs(PAM_MSG_MEMBER(msg, i, msg), stderr); + resp[i]->resp_retcode = PAM_SUCCESS; + break; + default: + goto fail; + } + } + return (PAM_SUCCESS); + fail: + while (i) + xfree(resp[--i]); + xfree(*resp); + *resp = NULL; + return (PAM_CONV_ERR); +} + +/* + * XXX this should be done in the authentication phase, but ssh1 doesn't + * support that + */ +void +do_pam_chauthtok(void) +{ + struct pam_conv pam_conv; + + pam_conv.conv = pam_chauthtok_conv; + pam_conv.appdata_ptr = NULL; + + if (use_privsep) + fatal("Password expired (unable to change with privsep)"); + sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, + (const void *)&pam_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)); +} + +/* + * 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); +} + +void +print_pam_messages(void) +{ + /* XXX */ +} + +char ** +fetch_pam_environment(void) +{ +#ifdef HAVE_PAM_GETENVLIST + debug("PAM: retrieving environment"); + return (pam_getenvlist(sshpam_handle)); +#else + return (NULL); +#endif +} + +void +free_pam_environment(char **env) +{ + char **envp; + + if (env == NULL) + return; + + for (envp = env; *envp; envp++) + xfree(*envp); + xfree(env); +} + +#endif /* USE_PAM */ diff -ruN --exclude CVS ssh-openbsd-2003091600/auth-pam.h openssh-3.7p1/auth-pam.h --- ssh-openbsd-2003091600/auth-pam.h 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/auth-pam.h 2003-09-02 23:18:53.000000000 +1000 @@ -0,0 +1,47 @@ +/* $Id: auth-pam.h,v 1.21 2003/09/02 13:18:53 djm 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(const char *); +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 ); +int is_pam_password_change_required(void); +void do_pam_chauthtok(void); +int do_pam_putenv(char *, char *); +void print_pam_messages(void); +char ** fetch_pam_environment(void); +void free_pam_environment(char **); + +#endif /* USE_PAM */ diff -ruN --exclude CVS ssh-openbsd-2003091600/auth-passwd.c openssh-3.7p1/auth-passwd.c --- ssh-openbsd-2003091600/auth-passwd.c 2003-09-03 12:07:14.000000000 +1000 +++ openssh-3.7p1/auth-passwd.c 2003-09-13 10:41:56.000000000 +1000 @@ -42,7 +42,11 @@ #include "log.h" #include "servconf.h" #include "auth.h" - +#ifdef WITH_AIXAUTHENTICATE +# include "buffer.h" +# include "canohost.h" +extern Buffer loginmsg; +#endif extern ServerOptions options; @@ -59,38 +63,101 @@ /* deny if no user. */ if (pw == NULL) return 0; - if (pw->pw_uid == 0 && options.permit_root_login != PERMIT_YES) +#ifndef HAVE_CYGWIN + if (pw && 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 defined(HAVE_OSF_SIA) + return auth_sia_password(authctxt, password) && ok; +#else +# 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 BSD_AUTH +# endif +# ifdef HAVE_CYGWIN + if (is_winnt) { + HANDLE hToken = cygwin_logon_user(pw, password); + + if (hToken == INVALID_HANDLE_VALUE) + return 0; + cygwin_set_impersonation_token(hToken); + return ok; + } +# endif +# ifdef WITH_AIXAUTHENTICATE + { + char *authmsg = NULL; + int reenter = 1; + int authsuccess = 0; + + if (authenticate(pw->pw_name, password, &reenter, + &authmsg) == 0 && ok) { + char *msg; + char *host = + (char *)get_canonical_hostname(options.use_dns); + + authsuccess = 1; + aix_remove_embedded_newlines(authmsg); + + debug3("AIX/authenticate succeeded for user %s: %.100s", + pw->pw_name, authmsg); + + /* No pty yet, so just label the line as "ssh" */ + aix_setauthdb(authctxt->user); + if (loginsuccess(authctxt->user, host, "ssh", + &msg) == 0) { + if (msg != NULL) { + debug("%s: msg %s", __func__, msg); + buffer_append(&loginmsg, msg, + strlen(msg)); + xfree(msg); + } + } + } else { + debug3("AIX/authenticate failed for user %s: %.100s", + pw->pw_name, authmsg); + } + + if (authmsg != NULL) + xfree(authmsg); + + return authsuccess; + } +# endif +# ifdef BSD_AUTH if (auth_userokay(pw->pw_name, authctxt->style, "auth-ssh", (char *)password) == 0) return 0; else return ok; -#else +# else + { + /* 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(password, "") == 0 && strcmp(pw->pw_passwd, "") == 0) + if (strcmp(pw_password, "") == 0 && strcmp(pw->pw_passwd, "") == 0) return ok; else { /* Encrypt the candidate password using the proper salt. */ - char *encrypted_password = crypt(password, - (pw->pw_passwd[0] && pw->pw_passwd[1]) ? - pw->pw_passwd : "xx"); + char *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->pw_passwd) == 0) && ok; + return (strcmp(encrypted_password, pw_password) == 0) && ok; } -#endif + + } +# endif +#endif /* !HAVE_OSF_SIA */ } diff -ruN --exclude CVS ssh-openbsd-2003091600/auth-sia.c openssh-3.7p1/auth-sia.c --- ssh-openbsd-2003091600/auth-sia.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/auth-sia.c 2003-06-03 10:25:48.000000000 +1000 @@ -0,0 +1,110 @@ +/* + * 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 "ssh.h" +#include "auth.h" +#include "auth-sia.h" +#include "log.h" +#include "servconf.h" +#include "canohost.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +extern ServerOptions options; +extern int saved_argc; +extern char **saved_argv; + +int +auth_sia_password(Authctxt *authctxt, 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); + + if (setreuid(geteuid(), geteuid()) < 0) + fatal("setreuid: %s", strerror(errno)); +} + +#endif /* HAVE_OSF_SIA */ diff -ruN --exclude CVS ssh-openbsd-2003091600/auth-sia.h openssh-3.7p1/auth-sia.h --- ssh-openbsd-2003091600/auth-sia.h 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/auth-sia.h 2003-05-19 00:50:02.000000000 +1000 @@ -0,0 +1,32 @@ +/* + * 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 + +int auth_sia_password(Authctxt *, char *); +void session_setup_sia(struct passwd *, char *); + +#endif /* HAVE_OSF_SIA */ diff -ruN --exclude CVS ssh-openbsd-2003091600/canohost.c openssh-3.7p1/canohost.c --- ssh-openbsd-2003091600/canohost.c 2003-06-03 10:18:47.000000000 +1000 +++ openssh-3.7p1/canohost.c 2003-08-07 13:29:04.000000000 +1000 @@ -42,6 +42,31 @@ debug("getpeername failed: %.100s", strerror(errno)); fatal_cleanup(); } +#ifdef IPV4_IN_IPV6 + if (from.ss_family == AF_INET6) { + struct sockaddr_in6 *from6 = (struct sockaddr_in6 *)&from; + + /* Detect IPv4 in IPv6 mapped address and convert it to */ + /* plain (AF_INET) IPv4 address */ + if (IN6_IS_ADDR_V4MAPPED(&from6->sin6_addr)) { + struct sockaddr_in *from4 = (struct sockaddr_in *)&from; + struct in_addr addr; + u_int16_t port; + + memcpy(&addr, ((char *)&from6->sin6_addr) + 12, sizeof(addr)); + port = from6->sin6_port; + + memset(&from, 0, sizeof(from)); + + from4->sin_family = AF_INET; + fromlen = sizeof(*from4); + memcpy(&from4->sin_addr, &addr, sizeof(addr)); + from4->sin_port = port; + } + } +#endif + 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) @@ -134,6 +159,7 @@ static void check_ip_options(int socket, char *ipaddr) { +#ifdef IP_OPTIONS u_char options[200]; char text[sizeof(options) * 3 + 1]; socklen_t option_size; @@ -156,6 +182,7 @@ packet_disconnect("Connection from %.100s with IP options:%.800s", ipaddr, text); } +#endif /* IP_OPTIONS */ } /* @@ -213,6 +240,11 @@ < 0) return NULL; } + + /* Work around Linux IPv6 weirdness */ + if (addr.ss_family == AF_INET6) + addrlen = sizeof(struct sockaddr_in6); + /* Get the address in ascii. */ if (getnameinfo((struct sockaddr *)&addr, addrlen, ntop, sizeof(ntop), NULL, 0, flags) != 0) { @@ -307,6 +339,11 @@ fatal_cleanup(); } } + + /* Work around Linux IPv6 weirdness */ + if (from.ss_family == AF_INET6) + fromlen = sizeof(struct sockaddr_in6); + /* Return port number. */ if (getnameinfo((struct sockaddr *)&from, fromlen, NULL, 0, strport, sizeof(strport), NI_NUMERICSERV) != 0) diff -ruN --exclude CVS ssh-openbsd-2003091600/ChangeLog openssh-3.7p1/ChangeLog --- ssh-openbsd-2003091600/ChangeLog 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/ChangeLog 2003-09-16 16:00:52.000000000 +1000 @@ -0,0 +1,1110 @@ +20030916 + - (dtucker) [acconfig.h configure.ac defines.h session.c] Bug #252: Retrieve + PATH (or SUPATH) and UMASK from /etc/default/login on platforms that have it + (eg Solaris, Reliant Unix). Patch from Robert.Dahlem at siemens.com. + ok djm@ + - (bal) OpenBSD Sync + - deraadt@cvs.openbsd.org 2003/09/16 03:03:47 + [buffer.c] + do not expand buffer before attempting to reallocate it; markus ok + - (djm) Crank spec versions + - (djm) Banish (safe) sprintf from auth-pam.c. Patch from bal + - (tim) [configure.ac] Fix portability issues. + - (djm) Release 3.7p1 + +20030914 + - (dtucker) [Makefile regress/Makefile] Fix portability issues preventing + the regression tests from running with Solaris' make. Patch from Brian + Poole (raj at cerias.purdue.edu). + - (dtucker) [regress/Makefile] AIX's make doesn't like " +=", so replace + with vanilla "=". + +20030913 + - (dtucker) [regress/agent-timeout.sh] Timeout of 5 sec is borderline for + slower hosts, increase to 10 sec. + - (dtucker) [auth-passwd.c] On AIX, call setauthdb() before loginsuccess(), + required to correctly reset failed login count when using a password + registry other than "files" (eg LDAP, see bug #543). + - (tim) [configure.ac] define WITH_ABBREV_NO_TTY for SCO. + Report by Roger Cornelius. + - (dtucker) [auth-pam.c] Use SSHD_PAM_SERVICE for PAM service name, patch + from cjwatson at debian.org. + +20030912 + - (tim) [regress/agent-ptrace.sh] sh doesn't like "if ! shell_function; then". + - (tim) [Makefile.in] only mkdir regress if it does not exist. + - (tim) [regress/yes-head.sh] shell portability fix. + +20030911 + - (dtucker) [configure.ac] Bug #588, #615: Move other libgen tests to after + the dirname test, to allow a broken dirname to be detected correctly. + Based partially on patch supplied by alex.kiernan at thus.net. ok djm@ + - (tim) [configure.ac] Move libgen tests to before libwrap to unbreak + UnixWare 2.03 using --with-tcp-wrappers. + - (tim) [configure.ac] Prefer setuid/setgid on UnixWare and Open Server. + - (tim) [regress/agent-ptrace.sh regress/dynamic-forward.sh + regress/sftp-cmds.sh regress/stderr-after-eof.sh regress/test-exec.sh] + no longer depends on which(1). patch by dtucker@ + +20030910 + - (dtucker) [configure.ac] Bug #636: Add support for Cray's new X1 machine. + Patch from wendyp at cray.com. + - (dtucker) [configure.ac] Part of bug #615: tcsendbreak might be a macro. + - (dtucker) [regressh/yes-head.sh] Some platforms (eg Solaris) don't have + "yes". + +20030909 + - (tim) [regress/Makefile] Fixes for building outside of a read-only + source tree. + - (tim) [regress/agent-timeout.sh] s/TIMEOUT/SSHAGENT_TIMEOUT/ Fixes conflict + with shell read-only variable. + - (tim) [regress/sftp-badcmds.sh regress/sftp-cmds.sh] Fix errors like + UX:rm: ERROR: Cannot remove '.' or '..' + +20030908 + - (tim) [configure.ac openbsd-compat/getrrsetbyname.c] wrap _getshort and + _getlong in #ifndef + - (tim) [configure.ac acconfig.h openbsd-compat/getrrsetbyname.c] test for + HEADER.ad in arpa/nameser.h + - (tim) [ssh-keygen.c] s/PATH_MAX/MAXPATHLEN/ ok mouring@ + +20030907 + - (dtucker) [agent-ptrace.sh dynamic-forward.sh (all regress/)] + Put "which" inside quotes. + - (dtucker) [dynamic-forward.sh forwarding.sh sftp-batch.sh (all regress/)] + Add ${EXEEXT}: required to work on Cygwin. + - (dtucker) [regress/sftp-batch.sh] Make temporary batch file name more + distinctive, so "rm ${BATCH}.*" doesn't match the script itself. + - (dtucker) [regress/sftp-cmds.sh] Skip quoted file test on Cygwin. + - (dtucker) [openbsd-compat/xcrypt.c] #elsif -> #elif + - (dtucker) [acconfig.h] Typo. + - (dtucker) [CREDITS Makefile.in configure.ac mdoc2man.awk mdoc2man.pl] + Replace mdoc2man.pl with mdoc2man.awk, provided by Peter Stuge. + +20030906 + - (dtucker) [acconfig.h configure.ac uidswap.c] Prefer setuid/setgid on AIX. + +20030905 + - (dtucker) [Makefile.in] Add distclean target for regress/, fix clean target. + +20030904 + - (dtucker) Portablize regression tests. Parts contributed by Roumen + Petrov, David M. Williams and Corinna Vinschen. + - [Makefile.in] Add "make tests" target and "make clean" hooks. + - [regress/agent-getpeereid.sh] Skip test on platforms that don't support + getpeereid. + - [regress/agent-ptrace.sh] Skip tests if platform doesn't support it or + gdb cannot be found. + - [regress/reconfigure/sh] Make path to sshd fully qualified if required. + - [regress/rekey.sh] Remove dependence on /dev/zero (not all platforms have + it). The sparse file will take less disk space too. + - [regress/sftp-cmds.sh] Ensure files used for test are readable. + - [regress/stderr-after-eof.sh] Search for a usable checksum program. + - [regress/sftp-badcmds.sh regress/sftp-cmds.sh regress/sftp.sh + regress/ssh-com-client.sh regress/ssh-com-sftp.sh regress/stderr-data.sh + regress/transfer.sh] Use ${EXEEXT} where appropriate. + - [regress/sftp.sh regress/ssh-com-sftp.sh] Remove dependency on /dev/stdin. + - [regress/agent-ptrace.sh regress/agent-timeout.sh] + "grep -q" -> "grep >/dev/null" + - [regress/agent.sh regress/proto-version.sh regress/ssh-com.sh + regress/test-exec.sh] Handle different ways of echoing without newlines. + - [regress/dynamic-forward.sh] Some "which" programs output on stderr. + - [regress/sftp-cmds.sh] Use portable "test" option. + - [regress/test-exec.sh] Use sudo, search for "whoami" equivalent, always + use Strictmodes no, wait longer for sshd startup. + - [regress/Makefile] Remove BSDisms. + - [regress/README.regress] Add a basic readme. + - [Makefile.in regress/agent-getpeereid.sh] config.h is now in $BUILDDIR + not $OBJ. + - [Makefile.in regress/agent-ptrace] Fix minor regress issues on Cygwin. + +20030903 + - (djm) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2003/08/26 09:58:43 + [auth-passwd.c auth.c auth.h auth1.c auth2-none.c auth2-passwd.c] + [auth2.c monitor.c] + fix passwd auth for 'username leaks via timing'; with djm@, original + patches from solar + - markus@cvs.openbsd.org 2003/08/28 12:54:34 + [auth.h] + remove kerberos support from ssh1, since it has been replaced with GSSAPI; + but keep kerberos passwd auth for ssh1 and 2; ok djm, hin, henning, ... + - markus@cvs.openbsd.org 2003/09/02 16:40:29 + [version.h] + enter 3.7 + - jmc@cvs.openbsd.org 2003/09/02 18:50:06 + [sftp.1 ssh_config.5] + escape punctuation; + ok deraadt@ + +20030902 + - (djm) OpenBSD CVS Sync + - deraadt@cvs.openbsd.org 2003/08/24 17:36:51 + [auth2-gss.c] + 64 bit cleanups; markus ok + - markus@cvs.openbsd.org 2003/08/28 12:54:34 + [auth-krb5.c auth.h auth1.c monitor.c monitor.h monitor_wrap.c] + [monitor_wrap.h readconf.c servconf.c session.c ssh_config.5] + [sshconnect1.c sshd.c sshd_config sshd_config.5] + remove kerberos support from ssh1, since it has been replaced with GSSAPI; + but keep kerberos passwd auth for ssh1 and 2; ok djm, hin, henning, ... + - markus@cvs.openbsd.org 2003/08/29 10:03:15 + [compat.c compat.h] + SSH_BUG_K5USER is unused; ok henning@ + - markus@cvs.openbsd.org 2003/08/29 10:04:36 + [channels.c nchan.c] + be less chatty; debug -> debug2, cleanup; ok henning@ + - markus@cvs.openbsd.org 2003/08/31 10:26:04 + [progressmeter.c] + pass file_size + 1 to snprintf: fixes printing of truncated + file names; fix based on patch/report from sturm@; + - markus@cvs.openbsd.org 2003/08/31 12:14:22 + [progressmeter.c] + do write to buf[-1] + - markus@cvs.openbsd.org 2003/08/31 13:29:05 + [session.c] + call ssh_gssapi_storecreds conditionally from do_exec(); + with sxw@inf.ed.ac.uk + - markus@cvs.openbsd.org 2003/08/31 13:30:18 + [gss-serv.c] + correct string termination in parse_ename(); sxw@inf.ed.ac.uk + - markus@cvs.openbsd.org 2003/08/31 13:31:57 + [gss-serv.c] + whitspace KNF + - markus@cvs.openbsd.org 2003/09/01 09:50:04 + [sshd_config.5] + gss kex is not supported; sxw@inf.ed.ac.uk + - markus@cvs.openbsd.org 2003/09/01 12:50:46 + [readconf.c] + rm gssapidelegatecreds alias; never supported before + - markus@cvs.openbsd.org 2003/09/01 13:52:18 + [ssh.h] + rm whitespace + - markus@cvs.openbsd.org 2003/09/01 18:15:50 + [readconf.c readconf.h servconf.c servconf.h ssh.c] + remove unused kerberos code; ok henning@ + - markus@cvs.openbsd.org 2003/09/01 20:44:54 + [auth2-gss.c] + fix leak + - (djm) Don't initialise pam_conv structures inline. Avoids HP/UX compiler + error. Part of Bug #423, patch from michael_steffens AT hp.com + - (djm) Bug #423: reorder setting of PAM_TTY and calling of PAM session + management (now done in do_setusercontext). Largely from + michael_steffens AT hp.com + - (djm) Fix openbsd-compat/ again - remove references to strl(cpy|cat).h + +20030829 + - (bal) openbsd-compat/ clean up. Considate headers, add in Id on our + files, and added missing license to header. + +20030826 + - (djm) Bug #629: Mark ssh_config option "pamauthenticationviakbdint" + as deprecated. Remove mention from README.privsep. Patch from + aet AT cc.hut.fi + - (dtucker) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2003/08/22 10:56:09 + [auth2.c auth2-gss.c auth.h compat.c compat.h gss-genr.c gss-serv-krb5.c + gss-serv.c monitor.c monitor.h monitor_wrap.c monitor_wrap.h readconf.c + readconf.h servconf.c servconf.h session.c session.h ssh-gss.h + ssh_config.5 sshconnect2.c sshd_config sshd_config.5] + support GSS API user authentication; patches from Simon Wilkinson, + stripped down and tested by Jakob and myself. + - markus@cvs.openbsd.org 2003/08/22 13:20:03 + [sshconnect2.c] + remove support for "kerberos-2@ssh.com" + - markus@cvs.openbsd.org 2003/08/22 13:22:27 + [auth2.c] (auth2-krb5.c removed) + nuke "kerberos-2@ssh.com" + - markus@cvs.openbsd.org 2003/08/22 20:55:06 + [LICENCE] + add Simon Wilkinson + - deraadt@cvs.openbsd.org 2003/08/24 17:36:52 + [monitor.c monitor_wrap.c sshconnect2.c] + 64 bit cleanups; markus ok + - fgsch@cvs.openbsd.org 2003/08/25 08:13:09 + [sftp-int.c] + fix div by zero when listing for filename lengths longer than width. + markus@ ok. + - djm@cvs.openbsd.org 2003/08/25 10:33:33 + [sshconnect2.c] + fprintf->logit to silence login banner with "ssh -q"; ok markus@ + - (dtucker) [Makefile.in acconfig.h auth-krb5.c auth-pam.c auth-pam.h + configure.ac defines.h gss-serv-krb5.c session.c ssh-gss.h sshconnect1.c + sshconnect2.c] Add Portable GSSAPI support, patch by Simon Wilkinson. + - (dtucker) [Makefile.in] Remove auth2-krb5. + - (dtucker) [contrib/aix/inventory.sh] Add public domain notice. ok mouring@ + (the original author) + - (dtucker) [auth.c] Do not check for locked accounts when PAM is enabled. + +20030825 + - (djm) Bug #621: Select OpenSC keys by usage attributes. Patch from + larsch@trustcenter.de + - (bal) openbsd-compat/ OpenBSD updates. Mostly licensing, ansifications + and minor fixes. OK djm@ + - (bal) redo how we handle 'mysignal()'. Move it to + openbsd-compat/bsd-misc.c, s/mysignal/signal/ and #define signal to + be our 'mysignal' by default. OK djm@ + - (dtucker) [acconfig.h auth.c configure.ac sshd.8] Bug #422 again: deny + any access to locked accounts. ok djm@ + - (djm) Bug #564: Perform PAM account checks for all authentications when + UsePAM=yes; ok dtucker + - (dtucker) [configure.ac] Bug #533, #551: define BROKEN_GETADDRINFO on + Tru64, solves getnameinfo and "bad addr or host" errors. ok djm@ + - (dtucker) [README buildbff.sh inventory.sh] (all in contrib/aix) + Update package builder: correctly handle config variables, use lsuser + rather than /etc/passwd, fix typos, add Id's. + +20030822 + - (djm) s/get_progname/ssh_get_progname/g to avoid conflict with Heimdal + -lbroken; ok dtucker + - (dtucker) [contrib/cygwin/ssh-user-config] Put keys in authorized_keys + rather that authorized_keys2. Patch from vinschen@redhat.com. + +20030821 + - (dtucker) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2003/08/14 16:08:58 + [ssh-keygen.c] + exit after primetest, ok djm@ + - (dtucker) [defines.h] Put CMSG_DATA, CMSG_FIRSTHDR with other CMSG* macros, + change CMSG_DATA to use __CMSG_ALIGN (and thus work properly), reformat for + consistency. + - (dtucker) [configure.ac] Move openpty/ctty test outside of case statement + and after normal openpty test. + +20030813 + - (dtucker) [session.c] Remove #ifdef TIOCSBRK kludge. + - (dtucker) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2003/08/13 08:33:02 + [session.c] + use more portable tcsendbreak(3) and ignore break_length; + ok deraadt, millert + - markus@cvs.openbsd.org 2003/08/13 08:46:31 + [auth1.c readconf.c readconf.h servconf.c servconf.h ssh.c ssh_config + ssh_config.5 sshconnect1.c sshd.8 sshd.c sshd_config sshd_config.5] + remove RhostsAuthentication; suggested by djm@ before; ok djm@, deraadt@, + fgsch@, miod@, henning@, jakob@ and others + - markus@cvs.openbsd.org 2003/08/13 09:07:10 + [readconf.c ssh.c] + socks4->socks, since with support both 4 and 5; dtucker@zip.com.au + - (dtucker) [configure.ac openbsd-compat/bsd-misc.c openbsd-compat/bsd-misc.h] + Add a tcsendbreak function for platforms that don't have one, based on the + one from OpenBSD. + +20030811 + - (dtucker) OpenBSD CVS Sync + (thanks to Simon Wilkinson for help with this -dt) + - markus@cvs.openbsd.org 2003/07/16 15:02:06 + [auth-krb5.c] + mcc -> fcc; from Love Hörnquist Åstrand + otherwise the kerberos credentinal is stored in a memory cache + in the privileged sshd. ok jabob@, hin@ (some time ago) + - (dtucker) [openbsd-compat/xcrypt.c] Remove Cygwin #ifdef block (duplicate + in bsd-cygwin_util.h). + +20030808 + - (dtucker) [openbsd-compat/fake-rfc2553.h] Older Linuxes have AI_PASSIVE and + AI_CANONNAME in netdb.h but not AI_NUMERICHOST, so check each definition + separately before defining them. + - (dtucker) [auth-pam.c] Don't set PAM_TTY if tty is null. ok djm@ + +20030807 + - (dtucker) [session.c] Have session_break_req not attempt to send a break + if TIOCSBRK and TIOCCBRK are not defined (eg Cygwin). + - (dtucker) [canohost.c] Bug #336: Only check ip options if IP_OPTIONS is + defined (fixes compile error on really old Linuxes). + - (dtucker) [defines.h] Bug #336: Add CMSG_DATA and CMSG_FIRSTHDR macros if + not already defined (eg Linux with some versions of libc5), based on those + from OpenBSD. + - (dtucker) [openbsd-compat/bsd-cygwin_util.c openbsd-compat/bsd-cygwin_util.h] + Remove incorrect filenames from comments (file names are in Id tags). + - (dtucker) [session.c openbsd-compat/bsd-cygwin_util.h] Move Cygwin + specific defines and includes to bsd-cygwin_util.h. Fixes build error too. + +20030802 + - (dtucker) [monitor.h monitor_wrap.h] Remove excess ident tags. + - (dtucker) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2003/07/22 13:35:22 + [auth1.c auth.h auth-passwd.c monitor.c monitor.h monitor_wrap.c + monitor_wrap.h readconf.c readconf.h servconf.c servconf.h session.c ssh.1 + ssh.c ssh_config.5 sshconnect1.c sshd.c sshd_config.5 ssh.h] + remove (already disabled) KRB4/AFS support, re-enable -k in ssh(1); + test+ok henning@ + - (dtucker) [Makefile.in acconfig.h configure.ac] Remove KRB4/AFS support. + - (dtucker) [auth-krb4.c radix.c radix.h] Remove KRB4/AFS specific files. + - (dtucker) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2003/07/23 07:42:43 + [sshd_config] + remove AFS; itojun@ + - djm@cvs.openbsd.org 2003/07/28 09:49:56 + [ssh-keygen.1 ssh-keygen.c] + Support for generating Diffie-Hellman groups (/etc/moduli) from ssh-keygen. + Based on code from Phil Karn, William Allen Simpson and Niels Provos. + ok markus@, thanks jmc@ + - markus@cvs.openbsd.org 2003/07/29 18:24:00 + [LICENCE progressmeter.c] + replace 4 clause BSD licensed progressmeter code with a replacement + from Nils Nordman and myself; ok deraadt@ + (copied from OpenBSD an re-applied portable changes) + - markus@cvs.openbsd.org 2003/07/29 18:26:46 + [progressmeter.c] + fix length for "- stalled -" (included with previous import) + - markus@cvs.openbsd.org 2003/07/30 07:44:14 + [progressmeter.c] + use only 4 digits in format_size (included with previous import) + - markus@cvs.openbsd.org 2003/07/30 07:53:27 + [progressmeter.c] + whitespace (included with previous import) + - markus@cvs.openbsd.org 2003/07/31 09:21:02 + [auth2-none.c] + check whether passwd auth is allowd, similar to proto 1; rob@pitman.co.za + ok henning + - avsm@cvs.openbsd.org 2003/07/31 15:50:16 + [atomicio.c] + correct comment: atomicio takes vwrite, not write; deraadt@ ok + - markus@cvs.openbsd.org 2003/07/31 22:34:03 + [progressmeter.c] + print rate similar old version; round instead truncate; + (included in previous progressmeter.c commit) + - (dtucker) [openbsd-compat/bsd-misc.c openbsd-compat/bsd-misc.h] + Add a tcgetpgrp function. + - (dtucker) [Makefile.in moduli.c moduli.h] Add new files and to Makefile. + - (dtucker) [openbsd-compat/bsd-misc.c] Fix cut-and-paste bug in tcgetpgrp. + +20030730 + - (djm) [auth-pam.c] Don't use crappy APIs like sprintf. Thanks bal + +20030726 + - (dtucker) [openbsd-compat/xcrypt.c] Fix typo: DISABLED_SHADOW -> + DISABLE_SHADOW. Fixes HP-UX compile error. + +20030724 + - (bal) [auth-passwd.c openbsd-compat/Makefile.in openbsd-compat/xcrypt.c + openbsd-compat/xcrypt.h] Split off encryption into xcrypt() interface, + and isolate shadow password functions. Tested in Solaris, but should + not break other platforms too badly (except maybe HP =). Also brings + auth-passwd.c into full sync with OpenBSD tree. + +20030723 + - (dtucker) [configure.ac] Back out change for bug #620. + +20030719 + - (dtucker) [configure.ac] Bug #620: Define BROKEN_GETADDRINFO for + Solaris/x86. Patch from jrhett at isite.net. + - (dtucker) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2003/07/14 12:36:37 + [sshd.c] + remove undocumented -V option. would be only useful if openssh is used + as ssh v1 server for ssh.com's ssh v2. + - markus@cvs.openbsd.org 2003/07/16 10:34:53 + [ssh.c sshd.c] + don't exit on multiple -v or -d; ok deraadt@ + - markus@cvs.openbsd.org 2003/07/16 10:36:28 + [sshtty.c] + clear IUCLC in enter_raw_mode; from rob@pitman.co.za; ok deraadt@, fgs@ + - deraadt@cvs.openbsd.org 2003/07/18 01:54:25 + [scp.c] + userid is unsigned, but well, force it anyways; andrushock@korovino.net + - djm@cvs.openbsd.org 2003/07/19 00:45:53 + [sftp-int.c] + fix sftp filename parsing for arguments with escaped quotes. bz #517; + ok markus + - djm@cvs.openbsd.org 2003/07/19 00:46:31 + [regress/sftp-cmds.sh] + regress test for sftp arguments with escaped quotes; ok markus + +20030714 + - (dtucker) [acconfig.h configure.ac port-aix.c] Older AIXes don't declare + loginfailed at all, so assume 3-arg loginfailed if not declared. + - (dtucker) [port-aix.h] Work around name collision on AIX for r_type by + undef'ing it. + - (dtucker) Bug #543: [configure.ac port-aix.c port-aix.h] + Call setauthdb() before loginfailed(), which may load password registry- + specific functions. Based on patch by cawlfiel at us.ibm.com. + - (dtucker) [port-aix.h] Fix prototypes. + - (dtucker) OpenBSD CVS Sync + - avsm@cvs.openbsd.org 2003/07/09 13:58:19 + [key.c] + minor tweak: when generating the hex fingerprint, give strlcat the full + bound to the buffer, and add a comment below explaining why the + zero-termination is one less than the bound. markus@ ok + - markus@cvs.openbsd.org 2003/07/10 14:42:28 + [packet.c] + the 2^(blocksize*2) rekeying limit is too expensive for 3DES, + blowfish, etc, so enforce a 1GB limit for small blocksizes. + - markus@cvs.openbsd.org 2003/07/10 20:05:55 + [sftp.c] + sync usage with manpage, add missing -R + +20030708 + - (dtucker) [acconfig.h auth-passwd.c configure.ac session.c port-aix.[ch]] + Include AIX headers for authentication functions and make calls match + prototypes. Test for and handle 3-arg and 4-arg variants of loginfailed. + - (dtucker) [session.c] Check return value of setpcred(). + - (dtucker) [auth-passwd.c auth.c session.c sshd.c port-aix.c port-aix.h] + Convert aixloginmsg into platform-independant Buffer loginmsg. + +20030707 + - (dtucker) [configure.ac] Bug #600: Check that getrusage is declared before + searching libraries for it. Fixes build errors on NCR MP-RAS. + +20030706 + - (dtucker) [ssh-rand-helper.c loginrec.c] + Apply atomicio typing change to these too. + +20030703 + - (dtucker) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2003/06/28 07:48:10 + [sshd.c] + report pidfile creation errors, based on patch from Roumen Petrov; + ok markus@ + - deraadt@cvs.openbsd.org 2003/06/28 16:23:06 + [atomicio.c atomicio.h authfd.c clientloop.c monitor_wrap.c msg.c + progressmeter.c scp.c sftp-client.c ssh-keyscan.c ssh.h sshconnect.c + sshd.c] + deal with typing of write vs read in atomicio + - markus@cvs.openbsd.org 2003/06/29 12:44:38 + [sshconnect.c] + memset 0, not \0; andrushock@korovino.net + - markus@cvs.openbsd.org 2003/07/02 12:56:34 + [channels.c] + deny dynamic forwarding with -R for v1, too; ok djm@ + - markus@cvs.openbsd.org 2003/07/02 14:51:16 + [channels.c ssh.1 ssh_config.5] + (re)add socks5 suppport to -D; ok djm@ + now ssh(1) can act both as a socks 4 and socks 5 server and + dynamically forward ports. + - markus@cvs.openbsd.org 2003/07/02 20:37:48 + [ssh.c] + convert hostkeyalias to lowercase, otherwise uppercase aliases will + not match at all; ok henning@ + - markus@cvs.openbsd.org 2003/07/03 08:21:46 + [regress/dynamic-forward.sh] + add socks5; speedup; reformat; based on patch from dtucker@zip.com.au + - markus@cvs.openbsd.org 2003/07/03 08:24:13 + [regress/Makefile] + enable tests for dynamic fwd via socks (-D), uses nc(1) + - djm@cvs.openbsd.org 2003/07/03 08:09:06 + [readconf.c readconf.h ssh-keysign.c ssh.c] + fix AddressFamily option in config file, from brent@graveland.net; + ok markus@ + +20030630 + - (djm) Search for support functions necessary to build our + getrrsetbyname() replacement. Patch from Roumen Petrov + +20030629 + - (dtucker) [includes.h] Bug #602: move #include of netdb.h to after in.h + (fixes compiler warnings on Solaris 2.5.1). + - (dtucker) [configure.ac] Add sanity test after system-dependant compiler + flag modifications. + +20030628 + - (djm) Bug #591: use PKCS#15 private key label as a comment in case + of OpenSC. Report and patch from larsch@trustcenter.de + - (djm) Bug #593: Sanity check OpenSC card reader number; patch from + aj@dungeon.inka.de + - (dtucker) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2003/06/23 09:02:44 + [ssh_config.5] + document EnableSSHKeysign; bugzilla #599; ok deraadt@, jmc@ + - markus@cvs.openbsd.org 2003/06/24 08:23:46 + [auth2-hostbased.c auth2-pubkey.c auth2.c channels.c key.c key.h + monitor.c packet.c packet.h serverloop.c sshconnect2.c sshd.c] + int -> u_int; ok djm@, deraadt@, mouring@ + - miod@cvs.openbsd.org 2003/06/25 22:39:36 + [sftp-server.c] + Typo police: attribute is better written with an 'r'. + - markus@cvs.openbsd.org 2003/06/26 20:08:33 + [readconf.c] + do not dump core for 'ssh -o proxycommand host'; ok deraadt@ + - (dtucker) [regress/dynamic-forward.sh] Import new regression test. + - (dtucker) [configure.ac] Bug #570: Have ./configure --enable-FEATURE + actually enable the feature, for those normally disabled. Patch by + openssh (at) roumenpetrov.info. + +20030624 + - (dtucker) Have configure refer the user to config.log and + contrib/findssl.sh for OpenSSL header/library mismatches. + +20030622 + - (dtucker) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2003/06/21 09:14:05 + [regress/reconfigure.sh] + missing $SUDO; from dtucker@zip.com.au + - markus@cvs.openbsd.org 2003/06/18 11:28:11 + [ssh-rsa.c] + backout last change, since it violates pkcs#1 + switch to share/misc/license.template + - djm@cvs.openbsd.org 2003/06/20 05:47:58 + [sshd_config.5] + sync description of protocol 2 cipher proposal; ok markus + - djm@cvs.openbsd.org 2003/06/20 05:48:21 + [sshd_config] + sync some implemented options; ok markus@ + - (dtucker) [regress/authorized_keys_root] Remove temp data file from CVS. + - (dtucker) [openbsd-compat/setproctitle.c] Ensure SPT_TYPE is defined before + testing its value. + +20030618 + - (djm) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2003/06/12 07:57:38 + [monitor.c sshlogin.c sshpty.c] + typos; dtucker at zip.com.au + - djm@cvs.openbsd.org 2003/06/12 12:22:47 + [LICENCE] + mention more copyright holders; ok markus@ + - nino@cvs.openbsd.org 2003/06/12 15:34:09 + [scp.c] + Typo. Ok markus@. + - markus@cvs.openbsd.org 2003/06/12 19:12:03 + [scard.c scard.h ssh-agent.c ssh.c] + add sc_get_key_label; larsch at trustcenter.de; bugzilla#591 + - markus@cvs.openbsd.org 2003/06/16 08:22:35 + [ssh-rsa.c] + make sure the signature has at least the expected length (don't + insist on len == hlen + oidlen, since this breaks some smartcards) + bugzilla #592; ok djm@ + - markus@cvs.openbsd.org 2003/06/16 10:22:45 + [ssh-add.c] + print out key comment on each prompt; make ssh-askpass more useable; ok djm@ + - markus@cvs.openbsd.org 2003/06/17 18:14:23 + [cipher-ctr.c] + use license from /usr/share/misc/license.template for new code + - (dtucker) [reconfigure.sh rekey.sh sftp-badcmds.sh] + Import new regression tests from OpenBSD + - (dtucker) [regress/copy.1 regress/copy.2] Remove temp data files from CVS. + - (dtucker) OpenBSD CVS Sync (regress/) + - markus@cvs.openbsd.org 2003/04/02 12:21:13 + [Makefile] + enable rekey test + - djm@cvs.openbsd.org 2003/04/04 09:34:22 + [Makefile sftp-cmds.sh] + More regression tests, including recent directory rename bug; ok markus@ + - markus@cvs.openbsd.org 2003/05/14 22:08:27 + [ssh-com-client.sh ssh-com-keygen.sh ssh-com-sftp.sh ssh-com.sh] + test against some new commerical versions + - mouring@cvs.openbsd.org 2003/05/15 04:07:12 + [sftp-cmds.sh] + Advanced put/get testing for sftp. OK @djm + - markus@cvs.openbsd.org 2003/06/12 15:40:01 + [try-ciphers.sh] + add ctr + - markus@cvs.openbsd.org 2003/06/12 15:43:32 + [Makefile] + test -HUP; dtucker at zip.com.au + +20030614 + - (djm) Update license on fake-rfc2553.[ch]; ok itojun@ + +20030611 + - (djm) Mention portable copyright holders in LICENSE + - (djm) Put licenses on substantial header files + - (djm) Sync LICENSE against OpenBSD + - (djm) OpenBSD CVS Sync + - jmc@cvs.openbsd.org 2003/06/10 09:12:11 + [scp.1 sftp-server.8 ssh.1 ssh-add.1 ssh-agent.1 ssh_config.5] + [sshd.8 sshd_config.5 ssh-keygen.1 ssh-keyscan.1 ssh-keysign.8] + - section reorder + - COMPATIBILITY merge + - macro cleanup + - kill whitespace at EOL + - new sentence, new line + ssh pages ok markus@ + - deraadt@cvs.openbsd.org 2003/06/10 22:20:52 + [packet.c progressmeter.c] + mostly ansi cleanup; pval ok + - jakob@cvs.openbsd.org 2003/06/11 10:16:16 + [sshconnect.c] + clean up check_host_key() and improve SSHFP feedback. ok markus@ + - jakob@cvs.openbsd.org 2003/06/11 10:18:47 + [dns.c] + sync with check_host_key() change + - djm@cvs.openbsd.org 2003/06/11 11:18:38 + [authfd.c authfd.h ssh-add.c ssh-agent.c] + make agent constraints (lifetime, confirm) work with smartcard keys; + ok markus@ + + +20030609 + - (djm) Sync README.smartcard with OpenBSD -current + - (djm) Re-merge OpenSC info into README.smartcard + +20030606 + - (dtucker) [uidswap.c] Fix setreuid and add missing args to fatal(). ok djm@ + +20030605 + - (djm) Support AI_NUMERICHOST in fake-getaddrinfo.c. Needed for recent + canohost.c changes. + - (djm) Implement paranoid priv dropping checks, based on: + "SetUID demystified" - Hao Chen, David Wagner and Drew Dean + Proceedings of USENIX Security Symposium 2002 + - (djm) Don't use xmalloc() or pull in toplevel headers in fake-* code + - (djm) Merge all the openbsd/fake-* into fake-rfc2553.[ch] + - (djm) Bug #588 - Add scard-opensc.o back to Makefile.in + Patch from larsch@trustcenter.de + - (djm) Bug #589 - scard-opensc: load only keys with a private keys + Patch from larsch@trustcenter.de + - (dtucker) Add includes.h to fake-rfc2553.c so it will build. + - (dtucker) Define EAI_NONAME in fake-rfc2553.h (used by fake-rfc2553.c). + +20030604 + - (djm) Bug #573 - Remove unneeded Krb headers and compat goop. Patch from + simon@sxw.org.uk (Also matches a change in OpenBSD a while ago) + - (djm) Bug #577 - wrong flag in scard-opensc.c sc_private_decrypt. + Patch from larsch@trustcenter.de; ok markus@ + - (djm) Bug #584: scard-opensc.c doesn't work without PIN. Patch from + larsch@trustcenter.de; ok markus@ + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2003/06/04 08:25:18 + [sshconnect.c] + disable challenge/response and keyboard-interactive auth methods + upon hostkey mismatch. based on patch from fcusack AT fcusack.com. + bz #580; ok markus@ + - djm@cvs.openbsd.org 2003/06/04 10:23:48 + [sshd.c] + remove duplicated group-dropping code; ok markus@ + - djm@cvs.openbsd.org 2003/06/04 12:03:59 + [serverloop.c] + remove bitrotten commet; ok markus@ + - djm@cvs.openbsd.org 2003/06/04 12:18:49 + [scp.c] + ansify; ok markus@ + - djm@cvs.openbsd.org 2003/06/04 12:40:39 + [scp.c] + kill ssh process upon receipt of signal, bz #241. + based on patch from esb AT hawaii.edu; ok markus@ + - djm@cvs.openbsd.org 2003/06/04 12:41:22 + [sftp.c] + kill ssh process on receipt of signal; ok markus@ + - (djm) Update to fix of bug #584: lock card before return. + From larsch@trustcenter.de + - (djm) Always use mysignal() for SIGALRM + +20030603 + - (djm) Replace setproctitle replacement with code derived from + UCB sendmail + - (djm) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2003/06/02 09:17:34 + [auth2-hostbased.c auth.c auth-options.c auth-rhosts.c auth-rh-rsa.c] + [canohost.c monitor.c servconf.c servconf.h session.c sshd_config] + [sshd_config.5] + deprecate VerifyReverseMapping since it's dangerous if combined + with IP based access control as noted by Mike Harding; replace with + a UseDNS option, UseDNS is on by default and includes the + VerifyReverseMapping check; with itojun@, provos@, jakob@ and deraadt@ + ok deraadt@, djm@ + - millert@cvs.openbsd.org 2003/06/03 02:56:16 + [scp.c] + Remove the advertising clause in the UCB license which Berkeley + rescinded 22 July 1999. Proofed by myself and Theo. + - (djm) Fix portable-specific uses of verify_reverse_mapping too + - (djm) Sync openbsd-compat with OpenBSD CVS. + - No more 4-term BSD licenses in linked code + - (dtucker) [port-aix.c bsd-cray.c] Fix uses of verify_reverse_mapping. + +20030602 + - (djm) Fix segv from bad reordering in auth-pam.c + - (djm) Always use saved_argv in sshd.c as compat_init_setproctitle may + clobber + - (tim) openbsd-compat/xmmap.[ch] License clarifications. Add missing + CVS ID. + - (djm) Remove "noip6" option from RedHat spec file. This may now be + set at runtime using AddressFamily option. + - (djm) Fix use of macro before #define in cipher-aes.c + - (djm) Sync license on openbsd-compat/bindresvport.c with OpenBSD CVS + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2003/05/26 12:54:40 + [sshconnect.c] + fix format strings; ok markus@ + - deraadt@cvs.openbsd.org 2003/05/29 16:58:45 + [sshd.c uidswap.c] + seteuid and setegid; markus ok + - jakob@cvs.openbsd.org 2003/06/02 08:31:10 + [ssh_config.5] + VerifyHostKeyDNS is v2 only. ok markus@ + +20030530 + - (dtucker) Add missing semicolon in md5crypt.c, patch from openssh at + roumenpetrov.info + - (dtucker) Define SSHD_ACQUIRES_CTTY for NCR MP-RAS and Reliant Unix. + +20030526 + - (djm) Avoid auth2-chall.c warning when compiling without + PAM, BSD_AUTH and SKEY + +20030525 +- (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2003/05/24 09:02:22 + [log.c] + pass logged data through strnvis; ok markus + - djm@cvs.openbsd.org 2003/05/24 09:30:40 + [authfile.c monitor.c sftp-common.c sshpty.c] + cast some types for printing; ok markus@ + +20030524 + - (dtucker) Correct --osfsia in INSTALL. Patch by skeleten at shillest.net + +20030523 + - (djm) Use VIS_SAFE on logged strings rather than default strnvis + encoding (which encodes many more characters) + - OpenBSD CVS Sync + - jmc@cvs.openbsd.org 2003/05/20 12:03:35 + [sftp.1] + - new sentence, new line + - added .Xr's + - typos + ok djm@ + - jmc@cvs.openbsd.org 2003/05/20 12:09:31 + [ssh.1 ssh_config.5 sshd.8 sshd_config.5 ssh-keygen.1] + new sentence, new line + - djm@cvs.openbsd.org 2003/05/23 08:29:30 + [sshconnect.c] + fix leak; ok markus@ + +20030520 + - (djm) OpenBSD CVS Sync + - deraadt@cvs.openbsd.org 2003/05/18 23:22:01 + [log.c] + use syslog_r() in a signal handler called place; markus ok + - (djm) Configure logic to detect syslog_r and friends + +20030519 + - (djm) Sync auth-pam.h with what we actually implement + +20030518 + - (djm) Return of the dreaded PAM_TTY_KLUDGE, which went missing in + recent merge + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2003/05/16 03:27:12 + [readconf.c ssh_config ssh_config.5 ssh-keysign.c] + add AddressFamily option to ssh_config (like -4, -6 on commandline). + Portable bug #534; ok markus@ + - itojun@cvs.openbsd.org 2003/05/17 03:25:58 + [auth-rhosts.c] + just in case, put numbers to sscanf %s arg. + - markus@cvs.openbsd.org 2003/05/17 04:27:52 + [cipher.c cipher-ctr.c myproposal.h] + experimental support for aes-ctr modes from + http://www.ietf.org/internet-drafts/draft-ietf-secsh-newmodes-00.txt + ok djm@ + - (djm) Remove IPv4 by default hack now that we can specify AF in config + - (djm) Tidy and trim TODO + - (djm) Sync openbsd-compat/ with OpenBSD CVS head + - (djm) Big KNF on openbsd-compat/ + - (djm) KNF on md5crypt.[ch] + - (djm) KNF on auth-sia.[ch] + +20030517 + - (bal) strcat -> strlcat on openbsd-compat/realpath.c (rev 1.8 OpenBSD) + +20030516 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2003/05/15 13:52:10 + [ssh.c] + Make "ssh -V" print the OpenSSL version in a human readable form. Patch + from Craig Leres (mindrot at ee.lbl.gov); ok markus@ + - jakob@cvs.openbsd.org 2003/05/15 14:02:47 + [readconf.c servconf.c] + warn for unsupported config option. ok markus@ + - markus@cvs.openbsd.org 2003/05/15 14:09:21 + [auth2-krb5.c] + fix 64bit issue; report itojun@ + - djm@cvs.openbsd.org 2003/05/15 14:55:25 + [readconf.c readconf.h ssh_config ssh_config.5 sshconnect.c] + add a ConnectTimeout option to ssh, based on patch from + Jean-Charles Longuet (jclonguet at free.fr); portable #207 ok markus@ + - (djm) Add warning for UsePAM when built without PAM support + - (djm) A few type mismatch fixes from Bug #565 + - (djm) Guard free_pam_environment against NULL argument. Works around + HP/UX PAM problems debugged by dtucker + +20030515 + - (djm) OpenBSD CVS Sync + - jmc@cvs.openbsd.org 2003/05/14 13:11:56 + [ssh-agent.1] + setup -> set up; + from wiz@netbsd + - jakob@cvs.openbsd.org 2003/05/14 18:16:20 + [key.c key.h readconf.c readconf.h ssh_config.5 sshconnect.c] + [dns.c dns.h README.dns ssh-keygen.1 ssh-keygen.c] + add experimental support for verifying hos keys using DNS as described + in draft-ietf-secsh-dns-xx.txt. more information in README.dns. + ok markus@ and henning@ + - markus@cvs.openbsd.org 2003/05/14 22:24:42 + [clientloop.c session.c ssh.1] + allow to send a BREAK to the remote system; ok various + - markus@cvs.openbsd.org 2003/05/15 00:28:28 + [sshconnect2.c] + cleanup unregister of per-method packet handlers; ok djm@ + - jakob@cvs.openbsd.org 2003/05/15 01:48:10 + [readconf.c readconf.h servconf.c servconf.h] + always parse kerberos options. ok djm@ markus@ + - jakob@cvs.openbsd.org 2003/05/15 02:27:15 + [dns.c] + add missing freerrset + - markus@cvs.openbsd.org 2003/05/15 03:08:29 + [cipher.c cipher-bf1.c cipher-aes.c cipher-3des1.c] + split out custom EVP ciphers + - djm@cvs.openbsd.org 2003/05/15 03:10:52 + [ssh-keygen.c] + avoid warning; ok jakob@ + - mouring@cvs.openbsd.org 2003/05/15 03:39:07 + [sftp-int.c] + Make put/get (globed and nonglobed) code more consistant. OK djm@ + - mouring@cvs.openbsd.org 2003/05/15 03:43:59 + [sftp-int.c sftp.c] + Teach ls how to display multiple column display and allow users + to return to single column format via 'ls -1'. OK @djm + - jakob@cvs.openbsd.org 2003/05/15 04:08:44 + [readconf.c servconf.c] + disable kerberos when not supported. ok markus@ + - markus@cvs.openbsd.org 2003/05/15 04:08:41 + [ssh.1] + ~B is ssh2 only + - (djm) Always parse UsePAM + - (djm) Configure glue for DNS support (code doesn't work in portable yet) + - (djm) Import getrrsetbyname() function from OpenBSD libc (for DNS support) + - (djm) Tidy Makefile clean targets + - (djm) Adapt README.dns for portable + - (djm) Avoid uuencode.c warnings + - (djm) Enable UsePAM when built --with-pam + - (djm) Only build getrrsetbyname replacement when using --with-dns + - (djm) Bug #529: sshd doesn't work correctly after SIGHUP (copy argv + correctly) + - (djm) Bug #444: Wrong paths after reconfigure + - (dtucker) HP-UX needs to include for TIOCSBRK + +20030514 + - (djm) Bug #117: Don't lie to PAM about username + - (djm) RCSID sync w/ OpenBSD + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2003/04/09 12:00:37 + [readconf.c] + strip trailing whitespace from config lines before parsing. + Fixes bz 528; ok markus@ + - markus@cvs.openbsd.org 2003/04/12 10:13:57 + [cipher.c] + hide cipher details; ok djm@ + - markus@cvs.openbsd.org 2003/04/12 10:15:36 + [misc.c] + debug->debug2 + - naddy@cvs.openbsd.org 2003/04/12 11:40:15 + [ssh.1] + document -V switch, fix wording; ok markus@ + - markus@cvs.openbsd.org 2003/04/14 14:17:50 + [channels.c sshconnect.c sshd.c ssh-keyscan.c] + avoid hardcoded SOCK_xx; with itojun@; should allow ssh over SCTP + - mouring@cvs.openbsd.org 2003/04/14 21:31:27 + [sftp-int.c] + Missing globfree(&g) in process_put() spotted by Vince Brimhall + . ok@ Theo + - markus@cvs.openbsd.org 2003/04/16 14:35:27 + [auth.h] + document struct Authctxt; with solar + - deraadt@cvs.openbsd.org 2003/04/26 04:29:49 + [ssh-keyscan.c] + -t in usage(); rogier@quaak.org + - mouring@cvs.openbsd.org 2003/04/30 01:16:20 + [sshd.8 sshd_config.5] + Escape ?, * and ! in .Ql for nroff compatibility. OpenSSH Portable + Bug #550 and * escaping suggested by jmc@. + - david@cvs.openbsd.org 2003/04/30 20:41:07 + [sshd.8] + fix invalid .Pf macro usage introduced in previous commit + ok jmc@ mouring@ + - markus@cvs.openbsd.org 2003/05/11 16:56:48 + [authfile.c ssh-keygen.c] + change key_load_public to try to read a public from: + rsa1 private or rsa1 public and ssh2 keys. + this makes ssh-keygen -e fail for ssh1 keys more gracefully + for example; report from itojun (netbsd pr 20550). + - markus@cvs.openbsd.org 2003/05/11 20:30:25 + [channels.c clientloop.c serverloop.c session.c ssh.c] + make channel_new() strdup the 'remote_name' (not the caller); ok theo + - markus@cvs.openbsd.org 2003/05/12 16:55:37 + [sshconnect2.c] + for pubkey authentication try the user keys in the following order: + 1. agent keys that are found in the config file + 2. other agent keys + 3. keys that are only listed in the config file + this helps when an agent has many keys, where the server might + close the connection before the correct key is used. report & ok pb@ + - markus@cvs.openbsd.org 2003/05/12 18:35:18 + [ssh-keyscan.1] + typo: DSA keys are of type ssh-dss; Brian Poole + - markus@cvs.openbsd.org 2003/05/14 00:52:59 + [ssh2.h] + ranges for per auth method messages + - djm@cvs.openbsd.org 2003/05/14 01:00:44 + [sftp.1] + emphasise the batchmode functionality and make reference to pubkey auth, + both of which are FAQs; ok markus@ + - markus@cvs.openbsd.org 2003/05/14 02:15:47 + [auth2.c monitor.c sshconnect2.c auth2-krb5.c] + implement kerberos over ssh2 ("kerberos-2@ssh.com"); tested with jakob@ + server interops with commercial client; ok jakob@ djm@ + - jmc@cvs.openbsd.org 2003/05/14 08:25:39 + [sftp.1] + - better formatting in SYNOPSIS + - whitespace at EOL + ok djm@ + - markus@cvs.openbsd.org 2003/05/14 08:57:49 + [monitor.c] + http://bugzilla.mindrot.org/show_bug.cgi?id=560 + Privsep child continues to run after monitor killed. + Pass monitor signals through to child; Darren Tucker + - (djm) Make portable build with MIT krb5 (some issues remain) + - (djm) Add new UsePAM configuration directive to allow runtime control + over usage of PAM. This allows non-root use of sshd when built with + --with-pam + - (djm) Die screaming if start_pam() is called when UsePAM=no + - (djm) Avoid KrbV leak for MIT Kerberos + - (dtucker) Set ai_socktype and ai_protocol in fake-getaddrinfo.c. ok djm@ + - (djm) Bug #258: sscanf("[0-9]") -> sscanf("[0123456789]") for portability + +20030512 + - (djm) Redhat spec: Don't install profile.d scripts when not + building with GNOME/GTK askpass (patch from bet@rahul.net) + +20030510 + - (dtucker) Bug #318: Create ssh_prng_cmds.out during "make" rather than + "make install". Patch by roth@feep.net. + - (dtucker) Bug #536: Test for and work around openpty/controlling tty + problem on Linux (fixes "could not set controlling tty" errors). + - (djm) Merge FreeBSD PAM code: replaces PAM password auth kludge with + proper challenge-response module + - (djm) 2-clause license on loginrec.c, with permission from + andre@ae-35.com + +20030504 + - (dtucker) Bug #497: Move #include of bsd-cygwin_util.h to openbsd-compat.h. + Patch from vinschen@redhat.com. + +20030503 + - (dtucker) Add missing "void" to record_failed_login in bsd-cray.c. Noted + by wendyp@cray.com. + +20030502 + - (dtucker) Bug #544: ignore invalid cmsg_type on Linux 2.0 kernels, + privsep should now work. + - (dtucker) Move handling of bad password authentications into a platform + specific record_failed_login() function (affects AIX & Unicos). ok mouring@ + +20030429 + - (djm) Add back radix.o (used by AFS support), after it went missing from + Makefile many moons ago + - (djm) Apply "owl-always-auth" patch from Openwall/Solar Designer + - (djm) Fix blibpath specification for AIX/gcc + - (djm) Some systems have basename in -lgen. Fix from ayamura@ayamura.org + +20030428 + - (bal) [defines.h progressmeter.c scp.c] Some more culling of non 64bit + hacked code. + +20030427 + - (bal) Bug #541: return; was dropped by mistake. Reported by + furrier@iglou.com + - (bal) Since we don't support platforms lacking u_int_64. We may + as well clean out some of those evil #ifdefs + - (bal) auth1.c minor resync while looking at the code. + - (bal) auth2.c same changed as above. + +20030409 + - (djm) Bug #539: Specify creation mode with O_CREAT for lastlog. Report + from matth@eecs.berkeley.edu + - (djm) Make the spec work with Redhat 9.0 (which renames sharutils) + - (djm) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2003/04/02 09:48:07 + [clientloop.c monitor.c monitor_wrap.c packet.c packet.h readconf.c] + [readconf.h serverloop.c sshconnect2.c] + reapply rekeying chage, tested by henning@, ok djm@ + - markus@cvs.openbsd.org 2003/04/02 14:36:26 + [ssh-keysign.c] + potential segfault if KEY_UNSPEC; cjwatson@debian.org; bug #526 + - itojun@cvs.openbsd.org 2003/04/03 07:25:27 + [progressmeter.c] + $OpenBSD$ + - itojun@cvs.openbsd.org 2003/04/03 10:17:35 + [progressmeter.c] + remove $OpenBSD$, as other *.c does not have it. + - markus@cvs.openbsd.org 2003/04/07 08:29:57 + [monitor_wrap.c] + typo: get correct counters; introduced during rekeying change. + - millert@cvs.openbsd.org 2003/04/07 21:58:05 + [progressmeter.c] + The UCB copyright here is incorrect. This code did not originate + at UCB, it was written by Luke Mewburn. Updated the copyright at + the author's request. markus@ OK + - itojun@cvs.openbsd.org 2003/04/08 20:21:29 + [*.c *.h] + rename log() into logit() to avoid name conflict. markus ok, from + netbsd + - (djm) XXX - Performed locally using: + "perl -p -i -e 's/(\s|^)log\(/$1logit\(/g' *.c *.h" + - hin@cvs.openbsd.org 2003/04/09 08:23:52 + [servconf.c] + Don't include when compiling with Kerberos 5 support + - (djm) Fix up missing include for packet.c + - (djm) Fix missed log => logit occurance (reference by function pointer) + +20030402 + - (bal) if IP_TOS is not found or broken don't try to compile in + packet_set_tos() function call. bug #527 + +20030401 + - (djm) OpenBSD CVS Sync + - jmc@cvs.openbsd.org 2003/03/28 10:11:43 + [scp.1 sftp.1 ssh.1 ssh-add.1 ssh-agent.1 ssh_config.5 sshd_config.5] + [ssh-keygen.1 ssh-keyscan.1 ssh-keysign.8] + - killed whitespace + - new sentence new line + - .Bk for arguments + ok markus@ + - markus@cvs.openbsd.org 2003/04/01 10:10:23 + [clientloop.c monitor.c monitor_wrap.c packet.c packet.h readconf.c] + [readconf.h serverloop.c sshconnect2.c] + rekeying bugfixes and automatic rekeying: + * both client and server rekey _automatically_ + (a) after 2^31 packets, because after 2^32 packets + the sequence number for packets wraps + (b) after 2^(blocksize_in_bits/4) blocks + (see: draft-ietf-secsh-newmodes-00.txt) + (a) and (b) are _enabled_ by default, and only disabled for known + openssh versions, that don't support rekeying properly. + * client option 'RekeyLimit' + * do not reply to requests during rekeying + - markus@cvs.openbsd.org 2003/04/01 10:22:21 + [clientloop.c monitor.c monitor_wrap.c packet.c packet.h readconf.c] + [readconf.h serverloop.c sshconnect2.c] + backout rekeying changes (for 3.6.1) + - markus@cvs.openbsd.org 2003/04/01 10:31:26 + [compat.c compat.h kex.c] + bugfix causes stalled connections for ssh.com < 3.0; noticed by ho@; + tested by ho@ and myself + - markus@cvs.openbsd.org 2003/04/01 10:56:46 + [version.h] + 3.6.1 + - (djm) Crank spec file versions + - (djm) Release 3.6.1p1 + +20030326 + - (djm) OpenBSD CVS Sync + - deraadt@cvs.openbsd.org 2003/03/26 04:02:51 + [sftp-server.c] + one last fix to the tree: race fix broke stuff; pr 3169; + srp@srparish.net, help from djm + +20030325 + - (djm) Fix getpeerid support for 64 bit BE systems. From + Arnd Bergmann + +20030324 + - (djm) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2003/03/23 19:02:00 + [monitor.c] + unbreak rekeying for privsep; ok millert@ + - Release 3.6p1 + - Fix sshd BindAddress and -b options for systems using fake-getaddrinfo. + Report from murple@murple.net, diagnosis from dtucker@zip.com.au + +$Id: ChangeLog,v 1.2994.2.4 2003/09/16 06:00:52 djm Exp $ diff -ruN --exclude CVS ssh-openbsd-2003091600/channels.c openssh-3.7p1/channels.c --- ssh-openbsd-2003091600/channels.c 2003-09-03 12:07:14.000000000 +1000 +++ openssh-3.7p1/channels.c 2003-09-02 22:52:31.000000000 +1000 @@ -186,6 +186,7 @@ } else { c->isatty = 0; } + c->wfd_isatty = isatty(c->wfd); /* enable nonblocking mode */ if (nonblock) { @@ -1395,6 +1396,11 @@ buffer_len(&c->output) > 0) { data = buffer_ptr(&c->output); dlen = buffer_len(&c->output); +#ifdef _AIX + /* XXX: Later AIX versions can't push as much data to tty */ + if (compat20 && c->wfd_isatty && dlen > 8*1024) + dlen = 8*1024; +#endif len = write(c->wfd, data, dlen); if (len < 0 && (errno == EINTR || errno == EAGAIN)) return 1; @@ -2180,7 +2186,11 @@ /* 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 */ - verbose("bind: %.100s", strerror(errno)); + if (!ai->ai_next) + error("bind: %.100s", strerror(errno)); + else + verbose("bind: %.100s", strerror(errno)); + close(sock); continue; } @@ -2299,6 +2309,7 @@ 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. @@ -2309,6 +2320,7 @@ port); if (host_port == 0) packet_disconnect("Dynamic forwarding denied."); +#endif /* Initiate forwarding */ channel_setup_local_fwd_listener(port, hostname, host_port, gateway_ports); @@ -2485,9 +2497,22 @@ sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (sock < 0) { - error("socket: %.100s", strerror(errno)); - return -1; + if ((errno != EINVAL) && (errno != EAFNOSUPPORT)) { + error("socket: %.100s", strerror(errno)); + return -1; + } else { + debug("x11_create_display_inet: Socket family %d not supported", + ai->ai_family); + continue; + } + } +#ifdef IPV6_V6ONLY + if (ai->ai_family == AF_INET6) { + int on = 1; + if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) + error("setsockopt IPV6_V6ONLY: %.100s", strerror(errno)); } +#endif if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) { debug2("bind port %d: %.100s", port, strerror(errno)); close(sock); @@ -2502,8 +2527,17 @@ break; } socks[num_socks++] = sock; +#ifndef DONT_TRY_OTHER_AF if (num_socks == NUM_SOCKS) break; +#else + if (x11_use_localhost) { + if (num_socks == NUM_SOCKS) + break; + } else { + break; + } +#endif } freeaddrinfo(aitop); if (num_socks > 0) diff -ruN --exclude CVS ssh-openbsd-2003091600/channels.h openssh-3.7p1/channels.h --- ssh-openbsd-2003091600/channels.h 2003-03-26 16:04:02.000000000 +1100 +++ openssh-3.7p1/channels.h 2002-07-23 01:28:54.000000000 +1000 @@ -77,6 +77,7 @@ int efd; /* extended fd */ int sock; /* sock fd */ int isatty; /* rfd is a tty */ + int wfd_isatty; /* wfd is a tty */ int force_drain; /* force close on iEOF */ int delayed; /* fdset hack */ Buffer input; /* data read from socket, to be sent over diff -ruN --exclude CVS ssh-openbsd-2003091600/cipher-3des1.c openssh-3.7p1/cipher-3des1.c --- ssh-openbsd-2003091600/cipher-3des1.c 2003-05-15 13:08:29.000000000 +1000 +++ openssh-3.7p1/cipher-3des1.c 2003-05-15 13:37:20.000000000 +1000 @@ -77,6 +77,11 @@ 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) { @@ -85,6 +90,7 @@ EVP_CIPHER_CTX_set_app_data(ctx, NULL); return (0); } +#endif return (1); } @@ -97,10 +103,16 @@ 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); } @@ -152,6 +164,8 @@ 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 -ruN --exclude CVS ssh-openbsd-2003091600/cipher-aes.c openssh-3.7p1/cipher-aes.c --- ssh-openbsd-2003091600/cipher-aes.c 2003-05-15 13:08:29.000000000 +1000 +++ openssh-3.7p1/cipher-aes.c 2003-06-02 18:57:59.000000000 +1000 @@ -22,8 +22,8 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#if OPENSSL_VERSION_NUMBER < 0x00907000L #include "includes.h" +#if OPENSSL_VERSION_NUMBER < 0x00907000L RCSID("$OpenBSD: cipher-aes.c,v 1.1 2003/05/15 03:08:29 markus Exp $"); #include @@ -147,8 +147,10 @@ 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 +#endif /* OPENSSL_VERSION_NUMBER */ diff -ruN --exclude CVS ssh-openbsd-2003091600/cipher-bf1.c openssh-3.7p1/cipher-bf1.c --- ssh-openbsd-2003091600/cipher-bf1.c 2003-05-15 13:08:29.000000000 +1000 +++ openssh-3.7p1/cipher-bf1.c 2003-05-15 13:37:20.000000000 +1000 @@ -54,6 +54,19 @@ } } +#ifdef SSH_OLD_EVP +static void bf_ssh1_init (EVP_CIPHER_CTX * ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + if (iv != NULL) + memcpy (&(ctx->oiv[0]), iv, 8); + memcpy (&(ctx->iv[0]), &(ctx->oiv[0]), 8); + if (key != NULL) + BF_set_key (&(ctx->c.bf_ks), EVP_CIPHER_CTX_key_length (ctx), + key); +} +#endif + static int (*orig_bf)(EVP_CIPHER_CTX *, u_char *, const u_char *, u_int) = NULL; static int @@ -75,6 +88,9 @@ 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 -ruN --exclude CVS ssh-openbsd-2003091600/cipher.c openssh-3.7p1/cipher.c --- ssh-openbsd-2003091600/cipher.c 2003-05-18 20:44:59.000000000 +1000 +++ openssh-3.7p1/cipher.c 2003-05-18 20:53:59.000000000 +1000 @@ -43,6 +43,11 @@ #include +#if OPENSSL_VERSION_NUMBER < 0x00906000L +#define SSH_OLD_EVP +#define EVP_CIPHER_CTX_get_app_data(e) ((e)->app_data) +#endif + #if OPENSSL_VERSION_NUMBER < 0x00907000L extern const EVP_CIPHER *evp_rijndael(void); extern void ssh_rijndael_iv(EVP_CIPHER_CTX *, int, u_char *, u_int); @@ -196,7 +201,11 @@ int encrypt) { static int dowarn = 1; +#ifdef SSH_OLD_EVP + EVP_CIPHER *type; +#else const EVP_CIPHER *type; +#endif int klen; if (cipher->number == SSH_CIPHER_DES) { @@ -221,6 +230,15 @@ 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, + (encrypt == CIPHER_ENCRYPT)); +#else if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv, (encrypt == CIPHER_ENCRYPT)) == 0) fatal("cipher_init: EVP_CipherInit failed for %s", @@ -235,6 +253,7 @@ 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 } void @@ -242,15 +261,23 @@ { if (len % cc->cipher->block_size) fatal("cipher_encrypt: bad plaintext length %d", len); +#ifdef SSH_OLD_EVP + EVP_Cipher(&cc->evp, dest, (u_char *)src, len); +#else if (EVP_Cipher(&cc->evp, dest, (u_char *)src, len) == 0) fatal("evp_crypt: EVP_Cipher failed"); +#endif } void cipher_cleanup(CipherContext *cc) { +#ifdef SSH_OLD_EVP + EVP_CIPHER_CTX_cleanup(&cc->evp); +#else if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0) error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed"); +#endif } /* diff -ruN --exclude CVS ssh-openbsd-2003091600/config.guess openssh-3.7p1/config.guess --- ssh-openbsd-2003091600/config.guess 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/config.guess 2003-03-21 12:05:38.000000000 +1100 @@ -0,0 +1,1357 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002 Free Software Foundation, Inc. + +timestamp='2002-07-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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 to . Submit a context +# diff and a properly formatted 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. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +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 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # 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. + +# This shell variable is my proudest work .. or something. --bje + +set_cc_for_build='tmpdir=${TMPDIR-/tmp}/config-guess-$$ ; +(old=`umask` && umask 077 && mkdir $tmpdir && umask $old && unset old) + || (echo "$me: cannot create $tmpdir" >&2 && exit 1) ; +dummy=$tmpdir/dummy ; +files="$dummy.c $dummy.o $dummy.rel $dummy" ; +trap '"'"'rm -f $files; rmdir $tmpdir; exit 1'"'"' 1 2 15 ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + rm -f $files ; + 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 ; +unset files' + +# 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 ;; + *) 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 __ELF__ >/dev/null + 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 + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + # 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 0 ;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + macppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvmeppc:OpenBSD:*:*) + echo powerpc-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mipseb-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sun3:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi + # 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. + eval $set_cc_for_build + cat <$dummy.s + .data +\$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + + .text + .globl main + .align 4 + .ent main +main: + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit + .end main +EOF + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + case `$dummy` in + 0-0) + UNAME_MACHINE="alpha" + ;; + 1-0) + UNAME_MACHINE="alphaev5" + ;; + 1-1) + UNAME_MACHINE="alphaev56" + ;; + 1-101) + UNAME_MACHINE="alphapca56" + ;; + 2-303) + UNAME_MACHINE="alphaev6" + ;; + 2-307) + UNAME_MACHINE="alphaev67" + ;; + 2-1307) + UNAME_MACHINE="alphaev68" + ;; + 3-1307) + UNAME_MACHINE="alphaev7" + ;; + esac + fi + rm -f $dummy.s $dummy && rmdir $tmpdir + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + 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 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit 0;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + 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 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + DRS?6000:UNIX_SV:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7 && exit 0 ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + 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 0 ;; + 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 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + 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 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + # 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 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy \ + && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0 + rm -f $dummy.c $dummy && rmdir $tmpdir + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit 0 ;; + Night_Hawk:*:*:PowerMAX_OS) + echo powerpc-harris-powermax + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + 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 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????: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 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + 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 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && $dummy && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0 + rm -f $dummy.c $dummy && rmdir $tmpdir + echo rs6000-ibm-aix3.2.5 + 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 0 ;; + *:AIX:*:[45]) + 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 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null) && HP_ARCH=`$dummy` + if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi + rm -f $dummy.c $dummy && rmdir $tmpdir + fi ;; + esac + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && $dummy && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0 + rm -f $dummy.c $dummy && rmdir $tmpdir + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + 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 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3D:*:*:*) + echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + *:UNICOS/mp:*:*) + echo nv1-cray-unicosmp | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + 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 0 ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + # Determine whether the default compiler uses glibc. + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #if __GLIBC__ >= 2 + LIBC=gnu + #else + LIBC= + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + rm -f $dummy.c && rmdir $tmpdir + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC} + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit 0 ;; + x86:Interix*:3*) + echo i386-pc-interix3 + exit 0 ;; + 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 i386-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit 0 ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + rm -f $dummy.c && rmdir $tmpdir + test x"${CPU}" != x && echo "${CPU}-pc-linux-gnu" && exit 0 + ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit 0 ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit 0 ;; + 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 ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit 0 ;; + 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 0 ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit 0 ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit 0 ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit 0 ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit 0 ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #ifdef __INTEL_COMPILER + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + rm -f $dummy.c && rmdir $tmpdir + test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 + test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 + ;; + 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 0 ;; + 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 0 ;; + 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 0 ;; + i*86:*:5:[78]*) + 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 0 ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + 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 i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + 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 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*: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) + 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 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *: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 0 ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit 0 ;; + 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 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + echo `uname -p`-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *: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 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-[GKLNPTVW]:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; + *: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 0 ;; + 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 0 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit 0 ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit 0 ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit 0 ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit 0 ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit 0 ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit 0 ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit 0 ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit 0 ;; +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 < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && $dummy && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0 +rm -f $dummy.c $dummy && rmdir $tmpdir + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# 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 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff -ruN --exclude CVS ssh-openbsd-2003091600/config.sub openssh-3.7p1/config.sub --- ssh-openbsd-2003091600/config.sub 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/config.sub 2003-03-21 12:05:38.000000000 +1100 @@ -0,0 +1,1467 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002 Free Software Foundation, Inc. + +timestamp='2002-07-03' + +# 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., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, 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 . Submit a context +# diff and a properly formatted 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. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +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 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # 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 0;; + + * ) + 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* | freebsd*-gnu* | storm-chaos* | os2-emx* | windows32-* | 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) + os= + basic_machine=$1 + ;; + -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 + ;; + -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/'` + ;; + -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] \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k \ + | m32r | m68000 | m68k | m88k | mcore \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mipsisa32 | mipsisa32el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | ns16k | ns32k \ + | openrisc | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | sh | sh[1234] | sh3e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \ + | strongarm \ + | tahoe | thumb | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xscale | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + + # 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-* \ + | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c54x-* \ + | clipper-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* \ + | m32r-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipstx39 | mipstx39el \ + | none-* | np1-* | ns16k-* | ns32k-* | nv1-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh3e-* | sh[34]eb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ + | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ + | xtensa-* \ + | ymp-* \ + | z8k-*) + ;; + # 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 + ;; + 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 + ;; + 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 + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + 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 + ;; + crds | unos) + basic_machine=m68k-crds + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + 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 + ;; + 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 + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + 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 + ;; + mmix*) + basic_machine=mmix-knuth + os=-mmixware + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + 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 + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + nv1) + basic_machine=nv1-cray + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + or32 | or32-*) + basic_machine=or32-unknown + os=-coff + ;; + 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 + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon) + basic_machine=i686-pc + ;; + pentiumii | pentium2) + basic_machine=i686-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-*) + basic_machine=i686-`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 + ;; + 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 + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + 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 + ;; + sx*-nec) + basic_machine=sx6-nec + os=-sysv + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3d) + basic_machine=alpha-cray + os=-unicos + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + 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 + ;; + windows32) + basic_machine=i386-pc + os=-windows32-msvcrt + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-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 + ;; + 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 + ;; + sh3 | sh4 | sh3eb | sh4eb | sh[1234]le | sh3ele) + basic_machine=sh-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparc | sparcv9 | sparcv9b) + 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 + ;; + c4x*) + basic_machine=c4x-none + os=-coff + ;; + *-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. + -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* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -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*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto*) + os=-nto-qnx + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -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 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -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 + ;; + -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 + ;; + -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 + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + # 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 + ;; + 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 + ;; + *-ibm) + os=-aix + ;; + *-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 + ;; + -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 + ;; + -ptx*) + vendor=sequent + ;; + -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 0 + +# 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 -ruN --exclude CVS ssh-openbsd-2003091600/configure.ac openssh-3.7p1/configure.ac --- ssh-openbsd-2003091600/configure.ac 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/configure.ac 2003-09-16 15:48:15.000000000 +1000 @@ -0,0 +1,2705 @@ +# $Id: configure.ac,v 1.154.2.1 2003/09/16 05:48:15 tim Exp $ + +AC_INIT +AC_CONFIG_SRCDIR([ssh.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_PATH_PROG(AR, ar) +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) + +# 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") +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 + +if test -z "$LD" ; then + LD=$CC +fi +AC_SUBST(LD) + +AC_C_INLINE +if test "$GCC" = "yes" || test "$GCC" = "egcs"; then + CFLAGS="$CFLAGS -Wall -Wpointer-arith -Wno-uninitialized" +fi + +# Check for some target-specific stuff +case "$host" in +*-*-aix*) + CPPFLAGS="$CPPFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + AC_MSG_CHECKING([how to specify blibpath for linker ($LD)]) + if (test -z "$blibpath"); then + blibpath="/usr/lib:/lib:/usr/local/lib" + fi + saved_LDFLAGS="$LDFLAGS" + for tryflags in -blibpath: -Wl,-blibpath: -Wl,-rpath, ;do + if (test -z "$blibflags"); then + LDFLAGS="$saved_LDFLAGS $tryflags$blibpath" + AC_TRY_LINK([], [], [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)], + [AC_CHECK_LIB(s,authenticate, + [ AC_DEFINE(WITH_AIXAUTHENTICATE) + LIBS="$LIBS -ls" + ]) + ]) + dnl Check if loginfailed is declared and takes 4 arguments (AIX >= 5.2) + AC_CHECK_DECL(loginfailed, + [AC_MSG_CHECKING(if loginfailed takes 4 arguments) + AC_TRY_COMPILE( + [#include ], + [(void)loginfailed("user","host","tty",0);], + [AC_MSG_RESULT(yes) + AC_DEFINE(AIX_LOGINFAILED_4ARG)], + [AC_MSG_RESULT(no)] + )], + [], + [#include ] + ) + AC_CHECK_FUNCS(setauthdb) + AC_DEFINE(BROKEN_GETADDRINFO) + AC_DEFINE(BROKEN_REALPATH) + AC_DEFINE(SETEUID_BREAKS_SETUID) + AC_DEFINE(BROKEN_SETREUID) + AC_DEFINE(BROKEN_SETREGID) + dnl AIX handles lastlog as part of its login message + AC_DEFINE(DISABLE_LASTLOG) + AC_DEFINE(LOGIN_NEEDS_UTMPX) + AC_DEFINE(SPT_TYPE,SPT_REUSEARGV) + ;; +*-*-cygwin*) + check_for_libcrypt_later=1 + LIBS="$LIBS /usr/lib/textmode.o" + AC_DEFINE(HAVE_CYGWIN) + AC_DEFINE(USE_PIPES) + AC_DEFINE(DISABLE_SHADOW) + AC_DEFINE(IP_TOS_IS_BROKEN) + AC_DEFINE(NO_X11_UNIX_SOCKETS) + AC_DEFINE(NO_IPPORT_RESERVED_CONCEPT) + AC_DEFINE(DISABLE_FD_PASSING) + AC_DEFINE(SETGROUPS_NOOP) + ;; +*-*-dgux*) + AC_DEFINE(IP_TOS_IS_BROKEN) + ;; +*-*-darwin*) + AC_MSG_CHECKING(if we have working getaddrinfo) + AC_TRY_RUN([#include +main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) + exit(0); + else + exit(1); +}], [AC_MSG_RESULT(working)], + [AC_MSG_RESULT(buggy) + AC_DEFINE(BROKEN_GETADDRINFO)], + [AC_MSG_RESULT(assume it is working)]) + ;; +*-*-hpux10.26) + if test -z "$GCC"; then + CFLAGS="$CFLAGS -Ae" + fi + CPPFLAGS="$CPPFLAGS -D_HPUX_SOURCE -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED=1" + IPADDR_IN_DISPLAY=yes + AC_DEFINE(HAVE_SECUREWARE) + AC_DEFINE(USE_PIPES) + AC_DEFINE(LOGIN_NO_ENDOPT) + AC_DEFINE(LOGIN_NEEDS_UTMPX) + AC_DEFINE(DISABLE_SHADOW) + AC_DEFINE(DISABLE_UTMP) + AC_DEFINE(LOCKED_PASSWD_STRING, "*") + AC_DEFINE(SPT_TYPE,SPT_PSTAT) + LIBS="$LIBS -lsec -lsecpw" + AC_CHECK_LIB(xnet, t_error, ,AC_MSG_ERROR([*** -lxnet needed on HP-UX - check config.log ***])) + disable_ptmx_check=yes + ;; +*-*-hpux10*) + if test -z "$GCC"; then + CFLAGS="$CFLAGS -Ae" + fi + 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) + AC_DEFINE(LOGIN_NEEDS_UTMPX) + AC_DEFINE(DISABLE_SHADOW) + AC_DEFINE(DISABLE_UTMP) + AC_DEFINE(LOCKED_PASSWD_STRING, "*") + AC_DEFINE(SPT_TYPE,SPT_PSTAT) + LIBS="$LIBS -lsec" + AC_CHECK_LIB(xnet, t_error, ,AC_MSG_ERROR([*** -lxnet needed on HP-UX - check config.log ***])) + ;; +*-*-hpux11*) + CPPFLAGS="$CPPFLAGS -D_HPUX_SOURCE -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED=1" + IPADDR_IN_DISPLAY=yes + AC_DEFINE(PAM_SUN_CODEBASE) + AC_DEFINE(USE_PIPES) + AC_DEFINE(LOGIN_NO_ENDOPT) + AC_DEFINE(LOGIN_NEEDS_UTMPX) + AC_DEFINE(DISABLE_SHADOW) + AC_DEFINE(DISABLE_UTMP) + AC_DEFINE(LOCKED_PASSWD_STRING, "*") + AC_DEFINE(SPT_TYPE,SPT_PSTAT) + LIBS="$LIBS -lsec" + AC_CHECK_LIB(xnet, t_error, ,AC_MSG_ERROR([*** -lxnet needed on HP-UX - check config.log ***])) + ;; +*-*-irix5*) + CPPFLAGS="$CPPFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS" + PATH="$PATH:/usr/etc" + AC_DEFINE(BROKEN_INET_NTOA) + AC_DEFINE(WITH_ABBREV_NO_TTY) + AC_DEFINE(LOCKED_PASSWD_STRING, "*LK*") + ;; +*-*-irix6*) + CPPFLAGS="$CPPFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS" + PATH="$PATH:/usr/etc" + AC_DEFINE(WITH_IRIX_ARRAY) + AC_DEFINE(WITH_IRIX_PROJECT) + AC_DEFINE(WITH_IRIX_AUDIT) + AC_CHECK_FUNC(jlimit_startjob, [AC_DEFINE(WITH_IRIX_JOBS)]) + AC_DEFINE(BROKEN_INET_NTOA) + AC_DEFINE(WITH_ABBREV_NO_TTY) + AC_DEFINE(LOCKED_PASSWD_STRING, "*LK*") + ;; +*-*-linux*) + no_dev_ptmx=1 + check_for_libcrypt_later=1 + check_for_openpty_ctty_bug=1 + AC_DEFINE(DONT_TRY_OTHER_AF) + AC_DEFINE(PAM_TTY_KLUDGE) + AC_DEFINE(LOCKED_PASSWD_PREFIX, "!!") + AC_DEFINE(SPT_TYPE,SPT_REUSEARGV) + inet6_default_4in6=yes + case `uname -r` in + 1.*|2.0.*) + AC_DEFINE(BROKEN_CMSG_TYPE) + ;; + esac + ;; +mips-sony-bsd|mips-sony-newsos4) + AC_DEFINE(HAVE_NEWS4) + SONY=1 + ;; +*-*-netbsd*) + check_for_libcrypt_before=1 + need_dash_r=1 + ;; +*-*-freebsd*) + check_for_libcrypt_later=1 + ;; +*-next-*) + conf_lastlog_location="/usr/adm/lastlog" + conf_utmp_location=/etc/utmp + conf_wtmp_location=/usr/adm/wtmp + MAIL=/usr/spool/mail + AC_DEFINE(HAVE_NEXT) + AC_DEFINE(BROKEN_REALPATH) + AC_DEFINE(USE_PIPES) + AC_DEFINE(BROKEN_SAVED_UIDS) + CPPFLAGS="$CPPFLAGS -I/usr/local/include" + CFLAGS="$CFLAGS" + ;; +*-*-solaris*) + CPPFLAGS="$CPPFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib -R/usr/local/lib" + need_dash_r=1 + AC_DEFINE(PAM_SUN_CODEBASE) + AC_DEFINE(LOGIN_NEEDS_UTMPX) + AC_DEFINE(LOGIN_NEEDS_TERM) + AC_DEFINE(PAM_TTY_KLUDGE) + AC_DEFINE(LOCKED_PASSWD_STRING, "*LK*") + # Pushing STREAMS modules will cause sshd to acquire a controlling tty. + AC_DEFINE(SSHD_ACQUIRES_CTTY) + 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) + else + AC_MSG_RESULT(no) + fi + ;; +*-*-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*) + CPPFLAGS="$CPPFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + LIBS="$LIBS -lc89" + AC_DEFINE(USE_PIPES) + AC_DEFINE(SSHD_ACQUIRES_CTTY) + ;; +*-sni-sysv*) + CPPFLAGS="$CPPFLAGS -I/usr/local/include" + # /usr/ucblib MUST NOT be searched on ReliantUNIX + LDFLAGS="$LDFLAGS -L/usr/local/lib" + IPADDR_IN_DISPLAY=yes + AC_DEFINE(USE_PIPES) + AC_DEFINE(IP_TOS_IS_BROKEN) + 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 + ;; +*-*-sysv4.2*) + CPPFLAGS="$CPPFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + AC_DEFINE(USE_PIPES) + AC_DEFINE(SETEUID_BREAKS_SETUID) + AC_DEFINE(BROKEN_SETREUID) + AC_DEFINE(BROKEN_SETREGID) + ;; +*-*-sysv5*) + CPPFLAGS="$CPPFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + AC_DEFINE(USE_PIPES) + AC_DEFINE(SETEUID_BREAKS_SETUID) + AC_DEFINE(BROKEN_SETREUID) + AC_DEFINE(BROKEN_SETREGID) + ;; +*-*-sysv*) + CPPFLAGS="$CPPFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + ;; +*-*-sco3.2v4*) + CPPFLAGS="$CPPFLAGS -Dftruncate=chsize -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + LIBS="$LIBS -los -lprot -lx -ltinfo -lm" + RANLIB=true + no_dev_ptmx=1 + AC_DEFINE(BROKEN_SYS_TERMIO_H) + AC_DEFINE(USE_PIPES) + AC_DEFINE(HAVE_SECUREWARE) + AC_DEFINE(DISABLE_SHADOW) + AC_DEFINE(BROKEN_SAVED_UIDS) + AC_DEFINE(WITH_ABBREV_NO_TTY) + AC_CHECK_FUNCS(getluid setluid) + MANTYPE=man + do_sco3_extra_lib_check=yes + ;; +*-*-sco3.2v5*) + if test -z "$GCC"; then + CFLAGS="$CFLAGS -belf" + fi + CPPFLAGS="$CPPFLAGS -I/usr/local/include" + LDFLAGS="$LDFLAGS -L/usr/local/lib" + 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_SETREUID) + AC_DEFINE(BROKEN_SETREGID) + AC_DEFINE(WITH_ABBREV_NO_TTY) + AC_CHECK_FUNCS(getluid setluid) + MANTYPE=man + ;; +*-*-unicosmk*) + AC_DEFINE(USE_PIPES) + AC_DEFINE(DISABLE_FD_PASSING) + LDFLAGS="$LDFLAGS" + LIBS="$LIBS -lgen -lrsc -lshare -luex -lacm" + MANTYPE=cat + ;; +*-*-unicosmp*) + AC_DEFINE(WITH_ABBREV_NO_TTY) + AC_DEFINE(USE_PIPES) + AC_DEFINE(DISABLE_FD_PASSING) + LDFLAGS="$LDFLAGS" + LIBS="$LIBS -lgen -lacid" + MANTYPE=cat + ;; +*-*-unicos*) + 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) + AC_DEFINE(DISABLE_LOGIN) + AC_DEFINE(DISABLE_FD_PASSING) + LIBS="$LIBS -lsecurity -ldb -lm -laud" + else + AC_MSG_RESULT(no) + fi + fi + AC_DEFINE(DISABLE_FD_PASSING) + AC_DEFINE(BROKEN_GETADDRINFO) + AC_DEFINE(LOCKED_PASSWD_SUBSTR, "Nologin") + ;; + +*-*-nto-qnx) + AC_DEFINE(USE_PIPES) + AC_DEFINE(NO_X11_UNIX_SOCKETS) + AC_DEFINE(MISSING_NFDBITS) + AC_DEFINE(MISSING_HOWMANY) + AC_DEFINE(MISSING_FD_MASK) + ;; +esac + +# Allow user to specify flags +AC_ARG_WITH(cflags, + [ --with-cflags Specify additional flags to pass to compiler], + [ + if test "x$withval" != "xno" ; then + CFLAGS="$CFLAGS $withval" + fi + ] +) +AC_ARG_WITH(cppflags, + [ --with-cppflags Specify additional flags to pass to preprocessor] , + [ + if test "x$withval" != "xno"; then + CPPFLAGS="$CPPFLAGS $withval" + fi + ] +) +AC_ARG_WITH(ldflags, + [ --with-ldflags Specify additional flags to pass to linker], + [ + if test "x$withval" != "xno" ; then + LDFLAGS="$LDFLAGS $withval" + fi + ] +) +AC_ARG_WITH(libs, + [ --with-libs Specify additional libraries to link with], + [ + if test "x$withval" != "xno" ; then + LIBS="$LIBS $withval" + fi + ] +) + +AC_MSG_CHECKING(compiler and flags for sanity) +AC_TRY_RUN([ +#include +int main(){exit(0);} + ], + [ AC_MSG_RESULT(yes) ], + [ + AC_MSG_RESULT(no) + AC_MSG_ERROR([*** compiler cannot create working executables, check config.log ***]) + ] +) + +# Checks for header files. +AC_CHECK_HEADERS(bstring.h crypt.h endian.h features.h floatingpoint.h \ + getopt.h glob.h ia.h lastlog.h limits.h login.h \ + login_cap.h maillock.h netdb.h netgroup.h \ + netinet/in_systm.h paths.h pty.h readpassphrase.h \ + rpc/types.h security/pam_appl.h shadow.h stddef.h stdint.h \ + strings.h sys/strtio.h sys/audit.h sys/bitypes.h sys/bsdtty.h \ + sys/cdefs.h sys/mman.h sys/pstat.h sys/select.h sys/stat.h \ + sys/stropts.h sys/sysmacros.h sys/time.h sys/timers.h \ + sys/un.h time.h tmpdir.h ttyent.h usersec.h \ + util.h utime.h utmp.h utmpx.h) + +# Checks for libraries. +AC_CHECK_FUNC(yp_match, , AC_CHECK_LIB(nsl, yp_match)) +AC_CHECK_FUNC(setsockopt, , AC_CHECK_LIB(socket, setsockopt)) + +dnl SCO OS3 needs this for libwrap +if test "x$with_tcp_wrappers" != "xno" ; then + if test "x$do_sco3_extra_lib_check" = "xyes" ; then + AC_CHECK_LIB(rpc, innetgr, LIBS="-lrpc -lyp -lrpc $LIBS" , , -lyp -lrpc) + fi +fi + +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_TRY_RUN( + [ +#include +#include + +int main(int argc, char **argv) { + char *s, buf[32]; + + strncpy(buf,"/etc", 32); + s = dirname(buf); + if (!s || strncmp(s, "/", 32) != 0) { + exit(1); + } else { + exit(0); + } +} + ], + [ ac_cv_have_broken_dirname="no" ], + [ ac_cv_have_broken_dirname="yes" ] + ) + 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)) + +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 + ] +) + +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 ***]) + fi + 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 + ] +) + +AC_CHECK_LIB(z, deflate, ,AC_MSG_ERROR([*** zlib missing - please install first or check config.log ***])) + +dnl UnixWare 2.x +AC_CHECK_FUNC(strcasecmp, + [], [ AC_CHECK_LIB(resolv, strcasecmp, LIBS="$LIBS -lresolv") ] +) +AC_CHECK_FUNC(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(login, util bsd, [AC_DEFINE(HAVE_LOGIN)]) +AC_CHECK_FUNCS(logout updwtmp logwtmp) + +AC_FUNC_STRFTIME + +# Check for ALTDIRFUNC glob() extension +AC_MSG_CHECKING(for GLOB_ALTDIRFUNC support) +AC_EGREP_CPP(FOUNDIT, + [ + #include + #ifdef GLOB_ALTDIRFUNC + FOUNDIT + #endif + ], + [ + AC_DEFINE(GLOB_HAS_ALTDIRFUNC) + 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_EGREP_CPP(FOUNDIT, + [ + #include + int main(void){glob_t g; g.gl_matchc = 1;} + ], + [ + AC_DEFINE(GLOB_HAS_GL_MATCHC) + AC_MSG_RESULT(yes) + ], + [ + AC_MSG_RESULT(no) + ] +) + +AC_MSG_CHECKING([whether struct dirent allocates space for d_name]) +AC_TRY_RUN( + [ +#include +#include +int main(void){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) + ] +) + +# 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) + LIBS="-lskey $LIBS" + SKEY_MSG="yes" + + AC_MSG_CHECKING([for s/key support]) + AC_TRY_RUN( + [ +#include +#include +int main() { char *ff = skey_keyinfo(""); ff=""; exit(0); } + ], + [AC_MSG_RESULT(yes)], + [ + AC_MSG_RESULT(no) + AC_MSG_ERROR([** Incomplete or missing s/key libraries.]) + ]) + 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}" -a "${withval}" != "yes"; 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 + LIBWRAP="-lwrap" + LIBS="$LIBWRAP $LIBS" + AC_MSG_CHECKING(for libwrap) + AC_TRY_LINK( + [ +#include + int deny_severity = 0, allow_severity = 0; + ], + [hosts_access(0);], + [ + AC_MSG_RESULT(yes) + AC_DEFINE(LIBWRAP) + AC_SUBST(LIBWRAP) + TCPW_MSG="yes" + ], + [ + AC_MSG_ERROR([*** libwrap missing]) + ] + ) + LIBS="$saved_LIBS" + fi + ] +) + +dnl Checks for library functions. Please keep in alphabetical order +AC_CHECK_FUNCS(\ + arc4random __b64_ntop b64_ntop __b64_pton b64_pton basename \ + bcopy bindresvport_sa clock fchmod fchown freeaddrinfo futimes \ + gai_strerror getaddrinfo getcwd getgrouplist getnameinfo getopt \ + getpeereid _getpty getrlimit getttyent glob inet_aton \ + inet_ntoa inet_ntop innetgr login_getcapbool md5_crypt memmove \ + mkdtemp mmap ngetaddrinfo nsleep ogetaddrinfo openlog_r openpty \ + pstat readpassphrase realpath recvmsg rresvport_af sendmsg \ + setdtablesize setegid setenv seteuid setgroups setlogin setpcred \ + setproctitle setregid setresgid setresuid setreuid setrlimit \ + setsid setvbuf sigaction sigvec snprintf socketpair strerror \ + strlcat strlcpy strmode strnvis sysconf tcgetpgrp \ + truncate utimes vhangup vsnprintf waitpid \ +) + +AC_SEARCH_LIBS(nanosleep, rt posix4, AC_DEFINE(HAVE_NANOSLEEP)) + +dnl Make sure prototypes are defined for these before using them. +AC_CHECK_DECL(strsep, [AC_CHECK_FUNCS(strsep)]) +AC_CHECK_DECL(getrusage, [AC_CHECK_FUNCS(getrusage)]) + +dnl tcsendbreak might be a macro +AC_CHECK_DECL(tcsendbreak, + [AC_DEFINE(HAVE_TCSENDBREAK)], + [AC_CHECK_FUNCS(tcsendbreak)], + [#include ] +) + +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 pututxline ) +AC_CHECK_FUNCS(setutxent utmpxname) + +AC_CHECK_FUNC(daemon, + [AC_DEFINE(HAVE_DAEMON)], + [AC_CHECK_LIB(bsd, daemon, [LIBS="$LIBS -lbsd"; AC_DEFINE(HAVE_DAEMON)])] +) + +AC_CHECK_FUNC(getpagesize, + [AC_DEFINE(HAVE_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_TRY_RUN( + [ +#include +int main(void){char b[5];snprintf(b,5,"123456789");exit(b[4]!='\0');} + ], + [AC_MSG_RESULT(yes)], + [ + AC_MSG_RESULT(no) + AC_DEFINE(BROKEN_SNPRINTF) + AC_MSG_WARN([****** Your snprintf() function is broken, complain to your vendor]) + ] + ) +fi + +dnl see whether mkstemp() requires XXXXXX +if test "x$ac_cv_func_mkdtemp" = "xyes" ; then +AC_MSG_CHECKING([for (overly) strict mkstemp]) +AC_TRY_RUN( + [ +#include +main() { 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) + ], + [ + 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_TRY_RUN( + [ +#include +#include +#include +#include + +int +main() +{ + pid_t pid; + int fd, ptyfd, ttyfd, status; + + pid = fork(); + if (pid < 0) { /* failed */ + exit(1); + } else if (pid > 0) { /* parent */ + waitpid(pid, &status, 0); + if (WIFEXITED(status)) + exit(WEXITSTATUS(status)); + else + exit(2); + } else { /* child */ + close(0); close(1); close(2); + setsid(); + openpty(&ptyfd, &ttyfd, NULL, NULL, NULL); + fd = open("/dev/tty", O_RDWR | O_NOCTTY); + if (fd >= 0) + exit(3); /* Acquired ctty: broken */ + else + exit(0); /* Did not acquire ctty: OK */ + } +} + ], + [ + AC_MSG_RESULT(yes) + ], + [ + AC_MSG_RESULT(no) + AC_DEFINE(SSHD_ACQUIRES_CTTY) + ] + ) +fi + +AC_FUNC_GETPGRP + +# 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" ; then + AC_MSG_ERROR([PAM headers not found]) + fi + + 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) + + disable_shadow=yes + PAM_MSG="yes" + + AC_DEFINE(USE_PAM) + if test $ac_cv_lib_dl_dlopen = yes; then + LIBPAM="-lpam -ldl" + else + LIBPAM="-lpam" + fi + AC_SUBST(LIBPAM) + 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_TRY_COMPILE( + [ +#include +#include + ], + [(void)pam_strerror((pam_handle_t *)NULL, -1);], + [AC_MSG_RESULT(no)], + [ + AC_DEFINE(HAVE_OLD_PAM) + AC_MSG_RESULT(yes) + PAM_MSG="yes (old library)" + ] + ) +fi + +# 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 + +# 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 + 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="$LIBS -lcrypto" +AC_TRY_LINK_FUNC(RAND_add, AC_DEFINE(HAVE_OPENSSL), + [ + 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_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_TRY_RUN( + [ +#include +#include +#include +#define DATA "conftest.sslincver" +int main(void) { + 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.) + ] +) + +# Determine OpenSSL library version +AC_MSG_CHECKING([OpenSSL library version]) +AC_TRY_RUN( + [ +#include +#include +#include +#include +#define DATA "conftest.ssllibver" +int main(void) { + 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.) + ] +) + +# Sanity check OpenSSL headers +AC_MSG_CHECKING([whether OpenSSL's headers match the library]) +AC_TRY_RUN( + [ +#include +#include +int main(void) { exit(SSLeay() == OPENSSL_VERSION_NUMBER ? 0 : 1); } + ], + [ + AC_MSG_RESULT(yes) + ], + [ + AC_MSG_RESULT(no) + AC_MSG_ERROR([Your OpenSSL headers do not match your library. +Check config.log for details. +Also see contrib/findssl.sh for help identifying header/library mismatches.]) + ] +) + +# Some Linux systems (Slackware) need crypt() from libcrypt, *not* the +# version in OpenSSL. Skip this for PAM +if test "x$check_for_libcrypt_later" = "x1"; then + AC_CHECK_LIB(crypt, crypt, LIBS="$LIBS -lcrypt") +fi + + +### Configure cryptographic random number support + +# Check wheter OpenSSL seeds itself +AC_MSG_CHECKING([whether OpenSSL's PRNG is internally seeded]) +AC_TRY_RUN( + [ +#include +#include +int main(void) { exit(RAND_status() == 1 ? 0 : 1); } + ], + [ + OPENSSL_SEEDS_ITSELF=yes + AC_MSG_RESULT(yes) + ], + [ + AC_MSG_RESULT(no) + # Default to use of the rand helper if OpenSSL doesn't + # seed itself + USE_RAND_HELPER=yes + ] +) + + +# Do we want to force the use of the rand helper? +AC_ARG_WITH(rand-helper, + [ --with-rand-helper Use subprocess to gather strong randomness ], + [ + if test "x$withval" = "xno" ; then + # Force use of OpenSSL's internal RNG, even if + # the previous test showed it to be unseeded. + if test -z "$OPENSSL_SEEDS_ITSELF" ; then + AC_MSG_WARN([*** Forcing use of OpenSSL's non-self-seeding PRNG]) + OPENSSL_SEEDS_ITSELF=yes + USE_RAND_HELPER="" + fi + else + USE_RAND_HELPER=yes + fi + ], +) + +# Which randomness source do we use? +if test ! -z "$OPENSSL_SEEDS_ITSELF" -a -z "$USE_RAND_HELPER" ; then + # OpenSSL only + AC_DEFINE(OPENSSL_PRNG_ONLY) + RAND_MSG="OpenSSL internal ONLY" + INSTALL_SSH_RAND_HELPER="" +elif test ! -z "$USE_RAND_HELPER" ; then + # install rand helper + RAND_MSG="ssh-rand-helper" + INSTALL_SSH_RAND_HELPER="yes" +fi +AC_SUBST(INSTALL_SSH_RAND_HELPER) + +### Configuration of ssh-rand-helper + +# 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) + 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") + fi + ], + [ + # Check for existing socket only if we don't have a random device already + if test "$USE_RAND_HELPER" = yes ; 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 + ] +) + +# Change default command timeout for hashing entropy source +entropy_timeout=200 +AC_ARG_WITH(entropy-timeout, + [ --with-entropy-timeout Specify entropy gathering command timeout (msec)], + [ + if test "x$withval" != "xno" ; then + entropy_timeout=$withval + fi + ] +) +AC_DEFINE_UNQUOTED(ENTROPY_TIMEOUT_MSEC, $entropy_timeout) + +SSH_PRIVSEP_USER=sshd +AC_ARG_WITH(privsep-user, + [ --with-privsep-user=user Specify non-privileged user for privilege separation], + [ + if test -n "$withval"; then + SSH_PRIVSEP_USER=$withval + fi + ] +) +AC_DEFINE_UNQUOTED(SSH_PRIVSEP_USER, "$SSH_PRIVSEP_USER") +AC_SUBST(SSH_PRIVSEP_USER) + +# We do this little dance with the search path to insure +# that programs that we select for use by installed programs +# (which may be run by the super-user) come from trusted +# locations before they come from the user's private area. +# This should help avoid accidentally configuring some +# random version of a program in someone's personal bin. + +OPATH=$PATH +PATH=/bin:/usr/bin +test -h /bin 2> /dev/null && PATH=/usr/bin +test -d /sbin && PATH=$PATH:/sbin +test -d /usr/sbin && PATH=$PATH:/usr/sbin +PATH=$PATH:/etc:$OPATH + +# These programs are used by the command hashing source to gather entropy +OSSH_PATH_ENTROPY_PROG(PROG_LS, ls) +OSSH_PATH_ENTROPY_PROG(PROG_NETSTAT, netstat) +OSSH_PATH_ENTROPY_PROG(PROG_ARP, arp) +OSSH_PATH_ENTROPY_PROG(PROG_IFCONFIG, ifconfig) +OSSH_PATH_ENTROPY_PROG(PROG_JSTAT, jstat) +OSSH_PATH_ENTROPY_PROG(PROG_PS, ps) +OSSH_PATH_ENTROPY_PROG(PROG_SAR, sar) +OSSH_PATH_ENTROPY_PROG(PROG_W, w) +OSSH_PATH_ENTROPY_PROG(PROG_WHO, who) +OSSH_PATH_ENTROPY_PROG(PROG_LAST, last) +OSSH_PATH_ENTROPY_PROG(PROG_LASTLOG, lastlog) +OSSH_PATH_ENTROPY_PROG(PROG_DF, df) +OSSH_PATH_ENTROPY_PROG(PROG_VMSTAT, vmstat) +OSSH_PATH_ENTROPY_PROG(PROG_UPTIME, uptime) +OSSH_PATH_ENTROPY_PROG(PROG_IPCS, ipcs) +OSSH_PATH_ENTROPY_PROG(PROG_TAIL, tail) +# restore PATH +PATH=$OPATH + +# Where does ssh-rand-helper get its randomness from? +INSTALL_SSH_PRNG_CMDS="" +if test ! -z "$INSTALL_SSH_RAND_HELPER" ; then + if test ! -z "$PRNGD_PORT" ; then + RAND_HELPER_MSG="TCP localhost:$PRNGD_PORT" + elif test ! -z "$PRNGD_SOCKET" ; then + RAND_HELPER_MSG="Unix domain socket \"$PRNGD_SOCKET\"" + else + RAND_HELPER_MSG="Command hashing (timeout $entropy_timeout)" + RAND_HELPER_CMDHASH=yes + INSTALL_SSH_PRNG_CMDS="yes" + fi +fi +AC_SUBST(INSTALL_SSH_PRNG_CMDS) + + +# Cheap hack to ensure NEWS-OS libraries are arranged right. +if test ! -z "$SONY" ; then + LIBS="$LIBS -liberty"; +fi + +# Checks for data types +AC_CHECK_SIZEOF(char, 1) +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 + +# More checks for data types +AC_CACHE_CHECK([for u_int type], ac_cv_have_u_int, [ + AC_TRY_COMPILE( + [ #include ], + [ u_int a; a = 1;], + [ ac_cv_have_u_int="yes" ], + [ ac_cv_have_u_int="no" ] + ) +]) +if test "x$ac_cv_have_u_int" = "xyes" ; then + AC_DEFINE(HAVE_U_INT) + have_u_int=1 +fi + +AC_CACHE_CHECK([for intXX_t types], ac_cv_have_intxx_t, [ + AC_TRY_COMPILE( + [ #include ], + [ int8_t a; int16_t b; int32_t c; a = b = c = 1;], + [ ac_cv_have_intxx_t="yes" ], + [ ac_cv_have_intxx_t="no" ] + ) +]) +if test "x$ac_cv_have_intxx_t" = "xyes" ; then + AC_DEFINE(HAVE_INTXX_T) + 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_TRY_COMPILE( + [ #include ], + [ int8_t a; int16_t b; int32_t c; a = b = c = 1;], + [ + AC_DEFINE(HAVE_INTXX_T) + AC_MSG_RESULT(yes) + ], + [ AC_MSG_RESULT(no) ] + ) +fi + +AC_CACHE_CHECK([for int64_t type], ac_cv_have_int64_t, [ + AC_TRY_COMPILE( + [ +#include +#ifdef HAVE_STDINT_H +# include +#endif +#include +#ifdef HAVE_SYS_BITYPES_H +# include +#endif + ], + [ int64_t a; a = 1;], + [ ac_cv_have_int64_t="yes" ], + [ ac_cv_have_int64_t="no" ] + ) +]) +if test "x$ac_cv_have_int64_t" = "xyes" ; then + AC_DEFINE(HAVE_INT64_T) +fi + +AC_CACHE_CHECK([for u_intXX_t types], ac_cv_have_u_intxx_t, [ + AC_TRY_COMPILE( + [ #include ], + [ u_int8_t a; u_int16_t b; u_int32_t c; a = b = c = 1;], + [ ac_cv_have_u_intxx_t="yes" ], + [ ac_cv_have_u_intxx_t="no" ] + ) +]) +if test "x$ac_cv_have_u_intxx_t" = "xyes" ; then + AC_DEFINE(HAVE_U_INTXX_T) + 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_TRY_COMPILE( + [ #include ], + [ u_int8_t a; u_int16_t b; u_int32_t c; a = b = c = 1;], + [ + AC_DEFINE(HAVE_U_INTXX_T) + AC_MSG_RESULT(yes) + ], + [ AC_MSG_RESULT(no) ] + ) +fi + +AC_CACHE_CHECK([for u_int64_t types], ac_cv_have_u_int64_t, [ + AC_TRY_COMPILE( + [ #include ], + [ u_int64_t a; a = 1;], + [ ac_cv_have_u_int64_t="yes" ], + [ ac_cv_have_u_int64_t="no" ] + ) +]) +if test "x$ac_cv_have_u_int64_t" = "xyes" ; then + AC_DEFINE(HAVE_U_INT64_T) + 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_TRY_COMPILE( + [ #include ], + [ u_int64_t a; a = 1], + [ + AC_DEFINE(HAVE_U_INT64_T) + AC_MSG_RESULT(yes) + ], + [ AC_MSG_RESULT(no) ] + ) +fi + +if test -z "$have_u_intxx_t" ; then + AC_CACHE_CHECK([for uintXX_t types], ac_cv_have_uintxx_t, [ + AC_TRY_COMPILE( + [ +#include + ], + [ uint8_t a; uint16_t b; uint32_t c; a = b = c = 1; ], + [ ac_cv_have_uintxx_t="yes" ], + [ ac_cv_have_uintxx_t="no" ] + ) + ]) + if test "x$ac_cv_have_uintxx_t" = "xyes" ; then + AC_DEFINE(HAVE_UINTXX_T) + fi +fi + +if test -z "$have_uintxx_t" ; then + AC_MSG_CHECKING([for uintXX_t types in stdint.h]) + AC_TRY_COMPILE( + [ #include ], + [ uint8_t a; uint16_t b; uint32_t c; a = b = c = 1;], + [ + AC_DEFINE(HAVE_UINTXX_T) + AC_MSG_RESULT(yes) + ], + [ AC_MSG_RESULT(no) ] + ) +fi + +if (test -z "$have_u_intxx_t" || test -z "$have_intxx_t" && \ + test "x$ac_cv_header_sys_bitypes_h" = "xyes") +then + AC_MSG_CHECKING([for intXX_t and u_intXX_t types in sys/bitypes.h]) + AC_TRY_COMPILE( + [ +#include + ], + [ + int8_t a; int16_t b; int32_t c; + u_int8_t e; u_int16_t f; u_int32_t g; + a = b = c = e = f = g = 1; + ], + [ + AC_DEFINE(HAVE_U_INTXX_T) + AC_DEFINE(HAVE_INTXX_T) + AC_MSG_RESULT(yes) + ], + [AC_MSG_RESULT(no)] + ) +fi + + +AC_CACHE_CHECK([for u_char], ac_cv_have_u_char, [ + AC_TRY_COMPILE( + [ +#include + ], + [ u_char foo; foo = 125; ], + [ ac_cv_have_u_char="yes" ], + [ ac_cv_have_u_char="no" ] + ) +]) +if test "x$ac_cv_have_u_char" = "xyes" ; then + AC_DEFINE(HAVE_U_CHAR) +fi + +TYPE_SOCKLEN_T + +AC_CHECK_TYPES(sig_atomic_t,,,[#include ]) + +AC_CACHE_CHECK([for size_t], ac_cv_have_size_t, [ + AC_TRY_COMPILE( + [ +#include + ], + [ size_t foo; foo = 1235; ], + [ ac_cv_have_size_t="yes" ], + [ ac_cv_have_size_t="no" ] + ) +]) +if test "x$ac_cv_have_size_t" = "xyes" ; then + AC_DEFINE(HAVE_SIZE_T) +fi + +AC_CACHE_CHECK([for ssize_t], ac_cv_have_ssize_t, [ + AC_TRY_COMPILE( + [ +#include + ], + [ ssize_t foo; foo = 1235; ], + [ ac_cv_have_ssize_t="yes" ], + [ ac_cv_have_ssize_t="no" ] + ) +]) +if test "x$ac_cv_have_ssize_t" = "xyes" ; then + AC_DEFINE(HAVE_SSIZE_T) +fi + +AC_CACHE_CHECK([for clock_t], ac_cv_have_clock_t, [ + AC_TRY_COMPILE( + [ +#include + ], + [ clock_t foo; foo = 1235; ], + [ ac_cv_have_clock_t="yes" ], + [ ac_cv_have_clock_t="no" ] + ) +]) +if test "x$ac_cv_have_clock_t" = "xyes" ; then + AC_DEFINE(HAVE_CLOCK_T) +fi + +AC_CACHE_CHECK([for sa_family_t], ac_cv_have_sa_family_t, [ + AC_TRY_COMPILE( + [ +#include +#include + ], + [ sa_family_t foo; foo = 1235; ], + [ ac_cv_have_sa_family_t="yes" ], + [ AC_TRY_COMPILE( + [ +#include +#include +#include + ], + [ sa_family_t foo; foo = 1235; ], + [ ac_cv_have_sa_family_t="yes" ], + + [ ac_cv_have_sa_family_t="no" ] + )] + ) +]) +if test "x$ac_cv_have_sa_family_t" = "xyes" ; then + AC_DEFINE(HAVE_SA_FAMILY_T) +fi + +AC_CACHE_CHECK([for pid_t], ac_cv_have_pid_t, [ + AC_TRY_COMPILE( + [ +#include + ], + [ pid_t foo; foo = 1235; ], + [ ac_cv_have_pid_t="yes" ], + [ ac_cv_have_pid_t="no" ] + ) +]) +if test "x$ac_cv_have_pid_t" = "xyes" ; then + AC_DEFINE(HAVE_PID_T) +fi + +AC_CACHE_CHECK([for mode_t], ac_cv_have_mode_t, [ + AC_TRY_COMPILE( + [ +#include + ], + [ mode_t foo; foo = 1235; ], + [ ac_cv_have_mode_t="yes" ], + [ ac_cv_have_mode_t="no" ] + ) +]) +if test "x$ac_cv_have_mode_t" = "xyes" ; then + AC_DEFINE(HAVE_MODE_T) +fi + + +AC_CACHE_CHECK([for struct sockaddr_storage], ac_cv_have_struct_sockaddr_storage, [ + AC_TRY_COMPILE( + [ +#include +#include + ], + [ struct sockaddr_storage s; ], + [ ac_cv_have_struct_sockaddr_storage="yes" ], + [ ac_cv_have_struct_sockaddr_storage="no" ] + ) +]) +if test "x$ac_cv_have_struct_sockaddr_storage" = "xyes" ; then + AC_DEFINE(HAVE_STRUCT_SOCKADDR_STORAGE) +fi + +AC_CACHE_CHECK([for struct sockaddr_in6], ac_cv_have_struct_sockaddr_in6, [ + AC_TRY_COMPILE( + [ +#include +#include + ], + [ struct sockaddr_in6 s; s.sin6_family = 0; ], + [ ac_cv_have_struct_sockaddr_in6="yes" ], + [ ac_cv_have_struct_sockaddr_in6="no" ] + ) +]) +if test "x$ac_cv_have_struct_sockaddr_in6" = "xyes" ; then + AC_DEFINE(HAVE_STRUCT_SOCKADDR_IN6) +fi + +AC_CACHE_CHECK([for struct in6_addr], ac_cv_have_struct_in6_addr, [ + AC_TRY_COMPILE( + [ +#include +#include + ], + [ struct in6_addr s; s.s6_addr[0] = 0; ], + [ ac_cv_have_struct_in6_addr="yes" ], + [ ac_cv_have_struct_in6_addr="no" ] + ) +]) +if test "x$ac_cv_have_struct_in6_addr" = "xyes" ; then + AC_DEFINE(HAVE_STRUCT_IN6_ADDR) +fi + +AC_CACHE_CHECK([for struct addrinfo], ac_cv_have_struct_addrinfo, [ + AC_TRY_COMPILE( + [ +#include +#include +#include + ], + [ struct addrinfo s; s.ai_flags = AI_PASSIVE; ], + [ ac_cv_have_struct_addrinfo="yes" ], + [ ac_cv_have_struct_addrinfo="no" ] + ) +]) +if test "x$ac_cv_have_struct_addrinfo" = "xyes" ; then + AC_DEFINE(HAVE_STRUCT_ADDRINFO) +fi + +AC_CACHE_CHECK([for struct timeval], ac_cv_have_struct_timeval, [ + AC_TRY_COMPILE( + [ #include ], + [ struct timeval tv; tv.tv_sec = 1;], + [ ac_cv_have_struct_timeval="yes" ], + [ ac_cv_have_struct_timeval="no" ] + ) +]) +if test "x$ac_cv_have_struct_timeval" = "xyes" ; then + AC_DEFINE(HAVE_STRUCT_TIMEVAL) + 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" -a \ + "x$ac_cv_sizeof_long_int" != "x8" -a \ + "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_TRY_RUN( + [ +#include +#include +#ifdef HAVE_SNPRINTF +main() +{ + char buf[50]; + char expected_out[50]; + int mazsize = 50 ; +#if (SIZEOF_LONG_INT == 8) + long int num = 0x7fffffffffffffff; +#else + long long num = 0x7fffffffffffffffll; +#endif + strcpy(expected_out, "9223372036854775807"); + snprintf(buf, mazsize, "%lld", num); + if(strcmp(buf, expected_out) != 0) + exit(1); + exit(0); +} +#else +main() { exit(0); } +#endif + ], [ true ], [ AC_DEFINE(BROKEN_SNPRINTF) ] + ) +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_CACHE_CHECK([for ss_family field in struct sockaddr_storage], + ac_cv_have_ss_family_in_struct_ss, [ + AC_TRY_COMPILE( + [ +#include +#include + ], + [ struct sockaddr_storage s; s.ss_family = 1; ], + [ ac_cv_have_ss_family_in_struct_ss="yes" ], + [ ac_cv_have_ss_family_in_struct_ss="no" ], + ) +]) +if test "x$ac_cv_have_ss_family_in_struct_ss" = "xyes" ; then + AC_DEFINE(HAVE_SS_FAMILY_IN_SS) +fi + +AC_CACHE_CHECK([for __ss_family field in struct sockaddr_storage], + ac_cv_have___ss_family_in_struct_ss, [ + AC_TRY_COMPILE( + [ +#include +#include + ], + [ struct sockaddr_storage s; s.__ss_family = 1; ], + [ ac_cv_have___ss_family_in_struct_ss="yes" ], + [ ac_cv_have___ss_family_in_struct_ss="no" ] + ) +]) +if test "x$ac_cv_have___ss_family_in_struct_ss" = "xyes" ; then + AC_DEFINE(HAVE___SS_FAMILY_IN_SS) +fi + +AC_CACHE_CHECK([for pw_class field in struct passwd], + ac_cv_have_pw_class_in_struct_passwd, [ + AC_TRY_COMPILE( + [ +#include + ], + [ 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) +fi + +AC_CACHE_CHECK([for pw_expire field in struct passwd], + ac_cv_have_pw_expire_in_struct_passwd, [ + AC_TRY_COMPILE( + [ +#include + ], + [ 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) +fi + +AC_CACHE_CHECK([for pw_change field in struct passwd], + ac_cv_have_pw_change_in_struct_passwd, [ + AC_TRY_COMPILE( + [ +#include + ], + [ 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) +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_TRY_RUN( + [ +#include +#include +#include +int main() { +#ifdef msg_accrights +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) +fi + +AC_CACHE_CHECK([for msg_control field in struct msghdr], + ac_cv_have_control_in_msghdr, [ + AC_TRY_RUN( + [ +#include +#include +#include +int main() { +#ifdef msg_control +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) +fi + +AC_CACHE_CHECK([if libc defines __progname], ac_cv_libc_defines___progname, [ + AC_TRY_LINK([], + [ 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) +fi + +AC_CACHE_CHECK([whether $CC implements __FUNCTION__], ac_cv_cc_implements___FUNCTION__, [ + AC_TRY_LINK([ +#include +], + [ printf("%s", __FUNCTION__); ], + [ ac_cv_cc_implements___FUNCTION__="yes" ], + [ ac_cv_cc_implements___FUNCTION__="no" ] + ) +]) +if test "x$ac_cv_cc_implements___FUNCTION__" = "xyes" ; then + AC_DEFINE(HAVE___FUNCTION__) +fi + +AC_CACHE_CHECK([whether $CC implements __func__], ac_cv_cc_implements___func__, [ + AC_TRY_LINK([ +#include +], + [ printf("%s", __func__); ], + [ ac_cv_cc_implements___func__="yes" ], + [ ac_cv_cc_implements___func__="no" ] + ) +]) +if test "x$ac_cv_cc_implements___func__" = "xyes" ; then + AC_DEFINE(HAVE___func__) +fi + +AC_CACHE_CHECK([whether getopt has optreset support], + ac_cv_have_getopt_optreset, [ + AC_TRY_LINK( + [ +#include + ], + [ extern int optreset; optreset = 0; ], + [ ac_cv_have_getopt_optreset="yes" ], + [ ac_cv_have_getopt_optreset="no" ] + ) +]) +if test "x$ac_cv_have_getopt_optreset" = "xyes" ; then + AC_DEFINE(HAVE_GETOPT_OPTRESET) +fi + +AC_CACHE_CHECK([if libc defines sys_errlist], ac_cv_libc_defines_sys_errlist, [ + AC_TRY_LINK([], + [ 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) +fi + + +AC_CACHE_CHECK([if libc defines sys_nerr], ac_cv_libc_defines_sys_nerr, [ + AC_TRY_LINK([], + [ 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) +fi + +SCARD_MSG="no" +# Check whether user wants sectok support +AC_ARG_WITH(sectok, + [ --with-sectok Enable smartcard support using libsectok], + [ + if test "x$withval" != "xno" ; then + if test "x$withval" != "xyes" ; then + CPPFLAGS="$CPPFLAGS -I${withval}" + LDFLAGS="$LDFLAGS -L${withval}" + if test ! -z "$need_dash_r" ; then + LDFLAGS="$LDFLAGS -R${withval}" + fi + if test ! -z "$blibpath" ; then + blibpath="$blibpath:${withval}" + fi + fi + AC_CHECK_HEADERS(sectok.h) + if test "$ac_cv_header_sectok_h" != yes; then + AC_MSG_ERROR(Can't find sectok.h) + fi + AC_CHECK_LIB(sectok, sectok_open) + if test "$ac_cv_lib_sectok_sectok_open" != yes; then + AC_MSG_ERROR(Can't find libsectok) + fi + AC_DEFINE(SMARTCARD) + AC_DEFINE(USE_SECTOK) + SCARD_MSG="yes, using sectok" + fi + ] +) + +# Check whether user wants OpenSC support +AC_ARG_WITH(opensc, + AC_HELP_STRING([--with-opensc=PFX], + [Enable smartcard support using OpenSC]), + opensc_config_prefix="$withval", opensc_config_prefix="") +if test x$opensc_config_prefix != x ; then + OPENSC_CONFIG=$opensc_config_prefix/bin/opensc-config + AC_PATH_PROG(OPENSC_CONFIG, opensc-config, no) + if test "$OPENSC_CONFIG" != "no"; then + LIBOPENSC_CFLAGS=`$OPENSC_CONFIG --cflags` + LIBOPENSC_LIBS=`$OPENSC_CONFIG --libs` + CPPFLAGS="$CPPFLAGS $LIBOPENSC_CFLAGS" + LDFLAGS="$LDFLAGS $LIBOPENSC_LIBS" + AC_DEFINE(SMARTCARD) + AC_DEFINE(USE_OPENSC) + SCARD_MSG="yes, using OpenSC" + fi +fi + +# Check whether user wants DNS support +DNS_MSG="no" +AC_ARG_WITH(dns, + [ --with-dns Support for fetching keys from DNS (experimental)], + [ + if test "x$withval" != "xno" ; then + DNS_MSG="yes" + AC_DEFINE(DNS) + AC_SEARCH_LIBS(getrrsetbyname, resolv, + [AC_DEFINE(HAVE_GETRRSETBYNAME)], + [ + # Needed by our getrrsetbyname() + AC_SEARCH_LIBS(res_query, resolv) + AC_SEARCH_LIBS(dn_expand, resolv) + AC_CHECK_FUNCS(_getshort _getlong) + AC_CHECK_MEMBER(HEADER.ad, + [AC_DEFINE(HAVE_HEADER_AD)],, + [#include ]) + ]) + fi + ] +) + +# 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 + CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include" + LDFLAGS="$LDFLAGS -L${KRB5ROOT}/lib" + AC_DEFINE(KRB5) + KRB5_MSG="yes" + AC_MSG_CHECKING(whether we are using Heimdal) + AC_TRY_COMPILE([ #include ], + [ char *tmp = heimdal_version; ], + [ AC_MSG_RESULT(yes) + AC_DEFINE(HEIMDAL) + K5LIBS="-lkrb5 -ldes -lcom_err -lasn1 -lroken" + ], + [ AC_MSG_RESULT(no) + K5LIBS="-lkrb5 -lk5crypto -lcom_err" + ] + ) + if test ! -z "$need_dash_r" ; then + LDFLAGS="$LDFLAGS -R${KRB5ROOT}/lib" + fi + if test ! -z "$blibpath" ; then + blibpath="$blibpath:${KRB5ROOT}/lib" + fi + AC_SEARCH_LIBS(dn_expand, resolv) + + AC_CHECK_LIB(gssapi,gss_init_sec_context, + [ AC_DEFINE(GSSAPI) + K5LIBS="-lgssapi $K5LIBS" ], + [ AC_CHECK_LIB(gssapi_krb5,gss_init_sec_context, + [ AC_DEFINE(GSSAPI) + K5LIBS="-lgssapi_krb5 $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" ]) + + KRB5=yes + fi + ] +) +LIBS="$LIBS $K5LIBS" + +# Looking for programs, paths and files + +PRIVSEP_PATH=/var/empty +AC_ARG_WITH(privsep-path, + [ --with-privsep-path=xxx Path for privilege separation chroot (default=/var/empty)], + [ + if test "x$withval" != "$no" ; then + PRIVSEP_PATH=$withval + fi + ] +) +AC_SUBST(PRIVSEP_PATH) + +AC_ARG_WITH(xauth, + [ --with-xauth=PATH Specify path to xauth program ], + [ + if test "x$withval" != "xno" ; 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") + XAUTH_PATH=$xauth_path + AC_SUBST(XAUTH_PATH) +fi + +# Check for mail directory (last resort if we cannot get it from headers) +if test ! -z "$MAIL" ; then + maildir=`dirname $MAIL` + AC_DEFINE_UNQUOTED(MAIL_DIRECTORY, "$maildir") +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) + have_dev_ptmx=1 + ] + ) + fi +fi +AC_CHECK_FILE("/dev/ptc", + [ + AC_DEFINE_UNQUOTED(HAVE_DEV_PTS_AND_PTC) + have_dev_ptc=1 + ] +) + +# 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) + 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_TRY_COMPILE( + [ +#include +#include + struct spwd sp; + ],[ sp.sp_expire = sp.sp_lstchg = sp.sp_inact = 0; ], + [ sp_expire_available=yes ], [] + ) + + if test "x$sp_expire_available" = "xyes" ; then + AC_MSG_RESULT(yes) + AC_DEFINE(HAS_SHADOW_EXPIRE) + 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) +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_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) +fi + +dnl BSD systems use /etc/login.conf so --with-default-path= has no effect +if test $ac_cv_func_login_getcapbool = "yes" -a \ + $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_TRY_RUN( + [ +/* find out what STDPATH is */ +#include +#ifdef HAVE_PATHS_H +# include +#endif +#ifndef _PATH_STDPATH +# ifdef _PATH_USERPATH /* Irix */ +# define _PATH_STDPATH _PATH_USERPATH +# else +# define _PATH_STDPATH "/usr/bin:/bin:/usr/sbin:/sbin" +# endif +#endif +#include +#include +#include +#define DATA "conftest.stdpath" + +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); +} + ], [ 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") + 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 "x$withval" != "xno" ; then + AC_DEFINE_UNQUOTED(SUPERUSER_PATH, "$withval") + 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) + 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) + 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 "x$withval" != "xno" ; 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") +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) + 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) + 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) + 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) + fi + ] +) +AC_ARG_WITH(lastlog, + [ --with-lastlog=FILE|DIR specify lastlog location [common locations]], + [ + if test "x$withval" = "xno" ; then + AC_DEFINE(DISABLE_LASTLOG) + else + 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_TRY_COMPILE([ +#include +#include +#ifdef HAVE_LASTLOG_H +# include +#endif +#ifdef HAVE_PATHS_H +# include +#endif +#ifdef HAVE_LOGIN_H +# include +#endif + ], + [ char *lastlog = LASTLOG_FILE; ], + [ AC_MSG_RESULT(yes) ], + [ + AC_MSG_RESULT(no) + AC_MSG_CHECKING([if your system defines _PATH_LASTLOG]) + AC_TRY_COMPILE([ +#include +#include +#ifdef HAVE_LASTLOG_H +# include +#endif +#ifdef HAVE_PATHS_H +# include +#endif + ], + [ char *lastlog = _PATH_LASTLOG; ], + [ AC_MSG_RESULT(yes) ], + [ + AC_MSG_RESULT(no) + system_lastlog_path=no + ]) + ] +) + +if test -z "$conf_lastlog_location"; then + if test x"$system_lastlog_path" = x"no" ; then + for f in /var/log/lastlog /usr/adm/lastlog /var/adm/lastlog /etc/security/lastlog ; do + if (test -d "$f" || test -f "$f") ; then + conf_lastlog_location=$f + fi + done + if test -z "$conf_lastlog_location"; then + AC_MSG_WARN([** Cannot find lastlog **]) + dnl Don't define DISABLE_LASTLOG - that means we don't try wtmp/wtmpx + fi + fi +fi + +if test -n "$conf_lastlog_location"; then + AC_DEFINE_UNQUOTED(CONF_LASTLOG_FILE, "$conf_lastlog_location") +fi + +dnl utmp detection +AC_MSG_CHECKING([if your system defines UTMP_FILE]) +AC_TRY_COMPILE([ +#include +#include +#ifdef HAVE_PATHS_H +# include +#endif + ], + [ char *utmp = UTMP_FILE; ], + [ AC_MSG_RESULT(yes) ], + [ AC_MSG_RESULT(no) + system_utmp_path=no ] +) +if test -z "$conf_utmp_location"; then + if test x"$system_utmp_path" = x"no" ; then + for f in /etc/utmp /usr/adm/utmp /var/run/utmp; do + if test -f $f ; then + conf_utmp_location=$f + fi + done + if test -z "$conf_utmp_location"; then + AC_DEFINE(DISABLE_UTMP) + fi + fi +fi +if test -n "$conf_utmp_location"; then + AC_DEFINE_UNQUOTED(CONF_UTMP_FILE, "$conf_utmp_location") +fi + +dnl wtmp detection +AC_MSG_CHECKING([if your system defines WTMP_FILE]) +AC_TRY_COMPILE([ +#include +#include +#ifdef HAVE_PATHS_H +# include +#endif + ], + [ char *wtmp = WTMP_FILE; ], + [ AC_MSG_RESULT(yes) ], + [ AC_MSG_RESULT(no) + system_wtmp_path=no ] +) +if test -z "$conf_wtmp_location"; then + if test x"$system_wtmp_path" = x"no" ; then + for f in /usr/adm/wtmp /var/log/wtmp; do + if test -f $f ; then + conf_wtmp_location=$f + fi + done + if test -z "$conf_wtmp_location"; then + AC_DEFINE(DISABLE_WTMP) + fi + fi +fi +if test -n "$conf_wtmp_location"; then + AC_DEFINE_UNQUOTED(CONF_WTMP_FILE, "$conf_wtmp_location") +fi + + +dnl utmpx detection - I don't know any system so perverse as to require +dnl utmpx, but not define UTMPX_FILE (ditto wtmpx.) No doubt it's out +dnl there, though. +AC_MSG_CHECKING([if your system defines UTMPX_FILE]) +AC_TRY_COMPILE([ +#include +#include +#ifdef HAVE_UTMPX_H +#include +#endif +#ifdef HAVE_PATHS_H +# include +#endif + ], + [ char *utmpx = UTMPX_FILE; ], + [ AC_MSG_RESULT(yes) ], + [ AC_MSG_RESULT(no) + system_utmpx_path=no ] +) +if test -z "$conf_utmpx_location"; then + if test x"$system_utmpx_path" = x"no" ; then + AC_DEFINE(DISABLE_UTMPX) + fi +else + AC_DEFINE_UNQUOTED(CONF_UTMPX_FILE, "$conf_utmpx_location") +fi + +dnl wtmpx detection +AC_MSG_CHECKING([if your system defines WTMPX_FILE]) +AC_TRY_COMPILE([ +#include +#include +#ifdef HAVE_UTMPX_H +#include +#endif +#ifdef HAVE_PATHS_H +# include +#endif + ], + [ char *wtmpx = WTMPX_FILE; ], + [ AC_MSG_RESULT(yes) ], + [ AC_MSG_RESULT(no) + system_wtmpx_path=no ] +) +if test -z "$conf_wtmpx_location"; then + if test x"$system_wtmpx_path" = x"no" ; then + AC_DEFINE(DISABLE_WTMPX) + fi +else + AC_DEFINE_UNQUOTED(CONF_WTMPX_FILE, "$conf_wtmpx_location") +fi + + +if test ! -z "$blibpath" ; then + LDFLAGS="$LDFLAGS $blibflags$blibpath" + AC_MSG_WARN([Please check and edit blibpath in LDFLAGS in Makefile]) +fi + +dnl remove pam and dl because they are in $LIBPAM +if test "$PAM_MSG" = yes ; then + LIBS=`echo $LIBS | sed 's/-lpam //'` +fi +if test "$ac_cv_lib_pam_pam_set_item" = yes ; then + LIBS=`echo $LIBS | sed 's/-ldl //'` +fi + +AC_EXEEXT +AC_CONFIG_FILES([Makefile openbsd-compat/Makefile scard/Makefile ssh_prng_cmds]) +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 " DNS support: $DNS_MSG" +echo " PAM support: $PAM_MSG" +echo " KerberosV support: $KRB5_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 " 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" +if test ! -z "$USE_RAND_HELPER" ; then +echo " ssh-rand-helper collects from: $RAND_HELPER_MSG" +fi + +echo "" + +echo " Host: ${host}" +echo " Compiler: ${CC}" +echo " Compiler flags: ${CFLAGS}" +echo "Preprocessor flags: ${CPPFLAGS}" +echo " Linker flags: ${LDFLAGS}" +echo " Libraries: ${LIBWRAP} ${LIBPAM} ${LIBS}" + +echo "" + +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 "$RAND_HELPER_CMDHASH" ; then + echo "WARNING: you are using the builtin random number collection " + echo "service. Please read WARNING.RNG and request that your OS " + echo "vendor includes kernel-based random number collection in " + echo "future versions of your OS." + echo "" +fi + diff -ruN --exclude CVS ssh-openbsd-2003091600/contrib/aix/buildbff.sh openssh-3.7p1/contrib/aix/buildbff.sh --- ssh-openbsd-2003091600/contrib/aix/buildbff.sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/contrib/aix/buildbff.sh 2003-08-25 15:01:04.000000000 +1000 @@ -0,0 +1,383 @@ +#!/bin/sh +# +# buildbff.sh: Create AIX SMIT-installable OpenSSH packages +# $Id: buildbff.sh,v 1.6 2003/08/25 05:01:04 dtucker 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` + +# 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 ssh_prng_cmds +do + mv $FAKE_ROOT/$sysconfdir/$cfgfile $FAKE_ROOT/$sysconfdir/$cfgfile.default +done + +# +# Generate lpp control files. +# working dir is $FAKE_ROOT but files are generated in dir above +# and moved into place just before creation of .bff +# +cd $FAKE_ROOT +echo Generating LPP control files +find . ! -name . -print >../openssh.al +$inventory >../openssh.inventory + +cat <../openssh.copyright +This software is distributed under a BSD-style license. +For the full text of the license, see /usr/lpp/openssh/LICENCE +EOD + +# +# openssh.size file allows filesystem expansion as required +# generate list of directories containing files +# then calculate disk usage for each directory and store in openssh.size +# +files=`find . -type f -print` +dirs=`for file in $files; do dirname $file; done | sort -u` +for dir in $dirs +do + du $dir +done > ../openssh.size + +# +# Create postinstall script +# +cat <>../openssh.post_i +#!/bin/sh + +echo Creating configs from defaults if necessary. +for cfgfile in ssh_config sshd_config ssh_prng_cmds +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 PrivSep user if PrivSep not disabled in config +echo Creating PrivSep prereqs if required. +if egrep '^[ \t]*UsePrivilegeSeparation[ \t]+no' $sysconfdir/sshd_config >/dev/null +then + echo "UsePrivilegeSeparation disabled in config, not creating PrivSep user," + echo "group or chroot directory." +else + echo "UsePrivilegeSeparation enabled in config (or defaulting to on)." + + # create group if required + 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 ALL | cut -f1 -d: | egrep '^'$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 + + # create chroot directory if required + if [ -d $PRIVSEP_PATH ] + then + echo "PrivSep chroot directory $PRIVSEP_PATH already exists." + else + echo "Creating PrivSep chroot directory $PRIVSEP_PATH." + mkdir $PRIVSEP_PATH + chown 0 $PRIVSEP_PATH + chgrp 0 $PRIVSEP_PATH + chmod 755 $PRIVSEP_PATH + fi +fi +echo + +# Generate keys unless they already exist +echo Creating host keys if required. +if [ -f "$sysconfdir/ssh_host_key" ] ; then + echo "$sysconfdir/ssh_host_key already exists, skipping." +else + $bindir/ssh-keygen -t rsa1 -f $sysconfdir/ssh_host_key -N "" +fi +if [ -f $sysconfdir/ssh_host_dsa_key ] ; then + echo "$sysconfdir/ssh_host_dsa_key already exists, skipping." +else + $bindir/ssh-keygen -t dsa -f $sysconfdir/ssh_host_dsa_key -N "" +fi +if [ -f $sysconfdir/ssh_host_rsa_key ] ; then + echo "$sysconfdir/ssh_host_rsa_key already exists, skipping." +else + $bindir/ssh-keygen -t rsa -f $sysconfdir/ssh_host_rsa_key -N "" +fi +echo + +# Set startup command depending on SRC support +if [ "$AIX_SRC" = "yes" ] +then + echo Creating SRC sshd subsystem. + rmssys -s sshd 2>&1 >/dev/null + mkssys -s sshd -p "$sbindir/sshd" -a '-D' -u 0 -S -n 15 -f 9 -R -G tcpip + startupcmd="start $sbindir/sshd \\\"\\\$src_running\\\"" + oldstartcmd="$sbindir/sshd" +else + startupcmd="$sbindir/sshd" + oldstartcmd="start $sbindir/sshd \\\"$src_running\\\"" +fi + +# If migrating to or from SRC, change previous startup command +# otherwise add to rc.tcpip +if egrep "^\$oldstartcmd" /etc/rc.tcpip >/dev/null +then + if sed "s|^\$oldstartcmd|\$startupcmd|g" /etc/rc.tcpip >/etc/rc.tcpip.new + then + chmod 0755 /etc/rc.tcpip.new + mv /etc/rc.tcpip /etc/rc.tcpip.old && \ + mv /etc/rc.tcpip.new /etc/rc.tcpip + else + echo "Updating /etc/rc.tcpip failed, please check." + fi +else + # Add to system startup if required + if grep "^\$startupcmd" /etc/rc.tcpip >/dev/null + then + echo "sshd found in rc.tcpip, not adding." + else + echo "Adding sshd to rc.tcpip" + echo >>/etc/rc.tcpip + echo "# Start sshd" >>/etc/rc.tcpip + echo "\$startupcmd" >>/etc/rc.tcpip + fi +fi +EOF + +# +# Create liblpp.a and move control files into it +# +echo Creating liblpp.a +( + cd .. + for i in openssh.al openssh.copyright openssh.inventory openssh.post_i openssh.size LICENCE README* + do + ar -r liblpp.a $i + rm $i + done +) + +# +# Create lpp_name +# +# This will end up looking something like: +# 4 R I OpenSSH { +# OpenSSH 3.0.2.1 1 N U en_US OpenSSH 3.0.2p1 Portable for AIX +# [ +# % +# /usr/local/bin 8073 +# /usr/local/etc 189 +# /usr/local/libexec 185 +# /usr/local/man/man1 145 +# /usr/local/man/man8 83 +# /usr/local/sbin 2105 +# /usr/local/share 3 +# % +# ] +# } + +echo Creating lpp_name +cat <../lpp_name +4 R I $PKGNAME { +$PKGNAME $BFFVERSION 1 N U en_US OpenSSH $VERSION Portable for AIX +[ +% +EOF + +for i in $bindir $sysconfdir $libexecdir $mandir/${mansubdir}1 $mandir/${mansubdir}8 $sbindir $datadir /usr/lpp/openssh +do + # get size in 512 byte blocks + if [ -d $FAKE_ROOT/$i ] + then + size=`du $FAKE_ROOT/$i | awk '{print $1}'` + echo "$i $size" >>../lpp_name + fi +done + +echo '%' >>../lpp_name +echo ']' >>../lpp_name +echo '}' >>../lpp_name + +# +# Move pieces into place +# +mkdir -p usr/lpp/openssh +mv ../liblpp.a usr/lpp/openssh +mv ../lpp_name . + +# +# Now invoke backup to create .bff file +# note: lpp_name needs to be the first file so we generate the +# file list on the fly and feed it to backup using -i +# +echo Creating $PKGNAME-$VERSION.bff with backup... +rm -f $PKGNAME-$VERSION.bff +( + echo "./lpp_name" + find . ! -name lpp_name -a ! -name . -print +) | backup -i -q -f ../$PKGNAME-$VERSION.bff $filelist + +# +# Move package into final location and clean up +# +mv ../$PKGNAME-$VERSION.bff $startdir +cd $startdir +rm -rf $objdir/$PKGDIR + +echo $0: done. + diff -ruN --exclude CVS ssh-openbsd-2003091600/contrib/aix/inventory.sh openssh-3.7p1/contrib/aix/inventory.sh --- ssh-openbsd-2003091600/contrib/aix/inventory.sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/contrib/aix/inventory.sh 2003-08-26 13:43:13.000000000 +1000 @@ -0,0 +1,63 @@ +#!/bin/sh +# +# inventory.sh +# $Id: inventory.sh,v 1.5 2003/08/26 03:43:13 dtucker 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 -ruN --exclude CVS ssh-openbsd-2003091600/contrib/aix/README openssh-3.7p1/contrib/aix/README --- ssh-openbsd-2003091600/contrib/aix/README 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/contrib/aix/README 2003-08-25 15:01:04.000000000 +1000 @@ -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 -ruN --exclude CVS ssh-openbsd-2003091600/contrib/caldera/openssh.spec openssh-3.7p1/contrib/caldera/openssh.spec --- ssh-openbsd-2003091600/contrib/caldera/openssh.spec 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/contrib/caldera/openssh.spec 2003-09-16 16:02:40.000000000 +1000 @@ -0,0 +1,367 @@ + +# 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 +%if %{use_stable} + %define version 3.7p1 + %define cvs %{nil} + %define release 1 +%else + %define version 2.9.9p2 + %define cvs cvs20011009 + %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 +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.sig +%endif +Source2: http://www.ntrnet.net/~jmknoble/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.ntrnet.net/~jmknoble/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 . + + +%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-ipv4-default \ + --with-privsep-path=%{_var}/empty/sshd \ + #leave this line for easy edits. + +%__make CFLAGS="$RPM_OPT_FLAGS" + +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 $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 +: # to protect the rpm database + + +%PostUn server +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 +%{_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}/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/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 +* Mon Jan 01 1998 ... +Template Version: 1.31 + +$Id: openssh.spec,v 1.43.2.2 2003/09/16 06:02:40 djm Exp $ diff -ruN --exclude CVS ssh-openbsd-2003091600/contrib/caldera/sshd.init openssh-3.7p1/contrib/caldera/sshd.init --- ssh-openbsd-2003091600/contrib/caldera/sshd.init 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/contrib/caldera/sshd.init 2001-11-04 06:09:33.000000000 +1100 @@ -0,0 +1,125 @@ +#! /bin/bash +# +# $Id: sshd.init,v 1.3 2001/11/03 19:09:33 tim 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 . +# Modified for Debian GNU/Linux by Ian Murdock . +# Modified for OpenLinux by Raymund Will + +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 -ruN --exclude CVS ssh-openbsd-2003091600/contrib/caldera/sshd.pam openssh-3.7p1/contrib/caldera/sshd.pam --- ssh-openbsd-2003091600/contrib/caldera/sshd.pam 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/contrib/caldera/sshd.pam 2001-01-05 09:54:51.000000000 +1100 @@ -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 -ruN --exclude CVS ssh-openbsd-2003091600/contrib/caldera/ssh-host-keygen openssh-3.7p1/contrib/caldera/ssh-host-keygen --- ssh-openbsd-2003091600/contrib/caldera/ssh-host-keygen 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/contrib/caldera/ssh-host-keygen 2001-04-27 15:50:50.000000000 +1000 @@ -0,0 +1,36 @@ +#! /bin/sh +# +# $Id: ssh-host-keygen,v 1.1 2001/04/27 05:50:50 tim 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 1024 bit SSH1 RSA host key." + $keygen -b 1024 -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 1024 bit SSH2 RSA host key." + $keygen -b 1024 -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 -ruN --exclude CVS ssh-openbsd-2003091600/contrib/cygwin/README openssh-3.7p1/contrib/cygwin/README --- ssh-openbsd-2003091600/contrib/cygwin/README 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/contrib/cygwin/README 2002-07-04 09:33:20.000000000 +1000 @@ -0,0 +1,208 @@ +This package is the actual port of OpenSSH to Cygwin 1.3. + +=========================================================================== +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. + --port -p sshd listens on port n. + +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 + +=========================================================================== +The following restrictions only apply to Cygwin versions up to 1.3.1 +=========================================================================== + +Authentication to sshd is possible in one of two ways. +You'll have to decide before starting sshd! + +- If you want to authenticate via RSA and you want to login to that + machine to exactly one user account you can do so by running sshd + under that user account. You must change /etc/sshd_config + to contain the following: + + RSAAuthentication yes + + Moreover it's possible to use rhosts and/or rhosts with + RSA authentication by setting the following in sshd_config: + + RhostsAuthentication yes + RhostsRSAAuthentication yes + +- If you want to be able to login to different user accounts you'll + have to start sshd under system account or any other account that + is able to switch user context. Note that administrators are _not_ + able to do that by default! You'll have to give the following + special user rights to the user: + "Act as part of the operating system" + "Replace process level token" + "Increase quotas" + and if used via service manager + "Logon as a service". + + The system account does of course own that user rights by default. + + Unfortunately, if you choose that way, you can only logon with + NT password authentification and you should change + /etc/sshd_config to contain the following: + + PasswordAuthentication yes + RhostsAuthentication no + RhostsRSAAuthentication no + RSAAuthentication no + + However you can login to the user which has started sshd with + RSA authentication anyway. If you want that, change the RSA + authentication setting back to "yes": + + RSAAuthentication yes + +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 the `login' port on sources.redhat.com: + + 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-... + +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='${exec_prefix}/sbin' + +You must have installed the zlib and openssl packages to be able to +build OpenSSH! + +Please send requests, error reports etc. to cygwin@cygwin.com. + +Have fun, + +Corinna Vinschen +Cygwin Developer +Red Hat Inc. diff -ruN --exclude CVS ssh-openbsd-2003091600/contrib/cygwin/ssh-host-config openssh-3.7p1/contrib/cygwin/ssh-host-config --- ssh-openbsd-2003091600/contrib/cygwin/ssh-host-config 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/contrib/cygwin/ssh-host-config 2002-11-10 02:59:29.000000000 +1100 @@ -0,0 +1,590 @@ +#!/bin/sh +# +# ssh-host-config, Copyright 2000, Red Hat Inc. +# +# This file is part of the Cygwin port of OpenSSH. + +# Subdirectory where the new package is being installed +PREFIX=/usr + +# Directory where the config files are stored +SYSCONFDIR=/etc + +# Subdirectory where an old package might be installed +OLDPREFIX=/usr/local +OLDSYSCONFDIR=${OLDPREFIX}/etc + +progname=$0 +auto_answer="" +port_number=22 + +privsep_configured=no +privsep_used=yes +sshd_in_passwd=no +sshd_in_sam=no + +request() +{ + if [ "${auto_answer}" = "yes" ] + then + return 0 + elif [ "${auto_answer}" = "no" ] + then + return 1 + fi + + answer="" + while [ "X${answer}" != "Xyes" -a "X${answer}" != "Xno" ] + do + echo -n "$1 (yes/no) " + read answer + done + if [ "X${answer}" = "Xyes" ] + then + return 0 + else + return 1 + fi +} + +# Check options + +while : +do + case $# in + 0) + break + ;; + esac + + option=$1 + shift + + case "$option" in + -d | --debug ) + set -x + ;; + + -y | --yes ) + auto_answer=yes + ;; + + -n | --no ) + auto_answer=no + ;; + + -p | --port ) + port_number=$1 + shift + ;; + + *) + 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 " --port -p sshd listens on port n." + echo + exit 1 + ;; + + esac +done + +# Check if running on NT +_sys="`uname -a`" +_nt=`expr "$_sys" : "CYGWIN_NT"` + +# Check for running ssh/sshd processes first. Refuse to do anything while +# some ssh processes are still running + +if ps -ef | grep -v grep | grep -q ssh +then + echo + echo "There are still ssh processes running. Please shut them down first." + echo + exit 1 +fi + +# Check for ${SYSCONFDIR} directory + +if [ -e "${SYSCONFDIR}" -a ! -d "${SYSCONFDIR}" ] +then + echo + echo "${SYSCONFDIR} is existant but not a directory." + echo "Cannot create global configuration files." + echo + exit 1 +fi + +# Create it if necessary + +if [ ! -e "${SYSCONFDIR}" ] +then + mkdir "${SYSCONFDIR}" + if [ ! -e "${SYSCONFDIR}" ] + then + echo + echo "Creating ${SYSCONFDIR} directory failed" + echo + exit 1 + fi +fi + +# Create /var/log and /var/log/lastlog if not already existing + +if [ -f /var/log ] +then + echo "Creating /var/log failed\!" +else + if [ ! -d /var/log ] + then + mkdir -p /var/log + fi + if [ -d /var/log/lastlog ] + then + echo "Creating /var/log/lastlog failed\!" + elif [ ! -f /var/log/lastlog ] + then + cat /dev/null > /var/log/lastlog + fi +fi + +# Create /var/empty file used as chroot jail for privilege separation +if [ -f /var/empty ] +then + echo "Creating /var/empty failed\!" +else + mkdir -p /var/empty + # On NT change ownership of that dir to user "system" + if [ $_nt -gt 0 ] + then + chmod 755 /var/empty + chown system.system /var/empty + fi +fi + +# Check for an old installation in ${OLDPREFIX} unless ${OLDPREFIX} isn't +# the same as ${PREFIX} + +old_install=0 +if [ "${OLDPREFIX}" != "${PREFIX}" ] +then + if [ -f "${OLDPREFIX}/sbin/sshd" ] + then + echo + echo "You seem to have an older installation in ${OLDPREFIX}." + echo + # Check if old global configuration files exist + if [ -f "${OLDSYSCONFDIR}/ssh_host_key" ] + then + if request "Do you want to copy your config files to your new installation?" + then + cp -f ${OLDSYSCONFDIR}/ssh_host_key ${SYSCONFDIR} + cp -f ${OLDSYSCONFDIR}/ssh_host_key.pub ${SYSCONFDIR} + cp -f ${OLDSYSCONFDIR}/ssh_host_dsa_key ${SYSCONFDIR} + cp -f ${OLDSYSCONFDIR}/ssh_host_dsa_key.pub ${SYSCONFDIR} + cp -f ${OLDSYSCONFDIR}/ssh_config ${SYSCONFDIR} + cp -f ${OLDSYSCONFDIR}/sshd_config ${SYSCONFDIR} + fi + fi + if request "Do you want to erase your old installation?" + then + rm -f ${OLDPREFIX}/bin/ssh.exe + rm -f ${OLDPREFIX}/bin/ssh-config + rm -f ${OLDPREFIX}/bin/scp.exe + rm -f ${OLDPREFIX}/bin/ssh-add.exe + rm -f ${OLDPREFIX}/bin/ssh-agent.exe + rm -f ${OLDPREFIX}/bin/ssh-keygen.exe + rm -f ${OLDPREFIX}/bin/slogin + rm -f ${OLDSYSCONFDIR}/ssh_host_key + rm -f ${OLDSYSCONFDIR}/ssh_host_key.pub + rm -f ${OLDSYSCONFDIR}/ssh_host_dsa_key + rm -f ${OLDSYSCONFDIR}/ssh_host_dsa_key.pub + rm -f ${OLDSYSCONFDIR}/ssh_config + rm -f ${OLDSYSCONFDIR}/sshd_config + rm -f ${OLDPREFIX}/man/man1/ssh.1 + rm -f ${OLDPREFIX}/man/man1/scp.1 + rm -f ${OLDPREFIX}/man/man1/ssh-add.1 + rm -f ${OLDPREFIX}/man/man1/ssh-agent.1 + rm -f ${OLDPREFIX}/man/man1/ssh-keygen.1 + rm -f ${OLDPREFIX}/man/man1/slogin.1 + rm -f ${OLDPREFIX}/man/man8/sshd.8 + rm -f ${OLDPREFIX}/sbin/sshd.exe + rm -f ${OLDPREFIX}/sbin/sftp-server.exe + fi + old_install=1 + fi +fi + +# First generate host keys if not already existing + +if [ ! -f "${SYSCONFDIR}/ssh_host_key" ] +then + echo "Generating ${SYSCONFDIR}/ssh_host_key" + ssh-keygen -t rsa1 -f ${SYSCONFDIR}/ssh_host_key -N '' > /dev/null +fi + +if [ ! -f "${SYSCONFDIR}/ssh_host_rsa_key" ] +then + echo "Generating ${SYSCONFDIR}/ssh_host_rsa_key" + ssh-keygen -t rsa -f ${SYSCONFDIR}/ssh_host_rsa_key -N '' > /dev/null +fi + +if [ ! -f "${SYSCONFDIR}/ssh_host_dsa_key" ] +then + echo "Generating ${SYSCONFDIR}/ssh_host_dsa_key" + ssh-keygen -t dsa -f ${SYSCONFDIR}/ssh_host_dsa_key -N '' > /dev/null +fi + +# Check if ssh_config exists. If yes, ask for overwriting + +if [ -f "${SYSCONFDIR}/ssh_config" ] +then + if request "Overwrite existing ${SYSCONFDIR}/ssh_config file?" + then + rm -f "${SYSCONFDIR}/ssh_config" + if [ -f "${SYSCONFDIR}/ssh_config" ] + then + echo "Can't overwrite. ${SYSCONFDIR}/ssh_config is write protected." + fi + fi +fi + +# Create default ssh_config from here script + +if [ ! -f "${SYSCONFDIR}/ssh_config" ] +then + echo "Generating ${SYSCONFDIR}/ssh_config file" + cat > ${SYSCONFDIR}/ssh_config << EOF +# This is the ssh client system-wide configuration file. See +# ssh_config(5) for more information. This file provides defaults for +# users, and the values can be changed in per-user configuration files +# or on the command line. + +# Configuration data is parsed as follows: +# 1. command line options +# 2. user-specific file +# 3. system-wide file +# Any configuration value is only changed the first time it is set. +# Thus, host-specific definitions should be at the beginning of the +# configuration file, and defaults at the end. + +# Site-wide defaults for various options + +# Host * +# ForwardAgent no +# ForwardX11 no +# RhostsAuthentication no +# RhostsRSAAuthentication no +# RSAAuthentication yes +# PasswordAuthentication yes +# BatchMode no +# CheckHostIP yes +# StrictHostKeyChecking ask +# IdentityFile ~/.ssh/identity +# IdentityFile ~/.ssh/id_dsa +# IdentityFile ~/.ssh/id_rsa +# Port 22 +# Protocol 2,1 +# Cipher 3des +# Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc +# EscapeChar ~ +EOF + if [ "$port_number" != "22" ] + then + echo "Host localhost" >> ${SYSCONFDIR}/ssh_config + echo " Port $port_number" >> ${SYSCONFDIR}/ssh_config + fi +fi + +# Check if sshd_config exists. If yes, ask for overwriting + +if [ -f "${SYSCONFDIR}/sshd_config" ] +then + if request "Overwrite existing ${SYSCONFDIR}/sshd_config file?" + then + rm -f "${SYSCONFDIR}/sshd_config" + if [ -f "${SYSCONFDIR}/sshd_config" ] + then + echo "Can't overwrite. ${SYSCONFDIR}/sshd_config is write protected." + fi + else + grep -q UsePrivilegeSeparation ${SYSCONFDIR}/sshd_config && privsep_configured=yes + fi +fi + +# Prior to creating or modifying sshd_config, care for privilege separation + +if [ "$privsep_configured" != "yes" ] +then + if [ $_nt -gt 0 ] + then + echo "Privilege separation is set to yes by default since OpenSSH 3.3." + echo "However, this requires a non-privileged account called 'sshd'." + echo "For more info on privilege separation read /usr/doc/openssh/README.privsep." + echo + if request "Shall privilege separation be used?" + then + privsep_used=yes + grep -q '^sshd:' ${SYSCONFDIR}/passwd && sshd_in_passwd=yes + net user sshd >/dev/null 2>&1 && sshd_in_sam=yes + if [ "$sshd_in_passwd" != "yes" ] + then + if [ "$sshd_in_sam" != "yes" ] + then + echo "Warning: The following function requires administrator privileges!" + if request "Shall this script create a local user 'sshd' on this machine?" + then + dos_var_empty=`cygpath -w /var/empty` + net user sshd /add /fullname:"sshd privsep" "/homedir:$dos_var_empty" /active:no > /dev/null 2>&1 && sshd_in_sam=yes + if [ "$sshd_in_sam" != "yes" ] + then + echo "Warning: Creating the user 'sshd' failed!" + fi + fi + fi + if [ "$sshd_in_sam" != "yes" ] + then + echo "Warning: Can't create user 'sshd' in ${SYSCONFDIR}/passwd!" + echo " Privilege separation set to 'no' again!" + echo " Check your ${SYSCONFDIR}/sshd_config file!" + privsep_used=no + else + mkpasswd -l -u sshd | sed -e 's/bash$/false/' >> ${SYSCONFDIR}/passwd + fi + fi + else + privsep_used=no + fi + else + # On 9x don't use privilege separation. Since security isn't + # available it just adds useless addtional processes. + privsep_used=no + fi +fi + +# Create default sshd_config from here script or modify to add the +# missing privsep configuration option + +if [ ! -f "${SYSCONFDIR}/sshd_config" ] +then + echo "Generating ${SYSCONFDIR}/sshd_config file" + cat > ${SYSCONFDIR}/sshd_config << EOF +# This is the sshd server system-wide configuration file. See +# sshd_config(5) for more information. + +# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin + +# The strategy used for options in the default sshd_config shipped with +# OpenSSH is to specify options with their default value where +# possible, but leave them commented. Uncommented options change a +# default value. + +Port $port_number +#Protocol 2,1 +#ListenAddress 0.0.0.0 +#ListenAddress :: + +# HostKey for protocol version 1 +#HostKey ${SYSCONFDIR}/ssh_host_key +# HostKeys for protocol version 2 +#HostKey ${SYSCONFDIR}/ssh_host_rsa_key +#HostKey ${SYSCONFDIR}/ssh_host_dsa_key + +# Lifetime and size of ephemeral version 1 server key +#KeyRegenerationInterval 3600 +#ServerKeyBits 768 + +# Logging +#obsoletes QuietMode and FascistLogging +#SyslogFacility AUTH +#LogLevel INFO + +# Authentication: + +#LoginGraceTime 120 +#PermitRootLogin yes +# The following setting overrides permission checks on host key files +# and directories. For security reasons set this to "yes" when running +# NT/W2K, NTFS and CYGWIN=ntsec. +StrictModes no + +#RSAAuthentication yes +#PubkeyAuthentication yes +#AuthorizedKeysFile .ssh/authorized_keys + +# rhosts authentication should not be used +#RhostsAuthentication no +# Don't read the user's ~/.rhosts and ~/.shosts files +#IgnoreRhosts yes +# For this to work you will also need host keys in ${SYSCONFDIR}/ssh_known_hosts +#RhostsRSAAuthentication no +# similar for protocol version 2 +#HostbasedAuthentication no +# Change to yes if you don't trust ~/.ssh/known_hosts for +# RhostsRSAAuthentication and HostbasedAuthentication +#IgnoreUserKnownHosts no + +# To disable tunneled clear text passwords, change to no here! +#PasswordAuthentication yes +#PermitEmptyPasswords no + +# Change to no to disable s/key passwords +#ChallengeResponseAuthentication yes + +#X11Forwarding no +#X11DisplayOffset 10 +#X11UseLocalhost yes +#PrintMotd yes +#PrintLastLog yes +#KeepAlive yes +#UseLogin no +UsePrivilegeSeparation $privsep_used +#PermitUserEnvironment no +#Compression yes + +#MaxStartups 10 +# no default banner path +#Banner /some/path +#VerifyReverseMapping no + +# override default of no subsystems +Subsystem sftp /usr/sbin/sftp-server +EOF +elif [ "$privsep_configured" != "yes" ] +then + echo >> ${SYSCONFDIR}/sshd_config + echo "UsePrivilegeSeparation $privsep_used" >> ${SYSCONFDIR}/sshd_config +fi + +# Care for services file +if [ $_nt -gt 0 ] +then + _wservices="${SYSTEMROOT}\\system32\\drivers\\etc\\services" + _wserv_tmp="${SYSTEMROOT}\\system32\\drivers\\etc\\srv.out.$$" +else + _wservices="${WINDIR}\\SERVICES" + _wserv_tmp="${WINDIR}\\SERV.$$" +fi +_services=`cygpath -u "${_wservices}"` +_serv_tmp=`cygpath -u "${_wserv_tmp}"` + +mount -t -f "${_wservices}" "${_services}" +mount -t -f "${_wserv_tmp}" "${_serv_tmp}" + +# Remove sshd 22/port from services +if [ `grep -q 'sshd[ \t][ \t]*22' "${_services}"; echo $?` -eq 0 ] +then + grep -v 'sshd[ \t][ \t]*22' "${_services}" > "${_serv_tmp}" + if [ -f "${_serv_tmp}" ] + then + if mv "${_serv_tmp}" "${_services}" + then + echo "Removing sshd from ${_services}" + else + echo "Removing sshd from ${_services} failed\!" + fi + rm -f "${_serv_tmp}" + else + echo "Removing sshd from ${_services} failed\!" + fi +fi + +# Add ssh 22/tcp and ssh 22/udp to services +if [ `grep -q 'ssh[ \t][ \t]*22' "${_services}"; echo $?` -ne 0 ] +then + awk '{ if ( $2 ~ /^23\/tcp/ ) print "ssh 22/tcp #SSH Remote Login Protocol\nssh 22/udp #SSH Remote Login Protocol"; print $0; }' < "${_services}" > "${_serv_tmp}" + if [ -f "${_serv_tmp}" ] + then + if mv "${_serv_tmp}" "${_services}" + then + echo "Added ssh to ${_services}" + else + echo "Adding ssh to ${_services} failed\!" + fi + rm -f "${_serv_tmp}" + else + echo "Adding ssh to ${_services} failed\!" + fi +fi + +umount "${_services}" +umount "${_serv_tmp}" + +# Care for inetd.conf file +_inetcnf="${SYSCONFDIR}/inetd.conf" +_inetcnf_tmp="${SYSCONFDIR}/inetd.conf.$$" + +if [ -f "${_inetcnf}" ] +then + # Check if ssh service is already in use as sshd + with_comment=1 + grep -q '^[ \t]*sshd' "${_inetcnf}" && with_comment=0 + # Remove sshd line from inetd.conf + if [ `grep -q '^[# \t]*sshd' "${_inetcnf}"; echo $?` -eq 0 ] + then + grep -v '^[# \t]*sshd' "${_inetcnf}" >> "${_inetcnf_tmp}" + if [ -f "${_inetcnf_tmp}" ] + then + if mv "${_inetcnf_tmp}" "${_inetcnf}" + then + echo "Removed sshd from ${_inetcnf}" + else + echo "Removing sshd from ${_inetcnf} failed\!" + fi + rm -f "${_inetcnf_tmp}" + else + echo "Removing sshd from ${_inetcnf} failed\!" + fi + fi + + # Add ssh line to inetd.conf + if [ `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 + echo "Added ssh to ${_inetcnf}" + fi +fi + +# On NT ask if sshd should be installed as service +if [ $_nt -gt 0 ] +then + echo + echo "Do you want to install sshd as service?" + if request "(Say \"no\" if it's already installed as service)" + then + echo + echo "Which value should the environment variable CYGWIN have when" + echo "sshd starts? It's recommended to set at least \"ntsec\" to be" + echo "able to change user context without password." + echo -n "Default is \"binmode ntsec tty\". CYGWIN=" + read _cygwin + [ -z "${_cygwin}" ] && _cygwin="binmode ntsec tty" + if cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd -a -D -e "CYGWIN=${_cygwin}" + then + chown system ${SYSCONFDIR}/ssh* + echo + echo "The service has been installed under LocalSystem account." + fi + fi +fi + +if [ "${old_install}" = "1" ] +then + echo + echo "Note: If you have used sshd as service or from inetd, don't forget to" + echo " change the path to sshd.exe in the service entry or in inetd.conf." +fi + +echo +echo "Host configuration finished. Have fun!" diff -ruN --exclude CVS ssh-openbsd-2003091600/contrib/cygwin/ssh-user-config openssh-3.7p1/contrib/cygwin/ssh-user-config --- ssh-openbsd-2003091600/contrib/cygwin/ssh-user-config 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/contrib/cygwin/ssh-user-config 2003-08-22 18:43:48.000000000 +1000 @@ -0,0 +1,200 @@ +#!/bin/sh +# +# ssh-user-config, Copyright 2000, Red Hat Inc. +# +# This file is part of the Cygwin port of OpenSSH. + +progname=$0 +auto_answer="" +auto_passphrase="no" +passphrase="" + +request() +{ + if [ "${auto_answer}" = "yes" ] + then + return 0 + elif [ "${auto_answer}" = "no" ] + then + return 1 + fi + + answer="" + while [ "X${answer}" != "Xyes" -a "X${answer}" != "Xno" ] + do + echo -n "$1 (yes/no) " + read answer + done + if [ "X${answer}" = "Xyes" ] + then + return 0 + else + return 1 + fi +} + +# Check options + +while : +do + case $# in + 0) + break + ;; + esac + + option=$1 + shift + + case "$option" in + -d | --debug ) + set -x + ;; + + -y | --yes ) + auto_answer=yes + ;; + + -n | --no ) + auto_answer=no + ;; + + -p | --passphrase ) + with_passphrase="yes" + passphrase=$1 + shift + ;; + + *) + echo "usage: ${progname} [OPTION]..." + echo + echo "This script creates an OpenSSH user configuration." + echo + echo "Options:" + echo " --debug -d Enable shell's debug output." + echo " --yes -y Answer all questions with \"yes\" automatically." + echo " --no -n Answer all questions with \"no\" automatically." + echo " --passphrase -p word Use \"word\" as passphrase automatically." + echo + exit 1 + ;; + + esac +done + +# Ask user if user identity should be generated + +if [ ! -f /etc/passwd ] +then + echo '/etc/passwd is nonexistant. Please generate an /etc/passwd file' + echo 'first using mkpasswd. Check if it contains an entry for you and' + echo 'please care for the home directory in your entry as well.' + exit 1 +fi + +uid=`id -u` +pwdhome=`awk -F: '{ if ( $3 == '${uid}' ) print $6; }' < /etc/passwd` + +if [ "X${pwdhome}" = "X" ] +then + echo 'There is no home directory set for you in /etc/passwd.' + echo 'Setting $HOME is not sufficient!' + exit 1 +fi + +if [ ! -d "${pwdhome}" ] +then + echo "${pwdhome} is set in /etc/passwd as your home directory" + echo 'but it is not a valid directory. Cannot create user identity files.' + exit 1 +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! + echo 'Your home directory in /etc/passwd is set to root (/). This is not recommended!' + if request "Would you like to proceed anyway?" + then + pwdhome='' + else + exit 1 + fi +fi + +if [ -e "${pwdhome}/.ssh" -a ! -d "${pwdhome}/.ssh" ] +then + echo "${pwdhome}/.ssh is existant but not a directory. Cannot create user identity files." + exit 1 +fi + +if [ ! -e "${pwdhome}/.ssh" ] +then + mkdir "${pwdhome}/.ssh" + if [ ! -e "${pwdhome}/.ssh" ] + then + echo "Creating users ${pwdhome}/.ssh directory failed" + exit 1 + fi +fi + +if [ ! -f "${pwdhome}/.ssh/identity" ] +then + if request "Shall I create an SSH1 RSA identity file for you?" + then + echo "Generating ${pwdhome}/.ssh/identity" + if [ "${with_passphrase}" = "yes" ] + then + ssh-keygen -t rsa1 -N "${passphrase}" -f "${pwdhome}/.ssh/identity" > /dev/null + else + ssh-keygen -t rsa1 -f "${pwdhome}/.ssh/identity" > /dev/null + fi + if request "Do you want to use this identity to login to this machine?" + then + echo "Adding to ${pwdhome}/.ssh/authorized_keys" + cat "${pwdhome}/.ssh/identity.pub" >> "${pwdhome}/.ssh/authorized_keys" + fi + fi +fi + +if [ ! -f "${pwdhome}/.ssh/id_rsa" ] +then + if request "Shall I create an SSH2 RSA identity file for you? (yes/no) " + then + echo "Generating ${pwdhome}/.ssh/id_rsa" + if [ "${with_passphrase}" = "yes" ] + then + ssh-keygen -t rsa -N "${passphrase}" -f "${pwdhome}/.ssh/id_rsa" > /dev/null + else + ssh-keygen -t rsa -f "${pwdhome}/.ssh/id_rsa" > /dev/null + fi + if request "Do you want to use this identity to login to this machine?" + then + echo "Adding to ${pwdhome}/.ssh/authorized_keys" + cat "${pwdhome}/.ssh/id_rsa.pub" >> "${pwdhome}/.ssh/authorized_keys" + fi + fi +fi + +if [ ! -f "${pwdhome}/.ssh/id_dsa" ] +then + if request "Shall I create an SSH2 DSA identity file for you? (yes/no) " + then + echo "Generating ${pwdhome}/.ssh/id_dsa" + if [ "${with_passphrase}" = "yes" ] + then + ssh-keygen -t dsa -N "${passphrase}" -f "${pwdhome}/.ssh/id_dsa" > /dev/null + else + ssh-keygen -t dsa -f "${pwdhome}/.ssh/id_dsa" > /dev/null + fi + if request "Do you want to use this identity to login to this machine?" + then + echo "Adding to ${pwdhome}/.ssh/authorized_keys" + cat "${pwdhome}/.ssh/id_dsa.pub" >> "${pwdhome}/.ssh/authorized_keys" + fi + fi +fi + +echo +echo "Configuration finished. Have fun!" diff -ruN --exclude CVS ssh-openbsd-2003091600/contrib/findssl.sh openssh-3.7p1/contrib/findssl.sh --- ssh-openbsd-2003091600/contrib/findssl.sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/contrib/findssl.sh 2003-06-24 20:22:10.000000000 +1000 @@ -0,0 +1,159 @@ +#!/bin/sh +# +# 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. +# +# $Id: findssl.sh,v 1.1 2003/06/24 10:22:10 dtucker Exp $ +# 2002-07-27: Initial release. +# 2002-08-04: Added public domain notice. +# 2003-06-24: Incorporated readme, set library paths. First cvs version. +# +# "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 + +# +# Set up conftest C source +# +rm -f findssl.log +cat >conftest.c < +int main(){printf("0x%08xL\n", SSLeay());} +EOD + +# +# Set default library paths if not already set +# +DEFAULT_LIBPATH=/usr/lib:/usr/local/lib +LIBPATH=${LIBPATH:=$DEFAULT_LIBPATH} +LD_LIBRARY_PATH=${LD_LIBRARY_PATH:=$DEFAULT_LIBPATH} +LIBRARY_PATH=${LIBRARY_PATH:=$DEFAULT_LIBPATH} +export LIBPATH LD_LIBRARY_PATH LIBRARY_PATH + +# +# 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 -ruN --exclude CVS ssh-openbsd-2003091600/contrib/gnome-ssh-askpass1.c openssh-3.7p1/contrib/gnome-ssh-askpass1.c --- ssh-openbsd-2003091600/contrib/gnome-ssh-askpass1.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/contrib/gnome-ssh-askpass1.c 2002-09-12 14:49:02.000000000 +1000 @@ -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 +#include +#include +#include +#include +#include + +void +report_failed_grab (void) +{ + GtkWidget *err; + + err = gnome_message_box_new("Could not grab keyboard or mouse.\n" + "A malicious client may be eavesdropping on your session.", + GNOME_MESSAGE_BOX_ERROR, "EXIT", NULL); + gtk_window_set_position(GTK_WINDOW(err), GTK_WIN_POS_CENTER); + gtk_object_set(GTK_OBJECT(err), "type", GTK_WINDOW_POPUP, NULL); + + gnome_dialog_run_and_close(GNOME_DIALOG(err)); +} + +int +passphrase_dialog(char *message) +{ + char *passphrase; + char **messages; + int result, i, grab_server, grab_pointer; + GtkWidget *dialog, *entry, *label; + + grab_server = (getenv("GNOME_SSH_ASKPASS_GRAB_SERVER") != NULL); + grab_pointer = (getenv("GNOME_SSH_ASKPASS_GRAB_POINTER") != NULL); + + dialog = gnome_dialog_new("OpenSSH", GNOME_STOCK_BUTTON_OK, + GNOME_STOCK_BUTTON_CANCEL, NULL); + + messages = g_strsplit(message, "\\n", 0); + if (messages) + for(i = 0; messages[i]; i++) { + label = gtk_label_new(messages[i]); + gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(dialog)->vbox), + label, FALSE, FALSE, 0); + } + + entry = gtk_entry_new(); + gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(dialog)->vbox), entry, FALSE, + FALSE, 0); + gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); + gtk_widget_grab_focus(entry); + + /* Center window and prepare for grab */ + gtk_object_set(GTK_OBJECT(dialog), "type", GTK_WINDOW_POPUP, NULL); + gnome_dialog_set_default(GNOME_DIALOG(dialog), 0); + gtk_window_set_position (GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); + gtk_window_set_policy(GTK_WINDOW(dialog), FALSE, FALSE, TRUE); + gnome_dialog_close_hides(GNOME_DIALOG(dialog), TRUE); + gtk_container_set_border_width(GTK_CONTAINER(GNOME_DIALOG(dialog)->vbox), + GNOME_PAD); + gtk_widget_show_all(dialog); + + /* Grab focus */ + if (grab_server) + XGrabServer(GDK_DISPLAY()); + if (grab_pointer && gdk_pointer_grab(dialog->window, TRUE, 0, + NULL, NULL, GDK_CURRENT_TIME)) + goto nograb; + if (gdk_keyboard_grab(dialog->window, FALSE, GDK_CURRENT_TIME)) + goto nograbkb; + + /* Make close dialog */ + gnome_dialog_editable_enters(GNOME_DIALOG(dialog), GTK_EDITABLE(entry)); + + /* Run dialog */ + result = gnome_dialog_run(GNOME_DIALOG(dialog)); + + /* Ungrab */ + if (grab_server) + XUngrabServer(GDK_DISPLAY()); + if (grab_pointer) + gdk_pointer_ungrab(GDK_CURRENT_TIME); + gdk_keyboard_ungrab(GDK_CURRENT_TIME); + gdk_flush(); + + /* Report passphrase if user selected OK */ + passphrase = gtk_entry_get_text(GTK_ENTRY(entry)); + if (result == 0) + puts(passphrase); + + /* Zero passphrase in memory */ + memset(passphrase, '\0', strlen(passphrase)); + gtk_entry_set_text(GTK_ENTRY(entry), passphrase); + + gnome_dialog_close(GNOME_DIALOG(dialog)); + return (result == 0 ? 0 : -1); + + /* At least one grab failed - ungrab what we got, and report + the failure to the user. Note that XGrabServer() cannot + fail. */ + nograbkb: + gdk_pointer_ungrab(GDK_CURRENT_TIME); + nograb: + if (grab_server) + XUngrabServer(GDK_DISPLAY()); + gnome_dialog_close(GNOME_DIALOG(dialog)); + + report_failed_grab(); + return (-1); +} + +int +main(int argc, char **argv) +{ + char *message; + int result; + + gnome_init("GNOME ssh-askpass", "0.1", argc, argv); + + if (argc == 2) + message = argv[1]; + else + message = "Enter your OpenSSH passphrase:"; + + setvbuf(stdout, 0, _IONBF, 0); + result = passphrase_dialog(message); + + return (result); +} diff -ruN --exclude CVS ssh-openbsd-2003091600/contrib/gnome-ssh-askpass2.c openssh-3.7p1/contrib/gnome-ssh-askpass2.c --- ssh-openbsd-2003091600/contrib/gnome-ssh-askpass2.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/contrib/gnome-ssh-askpass2.c 2003-02-24 11:48:23.000000000 +1100 @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2000-2002 Damien Miller. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* GTK2 support by Nalin Dahyabhai */ + +/* + * This is a simple GNOME SSH passphrase grabber. To use it, set the + * environment variable SSH_ASKPASS to point to the location of + * gnome-ssh-askpass before calling "ssh-add < /dev/null". + * + * There is only two run-time options: if you set the environment variable + * "GNOME_SSH_ASKPASS_GRAB_SERVER=true" then gnome-ssh-askpass will grab + * the X server. If you set "GNOME_SSH_ASKPASS_GRAB_POINTER=true", then the + * pointer will be grabbed too. These may have some benefit to security if + * you don't trust your X server. We grab the keyboard always. + */ + +#define GRAB_TRIES 16 +#define GRAB_WAIT 250 /* milliseconds */ + +/* + * Compile with: + * + * cc -Wall `pkg-config --cflags gtk+-2.0` \ + * gnome-ssh-askpass2.c -o gnome-ssh-askpass \ + * `pkg-config --libs gtk+-2.0` + * + */ + +#include +#include +#include +#include +#include +#include +#include + +static void +report_failed_grab (const char *what) +{ + GtkWidget *err; + + err = gtk_message_dialog_new(NULL, 0, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + "Could not grab %s. " + "A malicious client may be eavesdropping " + "on your session.", what); + gtk_window_set_position(GTK_WINDOW(err), GTK_WIN_POS_CENTER); + gtk_label_set_line_wrap(GTK_LABEL((GTK_MESSAGE_DIALOG(err))->label), + TRUE); + + gtk_dialog_run(GTK_DIALOG(err)); + + gtk_widget_destroy(err); +} + +static void +ok_dialog(GtkWidget *entry, gpointer dialog) +{ + g_return_if_fail(GTK_IS_DIALOG(dialog)); + gtk_dialog_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); +} + +static int +passphrase_dialog(char *message) +{ + const char *failed; + char *passphrase, *local; + int result, grab_tries, grab_server, grab_pointer; + GtkWidget *dialog, *entry; + GdkGrabStatus status; + + grab_server = (getenv("GNOME_SSH_ASKPASS_GRAB_SERVER") != NULL); + grab_pointer = (getenv("GNOME_SSH_ASKPASS_GRAB_POINTER") != NULL); + grab_tries = 0; + + dialog = gtk_message_dialog_new(NULL, 0, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_OK_CANCEL, + "%s", + message); + + entry = gtk_entry_new(); + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), entry, FALSE, + FALSE, 0); + gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); + gtk_widget_grab_focus(entry); + gtk_widget_show(entry); + + gtk_window_set_title(GTK_WINDOW(dialog), "OpenSSH"); + gtk_window_set_position (GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); + gtk_label_set_line_wrap(GTK_LABEL((GTK_MESSAGE_DIALOG(dialog))->label), + TRUE); + + /* Make close dialog */ + gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); + g_signal_connect(G_OBJECT(entry), "activate", + G_CALLBACK(ok_dialog), dialog); + + /* 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 -ruN --exclude CVS ssh-openbsd-2003091600/contrib/hpux/egd openssh-3.7p1/contrib/hpux/egd --- ssh-openbsd-2003091600/contrib/hpux/egd 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/contrib/hpux/egd 2000-10-19 00:45:40.000000000 +1100 @@ -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 -ruN --exclude CVS ssh-openbsd-2003091600/contrib/hpux/egd.rc openssh-3.7p1/contrib/hpux/egd.rc --- ssh-openbsd-2003091600/contrib/hpux/egd.rc 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/contrib/hpux/egd.rc 2000-10-19 00:45:40.000000000 +1100 @@ -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 -ruN --exclude CVS ssh-openbsd-2003091600/contrib/hpux/README openssh-3.7p1/contrib/hpux/README --- ssh-openbsd-2003091600/contrib/hpux/README 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/contrib/hpux/README 2000-12-12 11:08:12.000000000 +1100 @@ -0,0 +1,45 @@ +README for OpenSSH HP-UX contrib files +Kevin Steves + +sshd: configuration file for sshd.rc +sshd.rc: SSH startup script +egd: configuration file for egd.rc +egd.rc: EGD (entropy gathering daemon) startup script + +To install: + +sshd.rc: + +o Verify paths in sshd.rc match your local installation + (WHAT_PATH and WHAT_PID) +o Customize sshd if needed (SSHD_ARGS) +o Install: + + # cp sshd /etc/rc.config.d + # chmod 444 /etc/rc.config.d/sshd + # cp sshd.rc /sbin/init.d + # chmod 555 /sbin/init.d/sshd.rc + # ln -s /sbin/init.d/sshd.rc /sbin/rc1.d/K100sshd + # ln -s /sbin/init.d/sshd.rc /sbin/rc2.d/S900sshd + +egd.rc: + +o Verify egd.pl path in egd.rc matches your local installation + (WHAT_PATH) +o Customize egd if needed (EGD_ARGS and EGD_LOG) +o Add pseudo account: + + # groupadd egd + # useradd -g egd egd + # mkdir -p /etc/opt/egd + # chown egd:egd /etc/opt/egd + # chmod 711 /etc/opt/egd + +o Install: + + # cp egd /etc/rc.config.d + # chmod 444 /etc/rc.config.d/egd + # cp egd.rc /sbin/init.d + # chmod 555 /sbin/init.d/egd.rc + # ln -s /sbin/init.d/egd.rc /sbin/rc1.d/K600egd + # ln -s /sbin/init.d/egd.rc /sbin/rc2.d/S400egd diff -ruN --exclude CVS ssh-openbsd-2003091600/contrib/hpux/sshd openssh-3.7p1/contrib/hpux/sshd --- ssh-openbsd-2003091600/contrib/hpux/sshd 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/contrib/hpux/sshd 2000-09-16 15:39:57.000000000 +1100 @@ -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 -ruN --exclude CVS ssh-openbsd-2003091600/contrib/hpux/sshd.rc openssh-3.7p1/contrib/hpux/sshd.rc --- ssh-openbsd-2003091600/contrib/hpux/sshd.rc 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/contrib/hpux/sshd.rc 2000-09-16 15:39:57.000000000 +1100 @@ -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 -ruN --exclude CVS ssh-openbsd-2003091600/contrib/Makefile openssh-3.7p1/contrib/Makefile --- ssh-openbsd-2003091600/contrib/Makefile 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/contrib/Makefile 2002-09-30 10:44:40.000000000 +1000 @@ -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` + +clean: + rm -f *.o gnome-ssh-askpass1 gnome-ssh-askpass2 gnome-ssh-askpass diff -ruN --exclude CVS ssh-openbsd-2003091600/contrib/README openssh-3.7p1/contrib/README --- ssh-openbsd-2003091600/contrib/README 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/contrib/README 2002-09-30 10:40:41.000000000 +1000 @@ -0,0 +1,60 @@ +Other patches and addons for OpenSSH. Please send submissions to +djm@mindrot.org + +Externally maintained +--------------------- + +SSH Proxy Command -- connect.c + +Shun-ichi GOTO has written a very useful ProxyCommand +which allows the use of outbound SSH from behind a SOCKS4, SOCKS5 or +https CONNECT style proxy server. His page for connect.c has extensive +documentation on its use as well as compiled versions for Win32. + +http://www.taiyo.co.jp/~gotoh/ssh/connect.html + + +X11 SSH Askpass: + +Jim Knoble has written an excellent X11 +passphrase requester. This is highly recommended: + +http://www.ntrnet.net/~jmknoble/software/x11-ssh-askpass/index.html + + +In this directory +----------------- + +ssh-copy-id: + +Phil Hands' shell script to automate the process of adding +your public key to a remote machine's ~/.ssh/authorized_keys file. + +gnome-ssh-askpass[12]: + +A GNOME and Gtk2 passphrase requesters. Use "make gnome-ssh-askpass1" or +"make gnome-ssh-askpass2" to build. + +sshd.pam.generic: + +A generic PAM config file which may be useful on your system. YMMV + +sshd.pam.freebsd: + +A PAM config file which works with FreeBSD's PAM port. Contributed by +Dominik Brettnacher + +mdoc2man.pl: + +Converts mdoc formated manpages into normal manpages. This can be used +on Solaris machines to provide manpages that are not preformated. +Contributed by Mark D. Roth + +redhat: + +RPM spec file and scripts for building Redhat packages + +suse: + +RPM spec file and scripts for building SuSE packages + diff -ruN --exclude CVS ssh-openbsd-2003091600/contrib/redhat/gnome-ssh-askpass.csh openssh-3.7p1/contrib/redhat/gnome-ssh-askpass.csh --- ssh-openbsd-2003091600/contrib/redhat/gnome-ssh-askpass.csh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/contrib/redhat/gnome-ssh-askpass.csh 2002-05-10 12:19:23.000000000 +1000 @@ -0,0 +1 @@ +setenv SSH_ASKPASS /usr/libexec/openssh/gnome-ssh-askpass diff -ruN --exclude CVS ssh-openbsd-2003091600/contrib/redhat/gnome-ssh-askpass.sh openssh-3.7p1/contrib/redhat/gnome-ssh-askpass.sh --- ssh-openbsd-2003091600/contrib/redhat/gnome-ssh-askpass.sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/contrib/redhat/gnome-ssh-askpass.sh 2002-05-10 12:19:23.000000000 +1000 @@ -0,0 +1,2 @@ +SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass +export SSH_ASKPASS diff -ruN --exclude CVS ssh-openbsd-2003091600/contrib/redhat/openssh.spec openssh-3.7p1/contrib/redhat/openssh.spec --- ssh-openbsd-2003091600/contrib/redhat/openssh.spec 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/contrib/redhat/openssh.spec 2003-09-16 16:02:40.000000000 +1000 @@ -0,0 +1,793 @@ +%define ver 3.7p1 +%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} + +# 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 +Source1: http://www.pobox.com/~jmknoble/software/x11-ssh-askpass/x11-ssh-askpass-%{aversion}.tar.gz +License: BSD +Group: Applications/Internet +BuildRoot: %{_tmppath}/%{name}-%{version}-buildroot +Obsoletes: ssh +%if %{build6x} +PreReq: initscripts >= 5.00 +%else +PreReq: initscripts >= 5.20 +%endif +BuildPreReq: perl, openssl-devel, tcp_wrappers +BuildPreReq: /bin/login +%if ! %{build6x} +BuildPreReq: glibc-devel, pam +%else +BuildPreReq: /usr/include/security/pam_appl.h +%endif +%if ! %{no_x11_askpass} +BuildPreReq: XFree86-devel +%endif +%if ! %{no_gnome_askpass} +BuildPreReq: pkgconfig +%endif +%if %{kerberos5} +BuildPreReq: krb5-devel +BuildPreReq: 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 +PreReq: 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 + +%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 \ +%if %{scard} + --with-smartcard \ +%endif +%if %{rescue} + --without-pam --with-md5-passwords \ +%else + --with-pam \ +%endif +%if %{kerberos5} + --with-kerberos5=/usr/kerberos \ +%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* RFC* TODO WARNING* +%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(0644,root,root) %{_mandir}/man8/ssh-keysign.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/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 +* Mon Jun 2 2003 Damien Miller +- Remove noip6 option. This may be controlled at run-time in client config + file using new AddressFamily directive + +* Mon May 12 2003 Damien Miller +- Don't install profile.d scripts when not building with GNOME/GTK askpass + (patch from bet@rahul.net) + +* Wed Oct 01 2002 Damien Miller +- Install ssh-agent setgid nobody to prevent ptrace() key theft attacks + +* Mon Sep 30 2002 Damien Miller +- Use contrib/ Makefile for building askpass programs + +* Fri Jun 21 2002 Damien Miller +- Merge in spec changes from seba@iq.pl (Sebastian Pachuta) +- Add new {ssh,sshd}_config.5 manpages +- Add new ssh-keysign program and remove setuid from ssh client + +* Fri May 10 2002 Damien Miller +- Merge in spec changes from RedHat, reorgansie a little +- Add Privsep user, group and directory + +* Thu Mar 7 2002 Nalin Dahyabhai 3.1p1-2 +- bump and grind (through the build system) + +* Thu Mar 7 2002 Nalin Dahyabhai 3.1p1-1 +- require sharutils for building (mindrot #137) +- require db1-devel only when building for 6.x (#55105), which probably won't + work anyway (3.1 requires OpenSSL 0.9.6 to build), but what the heck +- require pam-devel by file (not by package name) again +- add Markus's patch to compile with OpenSSL 0.9.5a (from + http://bugzilla.mindrot.org/show_bug.cgi?id=141) and apply it if we're + building for 6.x + +* Thu Mar 7 2002 Nalin Dahyabhai 3.1p1-0 +- update to 3.1p1 + +* Tue Mar 5 2002 Nalin Dahyabhai SNAP-20020305 +- update to SNAP-20020305 +- drop debug patch, fixed upstream + +* Wed Feb 20 2002 Nalin Dahyabhai SNAP-20020220 +- update to SNAP-20020220 for testing purposes (you've been warned, if there's + anything to be warned about, gss patches won't apply, I don't mind) + +* Wed Feb 13 2002 Nalin Dahyabhai 3.0.2p1-3 +- add patches from Simon Wilkinson and Nicolas Williams for GSSAPI key + exchange, authentication, and named key support + +* Wed Jan 23 2002 Nalin Dahyabhai 3.0.2p1-2 +- remove dependency on db1-devel, which has just been swallowed up whole + by gnome-libs-devel + +* Sun Dec 29 2001 Nalin Dahyabhai +- adjust build dependencies so that build6x actually works right (fix + from Hugo van der Kooij) + +* Tue Dec 4 2001 Nalin Dahyabhai 3.0.2p1-1 +- update to 3.0.2p1 + +* Fri Nov 16 2001 Nalin Dahyabhai 3.0.1p1-1 +- update to 3.0.1p1 + +* Tue Nov 13 2001 Nalin Dahyabhai +- update to current CVS (not for use in distribution) + +* Thu Nov 8 2001 Nalin Dahyabhai 3.0p1-1 +- merge some of Damien Miller changes from the upstream + 3.0p1 spec file and init script + +* Wed Nov 7 2001 Nalin Dahyabhai +- update to 3.0p1 +- update to x11-ssh-askpass 1.2.4.1 +- change build dependency on a file from pam-devel to the pam-devel package +- replace primes with moduli + +* Thu Sep 27 2001 Nalin Dahyabhai 2.9p2-9 +- incorporate fix from Markus Friedl's advisory for IP-based authorization bugs + +* Thu Sep 13 2001 Bernhard Rosenkraenzer 2.9p2-8 +- Merge changes to rescue build from current sysadmin survival cd + +* Thu Sep 6 2001 Nalin Dahyabhai 2.9p2-7 +- fix scp's server's reporting of file sizes, and build with the proper + preprocessor define to get large-file capable open(), stat(), etc. + (sftp has been doing this correctly all along) (#51827) +- configure without --with-ipv4-default on RHL 7.x and newer (#45987,#52247) +- pull cvs patch to fix support for /etc/nologin for non-PAM logins (#47298) +- mark profile.d scriptlets as config files (#42337) +- refer to Jason Stone's mail for zsh workaround for exit-hanging quasi-bug +- change a couple of log() statements to debug() statements (#50751) +- pull cvs patch to add -t flag to sshd (#28611) +- clear fd_sets correctly (one bit per FD, not one byte per FD) (#43221) + +* Mon Aug 20 2001 Nalin Dahyabhai 2.9p2-6 +- add db1-devel as a BuildPrerequisite (noted by Hans Ecke) + +* Thu Aug 16 2001 Nalin Dahyabhai +- pull cvs patch to fix remote port forwarding with protocol 2 + +* Thu Aug 9 2001 Nalin Dahyabhai +- pull cvs patch to add session initialization to no-pty sessions +- pull cvs patch to not cut off challengeresponse auth needlessly +- refuse to do X11 forwarding if xauth isn't there, handy if you enable + it by default on a system that doesn't have X installed (#49263) + +* Wed Aug 8 2001 Nalin Dahyabhai +- don't apply patches to code we don't intend to build (spotted by Matt Galgoci) + +* Mon Aug 6 2001 Nalin Dahyabhai +- pass OPTIONS correctly to initlog (#50151) + +* Wed Jul 25 2001 Nalin Dahyabhai +- switch to x11-ssh-askpass 1.2.2 + +* Wed Jul 11 2001 Nalin Dahyabhai +- rebuild in new environment + +* Mon Jun 25 2001 Nalin Dahyabhai +- disable the gssapi patch + +* Mon Jun 18 2001 Nalin Dahyabhai +- update to 2.9p2 +- refresh to a new version of the gssapi patch + +* Thu Jun 7 2001 Nalin Dahyabhai +- change Copyright: BSD to License: BSD +- add Markus Friedl's unverified patch for the cookie file deletion problem + so that we can verify it +- drop patch to check if xauth is present (was folded into cookie patch) +- don't apply gssapi patches for the errata candidate +- clear supplemental groups list at startup + +* Fri May 25 2001 Nalin Dahyabhai +- fix an error parsing the new default sshd_config +- add a fix from Markus Friedl (via openssh-unix-dev) for ssh-keygen not + dealing with comments right + +* Thu May 24 2001 Nalin Dahyabhai +- add in Simon Wilkinson's GSSAPI patch to give it some testing in-house, + to be removed before the next beta cycle because it's a big departure + from the upstream version + +* Thu May 3 2001 Nalin Dahyabhai +- finish marking strings in the init script for translation +- modify init script to source /etc/sysconfig/sshd and pass $OPTIONS to sshd + at startup (change merged from openssh.com init script, originally by + Pekka Savola) +- refuse to do X11 forwarding if xauth isn't there, handy if you enable + it by default on a system that doesn't have X installed + +* Wed May 2 2001 Nalin Dahyabhai +- update to 2.9 +- drop various patches that came from or went upstream or to or from CVS + +* Wed Apr 18 2001 Nalin Dahyabhai +- only require initscripts 5.00 on 6.2 (reported by Peter Bieringer) + +* Sun Apr 8 2001 Preston Brown +- remove explicit openssl requirement, fixes builddistro issue +- make initscript stop() function wait until sshd really dead to avoid + races in condrestart + +* Mon Apr 2 2001 Nalin Dahyabhai +- mention that challengereponse supports PAM, so disabling password doesn't + limit users to pubkey and rsa auth (#34378) +- bypass the daemon() function in the init script and call initlog directly, + because daemon() won't start a daemon it detects is already running (like + open connections) +- require the version of openssl we had when we were built + +* Fri Mar 23 2001 Nalin Dahyabhai +- make do_pam_setcred() smart enough to know when to establish creds and + when to reinitialize them +- add in a couple of other fixes from Damien for inclusion in the errata + +* Thu Mar 22 2001 Nalin Dahyabhai +- update to 2.5.2p2 +- call setcred() again after initgroups, because the "creds" could actually + be group memberships + +* Tue Mar 20 2001 Nalin Dahyabhai +- update to 2.5.2p1 (includes endianness fixes in the rijndael implementation) +- don't enable challenge-response by default until we find a way to not + have too many userauth requests (we may make up to six pubkey and up to + three password attempts as it is) +- remove build dependency on rsh to match openssh.com's packages more closely + +* Sat Mar 3 2001 Nalin Dahyabhai +- remove dependency on openssl -- would need to be too precise + +* Fri Mar 2 2001 Nalin Dahyabhai +- rebuild in new environment + +* Mon Feb 26 2001 Nalin Dahyabhai +- Revert the patch to move pam_open_session. +- Init script and spec file changes from Pekka Savola. (#28750) +- Patch sftp to recognize '-o protocol' arguments. (#29540) + +* Thu Feb 22 2001 Nalin Dahyabhai +- Chuck the closing patch. +- Add a trigger to add host keys for protocol 2 to the config file, now that + configuration file syntax requires us to specify it with HostKey if we + specify any other HostKey values, which we do. + +* Tue Feb 20 2001 Nalin Dahyabhai +- Redo patch to move pam_open_session after the server setuid()s to the user. +- Rework the nopam patch to use be picked up by autoconf. + +* Mon Feb 19 2001 Nalin Dahyabhai +- Update for 2.5.1p1. +- Add init script mods from Pekka Savola. +- Tweak the init script to match the CVS contrib script more closely. +- Redo patch to ssh-add to try to adding both identity and id_dsa to also try + adding id_rsa. + +* Fri Feb 16 2001 Nalin Dahyabhai +- Update for 2.5.0p1. +- Use $RPM_OPT_FLAGS instead of -O when building gnome-ssh-askpass +- Resync with parts of Damien Miller's openssh.spec from CVS, including + update of x11 askpass to 1.2.0. +- Only require openssl (don't prereq) because we generate keys in the init + script now. + +* Tue Feb 13 2001 Nalin Dahyabhai +- Don't open a PAM session until we've forked and become the user (#25690). +- Apply Andrew Bartlett's patch for letting pam_authenticate() know which + host the user is attempting a login from. +- Resync with parts of Damien Miller's openssh.spec from CVS. +- Don't expose KbdInt responses in debug messages (from CVS). +- Detect and handle errors in rsa_{public,private}_decrypt (from CVS). + +* Wed Feb 7 2001 Trond Eivind Glomsrxd +- i18n-tweak to initscript. + +* Tue Jan 23 2001 Nalin Dahyabhai +- More gettextizing. +- Close all files after going into daemon mode (needs more testing). +- Extract patch from CVS to handle auth banners (in the client). +- Extract patch from CVS to handle compat weirdness. + +* Fri Jan 19 2001 Nalin Dahyabhai +- Finish with the gettextizing. + +* Thu Jan 18 2001 Nalin Dahyabhai +- Fix a bug in auth2-pam.c (#23877) +- Gettextize the init script. + +* Wed Dec 20 2000 Nalin Dahyabhai +- Incorporate a switch for using PAM configs for 6.x, just in case. + +* Tue Dec 5 2000 Nalin Dahyabhai +- Incorporate Bero's changes for a build specifically for rescue CDs. + +* Wed Nov 29 2000 Nalin Dahyabhai +- Don't treat pam_setcred() failure as fatal unless pam_authenticate() has + succeeded, to allow public-key authentication after a failure with "none" + authentication. (#21268) + +* Tue Nov 28 2000 Nalin Dahyabhai +- Update to x11-askpass 1.1.1. (#21301) +- Don't second-guess fixpaths, which causes paths to get fixed twice. (#21290) + +* Mon Nov 27 2000 Nalin Dahyabhai +- Merge multiple PAM text messages into subsequent prompts when possible when + doing keyboard-interactive authentication. + +* Sun Nov 26 2000 Nalin Dahyabhai +- Disable the built-in MD5 password support. We're using PAM. +- Take a crack at doing keyboard-interactive authentication with PAM, and + enable use of it in the default client configuration so that the client + will try it when the server disallows password authentication. +- Build with debugging flags. Build root policies strip all binaries anyway. + +* Tue Nov 21 2000 Nalin Dahyabhai +- Use DESTDIR instead of %%makeinstall. +- Remove /usr/X11R6/bin from the path-fixing patch. + +* Mon Nov 20 2000 Nalin Dahyabhai +- Add the primes file from the latest snapshot to the main package (#20884). +- Add the dev package to the prereq list (#19984). +- Remove the default path and mimic login's behavior in the server itself. + +* Fri Nov 17 2000 Nalin Dahyabhai +- Resync with conditional options in Damien Miller's .spec file for an errata. +- Change libexecdir from %%{_libexecdir}/ssh to %%{_libexecdir}/openssh. + +* Tue Nov 7 2000 Nalin Dahyabhai +- Update to OpenSSH 2.3.0p1. +- Update to x11-askpass 1.1.0. +- Enable keyboard-interactive authentication. + +* Mon Oct 30 2000 Nalin Dahyabhai +- Update to ssh-askpass-x11 1.0.3. +- Change authentication related messages to be private (#19966). + +* Tue Oct 10 2000 Nalin Dahyabhai +- Patch ssh-keygen to be able to list signatures for DSA public key files + it generates. + +* Thu Oct 5 2000 Nalin Dahyabhai +- Add BuildPreReq on /usr/include/security/pam_appl.h to be sure we always + build PAM authentication in. +- Try setting SSH_ASKPASS if gnome-ssh-askpass is installed. +- Clean out no-longer-used patches. +- Patch ssh-add to try to add both identity and id_dsa, and to error only + when neither exists. + +* Mon Oct 2 2000 Nalin Dahyabhai +- Update x11-askpass to 1.0.2. (#17835) +- Add BuildPreReqs for /bin/login and /usr/bin/rsh so that configure will + always find them in the right place. (#17909) +- Set the default path to be the same as the one supplied by /bin/login, but + add /usr/X11R6/bin. (#17909) +- Try to handle obsoletion of ssh-server more cleanly. Package names + are different, but init script name isn't. (#17865) + +* Wed Sep 6 2000 Nalin Dahyabhai +- Update to 2.2.0p1. (#17835) +- Tweak the init script to allow proper restarting. (#18023) + +* Wed Aug 23 2000 Nalin Dahyabhai +- Update to 20000823 snapshot. +- Change subpackage requirements from %%{version} to %%{version}-%%{release} +- Back out the pipe patch. + +* Mon Jul 17 2000 Nalin Dahyabhai +- Update to 2.1.1p4, which includes fixes for config file parsing problems. +- Move the init script back. +- Add Damien's quick fix for wackiness. + +* Wed Jul 12 2000 Nalin Dahyabhai +- Update to 2.1.1p3, which includes fixes for X11 forwarding and strtok(). + +* Thu Jul 6 2000 Nalin Dahyabhai +- Move condrestart to server postun. +- Move key generation to init script. +- Actually use the right patch for moving the key generation to the init script. +- Clean up the init script a bit. + +* Wed Jul 5 2000 Nalin Dahyabhai +- Fix X11 forwarding, from mail post by Chan Shih-Ping Richard. + +* Sun Jul 2 2000 Nalin Dahyabhai +- Update to 2.1.1p2. +- Use of strtok() considered harmful. + +* Sat Jul 1 2000 Nalin Dahyabhai +- Get the build root out of the man pages. + +* Thu Jun 29 2000 Nalin Dahyabhai +- Add and use condrestart support in the init script. +- Add newer initscripts as a prereq. + +* Tue Jun 27 2000 Nalin Dahyabhai +- Build in new environment (release 2) +- Move -clients subpackage to Applications/Internet group + +* Fri Jun 9 2000 Nalin Dahyabhai +- Update to 2.2.1p1 + +* Sat Jun 3 2000 Nalin Dahyabhai +- Patch to build with neither RSA nor RSAref. +- Miscellaneous FHS-compliance tweaks. +- Fix for possibly-compressed man pages. + +* Wed Mar 15 2000 Damien Miller +- Updated for new location +- Updated for new gnome-ssh-askpass build + +* Sun Dec 26 1999 Damien Miller +- Added Jim Knoble's askpass + +* Mon Nov 15 1999 Damien Miller +- Split subpackages further based on patch from jim knoble + +* Sat Nov 13 1999 Damien Miller +- Added 'Obsoletes' directives + +* Tue Nov 09 1999 Damien Miller +- Use make install +- Subpackages + +* Mon Nov 08 1999 Damien Miller +- Added links for slogin +- Fixed perms on manpages + +* Sat Oct 30 1999 Damien Miller +- Renamed init script + +* Fri Oct 29 1999 Damien Miller +- Back to old binary names + +* Thu Oct 28 1999 Damien Miller +- Use autoconf +- New binary names + +* Wed Oct 27 1999 Damien Miller +- Initial RPMification, based on Jan "Yenya" Kasprzak's spec. diff -ruN --exclude CVS ssh-openbsd-2003091600/contrib/redhat/sshd.init openssh-3.7p1/contrib/redhat/sshd.init --- ssh-openbsd-2003091600/contrib/redhat/sshd.init 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/contrib/redhat/sshd.init 2002-05-10 12:19:23.000000000 +1000 @@ -0,0 +1,154 @@ +#!/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 + +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 + success $"RSA1 key generation" + echo + else + 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 + success $"RSA key generation" + echo + else + 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 + success $"DSA key generation" + echo + else + failure $"DSA key generation" + echo + exit 1 + fi + fi +} + +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 + do_rsa1_keygen + do_rsa_keygen + do_dsa_keygen + + echo -n $"Starting $prog:" + initlog -c "$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 -ruN --exclude CVS ssh-openbsd-2003091600/contrib/redhat/sshd.init.old openssh-3.7p1/contrib/redhat/sshd.init.old --- ssh-openbsd-2003091600/contrib/redhat/sshd.init.old 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/contrib/redhat/sshd.init.old 2002-05-10 12:19:23.000000000 +1000 @@ -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 -ruN --exclude CVS ssh-openbsd-2003091600/contrib/redhat/sshd.pam openssh-3.7p1/contrib/redhat/sshd.pam --- ssh-openbsd-2003091600/contrib/redhat/sshd.pam 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/contrib/redhat/sshd.pam 2002-05-10 12:19:23.000000000 +1000 @@ -0,0 +1,8 @@ +#%PAM-1.0 +auth required /lib/security/pam_stack.so service=system-auth +auth required /lib/security/pam_nologin.so +account required /lib/security/pam_stack.so service=system-auth +password required /lib/security/pam_stack.so service=system-auth +session required /lib/security/pam_stack.so service=system-auth +session required /lib/security/pam_limits.so +session optional /lib/security/pam_console.so diff -ruN --exclude CVS ssh-openbsd-2003091600/contrib/redhat/sshd.pam.old openssh-3.7p1/contrib/redhat/sshd.pam.old --- ssh-openbsd-2003091600/contrib/redhat/sshd.pam.old 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/contrib/redhat/sshd.pam.old 2002-05-10 12:19:24.000000000 +1000 @@ -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 -ruN --exclude CVS ssh-openbsd-2003091600/contrib/solaris/buildpkg.sh openssh-3.7p1/contrib/solaris/buildpkg.sh --- ssh-openbsd-2003091600/contrib/solaris/buildpkg.sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/contrib/solaris/buildpkg.sh 2002-07-20 04:57:57.000000000 +1000 @@ -0,0 +1,379 @@ +#!/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 config.local with your customized options +# +# 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 +SYSVINIT_NAME=opensshd +MAKE=${MAKE:="make"} +SSHDUID=67 # Default privsep uid +SSHDGID=67 # Default privsep gid +# uncomment these next two as needed +#PERMIT_ROOT_LOGIN=no +#X11_FORWARDING=yes +# 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 \ +/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/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 /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 config.local to override the above options +[ -s ./config.local ] && . ./config.local + +## Start by faking root install +echo "Faking root install..." +START=`pwd` +OPENSSHD_IN=`dirname $0`/opensshd.in +FAKE_ROOT=$START/package +[ -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 + +## Fill in some details, like prefix and sysconfdir +for confvar in prefix exec_prefix bindir sbindir libexecdir datadir mandir sysconfdir piddir +do + eval $confvar=`grep "^$confvar=" Makefile | cut -d = -f 2` +done + + +## 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/,.*//'` + +UNAME_S=`uname -s` +case ${UNAME_S} in + SunOS) UNAME_S=Solaris + ARCH=`uname -p` + RCS_D=yes + DEF_MSG="(default: n)" + ;; + *) ARCH=`uname -m` + DEF_MSG="\n" ;; +esac + +## Setup our run level stuff while we are at it. +mkdir -p $FAKE_ROOT${TEST_DIR}/etc/init.d + +## setup our initscript correctly +sed -e "s#%%configDir%%#${sysconfdir}#g" \ + -e "s#%%openSSHDir%%#$prefix#g" \ + -e "s#%%pidDir%%#${piddir}#g" \ + ${OPENSSHD_IN} > $FAKE_ROOT${TEST_DIR}/etc/init.d/${SYSVINIT_NAME} +chmod 744 $FAKE_ROOT${TEST_DIR}/etc/init.d/${SYSVINIT_NAME} + +[ "${PERMIT_ROOT_LOGIN}" = no ] && \ + perl -p -i -e "s/#PermitRootLogin yes/PermitRootLogin no/" \ + $FAKE_ROOT/${sysconfdir}/sshd_config +[ "${X11_FORWARDING}" = yes ] && \ + perl -p -i -e "s/#X11Forwarding no/X11Forwarding yes/" \ + $FAKE_ROOT/${sysconfdir}/sshd_config +# fix PrintMotd +perl -p -i -e "s/#PrintMotd yes/PrintMotd no/" \ + $FAKE_ROOT/${sysconfdir}/sshd_config + +# We don't want to overwrite config files on multiple installs +mv $FAKE_ROOT/${sysconfdir}/ssh_config $FAKE_ROOT/${sysconfdir}/ssh_config.default +mv $FAKE_ROOT/${sysconfdir}/sshd_config $FAKE_ROOT/${sysconfdir}/sshd_config.default +[ -f $FAKE_ROOT/${sysconfdir}/ssh_prng_cmds ] && \ +mv $FAKE_ROOT/${sysconfdir}/ssh_prng_cmds $FAKE_ROOT/${sysconfdir}/ssh_prng_cmds.default + +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 +CATEGORY="Security,application" +BASEDIR=/ +CLASSES="none" +_EOF + +## Build preinstall file +echo "Building preinstall file..." +cat > preinstall << _EOF +#! /sbin/sh +# +[ "\${PRE_INS_STOP}" = "yes" ] && ${TEST_DIR}/etc/init.d/${SYSVINIT_NAME} stop +exit 0 +_EOF + +## Build postinstall file +echo "Building postinstall file..." +cat > postinstall << _EOF +#! /sbin/sh +# +[ -f \${PKG_INSTALL_ROOT}${sysconfdir}/ssh_config ] || \\ + cp -p \${PKG_INSTALL_ROOT}${sysconfdir}/ssh_config.default \\ + \${PKG_INSTALL_ROOT}${sysconfdir}/ssh_config +[ -f \${PKG_INSTALL_ROOT}${sysconfdir}/sshd_config ] || \\ + cp -p \${PKG_INSTALL_ROOT}${sysconfdir}/sshd_config.default \\ + \${PKG_INSTALL_ROOT}${sysconfdir}/sshd_config +[ -f \${PKG_INSTALL_ROOT}${sysconfdir}/ssh_prng_cmds.default ] && { + [ -f \${PKG_INSTALL_ROOT}${sysconfdir}/ssh_prng_cmds ] || \\ + cp -p \${PKG_INSTALL_ROOT}${sysconfdir}/ssh_prng_cmds.default \\ + \${PKG_INSTALL_ROOT}${sysconfdir}/ssh_prng_cmds +} + +# make rc?.d dirs only if we are doing a test install +[ -n "${TEST_DIR}" ] && { + [ "$RCS_D" = yes ] && mkdir -p ${TEST_DIR}/etc/rcS.d + mkdir -p ${TEST_DIR}/etc/rc0.d + mkdir -p ${TEST_DIR}/etc/rc1.d + mkdir -p ${TEST_DIR}/etc/rc2.d +} + +if [ "\${USE_SYM_LINKS}" = yes ] +then + [ "$RCS_D" = yes ] && \ +installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rcS.d/K30${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc0.d/K30${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc1.d/K30${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc2.d/S98${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s +else + [ "$RCS_D" = yes ] && \ +installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rcS.d/K30${SYSVINIT_NAME}=$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc0.d/K30${SYSVINIT_NAME}=$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc1.d/K30${SYSVINIT_NAME}=$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc2.d/S98${SYSVINIT_NAME}=$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l +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 755 root sys + +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 + +if egrep '^[ \t]*UsePrivilegeSeparation[ \t]+no' \${PKG_INSTALL_ROOT}/$sysconfdir/sshd_config >/dev/null +then + echo "UsePrivilegeSeparation disabled in config, not creating PrivSep user" + echo "or group." +else + echo "UsePrivilegeSeparation enabled in config (or defaulting to on)." + + # create group if required + if cut -f1 -d: \${PKG_INSTALL_ROOT}/etc/group | egrep '^'$SSH_PRIVSEP_USER'\$' >/dev/null + then + echo "PrivSep group $SSH_PRIVSEP_USER already exists." + else + # 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_USER." + \$chroot /usr/sbin/groupadd \$sshdgid $SSH_PRIVSEP_USER + fi + + # Create user if 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." + else + # Use uid of 67 if possible + if cut -f3 -d: \${PKG_INSTALL_ROOT}/etc/passwd | egrep '^'$SSHDGID'\$' >/dev/null + then + : + else + sshduid="-u $SSHDUID" + fi + echo "Creating PrivSep user $SSH_PRIVSEP_USER." + \$chroot /usr/sbin/useradd -c 'SSHD PrivSep User' -s /bin/false -g $SSH_PRIVSEP_USER \$sshduid $SSH_PRIVSEP_USER + \$chroot /usr/bin/passwd -l $SSH_PRIVSEP_USER + fi +fi + +[ "\${POST_INS_START}" = "yes" ] && ${TEST_DIR}/etc/init.d/${SYSVINIT_NAME} start +exit 0 +_EOF + +## Build preremove file +echo "Building preremove file..." +cat > preremove << _EOF +#! /sbin/sh +# +${TEST_DIR}/etc/init.d/${SYSVINIT_NAME} stop +exit 0 +_EOF + +## Build request file +echo "Building request file..." +cat > request << _EOF +trap 'exit 3' 15 +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 < space << _EOF +# extra space required by start/stop links added by installf in postinstall +$TEST_DIR/etc/rc0.d/K30${SYSVINIT_NAME} 0 1 +$TEST_DIR/etc/rc1.d/K30${SYSVINIT_NAME} 0 1 +$TEST_DIR/etc/rc2.d/S98${SYSVINIT_NAME} 0 1 +_EOF +[ "$RCS_D" = yes ] && \ +echo "$TEST_DIR/etc/rcS.d/K30${SYSVINIT_NAME} 0 1" >> space + +## Next Build our prototype +echo "Building prototype file..." +cat >mk-proto.awk << _EOF + BEGIN { print "i pkginfo"; print "i preinstall"; \\ + print "i postinstall"; print "i preremove"; \\ + print "i request"; print "i space"; \\ + split("$SYSTEM_DIR",sys_files); } + { + for (dir in sys_files) { if ( \$3 != sys_files[dir] ) + { \$5="root"; \$6="sys"; } + else + { \$4="?"; \$5="?"; \$6="?"; break;} + } } + { print; } +_EOF +find . | egrep -v "prototype|pkginfo|mk-proto.awk" | sort | \ + pkgproto $PROTO_ARGS | nawk -f mk-proto.awk > prototype + +## Step back a directory and now build the package. +echo "Building package.." +cd .. +pkgmk -d ${FAKE_ROOT} -f $FAKE_ROOT/prototype -o +echo | pkgtrans -os ${FAKE_ROOT} ${START}/$PKGNAME-$UNAME_S-$ARCH-$VERSION.pkg +rm -rf $FAKE_ROOT + diff -ruN --exclude CVS ssh-openbsd-2003091600/contrib/solaris/opensshd.in openssh-3.7p1/contrib/solaris/opensshd.in --- ssh-openbsd-2003091600/contrib/solaris/opensshd.in 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/contrib/solaris/opensshd.in 2002-11-14 10:50:07.000000000 +1100 @@ -0,0 +1,82 @@ +#!/sbin/sh +# Donated code that was put under PD license. +# +# Stripped PRNGd out of it for the time being. + +umask 022 + +CAT=/usr/bin/cat +KILL=/usr/bin/kill + +prefix=%%openSSHDir%% +etcdir=%%configDir%% +piddir=%%pidDir%% + +SSHD=$prefix/sbin/sshd +PIDFILE=$piddir/sshd.pid +SSH_KEYGEN=$prefix/bin/ssh-keygen +HOST_KEY_RSA1=$etcdir/ssh_host_key +HOST_KEY_DSA=$etcdir/ssh_host_dsa_key +HOST_KEY_RSA=$etcdir/ssh_host_rsa_key + + +checkkeys() { + if [ ! -f $HOST_KEY_RSA1 ]; then + ${SSH_KEYGEN} -t rsa1 -f ${HOST_KEY_RSA1} -N "" + fi + if [ ! -f $HOST_KEY_DSA ]; then + ${SSH_KEYGEN} -t dsa -f ${HOST_KEY_DSA} -N "" + fi + if [ ! -f $HOST_KEY_RSA ]; then + ${SSH_KEYGEN} -t rsa -f ${HOST_KEY_RSA} -N "" + fi +} + +stop_service() { + if [ -r $PIDFILE -a ! -z ${PIDFILE} ]; then + PID=`${CAT} ${PIDFILE}` + fi + if [ ${PID:=0} -gt 1 -a ! "X$PID" = "X " ]; then + ${KILL} ${PID} + else + echo "Unable to read PID file" + fi +} + +start_service() { + # XXX We really should check if the service is already going, but + # XXX we will opt out at this time. - Bal + + # Check to see if we have keys that need to be made + checkkeys + + # Start SSHD + echo "starting $SSHD... \c" ; $SSHD + + sshd_rc=$? + if [ $sshd_rc -ne 0 ]; then + echo "$0: Error ${sshd_rc} starting ${SSHD}... bailing." + exit $sshd_rc + fi + echo done. +} + +case $1 in + +'start') + start_service + ;; + +'stop') + stop_service + ;; + +'restart') + stop_service + start_service + ;; + +*) + echo "$0: usage: $0 {start|stop|restart}" + ;; +esac diff -ruN --exclude CVS ssh-openbsd-2003091600/contrib/solaris/README openssh-3.7p1/contrib/solaris/README --- ssh-openbsd-2003091600/contrib/solaris/README 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/contrib/solaris/README 2002-03-12 15:55:54.000000000 +1100 @@ -0,0 +1,24 @@ +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 contrib/solaris/buildpkg.sh for the configurable options. +4. ./contrib/solaris/buildpkg.sh + +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 -ruN --exclude CVS ssh-openbsd-2003091600/contrib/ssh-copy-id openssh-3.7p1/contrib/ssh-copy-id --- ssh-openbsd-2003091600/contrib/ssh-copy-id 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/contrib/ssh-copy-id 2003-01-03 14:34:07.000000000 +1100 @@ -0,0 +1,50 @@ +#!/bin/sh + +# Shell script to install your identity.pub 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/identity.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" ; 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 ] ; then + GET_ID="$GET_ID ssh-add -L" + fi +fi + +if [ -z "`eval $GET_ID`" -a -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 + +{ eval "$GET_ID" ; } | ssh $1 "umask 077; test -d .ssh || mkdir .ssh ; cat >> .ssh/authorized_keys" + +cat < + +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 identity.pub 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 (presumably +using a login password, so password authentication should be enabled, +unless you've done some clever use of multiple identities) +.PP +It also changes the permissions of the remote user's home, +.BR ~/.ssh , +and +.B ~/.ssh/authorized_keys +to remove group writability (which would otherwise prevent you from logging in, if the remote +.B sshd +has +.B StrictModes +set in its configuration). +.PP +If the +.B -i +option is given then the identity file (defaults to +.BR ~/.ssh/identity.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 "SEE ALSO" +.BR ssh (1), +.BR ssh-agent (1), +.BR sshd (8) diff -ruN --exclude CVS ssh-openbsd-2003091600/contrib/sshd.pam.freebsd openssh-3.7p1/contrib/sshd.pam.freebsd --- ssh-openbsd-2003091600/contrib/sshd.pam.freebsd 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/contrib/sshd.pam.freebsd 2000-03-15 12:25:06.000000000 +1100 @@ -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 -ruN --exclude CVS ssh-openbsd-2003091600/contrib/sshd.pam.generic openssh-3.7p1/contrib/sshd.pam.generic --- ssh-openbsd-2003091600/contrib/sshd.pam.generic 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/contrib/sshd.pam.generic 2000-03-15 12:25:06.000000000 +1100 @@ -0,0 +1,8 @@ +#%PAM-1.0 +auth required /lib/security/pam_unix.so shadow nodelay +auth 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 -ruN --exclude CVS ssh-openbsd-2003091600/contrib/suse/openssh.spec openssh-3.7p1/contrib/suse/openssh.spec --- ssh-openbsd-2003091600/contrib/suse/openssh.spec 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/contrib/suse/openssh.spec 2003-09-16 13:59:43.000000000 +1000 @@ -0,0 +1,199 @@ +Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation +Name: openssh +Version: 3.7p1 +URL: http://www.openssh.com/ +Release: 1 +Source0: openssh-%{version}.tar.gz +Copyright: BSD +Group: Applications/Internet +BuildRoot: /tmp/openssh-%{version}-buildroot +PreReq: openssl +Obsoletes: ssh +# +# (Build[ing] Prereq[uisites] only work for RPM 2.95 and newer.) +# building prerequisites -- stuff for +# OpenSSL (openssl-devel), +# TCP Wrappers (nkitb), +# and Gnome (glibdev, gtkdev, and gnlibsd) +# +BuildPrereq: openssl +BuildPrereq: nkitb +BuildPrereq: glibdev +BuildPrereq: gtkdev +BuildPrereq: gnlibsd + +%description +Ssh (Secure Shell) 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. Additionally, this package contains the GNOME +passphrase dialog. + +%changelog +* Mon Jun 12 2000 Damien Miller +- Glob manpages to catch compressed files +* Wed Mar 15 2000 Damien Miller +- Updated for new location +- Updated for new gnome-ssh-askpass build +* Sun Dec 26 1999 Chris Saia +- Made symlink to gnome-ssh-askpass called ssh-askpass +* Wed Nov 24 1999 Chris Saia +- Removed patches that included /etc/pam.d/sshd, /sbin/init.d/rc.sshd, and + /var/adm/fillup-templates/rc.config.sshd, since Damien merged these into + his released tarfile +- Changed permissions on ssh_config in the install procedure to 644 from 600 + even though it was correct in the %files section and thus right in the RPMs +- Postinstall script for the server now only prints "Generating SSH host + key..." if we need to actually do this, in order to eliminate a confusing + message if an SSH host key is already in place +- Marked all manual pages as %doc(umentation) +* Mon Nov 22 1999 Chris Saia +- Added flag to configure daemon with TCP Wrappers support +- Added building prerequisites (works in RPM 3.0 and newer) +* Thu Nov 18 1999 Chris Saia +- Made this package correct for SuSE. +- Changed instances of pam_pwdb.so to pam_unix.so, since it works more properly + with SuSE, and lib_pwdb.so isn't installed by default. +* Mon Nov 15 1999 Damien Miller +- Split subpackages further based on patch from jim knoble +* Sat Nov 13 1999 Damien Miller +- Added 'Obsoletes' directives +* Tue Nov 09 1999 Damien Miller +- Use make install +- Subpackages +* Mon Nov 08 1999 Damien Miller +- Added links for slogin +- Fixed perms on manpages +* Sat Oct 30 1999 Damien Miller +- Renamed init script +* Fri Oct 29 1999 Damien Miller +- Back to old binary names +* Thu Oct 28 1999 Damien Miller +- Use autoconf +- New binary names +* Wed Oct 27 1999 Damien Miller +- Initial RPMification, based on Jan "Yenya" Kasprzak's spec. + +%prep + +%setup -q + +%build +CFLAGS="$RPM_OPT_FLAGS" \ +./configure --prefix=/usr \ + --sysconfdir=/etc/ssh \ + --datadir=/usr/share/openssh \ + --with-pam \ + --with-gnome-askpass \ + --with-tcp-wrappers \ + --with-ipv4-default \ + --libexecdir=/usr/lib/ssh +make + +cd contrib +gcc -O -g `gnome-config --cflags gnome gnomeui` \ + gnome-ssh-askpass.c -o gnome-ssh-askpass \ + `gnome-config --libs gnome gnomeui` +cd .. + +%install +rm -rf $RPM_BUILD_ROOT +make install DESTDIR=$RPM_BUILD_ROOT/ +install -d $RPM_BUILD_ROOT/etc/ssh/ +install -d $RPM_BUILD_ROOT/etc/pam.d/ +install -d $RPM_BUILD_ROOT/sbin/init.d/ +install -d $RPM_BUILD_ROOT/var/adm/fillup-templates +install -d $RPM_BUILD_ROOT/usr/lib/ssh +install -m644 contrib/sshd.pam.generic $RPM_BUILD_ROOT/etc/pam.d/sshd +install -m744 contrib/suse/rc.sshd $RPM_BUILD_ROOT/sbin/init.d/sshd +ln -s ../../sbin/init.d/sshd $RPM_BUILD_ROOT/usr/sbin/rcsshd +install -s contrib/gnome-ssh-askpass $RPM_BUILD_ROOT/usr/lib/ssh/gnome-ssh-askpass +ln -s gnome-ssh-askpass $RPM_BUILD_ROOT/usr/lib/ssh/ssh-askpass +install -m744 contrib/suse/rc.config.sshd \ + $RPM_BUILD_ROOT/var/adm/fillup-templates + +%clean +rm -rf $RPM_BUILD_ROOT + +%post +if [ "$1" = 1 ]; then + echo "Creating SSH stop/start scripts in the rc directories..." + ln -s ../sshd /sbin/init.d/rc2.d/K20sshd + ln -s ../sshd /sbin/init.d/rc2.d/S20sshd + ln -s ../sshd /sbin/init.d/rc3.d/K20sshd + ln -s ../sshd /sbin/init.d/rc3.d/S20sshd +fi +echo "Updating /etc/rc.config..." +if [ -x /bin/fillup ] ; then + /bin/fillup -q -d = etc/rc.config var/adm/fillup-templates/rc.config.sshd +else + echo "ERROR: fillup not found. This should NOT happen in SuSE Linux." + echo "Update /etc/rc.config by hand from the following template file:" + echo " /var/adm/fillup-templates/rc.config.sshd" +fi +if [ ! -f /etc/ssh/ssh_host_key -o ! -s /etc/ssh/ssh_host_key ]; then + echo "Generating SSH host key..." + /usr/bin/ssh-keygen -b 1024 -f /etc/ssh/ssh_host_key -N '' >&2 +fi +if [ ! -f /etc/ssh/ssh_host_dsa_key -o ! -s /etc/ssh/ssh_host_dsa_key ]; then + echo "Generating SSH DSA host key..." + /usr/bin/ssh-keygen -d -f /etc/ssh/ssh_host_dsa_key -N '' >&2 +fi +if test -r /var/run/sshd.pid +then + echo "Restarting the running SSH daemon..." + /usr/sbin/rcsshd restart >&2 +fi + +%preun +if [ "$1" = 0 ] +then + echo "Stopping the SSH daemon..." + /usr/sbin/rcsshd stop >&2 + echo "Removing SSH stop/start scripts from the rc directories..." + rm /sbin/init.d/rc2.d/K20sshd + rm /sbin/init.d/rc2.d/S20sshd + rm /sbin/init.d/rc3.d/K20sshd + rm /sbin/init.d/rc3.d/S20sshd +fi + +%files +%defattr(-,root,root) +%doc ChangeLog OVERVIEW README* +%doc RFC.nroff TODO CREDITS LICENCE +%attr(0755,root,root) %dir /etc/ssh +%attr(0644,root,root) %config /etc/ssh/ssh_config +%attr(0600,root,root) %config /etc/ssh/sshd_config +%attr(0600,root,root) %config /etc/ssh/moduli +%attr(0644,root,root) %config /etc/pam.d/sshd +%attr(0755,root,root) %config /sbin/init.d/sshd +%attr(0755,root,root) /usr/bin/ssh-keygen +%attr(0755,root,root) /usr/bin/scp +%attr(4755,root,root) /usr/bin/ssh +%attr(-,root,root) /usr/bin/slogin +%attr(0755,root,root) /usr/bin/ssh-agent +%attr(0755,root,root) /usr/bin/ssh-add +%attr(0755,root,root) /usr/bin/ssh-keyscan +%attr(0755,root,root) /usr/bin/sftp +%attr(0755,root,root) /usr/sbin/sshd +%attr(-,root,root) /usr/sbin/rcsshd +%attr(0755,root,root) %dir /usr/lib/ssh +%attr(0755,root,root) /usr/lib/ssh/ssh-askpass +%attr(0755,root,root) /usr/lib/ssh/gnome-ssh-askpass +%attr(0644,root,root) %doc /usr/man/man1/scp.1* +%attr(0644,root,root) %doc /usr/man/man1/ssh.1* +%attr(-,root,root) %doc /usr/man/man1/slogin.1* +%attr(0644,root,root) %doc /usr/man/man1/ssh-agent.1* +%attr(0644,root,root) %doc /usr/man/man1/ssh-add.1* +%attr(0644,root,root) %doc /usr/man/man1/ssh-keygen.1* +%attr(0644,root,root) %doc /usr/man/man8/sshd.8* +%attr(0644,root,root) /var/adm/fillup-templates/rc.config.sshd + diff -ruN --exclude CVS ssh-openbsd-2003091600/contrib/suse/rc.config.sshd openssh-3.7p1/contrib/suse/rc.config.sshd --- ssh-openbsd-2003091600/contrib/suse/rc.config.sshd 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/contrib/suse/rc.config.sshd 2000-03-15 12:25:07.000000000 +1100 @@ -0,0 +1,5 @@ +# +# Start the Secure Shell (SSH) Daemon? +# +START_SSHD="yes" + diff -ruN --exclude CVS ssh-openbsd-2003091600/contrib/suse/rc.sshd openssh-3.7p1/contrib/suse/rc.sshd --- ssh-openbsd-2003091600/contrib/suse/rc.sshd 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/contrib/suse/rc.sshd 2000-03-15 12:25:07.000000000 +1100 @@ -0,0 +1,80 @@ +#! /bin/sh +# Copyright (c) 1995-1998 SuSE GmbH Nuernberg, Germany. +# +# Author: Chris Saia +# +# /sbin/init.d/sshd +# +# and symbolic its link +# +# /sbin/rcsshd +# + +. /etc/rc.config + +# Determine the base and follow a runlevel link name. +base=${0##*/} +link=${base#*[SK][0-9][0-9]} + +# Force execution if not called by a runlevel directory. +test $link = $base && START_SSHD=yes +test "$START_SSHD" = yes || exit 0 + +# The echo return value for success (defined in /etc/rc.config). +return=$rc_done +case "$1" in + start) + echo -n "Starting service sshd" + ## Start daemon with startproc(8). If this fails + ## the echo return value is set appropriate. + + startproc /usr/sbin/sshd || return=$rc_failed + + echo -e "$return" + ;; + stop) + echo -n "Stopping service sshd" + ## Stop daemon with killproc(8) and if this fails + ## set echo the echo return value. + + killproc -TERM /usr/sbin/sshd || return=$rc_failed + + echo -e "$return" + ;; + restart) + ## If first returns OK call the second, if first or + ## second command fails, set echo return value. + $0 stop && $0 start || return=$rc_failed + ;; + reload) + ## Choose ONE of the following two cases: + + ## First possibility: A few services accepts a signal + ## to reread the (changed) configuration. + + echo -n "Reload service sshd" + killproc -HUP /usr/sbin/sshd || return=$rc_failed + echo -e "$return" + ;; + status) + echo -n "Checking for service sshd" + ## Check status with checkproc(8), if process is running + ## checkproc will return with exit status 0. + + checkproc /usr/sbin/sshd && echo OK || echo No process + ;; + 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 /var/run/sshd.pid && echo reload + ;; + *) + echo "Usage: $0 {start|stop|status|restart|reload[|probe]}" + exit 1 + ;; +esac + +# Inform the caller not only verbosely and set an exit status. +test "$return" = "$rc_done" || exit 1 +exit 0 diff -ruN --exclude CVS ssh-openbsd-2003091600/crc32.c openssh-3.7p1/crc32.c --- ssh-openbsd-2003091600/crc32.c 2003-03-26 16:04:03.000000000 +1100 +++ openssh-3.7p1/crc32.c 2003-02-25 10:22:36.000000000 +1100 @@ -23,8 +23,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - -#include +#include "includes.h" #include "crc32.h" static const u_int32_t crc32tab[] = { diff -ruN --exclude CVS ssh-openbsd-2003091600/CREDITS openssh-3.7p1/CREDITS --- ssh-openbsd-2003091600/CREDITS 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/CREDITS 2003-09-07 12:34:54.000000000 +1000 @@ -0,0 +1,98 @@ +Tatu Ylonen - Creator of SSH + +Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, +Theo de Raadt, and Dug Song - Creators of OpenSSH + +Alain St-Denis - Irix fix +Alexandre Oliva - AIX fixes +Andre Lucas - new login code, many fixes +Andreas Steinmetz - Shadow password expiry support +Andrew McGill - SCO fixes +Andrew Morgan - PAM bugfixes +Andrew Stribblehill - Bugfixes +Andy Sloane - bugfixes +Aran Cox - SCO bugfixes +Arkadiusz Miskiewicz - IPv6 compat fixes +Ben Lindstrom - NeXT support +Ben Taylor - Solaris debugging and fixes +Bratislav ILICH - Configure fix +Charles Levert - SunOS 4 & bug fixes +Chip Salzenberg - Assorted patches +Chris Adams - OSF SIA support +Chris Saia - SuSE packaging +Chris, the Young One - Password auth fixes +Christos Zoulas - Autoconf fixes +Chun-Chung Chen - RPM fixes +Corinna Vinschen - Cygwin support +Dan Brosemer - Autoconf support, build fixes +Darren Hall - AIX patches +Darren Tucker - AIX BFF package scripts +David Agraz - Build fixes +David Del Piero - bug fixes +David Hesprich - Configure fixes +David Rankin - libwrap, AIX, NetBSD fixes +Ed Eden - configure fixes +Garrick James - configure fixes +Gary E. Miller - SCO support +Ged Lodder - HPUX fixes and enhancements +Gert Doering - bug and portability fixes +HARUYAMA Seigo - Translations & doc fixes +Hideaki YOSHIFUJI - IPv6 and bug fixes +Hiroshi Takekawa - Configure fixes +Holger Trapp - KRB4/AFS config patch +IWAMURO Motonori - bugfixes +Jani Hakala - Patches +Jarno Huuskonen - Bugfixes +Jim Knoble - Many patches +Jonchen (email unknown) - the original author of PAM support of SSH +Juergen Keil - scp bugfixing +KAMAHARA Junzo - Configure fixes +Kees Cook - scp fixes +Kenji Miyake - Configure fixes +Kevin Cawlfield - AIX fixes. +Kevin O'Connor - RSAless operation +Kevin Steves - HP support, bugfixes, improvements +Kiyokazu SUTO - Bugfixes +Larry Jones - Bugfixes +Lutz Jaenicke - Bugfixes +Marc G. Fournier - Solaris patches +Mark D. Baushke - bug fixes +Martin Johansson - Linux fixes +Mark D. Roth - Features, bug fixes +Mark Miller - Bugfixes +Matt Richards - AIX patches +Michael Stone - Irix enhancements +Nakaji Hiroyuki - Sony News-OS patch +Nalin Dahyabhai - PAM environment patch +Nate Itkin - SunOS 4.1.x fixes +Niels Kristian Bech Jensen - Assorted patches +Pavel Kankovsky - Security fixes +Pavel Troller - Bugfixes +Pekka Savola - Bugfixes +Peter Kocks - Makefile fixes +Peter Stuge - mdoc2man.awk script +Phil Hands - Debian scripts, assorted patches +Phil Karn - Autoconf fixes +Philippe WILLEM - Bugfixes +Phill Camp - login code fix +Rip Loomis - Solaris package support, fixes +Roumen Petrov - Compile & configure fixes +SAKAI Kiyotaka - Multiple bugfixes +Simon Wilkinson - PAM fixes, Compat with MIT KrbV +Solar Designer - many patches and technical assistance +Svante Signell - Bugfixes +Thomas Neumann - Shadow passwords +Tim Rice - Portability & SCO fixes +Tobias Oetiker - Bugfixes +Tom Bertelson's - AIX auth fixes +Tor-Ake Fransson - AIX support +Tudor Bosman - MD5 password support +Udo Schweigert - ReliantUNIX support +Zack Weinberg - GNOME askpass enhancement + +Apologies to anyone I have missed. + +Damien Miller + +$Id: CREDITS,v 1.74 2003/09/07 02:34:54 dtucker Exp $ + diff -ruN --exclude CVS ssh-openbsd-2003091600/.cvsignore openssh-3.7p1/.cvsignore --- ssh-openbsd-2003091600/.cvsignore 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/.cvsignore 2002-06-26 19:24:56.000000000 +1000 @@ -0,0 +1,24 @@ +ssh +scp +sshd +ssh-add +ssh-keygen +ssh-keyscan +ssh-keysign +ssh-agent +sftp-server +sftp +configure +config.h.in +config.h +config.status +config.cache +config.log +stamp-h.in +Makefile +ssh_prng_cmds +*.out +*.0 +buildit.sh +autom4te.cache +ssh-rand-helper diff -ruN --exclude CVS ssh-openbsd-2003091600/defines.h openssh-3.7p1/defines.h --- ssh-openbsd-2003091600/defines.h 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/defines.h 2003-09-16 11:52:19.000000000 +1000 @@ -0,0 +1,605 @@ +/* + * 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.103 2003/09/16 01:52:19 dtucker Exp $ */ + + +/* Constants */ + +#ifndef SHUT_RDWR +enum +{ + SHUT_RD = 0, /* No more receptions. */ + SHUT_WR, /* No more transmissions. */ + SHUT_RDWR /* No more receptions or transmissions. */ +}; +# define SHUT_RD SHUT_RD +# define SHUT_WR SHUT_WR +# define SHUT_RDWR SHUT_RDWR +#endif + +#ifndef IPTOS_LOWDELAY +# define IPTOS_LOWDELAY 0x10 +# define IPTOS_THROUGHPUT 0x08 +# define IPTOS_RELIABILITY 0x04 +# define IPTOS_LOWCOST 0x02 +# define IPTOS_MINCOST IPTOS_LOWCOST +#endif /* IPTOS_LOWDELAY */ + +#ifndef MAXPATHLEN +# ifdef PATH_MAX +# define MAXPATHLEN PATH_MAX +# else /* PATH_MAX */ +# define MAXPATHLEN 64 /* Should be safe */ +# endif /* PATH_MAX */ +#endif /* MAXPATHLEN */ + +#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 + +#ifndef O_NONBLOCK /* Non Blocking Open */ +# define O_NONBLOCK 00004 +#endif + +#ifndef S_ISDIR +# define S_ISDIR(mode) (((mode) & (_S_IFMT)) == (_S_IFDIR)) +#endif /* S_ISDIR */ + +#ifndef S_ISREG +# define S_ISREG(mode) (((mode) & (_S_IFMT)) == (_S_IFREG)) +#endif /* S_ISREG */ + +#ifndef S_ISLNK +# define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK) +#endif /* S_ISLNK */ + +#ifndef S_IXUSR +# define S_IXUSR 0000100 /* execute/search permission, */ +# define S_IXGRP 0000010 /* execute/search permission, */ +# define S_IXOTH 0000001 /* execute/search permission, */ +# define _S_IWUSR 0000200 /* write permission, */ +# define S_IWUSR _S_IWUSR /* write permission, owner */ +# define S_IWGRP 0000020 /* write permission, group */ +# define S_IWOTH 0000002 /* write permission, other */ +# define S_IRUSR 0000400 /* read permission, owner */ +# define S_IRGRP 0000040 /* read permission, group */ +# define S_IROTH 0000004 /* read permission, other */ +# define S_IRWXU 0000700 /* read, write, execute */ +# define S_IRWXG 0000070 /* read, write, execute */ +# define S_IRWXO 0000007 /* read, write, execute */ +#endif /* S_IXUSR */ + +#if !defined(MAP_ANON) && defined(MAP_ANONYMOUS) +#define MAP_ANON MAP_ANONYMOUS +#endif + +#ifndef MAP_FAILED +# define MAP_FAILED ((void *)-1) +#endif + +/* *-*-nto-qnx doesn't define this constant in the system headers */ +#ifdef MISSING_NFDBITS +# define NFDBITS (8 * sizeof(unsigned long)) +#endif + +/* +SCO Open Server 3 has INADDR_LOOPBACK defined in rpc/rpc.h but +including rpc/rpc.h breaks Solaris 6 +*/ +#ifndef INADDR_LOOPBACK +#define INADDR_LOOPBACK ((u_long)0x7f000001) +#endif + +/* Types */ + +/* If sys/types.h does not supply intXX_t, supply them ourselves */ +/* (or die trying) */ + + +#ifndef HAVE_U_INT +typedef unsigned int u_int; +#endif + +#ifndef HAVE_INTXX_T +# if (SIZEOF_CHAR == 1) +typedef char int8_t; +# else +# error "8 bit int type not found." +# endif +# if (SIZEOF_SHORT_INT == 2) +typedef short int int16_t; +# else +# ifdef _UNICOS +# if (SIZEOF_SHORT_INT == 4) +typedef short int16_t; +# else +typedef long int16_t; +# endif +# else +# error "16 bit int type not found." +# endif /* _UNICOS */ +# endif +# if (SIZEOF_INT == 4) +typedef int int32_t; +# else +# ifdef _UNICOS +typedef long int32_t; +# else +# error "32 bit int type not found." +# endif /* _UNICOS */ +# endif +#endif + +/* If sys/types.h does not supply u_intXX_t, supply them ourselves */ +#ifndef HAVE_U_INTXX_T +# ifdef HAVE_UINTXX_T +typedef uint8_t u_int8_t; +typedef uint16_t u_int16_t; +typedef uint32_t u_int32_t; +# define HAVE_U_INTXX_T 1 +# else +# if (SIZEOF_CHAR == 1) +typedef unsigned char u_int8_t; +# else +# error "8 bit int type not found." +# endif +# if (SIZEOF_SHORT_INT == 2) +typedef unsigned short int u_int16_t; +# else +# ifdef _UNICOS +# if (SIZEOF_SHORT_INT == 4) +typedef unsigned short u_int16_t; +# else +typedef unsigned long u_int16_t; +# endif +# else +# error "16 bit int type not found." +# endif +# endif +# if (SIZEOF_INT == 4) +typedef unsigned int u_int32_t; +# else +# ifdef _UNICOS +typedef unsigned long u_int32_t; +# else +# error "32 bit int type not found." +# endif +# endif +# endif +#define __BIT_TYPES_DEFINED__ +#endif + +/* 64-bit types */ +#ifndef HAVE_INT64_T +# if (SIZEOF_LONG_INT == 8) +typedef long int int64_t; +# else +# if (SIZEOF_LONG_LONG_INT == 8) +typedef long long int int64_t; +# endif +# endif +#endif +#ifndef HAVE_U_INT64_T +# if (SIZEOF_LONG_INT == 8) +typedef unsigned long int u_int64_t; +# else +# if (SIZEOF_LONG_LONG_INT == 8) +typedef unsigned long long int u_int64_t; +# endif +# endif +#endif + +#ifndef HAVE_U_CHAR +typedef unsigned char u_char; +# define HAVE_U_CHAR +#endif /* HAVE_U_CHAR */ + +#ifndef SIZE_T_MAX +#define SIZE_T_MAX ULONG_MAX +#endif /* SIZE_T_MAX */ + +#ifndef HAVE_SIZE_T +typedef unsigned int size_t; +# define HAVE_SIZE_T +#endif /* HAVE_SIZE_T */ + +#ifndef HAVE_SSIZE_T +typedef int ssize_t; +# define HAVE_SSIZE_T +#endif /* HAVE_SSIZE_T */ + +#ifndef HAVE_CLOCK_T +typedef long clock_t; +# define HAVE_CLOCK_T +#endif /* HAVE_CLOCK_T */ + +#ifndef HAVE_SA_FAMILY_T +typedef int sa_family_t; +# define HAVE_SA_FAMILY_T +#endif /* HAVE_SA_FAMILY_T */ + +#ifndef HAVE_PID_T +typedef int pid_t; +# define HAVE_PID_T +#endif /* HAVE_PID_T */ + +#ifndef HAVE_SIG_ATOMIC_T +typedef int sig_atomic_t; +# define HAVE_SIG_ATOMIC_T +#endif /* HAVE_SIG_ATOMIC_T */ + +#ifndef HAVE_MODE_T +typedef int mode_t; +# define HAVE_MODE_T +#endif /* HAVE_MODE_T */ + +#if !defined(HAVE_SS_FAMILY_IN_SS) && defined(HAVE___SS_FAMILY_IN_SS) +# define ss_family __ss_family +#endif /* !defined(HAVE_SS_FAMILY_IN_SS) && defined(HAVE_SA_FAMILY_IN_SS) */ + +#ifndef HAVE_SYS_UN_H +struct sockaddr_un { + short sun_family; /* AF_UNIX */ + char sun_path[108]; /* path name (gag) */ +}; +#endif /* HAVE_SYS_UN_H */ + +#if defined(BROKEN_SYS_TERMIO_H) && !defined(_STRUCT_WINSIZE) +#define _STRUCT_WINSIZE +struct winsize { + unsigned short ws_row; /* rows, in characters */ + unsigned short ws_col; /* columns, in character */ + unsigned short ws_xpixel; /* horizontal size, pixels */ + unsigned short ws_ypixel; /* vertical size, pixels */ +}; +#endif + +/* *-*-nto-qnx does not define this type in the system headers */ +#ifdef MISSING_FD_MASK + typedef unsigned long int fd_mask; +#endif + +/* Paths */ + +#ifndef _PATH_BSHELL +# define _PATH_BSHELL "/bin/sh" +#endif +#ifndef _PATH_CSHELL +# define _PATH_CSHELL "/bin/csh" +#endif +#ifndef _PATH_SHELLS +# define _PATH_SHELLS "/etc/shells" +#endif + +#ifdef USER_PATH +# ifdef _PATH_STDPATH +# undef _PATH_STDPATH +# endif +# define _PATH_STDPATH USER_PATH +#endif + +#ifndef _PATH_STDPATH +# define _PATH_STDPATH "/usr/bin:/bin:/usr/sbin:/sbin" +#endif + +#ifndef SUPERUSER_PATH +# define SUPERUSER_PATH _PATH_STDPATH +#endif + +#ifndef _PATH_DEVNULL +# define _PATH_DEVNULL "/dev/null" +#endif + +#ifndef MAIL_DIRECTORY +# define MAIL_DIRECTORY "/var/spool/mail" +#endif + +#ifndef MAILDIR +# define MAILDIR MAIL_DIRECTORY +#endif + +#if !defined(_PATH_MAILDIR) && defined(MAILDIR) +# define _PATH_MAILDIR MAILDIR +#endif /* !defined(_PATH_MAILDIR) && defined(MAILDIR) */ + +#ifndef _PATH_NOLOGIN +# define _PATH_NOLOGIN "/etc/nologin" +#endif + +/* Define this to be the path of the xauth program. */ +#ifdef XAUTH_PATH +#define _PATH_XAUTH XAUTH_PATH +#endif /* XAUTH_PATH */ + +/* derived from XF4/xc/lib/dps/Xlibnet.h */ +#ifndef X_UNIX_PATH +# ifdef __hpux +# define X_UNIX_PATH "/var/spool/sockets/X11/%u" +# else +# define X_UNIX_PATH "/tmp/.X11-unix/X%u" +# endif +#endif /* X_UNIX_PATH */ +#define _PATH_UNIX_X X_UNIX_PATH + +#ifndef _PATH_TTY +# define _PATH_TTY "/dev/tty" +#endif + +/* Macros */ + +#if defined(HAVE_LOGIN_GETCAPBOOL) && defined(HAVE_LOGIN_CAP_H) +# define HAVE_LOGIN_CAP +#endif + +#ifndef MAX +# define MAX(a,b) (((a)>(b))?(a):(b)) +# define MIN(a,b) (((a)<(b))?(a):(b)) +#endif + +#ifndef roundup +# define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) +#endif + +#ifndef timersub +#define timersub(a, b, result) \ + do { \ + (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ + (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ + if ((result)->tv_usec < 0) { \ + --(result)->tv_sec; \ + (result)->tv_usec += 1000000; \ + } \ + } while (0) +#endif + +#ifndef TIMEVAL_TO_TIMESPEC +#define TIMEVAL_TO_TIMESPEC(tv, ts) { \ + (ts)->tv_sec = (tv)->tv_sec; \ + (ts)->tv_nsec = (tv)->tv_usec * 1000; \ +} +#endif + +#ifndef TIMESPEC_TO_TIMEVAL +#define TIMESPEC_TO_TIMEVAL(tv, ts) { \ + (tv)->tv_sec = (ts)->tv_sec; \ + (tv)->tv_usec = (ts)->tv_nsec / 1000; \ +} +#endif + +#ifndef __P +# define __P(x) x +#endif + +#if !defined(IN6_IS_ADDR_V4MAPPED) +# define IN6_IS_ADDR_V4MAPPED(a) \ + ((((u_int32_t *) (a))[0] == 0) && (((u_int32_t *) (a))[1] == 0) && \ + (((u_int32_t *) (a))[2] == htonl (0xffff))) +#endif /* !defined(IN6_IS_ADDR_V4MAPPED) */ + +#if !defined(__GNUC__) || (__GNUC__ < 2) +# define __attribute__(x) +#endif /* !defined(__GNUC__) || (__GNUC__ < 2) */ + +/* *-*-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 */ + + +/* 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 + +/* In older versions of libpam, pam_strerror takes a single argument */ +#ifdef HAVE_OLD_PAM +# define PAM_STRERROR(a,b) pam_strerror((b)) +#else +# define PAM_STRERROR(a,b) pam_strerror((a),(b)) +#endif + +#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 + +#if defined(BROKEN_GETADDRINFO) && defined(HAVE_GETADDRINFO) +# undef HAVE_GETADDRINFO +#endif +#if defined(BROKEN_GETADDRINFO) && defined(HAVE_FREEADDRINFO) +# undef HAVE_FREEADDRINFO +#endif +#if defined(BROKEN_GETADDRINFO) && defined(HAVE_GAI_STRERROR) +# undef HAVE_GAI_STRERROR +#endif + +#if !defined(HAVE_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 +# define getpgrp() getpgrp(0) +#endif + +/* OPENSSL_free() is Free() in versions before OpenSSL 0.9.6 */ +#if !defined(OPENSSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x0090600f) +# define OPENSSL_free(x) Free(x) +#endif + +#if !defined(HAVE___func__) && defined(HAVE___FUNCTION__) +# define __func__ __FUNCTION__ +#elif !defined(HAVE___func__) +# define __func__ "" +#endif + +#if defined(KRB5) && !defined(HEIMDAL) +# define krb5_get_err_text(context,code) error_message(code) +#endif + +/* + * 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 + + +/* The login() library function in libutil is first choice */ +#if defined(HAVE_LOGIN) && !defined(DISABLE_LOGIN) +# define USE_LOGIN + +#else +/* Simply select your favourite login types. */ +/* Can't do if-else because some systems use several... */ +# if defined(UTMPX_FILE) && !defined(DISABLE_UTMPX) +# define USE_UTMPX +# endif +# if defined(UTMP_FILE) && !defined(DISABLE_UTMP) +# define USE_UTMP +# endif +# if defined(WTMPX_FILE) && !defined(DISABLE_WTMPX) +# define USE_WTMPX +# endif +# if defined(WTMP_FILE) && !defined(DISABLE_WTMP) +# define USE_WTMP +# endif + +#endif + +/* I hope that the presence of LASTLOG_FILE is enough to detect this */ +#if defined(LASTLOG_FILE) && !defined(DISABLE_LASTLOG) +# define USE_LASTLOG +#endif + +/** end of login recorder definitions */ + +#endif /* _DEFINES_H */ diff -ruN --exclude CVS ssh-openbsd-2003091600/entropy.c openssh-3.7p1/entropy.c --- ssh-openbsd-2003091600/entropy.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/entropy.c 2003-08-25 11:16:21.000000000 +1000 @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2001 Damien Miller. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#include +#include + +#include "ssh.h" +#include "misc.h" +#include "xmalloc.h" +#include "atomicio.h" +#include "pathnames.h" +#include "log.h" + +/* + * Portable OpenSSH PRNG seeding: + * If OpenSSL has not "internally seeded" itself (e.g. pulled data from + * /dev/random), then we execute a "ssh-rand-helper" program which + * collects entropy and writes it to stdout. The child program must + * write at least RANDOM_SEED_SIZE bytes. The child is run with stderr + * attached, so error/debugging output should be visible. + * + * XXX: we should tell the child how many bytes we need. + */ + +RCSID("$Id: entropy.c,v 1.46 2003/08/25 01:16:21 mouring Exp $"); + +#ifndef OPENSSL_PRNG_ONLY +#define RANDOM_SEED_SIZE 48 +static uid_t original_uid, original_euid; +#endif + +void +seed_rng(void) +{ +#ifndef OPENSSL_PRNG_ONLY + int devnull; + int p[2]; + pid_t pid; + int ret; + unsigned char buf[RANDOM_SEED_SIZE]; + mysig_t old_sigchld; + + if (RAND_status() == 1) { + debug3("RNG is ready, skipping seeding"); + return; + } + + debug3("Seeding PRNG from %s", SSH_RAND_HELPER); + + if ((devnull = open("/dev/null", O_RDWR)) == -1) + fatal("Couldn't open /dev/null: %s", strerror(errno)); + if (pipe(p) == -1) + fatal("pipe: %s", strerror(errno)); + + old_sigchld = signal(SIGCHLD, SIG_DFL); + if ((pid = fork()) == -1) + fatal("Couldn't fork: %s", strerror(errno)); + if (pid == 0) { + dup2(devnull, STDIN_FILENO); + dup2(p[1], STDOUT_FILENO); + /* Keep stderr open for errors */ + close(p[0]); + close(p[1]); + close(devnull); + + if (original_uid != original_euid && + ( seteuid(getuid()) == -1 || + setuid(original_uid) == -1) ) { + fprintf(stderr, "(rand child) setuid(%li): %s\n", + (long int)original_uid, strerror(errno)); + _exit(1); + } + + execl(SSH_RAND_HELPER, "ssh-rand-helper", NULL); + fprintf(stderr, "(rand child) Couldn't exec '%s': %s\n", + SSH_RAND_HELPER, strerror(errno)); + _exit(1); + } + + close(devnull); + close(p[1]); + + memset(buf, '\0', sizeof(buf)); + ret = atomicio(read, p[0], buf, sizeof(buf)); + if (ret == -1) + fatal("Couldn't read from ssh-rand-helper: %s", + strerror(errno)); + if (ret != sizeof(buf)) + fatal("ssh-rand-helper child produced insufficient data"); + + close(p[0]); + + if (waitpid(pid, &ret, 0) == -1) + fatal("Couldn't wait for ssh-rand-helper completion: %s", + strerror(errno)); + signal(SIGCHLD, old_sigchld); + + /* We don't mind if the child exits upon a SIGPIPE */ + if (!WIFEXITED(ret) && + (!WIFSIGNALED(ret) || WTERMSIG(ret) != SIGPIPE)) + fatal("ssh-rand-helper terminated abnormally"); + if (WEXITSTATUS(ret) != 0) + fatal("ssh-rand-helper exit with exit status %d", ret); + + 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"); +} + +void +init_rng(void) +{ + /* + * OpenSSL version numbers: MNNFFPPS: major minor fix patch status + * We match major, minor, fix and status (not patch) + */ + if ((SSLeay() ^ OPENSSL_VERSION_NUMBER) & ~0xff0L) + fatal("OpenSSL version mismatch. Built against %lx, you " + "have %lx", OPENSSL_VERSION_NUMBER, SSLeay()); + +#ifndef OPENSSL_PRNG_ONLY + if ((original_uid = getuid()) == -1) + fatal("getuid: %s", strerror(errno)); + if ((original_euid = geteuid()) == -1) + fatal("geteuid: %s", strerror(errno)); +#endif +} + diff -ruN --exclude CVS ssh-openbsd-2003091600/entropy.h openssh-3.7p1/entropy.h --- ssh-openbsd-2003091600/entropy.h 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/entropy.h 2001-02-09 12:55:36.000000000 +1100 @@ -0,0 +1,33 @@ +/* + * 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.4 2001/02/09 01:55:36 djm Exp $ */ + +#ifndef _RANDOMS_H +#define _RANDOMS_H + +void seed_rng(void); +void init_rng(void); + +#endif /* _RANDOMS_H */ diff -ruN --exclude CVS ssh-openbsd-2003091600/fixpaths openssh-3.7p1/fixpaths --- ssh-openbsd-2003091600/fixpaths 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/fixpaths 2002-12-05 20:59:33.000000000 +1100 @@ -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 -ruN --exclude CVS ssh-openbsd-2003091600/fixprogs openssh-3.7p1/fixprogs --- ssh-openbsd-2003091600/fixprogs 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/fixprogs 2000-09-16 16:10:56.000000000 +1100 @@ -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 \n"); +} + +if (($#ARGV == -1) || ($#ARGV>1)) { + die(&usage); +} + +# 'undocumented' option - run ent (in second param) on the output +if ($#ARGV==1) { + $entcmd=$ARGV[1] +} else { + $entcmd = "" +}; + +$infilename = $ARGV[0]; + +if (!open(IN, "<".$infilename)) { + die("Couldn't open input file"); +} +$outfilename=$infilename.".out"; +if (!open(OUT, ">$outfilename")) { + die("Couldn't open output file $outfilename"); +} +@infile=; + +select(OUT); $|=1; select(STDOUT); + +foreach (@infile) { + if (/^\s*\#/ || /^\s*$/) { + print OUT; + next; + } + ($cmd, $path, $est) = /^\"([^\"]+)\"\s+([\w\/_-]+)\s+([\d\.\-]+)/o; + @args = split(/ /, $cmd); + if (! ($pid = fork())) { + # child + close STDIN; close STDOUT; close STDERR; + open (STDIN, "/dev/null"); + open (STDERR, ">/dev/null"); + exec $path @args; + exit 1; # shouldn't be here + } + # parent + waitpid ($pid, 0); $ret=$? >> 8; + + if ($ret != 0) { + $path = "undef"; + } else { + if ($entcmd ne "") { + # now try to run ent on the command + $mostargs=join(" ", splice(@args,1)); + print "Evaluating '$path $mostargs'\n"; + @ent = qx{$path $mostargs | $entcmd -b -t}; + @ent = grep(/^1,/, @ent); + ($null, $null, $rate) = split(/,/, $ent[0]); + $est = $rate / $entscale; # scale the estimate back + } + } + print OUT "\"$cmd\" $path $est\n"; +} + +close(IN); diff -ruN --exclude CVS ssh-openbsd-2003091600/gss-serv-krb5.c openssh-3.7p1/gss-serv-krb5.c --- ssh-openbsd-2003091600/gss-serv-krb5.c 2003-08-22 20:56:09.000000000 +1000 +++ openssh-3.7p1/gss-serv-krb5.c 2003-08-26 11:58:16.000000000 +1000 @@ -38,7 +38,11 @@ extern ServerOptions options; +#ifdef HEIMDAL #include +#else +#include +#endif static krb5_context krb_context = NULL; @@ -113,11 +117,39 @@ 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 + { + int tmpfd; + char ccname[40]; + + snprintf(ccname, sizeof(ccname), + "FILE:/tmp/krb5cc_%d_XXXXXX", geteuid()); + + if ((tmpfd = mkstemp(ccname + strlen("FILE:"))) == -1) { + logit("mkstemp(): %.100s", strerror(errno)); + problem = errno; + return; + } + if (fchmod(tmpfd, S_IRUSR | S_IWUSR) == -1) { + logit("fchmod(): %.100s", strerror(errno)); + close(tmpfd); + problem = errno; + return; + } + close(tmpfd); + if ((problem = krb5_cc_resolve(krb_context, ccname, &ccache))) { + logit("krb5_cc_resolve(): %.100s", + krb5_get_err_text(krb_context, problem)); + return; + } + } +#endif /* #ifdef HEIMDAL */ if ((problem = krb5_parse_name(krb_context, client->exportedname.value, &princ))) { @@ -148,6 +180,11 @@ client->store.envvar = "KRB5CCNAME"; client->store.envval = xstrdup(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; diff -ruN --exclude CVS ssh-openbsd-2003091600/includes.h openssh-3.7p1/includes.h --- ssh-openbsd-2003091600/includes.h 2003-03-26 16:04:03.000000000 +1100 +++ openssh-3.7p1/includes.h 2003-06-29 21:23:37.000000000 +1000 @@ -19,48 +19,160 @@ #define RCSID(msg) \ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "config.h" -#include -#include -#include -#include -#include -#include - -#include #include #include #include -#include +#include /* For O_NONBLOCK */ #include -#include #include #include #include #include #include -#include #include -#include #include -#include "version.h" +#ifdef HAVE_LIMITS_H +# include /* For PATH_MAX */ +#endif +#ifdef HAVE_GETOPT_H +# include +#endif +#ifdef HAVE_BSTRING_H +# include +#endif +#if defined(HAVE_GLOB_H) && defined(GLOB_HAS_ALTDIRFUNC) && \ + defined(GLOB_HAS_GL_MATCHC) +# include +#endif +#ifdef HAVE_NETGROUP_H +# include +#endif +#ifdef HAVE_ENDIAN_H +# include +#endif +#ifdef HAVE_TTYENT_H +# include +#endif +#ifdef HAVE_UTIME_H +# include +#endif +#ifdef HAVE_MAILLOCK_H +# include /* For _PATH_MAILDIR */ +#endif +#ifdef HAVE_NEXT +# include +#endif +#define __USE_GNU /* before unistd.h, activate extra prototypes for glibc */ +#include /* For STDIN_FILENO, etc */ +#include /* Struct winsize */ /* - * Define this to use pipes instead of socketpairs for communicating with the - * client program. Socketpairs do not seem to work on all systems. + *-*-nto-qnx needs these headers for strcasecmp and LASTLOG_FILE respectively */ -#define USE_PIPES 1 +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_LOGIN_H +# include +#endif + +#ifdef HAVE_UTMP_H +# include +#endif +#ifdef HAVE_UTMPX_H +# ifdef HAVE_TV_IN_UTMPX +# include +# endif +# include +#endif +#ifdef HAVE_LASTLOG_H +# include +#endif +#ifdef HAVE_PATHS_H +# include /* For _PATH_XXX */ +#endif + +#include +#include +#include +#include +#ifdef HAVE_SYS_TIME_H +# include /* For timersub */ +#endif +#include +#ifdef HAVE_SYS_SELECT_H +# include +#endif +#ifdef HAVE_SYS_BSDTTY_H +# include +#endif +#include /* For MAXPATHLEN and roundup() */ +#ifdef HAVE_SYS_UN_H +# include /* For sockaddr_un */ +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_SYS_BITYPES_H +# include /* For u_intXX_t */ +#endif +#ifdef HAVE_SYS_CDEFS_H +# include /* For __P() */ +#endif +#ifdef HAVE_SYS_STAT_H +# include /* For S_* constants and macros */ +#endif +#ifdef HAVE_SYS_SYSMACROS_H +# include /* For MIN, MAX, etc */ +#endif +#ifdef HAVE_SYS_MMAN_H +#include /* for MAP_ANONYMOUS */ +#endif +#ifdef HAVE_SYS_STRTIO_H +#include /* for TIOCCBRK on HP-UX */ +#endif + +#include /* For typedefs */ +#include /* For IPv6 macros */ +#include /* For IPTOS macros */ +#include +#include +#if defined(HAVE_NETDB_H) +# include +#endif +#ifdef HAVE_RPC_TYPES_H +# include /* For INADDR_LOOPBACK */ +#endif +#ifdef USE_PAM +# include +#endif +#ifdef HAVE_READPASSPHRASE_H +# include +#endif + +#ifdef HAVE_IA_H +# include +#endif + +#ifdef HAVE_TMPDIR_H +# include +#endif + +#ifdef HAVE_LIBUTIL_H +# include /* Openpty on FreeBSD at least */ +#endif + +#include /* For OPENSSL_VERSION_NUMBER */ + +#include "defines.h" + +#include "version.h" +#include "openbsd-compat/openbsd-compat.h" +#include "openbsd-compat/bsd-nextstep.h" + +#include "entropy.h" -#endif /* INCLUDES_H */ +#endif /* INCLUDES_H */ diff -ruN --exclude CVS ssh-openbsd-2003091600/INSTALL openssh-3.7p1/INSTALL --- ssh-openbsd-2003091600/INSTALL 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/INSTALL 2003-05-24 11:41:16.000000000 +1000 @@ -0,0 +1,220 @@ +1. Prerequisites +---------------- + +You will need working installations of Zlib and OpenSSL. + +Zlib: +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.) + +OpenSSH can utilise Pluggable Authentication Modules (PAM) if your system +supports it. PAM is standard on Redhat and Debian Linux, Solaris and +HP-UX 11. + +NB. If you operating system supports /dev/random, you should configure +OpenSSL to use it. OpenSSH relies on OpenSSL's direct support of +/dev/random. If you don't you will have to rely on ssh-rand-helper, which +is inferior to a good kernel-based solution. + +PAM: +http://www.kernel.org/pub/linux/libs/pam/ + +If you wish to build the GNOME passphrase requester, you will need the GNOME +libraries and headers. + +GNOME: +http://www.gnome.org/ + +Alternatively, Jim Knoble has written an excellent X11 +passphrase requester. This is maintained separately at: + +http://www.ntrnet.net/~jmknoble/software/x11-ssh-askpass/index.html + +PRNGD: + +If your system lacks Kernel based random collection, the use of Lutz +Jaenicke's PRNGd is recommended. + +http://www.aet.tu-cottbus.de/personen/jaenicke/postfix_tls/prngd.html + +EGD: + +The Entropy Gathering Daemon (EGD) is supported if you have a system which +lacks /dev/random and don't want to use OpenSSH's internal entropy collection. + +http://www.lothar.com/tech/crypto/ + +S/Key Libraries: +http://www.sparc.spb.su/solaris/skey/ + +If you wish to use --with-skey then you will need the above library +installed. No other current S/Key library is currently known to be +supported. + +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 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-pam enables PAM support. + +--enable-gnome-askpass will build the GNOME passphrase dialog. You +need a working installation of GNOME, including the development +headers, for this to work. + +--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-kerberos4=PATH will enable Kerberos IV support. You will need +to have the Kerberos libraries and header files installed for this +to work. Use the optional PATH argument to specify the root of your +Kerberos installation. + +--with-afs=PATH will enable AFS support. You will need to have the +Kerberos IV and the AFS libraries and header files installed for this +to work. Use the optional PATH argument to specify the root of your +AFS installation. AFS requires Kerberos support to be enabled. + +--with-skey=PATH will enable S/Key one time password support. You will +need the S/Key libraries and header files installed for this to work. + +--with-tcp-wrappers will enable TCP Wrappers (/etc/hosts.allow|deny) +support. You will need libwrap.a and tcpd.h installed. + +--with-md5-passwords will enable the use of MD5 passwords. Enable this +if your operating system uses MD5 passwords without using PAM. + +--with-utmpx enables utmpx support. utmpx support is automatic for +some platforms. + +--without-shadow disables shadow password support. + +--with-ipaddr-display forces the use of a numeric IP address in the +$DISPLAY environment variable. Some broken systems need this. + +--with-default-path=PATH allows you to specify a default $PATH for sessions +started by sshd. This replaces the standard path entirely. + +--with-pid-dir=PATH specifies the directory in which the ssh.pid file is +created. + +--with-xauth=PATH specifies the location of the xauth binary + +--with-ipv4-default instructs OpenSSH to use IPv4 by default for new +connections. Normally OpenSSH will try attempt to lookup both IPv6 and +IPv4 addresses. On Linux/glibc-2.1.2 this causes long delays in name +resolution. If this option is specified, you can still attempt to +connect to IPv6 addresses using the command line option '-6'. + +--with-ssl-dir=DIR allows you to specify where your OpenSSL libraries +are installed. + +--with-4in6 Check for IPv4 in IPv6 mapped addresses and convert them to +real (AF_INET) IPv4 addresses. Works around some quirks on Linux. + +--with-opensc=DIR +--with-sectok=DIR allows for OpenSC or sectok smartcard libraries to +be used with OpenSSH. See 'README.smartcard' for more details. + +If you need to pass special options to the compiler or linker, you +can specify these as environment variables before running ./configure. +For example: + +CFLAGS="-O -m486" LDFLAGS="-s" LIBS="-lrubbish" LD="/usr/foo/ld" ./configure + +3. Configuration +---------------- + +The runtime configuration files are installed by in ${prefix}/etc or +whatever you specified as your --sysconfdir (/usr/local/etc by default). + +The default configuration should be instantly usable, though you should +review it to ensure that it matches your security requirements. + +To generate a host key, run "make host-key". Alternately you can do so +manually using the following commands: + + ssh-keygen -t rsa1 -f /etc/ssh/ssh_host_key -N "" + ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N "" + ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key -N "" + +Replacing /etc/ssh with the correct path to the configuration directory. +(${prefix}/etc or whatever you specified with --sysconfdir during +configuration) + +If you have configured OpenSSH with EGD support, ensure that EGD is +running and has collected some Entropy. + +For more information on configuration, please refer to the manual pages +for sshd, ssh and ssh-agent. + +4. 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.56 2003/05/24 01:41:16 dtucker Exp $ diff -ruN --exclude CVS ssh-openbsd-2003091600/install-sh openssh-3.7p1/install-sh --- ssh-openbsd-2003091600/install-sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/install-sh 1999-11-25 12:31:26.000000000 +1100 @@ -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 -ruN --exclude CVS ssh-openbsd-2003091600/lib/Makefile openssh-3.7p1/lib/Makefile --- ssh-openbsd-2003091600/lib/Makefile 2003-09-03 12:07:15.000000000 +1000 +++ openssh-3.7p1/lib/Makefile 1970-01-01 10:00:00.000000000 +1000 @@ -1,31 +0,0 @@ -# $OpenBSD: Makefile,v 1.44 2003/08/22 10:56:09 markus Exp $ - -.PATH: ${.CURDIR}/.. - -LIB= ssh -SRCS= authfd.c authfile.c bufaux.c buffer.c canohost.c channels.c \ - cipher.c cipher-3des1.c cipher-aes.c cipher-bf1.c cipher-ctr.c \ - compat.c compress.c crc32.c deattack.c fatal.c \ - hostfile.c log.c match.c mpaux.c nchan.c packet.c readpass.c \ - rsa.c tildexpand.c ttymodes.c xmalloc.c atomicio.c \ - key.c dispatch.c kex.c mac.c uuencode.c misc.c \ - rijndael.c ssh-dss.c ssh-rsa.c dh.c kexdh.c kexgex.c \ - kexdhc.c kexgexc.c scard.c msg.c progressmeter.c dns.c - -DEBUGLIBS= no -NOPROFILE= yes -NOPIC= yes - -install: - @echo -n - -.include - -.if (${KERBEROS5:L} == "yes") -CFLAGS+= -DKRB5 -I${DESTDIR}/usr/include/kerberosV - -SRCS+= gss-genr.c -CFLAGS+= -DGSSAPI -.endif # KERBEROS5 - -.include diff -ruN --exclude CVS ssh-openbsd-2003091600/LICENCE openssh-3.7p1/LICENCE --- ssh-openbsd-2003091600/LICENCE 2003-09-03 12:07:14.000000000 +1000 +++ openssh-3.7p1/LICENCE 2003-08-26 12:09:53.000000000 +1000 @@ -177,11 +177,33 @@ Damien Miller Kevin Steves Daniel Kouril + Per Allansson 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 + * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -202,5 +224,109 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +8) Portable OpenSSH contains the following additional licenses: + + a) md5crypt.c, md5crypt.h + + * "THE BEER-WARE LICENSE" (Revision 42): + * wrote this file. As long as you retain this + * notice you can do whatever you want with this stuff. If we meet + * some day, and you think this stuff is worth it, you can buy me a + * beer in return. Poul-Henning Kamp + + b) snprintf replacement + + * Copyright Patrick Powell 1995 + * This code is based on code written by Patrick Powell + * (papowell@astart.com) It may be used for any purpose as long as this + * notice remains intact on all source code distributions + + c) Compatibility code (openbsd-compat) + + Apart from the previously mentioned licenses, various pieces of code + in the openbsd-compat/ subdirectory are licensed as follows: + + Some code is licensed under a 3-term BSD license, to the following + copyright holders: + + Todd C. Miller + Theo de Raadt + Damien Miller + Eric P. Allman + The Regents of the University of California + + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + + Some code is licensed under an ISC-style license, to the following + copyright holders: + + Internet Software Consortium. + Todd C. Miller + + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE + * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Some code is licensed under a MIT-style license to the following + copyright holders: + + Free Software Foundation, Inc. + + * Permission is hereby granted, free of charge, to any person obtaining a * + * copy of this software and associated documentation files (the * + * "Software"), to deal in the Software without restriction, including * + * without limitation the rights to use, copy, modify, merge, publish, * + * distribute, distribute with modifications, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the Software is * + * furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included * + * in all copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * + * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + * * + * Except as contained in this notice, the name(s) of the above copyright * + * holders shall not be used in advertising or otherwise to promote the * + * sale, use or other dealings in this Software without prior written * + * authorization. * + ****************************************************************************/ + + ------ $OpenBSD: LICENCE,v 1.17 2003/08/22 20:55:06 markus Exp $ diff -ruN --exclude CVS ssh-openbsd-2003091600/log.c openssh-3.7p1/log.c --- ssh-openbsd-2003091600/log.c 2003-05-25 14:26:30.000000000 +1000 +++ openssh-3.7p1/log.c 2003-05-25 14:45:02.000000000 +1000 @@ -40,7 +40,6 @@ #include "xmalloc.h" #include -#include static LogLevel log_level = SYSLOG_LEVEL_INFO; static int log_on_stderr = 1; @@ -58,6 +57,9 @@ { "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 }, @@ -295,6 +297,11 @@ 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; @@ -332,7 +339,9 @@ void do_log(LogLevel level, const char *fmt, va_list args) { +#ifdef OPENLOG_R struct syslog_data sdata = SYSLOG_DATA_INIT; +#endif char msgbuf[MSGBUFSIZ]; char fmtbuf[MSGBUFSIZ]; char *txt = NULL; @@ -386,8 +395,14 @@ snprintf(msgbuf, sizeof msgbuf, "%s\r\n", fmtbuf); write(STDERR_FILENO, msgbuf, strlen(msgbuf)); } else { +#ifdef OPENLOG_R 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 } } diff -ruN --exclude CVS ssh-openbsd-2003091600/log.h openssh-3.7p1/log.h --- ssh-openbsd-2003091600/log.h 2003-05-13 13:34:30.000000000 +1000 +++ openssh-3.7p1/log.h 2003-05-14 13:40:07.000000000 +1000 @@ -15,11 +15,16 @@ #ifndef SSH_LOG_H #define SSH_LOG_H +#include /* Needed for LOG_AUTHPRIV (if present) */ + /* 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, diff -ruN --exclude CVS ssh-openbsd-2003091600/loginrec.c openssh-3.7p1/loginrec.c --- ssh-openbsd-2003091600/loginrec.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/loginrec.c 2003-07-06 15:20:46.000000000 +1000 @@ -0,0 +1,1549 @@ +/* + * 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. + */ + +/** + ** loginrec.c: platform-independent login recording and lastlog retrieval + **/ + +/* + The new login code explained + ============================ + + This code attempts to provide a common interface to login recording + (utmp and friends) and last login time retrieval. + + Its primary means of achieving this is to use 'struct logininfo', a + union of all the useful fields in the various different types of + system login record structures one finds on UNIX variants. + + We depend on autoconf to define which recording methods are to be + used, and which fields are contained in the relevant data structures + on the local system. Many C preprocessor symbols affect which code + gets compiled here. + + The code is designed to make it easy to modify a particular + recording method, without affecting other methods nor requiring so + many nested conditional compilation blocks as were commonplace in + the old code. + + For login recording, we try to use the local system's libraries as + these are clearly most likely to work correctly. For utmp systems + this usually means login() and logout() or setutent() etc., probably + in libutil, along with logwtmp() etc. On these systems, we fall back + to writing the files directly if we have to, though this method + requires very thorough testing so we do not corrupt local auditing + information. These files and their access methods are very system + specific indeed. + + For utmpx systems, the corresponding library functions are + setutxent() etc. To the author's knowledge, all utmpx systems have + these library functions and so no direct write is attempted. If such + a system exists and needs support, direct analogues of the [uw]tmp + code should suffice. + + Retrieving the time of last login ('lastlog') is in some ways even + more problemmatic than login recording. Some systems provide a + simple table of all users which we seek based on uid and retrieve a + relatively standard structure. Others record the same information in + a directory with a separate file, and others don't record the + information separately at all. For systems in the latter category, + we look backwards in the wtmp or wtmpx file for the last login entry + for our user. Naturally this is slower and on busy systems could + incur a significant performance penalty. + + Calling the new code + -------------------- + + In OpenSSH all login recording and retrieval is performed in + login.c. Here you'll find working examples. Also, in the logintest.c + program there are more examples. + + Internal handler calling method + ------------------------------- + + When a call is made to login_login() or login_logout(), both + routines set a struct logininfo flag defining which action (log in, + or log out) is to be taken. They both then call login_write(), which + calls whichever of the many structure-specific handlers autoconf + selects for the local system. + + The handlers themselves handle system data structure specifics. Both + struct utmp and struct utmpx have utility functions (see + construct_utmp*()) to try to make it simpler to add extra systems + that introduce new features to either structure. + + While it may seem terribly wasteful to replicate so much similar + code for each method, experience has shown that maintaining code to + write both struct utmp and utmpx in one function, whilst maintaining + support for all systems whether they have library support or not, is + a difficult and time-consuming task. + + Lastlog support proceeds similarly. Functions login_get_lastlog() + (and its OpenSSH-tuned friend login_get_lastlog_time()) call + getlast_entry(), which tries one of three methods to find the last + login time. It uses local system lastlog support if it can, + otherwise it tries wtmp or wtmpx before giving up and returning 0, + meaning "tilt". + + Maintenance + ----------- + + In many cases it's possible to tweak autoconf to select the correct + methods for a particular platform, either by improving the detection + code (best), or by presetting DISABLE_ or CONF__FILE + symbols for the platform. + + Use logintest to check which symbols are defined before modifying + configure.ac and loginrec.c. (You have to build logintest yourself + with 'make logintest' as it's not built by default.) + + Otherwise, patches to the specific method(s) are very helpful! + +*/ + +/** + ** TODO: + ** homegrown ttyslot() + ** test, test, test + ** + ** Platform status: + ** ---------------- + ** + ** Known good: + ** Linux (Redhat 6.2, Debian) + ** Solaris + ** HP-UX 10.20 (gcc only) + ** IRIX + ** NeXT - M68k/HPPA/Sparc (4.2/3.3) + ** + ** Testing required: Please send reports! + ** NetBSD + ** HP-UX 11 + ** AIX + ** + ** Platforms with known problems: + ** Some variants of Slackware Linux + ** + **/ + +#include "includes.h" + +#include "ssh.h" +#include "xmalloc.h" +#include "loginrec.h" +#include "log.h" +#include "atomicio.h" + +RCSID("$Id: loginrec.c,v 1.52 2003/07/06 05:20:46 dtucker Exp $"); + +#ifdef HAVE_UTIL_H +# include +#endif + +#ifdef HAVE_LIBUTIL_H +# include +#endif + +/** + ** prototypes for helper functions in this file + **/ + +#if HAVE_UTMP_H +void set_utmp_time(struct logininfo *li, struct utmp *ut); +void construct_utmp(struct logininfo *li, struct utmp *ut); +#endif + +#ifdef HAVE_UTMPX_H +void set_utmpx_time(struct logininfo *li, struct utmpx *ut); +void construct_utmpx(struct logininfo *li, struct utmpx *ut); +#endif + +int utmp_write_entry(struct logininfo *li); +int utmpx_write_entry(struct logininfo *li); +int wtmp_write_entry(struct logininfo *li); +int wtmpx_write_entry(struct logininfo *li); +int lastlog_write_entry(struct logininfo *li); +int syslogin_write_entry(struct logininfo *li); + +int getlast_entry(struct logininfo *li); +int lastlog_get_entry(struct logininfo *li); +int wtmp_get_entry(struct logininfo *li); +int wtmpx_get_entry(struct logininfo *li); + +/* 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 int 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 int 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("login_get_lastlog: Cannot find account for uid %i", uid); + + /* No MIN_SIZEOF here - we absolutely *must not* truncate the + * username */ + 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(int pid, const char *username, + const char *hostname, const char *line) +{ + struct logininfo *newli; + + newli = (struct logininfo *) xmalloc (sizeof(*newli)); + (void)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, int 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("login_init_entry: Cannot find user \"%s\"", 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((void *)&(li->hostaddr.sa), (const void *)sa, bufsize); +} + + +/** + ** login_write: Call low-level recording functions based on autoconf + ** results + **/ +int +login_write (struct logininfo *li) +{ +#ifndef HAVE_CYGWIN + if ((int)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 + 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 */ + +#ifdef DISABLE_LASTLOG + /* On some systems we shouldn't even try to obtain last login + * time, e.g. AIX */ + return 0; +# else /* DISABLE_LASTLOG */ + /* Try to retrieve the last login time from wtmp */ +# if defined(USE_WTMP) && (defined(HAVE_TIME_IN_UTMP) || defined(HAVE_TV_IN_UTMP)) + /* retrieve last login time from utmp */ + return (wtmp_get_entry(li)); +# else /* defined(USE_WTMP) && (defined(HAVE_TIME_IN_UTMP) || defined(HAVE_TV_IN_UTMP)) */ + /* If wtmp isn't available, try wtmpx */ +# if defined(USE_WTMPX) && (defined(HAVE_TIME_IN_UTMPX) || defined(HAVE_TV_IN_UTMPX)) + /* retrieve last login time from utmpx */ + return (wtmpx_get_entry(li)); +# else + /* Give up: No means of retrieving last login time */ + return 0; +# endif /* USE_WTMPX && (HAVE_TIME_IN_UTMPX || HAVE_TV_IN_UTMPX) */ +# endif /* USE_WTMP && (HAVE_TIME_IN_UTMP || HAVE_TV_IN_UTMP) */ +# 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, int dstsize) +{ + memset(dst, '\0', dstsize); + if ((strncmp(src, "/dev/", 5) == 0) || (dstsize < (strlen(src) + 5))) { + strlcpy(dst, src, dstsize); + } else { + strlcpy(dst, "/dev/", dstsize); + strlcat(dst, src, dstsize); + } + return dst; +} + +/* line_stripname(): strip the leading '/dev' if it exists, return dst */ +char * +line_stripname(char *dst, const char *src, int dstsize) +{ + memset(dst, '\0', dstsize); + if (strncmp(src, "/dev/", 5) == 0) + strlcpy(dst, src + 5, dstsize); + else + strlcpy(dst, src, dstsize); + return dst; +} + +/* line_abbrevname(): Return the abbreviated (usually four-character) + * form of the line (Just use the last characters of the + * full name.) + * + * NOTE: use strncpy because we do NOT necessarily want zero + * termination */ +char * +line_abbrevname(char *dst, const char *src, int dstsize) +{ + size_t len; + + memset(dst, '\0', dstsize); + + /* Always skip prefix if present */ + if (strncmp(src, "/dev/", 5) == 0) + src += 5; + +#ifdef WITH_ABBREV_NO_TTY + if (strncmp(src, "tty", 3) == 0) + src += 3; +#endif + + len = strlen(src); + + if (len > 0) { + if (((int)len - dstsize) > 0) + src += ((int)len - dstsize); + + /* note: _don't_ change this to strlcpy */ + strncpy(dst, src, (size_t)dstsize); + } + + return dst; +} + +/** + ** utmp utility functions + ** + ** These functions manipulate struct utmp, taking system differences + ** into account. + **/ + +#if defined(USE_UTMP) || defined (USE_WTMP) || defined (USE_LOGIN) + +/* build the utmp structure */ +void +set_utmp_time(struct logininfo *li, struct utmp *ut) +{ +# ifdef HAVE_TV_IN_UTMP + ut->ut_tv.tv_sec = li->tv_sec; + ut->ut_tv.tv_usec = li->tv_usec; +# else +# ifdef HAVE_TIME_IN_UTMP + ut->ut_time = li->tv_sec; +# endif +# 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) +{ +# ifdef HAVE_TV_IN_UTMPX + utx->ut_tv.tv_sec = li->tv_sec; + utx->ut_tv.tv_usec = li->tv_usec; +# else /* HAVE_TV_IN_UTMPX */ +# ifdef HAVE_TIME_IN_UTMPX + utx->ut_time = li->tv_sec; +# endif /* HAVE_TIME_IN_UTMPX */ +# endif /* HAVE_TV_IN_UTMPX */ +} + +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_name, li->username, MIN_SIZEOF(utx->ut_name, 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) + register struct ttyent *ty; + + tty=0; + + setttyent(); + while ((struct ttyent *)0 != (ty = getttyent())) { + tty++; + if (!strncmp(ty->ty_name, ut->ut_line, sizeof(ut->ut_line))) + break; + } + endttyent(); + + if((struct ttyent *)0 == ty) { + logit("utmp_write_entry: tty not found"); + return(1); + } +#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) { + (void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET); + /* + * 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)) { + (void)memcpy(ut->ut_host, old_ut.ut_host, sizeof(ut->ut_host)); + } + + (void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET); + if (atomicio(vwrite, fd, ut, sizeof(*ut)) != sizeof(*ut)) + logit("utmp_write_direct: error writing %s: %s", + UTMP_FILE, strerror(errno)); + + (void)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("utmp_perform_login: utmp_write_library() failed"); + return 0; + } +# else + if (!utmp_write_direct(li, &ut)) { + logit("utmp_perform_login: utmp_write_direct() failed"); + 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("utmp_perform_logout: utmp_write_library() failed"); + return 0; + } +# else + if (!utmp_write_direct(li, &ut)) { + logit("utmp_perform_logout: utmp_write_direct() failed"); + 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("utmp_write_entry: invalid type field"); + 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("utmpx_write_direct: not implemented!"); + 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("utmpx_perform_login: utmp_write_library() failed"); + return 0; + } +# else + if (!utmpx_write_direct(li, &ut)) { + logit("utmpx_perform_login: utmp_write_direct() failed"); + 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("utmpx_write_entry: invalid type field"); + 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("wtmp_write: problem writing %s: %s", + 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("wtmp_write: problem writing %s: %s", + WTMP_FILE, strerror(errno)); + ret = 0; + } + (void)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("wtmp_write_entry: invalid type field"); + 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("wtmp_get_entry: problem opening %s: %s", + WTMP_FILE, strerror(errno)); + return 0; + } + if (fstat(fd, &st) != 0) { + logit("wtmp_get_entry: couldn't stat %s: %s", + 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("wtmp_get_entry: read of %s failed: %s", + 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) +{ + struct stat buf; + int fd, ret = 1; + + if ((fd = open(WTMPX_FILE, O_WRONLY|O_APPEND, 0)) < 0) { + logit("wtmpx_write: problem opening %s: %s", + 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("wtmpx_write: problem writing %s: %s", + WTMPX_FILE, strerror(errno)); + ret = 0; + } + (void)close(fd); + + return ret; +} + + +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("wtmpx_write_entry: invalid type field"); + 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_name, + MIN_SIZEOF(li->username, utx->ut_name)) == 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("wtmpx_get_entry: problem opening %s: %s", + WTMPX_FILE, strerror(errno)); + return 0; + } + if (fstat(fd, &st) != 0) { + logit("wtmpx_get_entry: couldn't stat %s: %s", + 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("wtmpx_get_entry: read of %s failed: %s", + 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; +# ifdef HAVE_TV_IN_UTMPX + li->tv_sec = utx.ut_tv.tv_sec; +# else +# ifdef HAVE_TIME_IN_UTMPX + li->tv_sec = utx.ut_time; +# endif +# endif + line_fullname(li->line, utx.ut_line, sizeof(li->line)); +# ifdef 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; + + if (! (ut = (struct utmp *)malloc(sizeof(*ut)))) { + logit("syslogin_perform_login: couldn't malloc()"); + return 0; + } + construct_utmp(li, ut); + login(ut); + free(ut); + + return 1; +} + +static int +syslogin_perform_logout(struct logininfo *li) +{ +# ifdef HAVE_LOGOUT + char line[8]; + + (void)line_stripname(line, li->line, sizeof(line)); + + if (!logout(line)) { + logit("syslogin_perform_logout: logout() returned an error"); +# 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("syslogin_write_entry: Invalid type field"); + return 0; + } +} +#endif /* USE_LOGIN */ + +/* end of file log-syslogin.c */ + +/** + ** Low-level lastlog functions + **/ + +#ifdef USE_LASTLOG +#define LL_FILE 1 +#define LL_DIR 2 +#define LL_OTHER 3 + +static void +lastlog_construct(struct logininfo *li, struct lastlog *last) +{ + /* clear the structure */ + memset(last, '\0', sizeof(*last)); + + (void)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; +} + +static int +lastlog_filetype(char *filename) +{ + struct stat st; + + if (stat(LASTLOG_FILE, &st) != 0) { + logit("lastlog_perform_login: Couldn't stat %s: %s", LASTLOG_FILE, + strerror(errno)); + return 0; + } + if (S_ISDIR(st.st_mode)) + return LL_DIR; + else if (S_ISREG(st.st_mode)) + return LL_FILE; + else + return LL_OTHER; +} + + +/* 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; + int type; + char lastlog_file[1024]; + + type = lastlog_filetype(LASTLOG_FILE); + switch (type) { + case LL_FILE: + strlcpy(lastlog_file, LASTLOG_FILE, sizeof(lastlog_file)); + break; + case LL_DIR: + snprintf(lastlog_file, sizeof(lastlog_file), "%s/%s", + LASTLOG_FILE, li->username); + break; + default: + logit("lastlog_openseek: %.100s is not a file or directory!", + LASTLOG_FILE); + return 0; + } + + *fd = open(lastlog_file, filemode, 0600); + if ( *fd < 0) { + debug("lastlog_openseek: Couldn't open %s: %s", + lastlog_file, strerror(errno)); + return 0; + } + + if (type == LL_FILE) { + /* find this uid's offset in the lastlog file */ + offset = (off_t) ((long)li->uid * sizeof(struct lastlog)); + + if ( lseek(*fd, offset, SEEK_SET) != offset ) { + logit("lastlog_openseek: %s->lseek(): %s", + lastlog_file, strerror(errno)); + return 0; + } + } + + return 1; +} + +static int +lastlog_perform_login(struct logininfo *li) +{ + struct lastlog last; + int fd; + + /* create our struct lastlog */ + lastlog_construct(li, &last); + + 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("lastlog_write_filemode: Error writing to %s: %s", + LASTLOG_FILE, strerror(errno)); + return 0; + } + + close(fd); + return 1; +} + +int +lastlog_write_entry(struct logininfo *li) +{ + switch(li->type) { + case LTYPE_LOGIN: + return lastlog_perform_login(li); + default: + logit("lastlog_write_entry: Invalid type field"); + return 0; + } +} + +static void +lastlog_populate_entry(struct logininfo *li, struct lastlog *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; +} + +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): + lastlog_populate_entry(li, &last); + 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, sizeof(last), ret); + return (0); + } + + /* NOTREACHED */ + return (0); +} +#endif /* USE_LASTLOG */ diff -ruN --exclude CVS ssh-openbsd-2003091600/loginrec.h openssh-3.7p1/loginrec.h --- ssh-openbsd-2003091600/loginrec.h 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/loginrec.h 2003-06-03 12:18:50.000000000 +1000 @@ -0,0 +1,135 @@ +#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" + +#include +#include +#include + +/* RCSID("$Id: loginrec.h,v 1.7 2003/06/03 02:18:50 djm Exp $"); */ + +/** + ** 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 64 +#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_*) */ + int pid; /* PID of login process */ + int 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(int 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, int 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 int uid); +/* lastlog *time* functions return time_t equivalent (uint) */ +unsigned int login_get_lastlog_time(const int uid); + +/* produce various forms of the line filename */ +char *line_fullname(char *dst, const char *src, int dstsize); +char *line_stripname(char *dst, const char *src, int dstsize); +char *line_abbrevname(char *dst, const char *src, int dstsize); + +#endif /* _HAVE_LOGINREC_H_ */ diff -ruN --exclude CVS ssh-openbsd-2003091600/logintest.c openssh-3.7p1/logintest.c --- ssh-openbsd-2003091600/logintest.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/logintest.c 2003-08-22 09:34:41.000000000 +1000 @@ -0,0 +1,310 @@ +/* + * Copyright (c) 2000 Andre Lucas. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + ** logintest.c: simple test driver for platform-independent login recording + ** and lastlog retrieval + **/ + +#include "includes.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_TIME_H +#include +#endif + +#include "loginrec.h" + +RCSID("$Id: logintest.c,v 1.10 2003/08/21 23:34:41 djm Exp $"); + +#ifdef HAVE___PROGNAME +extern char *__progname; +#else +char *__progname; +#endif + +#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 (UTMPX_FILE=%s)\n", UTMPX_FILE); +#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 -ruN --exclude CVS ssh-openbsd-2003091600/Makefile openssh-3.7p1/Makefile --- ssh-openbsd-2003091600/Makefile 2003-03-26 16:04:01.000000000 +1100 +++ openssh-3.7p1/Makefile 1970-01-01 10:00:00.000000000 +1000 @@ -1,14 +0,0 @@ -# $OpenBSD: Makefile,v 1.11 2002/05/23 19:24:30 markus Exp $ - -.include - -SUBDIR= lib ssh sshd ssh-add ssh-keygen ssh-agent scp sftp-server \ - ssh-keysign ssh-keyscan sftp scard - -distribution: - install -C -o root -g wheel -m 0644 ${.CURDIR}/ssh_config \ - ${DESTDIR}/etc/ssh/ssh_config - install -C -o root -g wheel -m 0644 ${.CURDIR}/sshd_config \ - ${DESTDIR}/etc/ssh/sshd_config - -.include diff -ruN --exclude CVS ssh-openbsd-2003091600/Makefile.in openssh-3.7p1/Makefile.in --- ssh-openbsd-2003091600/Makefile.in 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/Makefile.in 2003-09-14 11:40:36.000000000 +1000 @@ -0,0 +1,400 @@ +# $Id: Makefile.in,v 1.249 2003/09/14 01:40:36 dtucker 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@ +mandir=@mandir@ +mansubdir=@mansubdir@ +sysconfdir=@sysconfdir@ +piddir=@piddir@ +srcdir=@srcdir@ +top_srcdir=@top_srcdir@ + +DESTDIR= +VPATH=@srcdir@ +SSH_PROGRAM=@bindir@/ssh +ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass +SFTP_SERVER=$(libexecdir)/sftp-server +SSH_KEYSIGN=$(libexecdir)/ssh-keysign +RAND_HELPER=$(libexecdir)/ssh-rand-helper +PRIVSEP_PATH=@PRIVSEP_PATH@ +SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ +STRIP_OPT=@STRIP_OPT@ + +PATHS= -DSSHDIR=\"$(sysconfdir)\" \ + -D_PATH_SSH_PROGRAM=\"$(SSH_PROGRAM)\" \ + -D_PATH_SSH_ASKPASS_DEFAULT=\"$(ASKPASS_PROGRAM)\" \ + -D_PATH_SFTP_SERVER=\"$(SFTP_SERVER)\" \ + -D_PATH_SSH_KEY_SIGN=\"$(SSH_KEYSIGN)\" \ + -D_PATH_SSH_PIDDIR=\"$(piddir)\" \ + -D_PATH_PRIVSEP_CHROOT_DIR=\"$(PRIVSEP_PATH)\" \ + -DSSH_RAND_HELPER=\"$(RAND_HELPER)\" + +CC=@CC@ +LD=@LD@ +CFLAGS=@CFLAGS@ +CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@ +LIBS=@LIBS@ +LIBPAM=@LIBPAM@ +LIBWRAP=@LIBWRAP@ +AR=@AR@ +AWK=@AWK@ +RANLIB=@RANLIB@ +INSTALL=@INSTALL@ +PERL=@PERL@ +SED=@SED@ +ENT=@ENT@ +XAUTH_PATH=@XAUTH_PATH@ +LDFLAGS=-L. -Lopenbsd-compat/ @LDFLAGS@ +EXEEXT=@EXEEXT@ + +INSTALL_SSH_PRNG_CMDS=@INSTALL_SSH_PRNG_CMDS@ +INSTALL_SSH_RAND_HELPER=@INSTALL_SSH_RAND_HELPER@ + +TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-agent$(EXEEXT) scp$(EXEEXT) ssh-rand-helper${EXEEXT} sftp-server$(EXEEXT) sftp$(EXEEXT) + +LIBSSH_OBJS=authfd.o authfile.o bufaux.o buffer.o canohost.o channels.o \ + cipher.o cipher-aes.o cipher-bf1.o cipher-ctr.o cipher-3des1.o \ + compat.o compress.o crc32.o deattack.o fatal.o \ + hostfile.o log.o match.o moduli.o mpaux.o nchan.o packet.o \ + readpass.o rsa.o tildexpand.o ttymodes.o xmalloc.o atomicio.o \ + key.o dispatch.o kex.o mac.o uuencode.o misc.o \ + rijndael.o ssh-dss.o ssh-rsa.o dh.o kexdh.o kexgex.o \ + kexdhc.o kexgexc.o scard.o msg.o progressmeter.o dns.o \ + entropy.o scard-opensc.o gss-genr.o + +SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ + sshconnect.o sshconnect1.o sshconnect2.o + +SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ + sshpty.o sshlogin.o servconf.o serverloop.o uidswap.o \ + auth.o auth1.o auth2.o auth-options.o session.o \ + auth-chall.o auth2-chall.o groupaccess.o \ + auth-skey.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ + auth2-none.o auth2-passwd.o auth2-pubkey.o \ + monitor_mm.o monitor.o monitor_wrap.o monitor_fdpass.o \ + kexdhs.o kexgexs.o \ + auth-krb5.o \ + auth2-gss.o gss-serv.o gss-serv-krb5.o \ + loginrec.o auth-pam.o auth-sia.o md5crypt.o + +MANPAGES = scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-rand-helper.8.out ssh-keysign.8.out sshd_config.5.out ssh_config.5.out +MANPAGES_IN = scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-rand-helper.8 ssh-keysign.8 sshd_config.5 ssh_config.5 +MANTYPE = @MANTYPE@ + +CONFIGFILES=sshd_config.out ssh_config.out moduli.out +CONFIGFILES_IN=sshd_config ssh_config moduli + +PATHSUBS = \ + -e 's|/etc/ssh/ssh_prng_cmds|$(sysconfdir)/ssh_prng_cmds|g' \ + -e 's|/etc/ssh/ssh_config|$(sysconfdir)/ssh_config|g' \ + -e 's|/etc/ssh/ssh_known_hosts|$(sysconfdir)/ssh_known_hosts|g' \ + -e 's|/etc/ssh/sshd_config|$(sysconfdir)/sshd_config|g' \ + -e 's|/usr/libexec|$(libexecdir)|g' \ + -e 's|/etc/shosts.equiv|$(sysconfdir)/shosts.equiv|g' \ + -e 's|/etc/ssh/ssh_host_key|$(sysconfdir)/ssh_host_key|g' \ + -e 's|/etc/ssh/ssh_host_dsa_key|$(sysconfdir)/ssh_host_dsa_key|g' \ + -e 's|/etc/ssh/ssh_host_rsa_key|$(sysconfdir)/ssh_host_rsa_key|g' \ + -e 's|/var/run/sshd.pid|$(piddir)/sshd.pid|g' \ + -e 's|/etc/ssh/moduli|$(sysconfdir)/moduli|g' \ + -e 's|/etc/sshrc|$(sysconfdir)/sshrc|g' \ + -e 's|/usr/X11R6/bin/xauth|$(XAUTH_PATH)|g' \ + -e 's|/var/empty|$(PRIVSEP_PATH)|g' \ + -e 's|/usr/bin:/bin:/usr/sbin:/sbin|@user_path@|g' + +FIXPATHSCMD = $(SED) $(PATHSUBS) + +all: $(CONFIGFILES) ssh_prng_cmds.out $(MANPAGES) $(TARGETS) + +$(LIBSSH_OBJS): Makefile.in config.h +$(SSHOBJS): Makefile.in config.h +$(SSHDOBJS): Makefile.in config.h + +.c.o: + $(CC) $(CFLAGS) $(CPPFLAGS) -c $< + +LIBCOMPAT=openbsd-compat/libopenbsd-compat.a +$(LIBCOMPAT): always + (cd openbsd-compat && $(MAKE)) +always: + +libssh.a: $(LIBSSH_OBJS) + $(AR) rv $@ $(LIBSSH_OBJS) + $(RANLIB) $@ + +ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS) + $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS) + $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBWRAP) $(LIBPAM) $(LIBS) + +scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o + $(LD) -o $@ scp.o progressmeter.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-add.o + $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-agent.o + $(LD) -o $@ ssh-agent.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o + $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o + $(LD) -o $@ ssh-keysign.o readconf.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o + $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) + +sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o + $(LD) -o $@ sftp-server.o sftp-common.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +sftp$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-client.o sftp-int.o sftp-common.o sftp-glob.o progressmeter.o + $(LD) -o $@ progressmeter.o sftp.o sftp-client.o sftp-common.o sftp-int.o sftp-glob.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +ssh-rand-helper${EXEEXT}: $(LIBCOMPAT) libssh.a ssh-rand-helper.o + $(LD) -o $@ ssh-rand-helper.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + +# test driver for the loginrec code - not built by default +logintest: logintest.o $(LIBCOMPAT) libssh.a loginrec.o + $(LD) -o $@ logintest.o $(LDFLAGS) loginrec.o -lopenbsd-compat -lssh $(LIBS) + +$(MANPAGES): $(MANPAGES_IN) + if test "$(MANTYPE)" = "cat"; then \ + manpage=$(srcdir)/`echo $@ | sed 's/\.[1-9]\.out$$/\.0/'`; \ + else \ + manpage=$(srcdir)/`echo $@ | sed 's/\.out$$//'`; \ + fi; \ + if test "$(MANTYPE)" = "man"; then \ + $(FIXPATHSCMD) $${manpage} | $(AWK) -f $(srcdir)/mdoc2man.awk > $@; \ + else \ + $(FIXPATHSCMD) $${manpage} > $@; \ + fi + +$(CONFIGFILES): $(CONFIGFILES_IN) + conffile=`echo $@ | sed 's/.out$$//'`; \ + $(FIXPATHSCMD) $(srcdir)/$${conffile} > $@ + +ssh_prng_cmds.out: ssh_prng_cmds + if test ! -z "$(INSTALL_SSH_PRNG_CMDS)"; then \ + $(PERL) $(srcdir)/fixprogs ssh_prng_cmds $(ENT); \ + fi + +# fake rule to stop make trying to compile moduli.o into a binary "modulo" +moduli: + echo + +clean: + rm -f *.o *.a $(TARGETS) logintest config.cache config.log + rm -f *.out core + (cd openbsd-compat && $(MAKE) clean) + (cd regress && $(MAKE) clean) + +distclean: + rm -f *.o *.a $(TARGETS) logintest config.cache config.log + rm -f *.out core + rm -f Makefile config.h config.status ssh_prng_cmds *~ + rm -rf autom4te.cache + (cd openbsd-compat && $(MAKE) distclean) + (cd scard && $(MAKE) distclean) + (cd regress && $(MAKE) distclean) + +veryclean: distclean + rm -f configure config.h.in *.0 + +mrproper: veryclean + +realclean: veryclean + +catman-do: + @for f in $(MANPAGES_IN) ; do \ + base=`echo $$f | sed 's/\..*$$//'` ; \ + echo "$$f -> $$base.0" ; \ + nroff -mandoc $$f | cat -v | sed -e 's/.\^H//g' \ + >$$base.0 ; \ + done + +distprep: catman-do + $(AUTORECONF) + (cd scard && $(MAKE) -f Makefile.in distprep) + +install: $(CONFIGFILES) ssh_prng_cmds.out $(MANPAGES) $(TARGETS) install-files host-key check-config +install-nokeys: $(CONFIGFILES) ssh_prng_cmds.out $(MANPAGES) $(TARGETS) install-files + +check-config: + -$(DESTDIR)$(sbindir)/sshd -t -f $(DESTDIR)$(sysconfdir)/sshd_config + +scard-install: + (cd scard && $(MAKE) DESTDIR=$(DESTDIR) install) + +install-files: scard-install + $(srcdir)/mkinstalldirs $(DESTDIR)$(bindir) + $(srcdir)/mkinstalldirs $(DESTDIR)$(sbindir) + $(srcdir)/mkinstalldirs $(DESTDIR)$(mandir) + $(srcdir)/mkinstalldirs $(DESTDIR)$(datadir) + $(srcdir)/mkinstalldirs $(DESTDIR)$(mandir)/$(mansubdir)1 + $(srcdir)/mkinstalldirs $(DESTDIR)$(mandir)/$(mansubdir)5 + $(srcdir)/mkinstalldirs $(DESTDIR)$(mandir)/$(mansubdir)8 + $(srcdir)/mkinstalldirs $(DESTDIR)$(libexecdir) + (umask 022 ; $(srcdir)/mkinstalldirs $(DESTDIR)$(PRIVSEP_PATH)) + $(INSTALL) -m 0755 $(STRIP_OPT) ssh $(DESTDIR)$(bindir)/ssh + $(INSTALL) -m 0755 $(STRIP_OPT) scp $(DESTDIR)$(bindir)/scp + $(INSTALL) -m 0755 $(STRIP_OPT) ssh-add $(DESTDIR)$(bindir)/ssh-add + $(INSTALL) -m 0755 $(STRIP_OPT) ssh-agent $(DESTDIR)$(bindir)/ssh-agent + $(INSTALL) -m 0755 $(STRIP_OPT) ssh-keygen $(DESTDIR)$(bindir)/ssh-keygen + $(INSTALL) -m 0755 $(STRIP_OPT) ssh-keyscan $(DESTDIR)$(bindir)/ssh-keyscan + $(INSTALL) -m 0755 $(STRIP_OPT) sshd $(DESTDIR)$(sbindir)/sshd + if test ! -z "$(INSTALL_SSH_RAND_HELPER)" ; then \ + $(INSTALL) -m 0755 $(STRIP_OPT) ssh-rand-helper $(DESTDIR)$(libexecdir)/ssh-rand-helper ; \ + fi + $(INSTALL) -m 4711 $(STRIP_OPT) ssh-keysign $(DESTDIR)$(SSH_KEYSIGN) + $(INSTALL) -m 0755 $(STRIP_OPT) sftp $(DESTDIR)$(bindir)/sftp + $(INSTALL) -m 0755 $(STRIP_OPT) sftp-server $(DESTDIR)$(SFTP_SERVER) + $(INSTALL) -m 644 ssh.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 + $(INSTALL) -m 644 scp.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1 + $(INSTALL) -m 644 ssh-add.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1 + $(INSTALL) -m 644 ssh-agent.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-agent.1 + $(INSTALL) -m 644 ssh-keygen.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keygen.1 + $(INSTALL) -m 644 ssh-keyscan.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keyscan.1 + $(INSTALL) -m 644 sshd_config.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/sshd_config.5 + $(INSTALL) -m 644 ssh_config.5.out $(DESTDIR)$(mandir)/$(mansubdir)5/ssh_config.5 + $(INSTALL) -m 644 sshd.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sshd.8 + if [ ! -z "$(INSTALL_SSH_RAND_HELPER)" ]; then \ + $(INSTALL) -m 644 ssh-rand-helper.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-rand-helper.8 ; \ + fi + $(INSTALL) -m 644 sftp.1.out $(DESTDIR)$(mandir)/$(mansubdir)1/sftp.1 + $(INSTALL) -m 644 sftp-server.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8 + $(INSTALL) -m 644 ssh-keysign.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8 + -rm -f $(DESTDIR)$(bindir)/slogin + ln -s ./ssh$(EXEEXT) $(DESTDIR)$(bindir)/slogin + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 + ln -s ./ssh.1 $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 + if [ ! -d $(DESTDIR)$(sysconfdir) ]; then \ + $(srcdir)/mkinstalldirs $(DESTDIR)$(sysconfdir); \ + fi + @if [ ! -f $(DESTDIR)$(sysconfdir)/ssh_config ]; then \ + $(INSTALL) -m 644 ssh_config.out $(DESTDIR)$(sysconfdir)/ssh_config; \ + else \ + echo "$(DESTDIR)$(sysconfdir)/ssh_config already exists, install will not overwrite"; \ + fi + @if [ ! -f $(DESTDIR)$(sysconfdir)/sshd_config ]; then \ + $(INSTALL) -m 644 sshd_config.out $(DESTDIR)$(sysconfdir)/sshd_config; \ + else \ + echo "$(DESTDIR)$(sysconfdir)/sshd_config already exists, install will not overwrite"; \ + fi + @if [ -f ssh_prng_cmds -a ! -z "$(INSTALL_SSH_PRNG_CMDS)" ]; then \ + if [ ! -f $(DESTDIR)$(sysconfdir)/ssh_prng_cmds ] ; then \ + $(INSTALL) -m 644 ssh_prng_cmds.out $(DESTDIR)$(sysconfdir)/ssh_prng_cmds; \ + else \ + echo "$(DESTDIR)$(sysconfdir)/ssh_prng_cmds already exists, install will not overwrite"; \ + fi ; \ + fi + @if [ ! -f $(DESTDIR)$(sysconfdir)/moduli ]; then \ + if [ -f $(DESTDIR)$(sysconfdir)/primes ]; then \ + echo "moving $(DESTDIR)$(sysconfdir)/primes to $(DESTDIR)$(sysconfdir)/moduli"; \ + mv "$(DESTDIR)$(sysconfdir)/primes" "$(DESTDIR)$(sysconfdir)/moduli"; \ + else \ + $(INSTALL) -m 644 moduli.out $(DESTDIR)$(sysconfdir)/moduli; \ + fi ; \ + else \ + echo "$(DESTDIR)$(sysconfdir)/moduli already exists, install will not overwrite"; \ + fi + +host-key: ssh-keygen$(EXEEXT) + @if [ -z "$(DESTDIR)" ] ; then \ + if [ -f "$(DESTDIR)$(sysconfdir)/ssh_host_key" ] ; then \ + echo "$(DESTDIR)$(sysconfdir)/ssh_host_key already exists, skipping." ; \ + else \ + ./ssh-keygen -t rsa1 -f $(DESTDIR)$(sysconfdir)/ssh_host_key -N "" ; \ + fi ; \ + if [ -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key ] ; then \ + echo "$(DESTDIR)$(sysconfdir)/ssh_host_dsa_key already exists, skipping." ; \ + else \ + ./ssh-keygen -t dsa -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key -N "" ; \ + fi ; \ + if [ -f $(DESTDIR)$(sysconfdir)/ssh_host_rsa_key ] ; then \ + echo "$(DESTDIR)$(sysconfdir)/ssh_host_rsa_key already exists, skipping." ; \ + else \ + ./ssh-keygen -t rsa -f $(DESTDIR)$(sysconfdir)/ssh_host_rsa_key -N "" ; \ + fi ; \ + fi ; + +host-key-force: ssh-keygen$(EXEEXT) + ./ssh-keygen -t rsa1 -f $(DESTDIR)$(sysconfdir)/ssh_host_key -N "" + ./ssh-keygen -t dsa -f $(DESTDIR)$(sysconfdir)/ssh_host_dsa_key -N "" + ./ssh-keygen -t rsa -f $(DESTDIR)$(sysconfdir)/ssh_host_rsa_key -N "" + +uninstallall: uninstall + -rm -f $(DESTDIR)$(sysconfdir)/ssh_config + -rm -f $(DESTDIR)$(sysconfdir)/sshd_config + -rm -f $(DESTDIR)$(sysconfdir)/ssh_prng_cmds + -rmdir $(DESTDIR)$(sysconfdir) + -rmdir $(DESTDIR)$(bindir) + -rmdir $(DESTDIR)$(sbindir) + -rmdir $(DESTDIR)$(mandir)/$(mansubdir)1 + -rmdir $(DESTDIR)$(mandir)/$(mansubdir)8 + -rmdir $(DESTDIR)$(mandir) + -rmdir $(DESTDIR)$(libexecdir) + +uninstall: + -rm -f $(DESTDIR)$(bindir)/slogin + -rm -f $(DESTDIR)$(bindir)/ssh$(EXEEXT) + -rm -f $(DESTDIR)$(bindir)/scp$(EXEEXT) + -rm -f $(DESTDIR)$(bindir)/ssh-add$(EXEEXT) + -rm -f $(DESTDIR)$(bindir)/ssh-agent$(EXEEXT) + -rm -f $(DESTDIR)$(bindir)/ssh-keygen$(EXEEXT) + -rm -f $(DESTDIR)$(bindir)/ssh-keyscan$(EXEEXT) + -rm -f $(DESTDIR)$(bindir)/sftp$(EXEEXT) + -rm -f $(DESTDIR)$(sbindir)/sshd$(EXEEXT) + -rm -r $(DESTDIR)$(SFTP_SERVER)$(EXEEXT) + -rm -f $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT) + -rm -f $(DESTDIR)$(RAND_HELPER)$(EXEEXT) + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-agent.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keygen.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/sftp.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keyscan.1 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sshd.8 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-rand-helper.8 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8 + -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 + +tests: $(TARGETS) + BUILDDIR=`pwd`; \ + [ -d `pwd`/regress ] || mkdir -p `pwd`/regress; \ + TEST_SSH_SSH="$${BUILDDIR}/ssh"; \ + TEST_SSH_SSHD="$${BUILDDIR}/sshd"; \ + TEST_SSH_SSHAGENT="$${BUILDDIR}/ssh-agent"; \ + TEST_SSH_SSHADD="$${BUILDDIR}/ssh-add"; \ + TEST_SSH_SSHKEYGEN="$${BUILDDIR}/ssh-keygen"; \ + TEST_SSH_SSHKEYSCAN="$${BUILDDIR}/ssh-keyscan"; \ + TEST_SSH_SFTP="$${BUILDDIR}/sftp"; \ + TEST_SSH_SFTPSERVER="$${BUILDDIR}/sftp-server"; \ + cd $(srcdir)/regress || exit $$?; \ + $(MAKE) \ + .OBJDIR="$${BUILDDIR}/regress" \ + .CURDIR="`pwd`" \ + BUILDDIR="$${BUILDDIR}" \ + OBJ="$${BUILDDIR}/regress/" \ + PATH="$${BUILDDIR}:$${PATH}" \ + TEST_SSH_SSH="$${TEST_SSH_SSH}" \ + TEST_SSH_SSHD="$${TEST_SSH_SSHD}" \ + TEST_SSH_SSHAGENT="$${TEST_SSH_SSHAGENT}" \ + TEST_SSH_SSHADD="$${TEST_SSH_SSHADD}" \ + TEST_SSH_SSHKEYGEN="$${TEST_SSH_SSHKEYGEN}" \ + TEST_SSH_SSHKEYSCAN="$${TEST_SSH_SSHKEYSCAN}" \ + TEST_SSH_SFTP="$${TEST_SSH_SFTP}" \ + TEST_SSH_SFTPSERVER="$${TEST_SSH_SFTPSERVER}" \ + EXEEXT="$(EXEEXT)" \ + $@ diff -ruN --exclude CVS ssh-openbsd-2003091600/Makefile.inc openssh-3.7p1/Makefile.inc --- ssh-openbsd-2003091600/Makefile.inc 2003-05-15 10:10:35.000000000 +1000 +++ openssh-3.7p1/Makefile.inc 1970-01-01 10:00:00.000000000 +1000 @@ -1,28 +0,0 @@ -# $OpenBSD: Makefile.inc,v 1.24 2003/05/14 18:16:20 jakob Exp $ - -CFLAGS+= -I${.CURDIR}/.. - -CDIAGFLAGS= -Wall -#CDIAGFLAGS+= -Werror -CDIAGFLAGS+= -Wpointer-arith -CDIAGFLAGS+= -Wno-uninitialized -#CDIAGFLAGS+= -Wstrict-prototypes -CDIAGFLAGS+= -Wmissing-prototypes -CDIAGFLAGS+= -Wunused - -#DEBUG=-g - -#CFLAGS+= -DSMARTCARD -#LDADD+= -lsectok - -#CFLAGS+= -DDNS - -.include - -.if exists(${.CURDIR}/../lib/${__objdir}) -LDADD+= -L${.CURDIR}/../lib/${__objdir} -lssh -DPADD+= ${.CURDIR}/../lib/${__objdir}/libssh.a -.else -LDADD+= -L${.CURDIR}/../lib -lssh -DPADD+= ${.CURDIR}/../lib/libssh.a -.endif diff -ruN --exclude CVS ssh-openbsd-2003091600/md5crypt.c openssh-3.7p1/md5crypt.c --- ssh-openbsd-2003091600/md5crypt.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/md5crypt.c 2003-05-30 16:58:23.000000000 +1000 @@ -0,0 +1,165 @@ +/* + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * wrote this file. As long as you retain this + * notice you can do whatever you want with this stuff. If we meet some + * day, and you think this stuff is worth it, you can buy me a beer in + * return. Poul-Henning Kamp + * ---------------------------------------------------------------------------- + */ + +#include "includes.h" + +#if defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) +#include + +RCSID("$Id: md5crypt.c,v 1.7 2003/05/30 06:58:23 dtucker Exp $"); + +/* 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 -ruN --exclude CVS ssh-openbsd-2003091600/md5crypt.h openssh-3.7p1/md5crypt.h --- ssh-openbsd-2003091600/md5crypt.h 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/md5crypt.h 2003-05-19 00:46:46.000000000 +1000 @@ -0,0 +1,24 @@ +/* + * ---------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp + * ---------------------------------------------------------------------------- + */ + +/* $Id: md5crypt.h,v 1.4 2003/05/18 14:46:46 djm Exp $ */ + +#ifndef _MD5CRYPT_H +#define _MD5CRYPT_H + +#include "config.h" + +#if defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) + +int is_md5_salt(const char *); +char *md5_crypt(const char *, const char *); + +#endif /* defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) */ + +#endif /* MD5CRYPT_H */ diff -ruN --exclude CVS ssh-openbsd-2003091600/mdoc2man.awk openssh-3.7p1/mdoc2man.awk --- ssh-openbsd-2003091600/mdoc2man.awk 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/mdoc2man.awk 2003-09-07 12:34:54.000000000 +1000 @@ -0,0 +1,340 @@ +#!/usr/bin/awk +# +# Version history: +# v3, I put the program under a proper license +# Dan Nelson added .An, .Aq and fixed a typo +# v2, fixed to work on GNU awk --posix and MacOS X +# v1, first attempt, didn't work on MacOS X +# +# Copyright (c) 2003 Peter Stuge +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + +BEGIN { + optlist=0 + oldoptlist=0 + nospace=0 + synopsis=0 + reference=0 + block=0 + ext=0 + extopt=0 + literal=0 + prenl=0 + line="" +} + +function wtail() { + retval="" + while(w0;i--) { + add(refauthors[i]) + if(i>1) + add(", ") + } + if(nrefauthors>1) + add(" and ") + add(refauthors[0] ", \\fI" reftitle "\\fP") + if(length(refissue)) + add(", " refissue) + 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() } + } else if(match(words[w],"^Nm$")) { + if(synopsis) { + add(".br") + prenl++ + } + n=words[++w] + if(!length(name)) + name=n + if(!length(n)) + n=name + add("\\fB" n "\\fP") + if(!nospace&&match(words[w+1],"^[\\.,]")) + nospace=1 + } else if(match(words[w],"^Nd$")) { + add("\\- " wtail()) + } else if(match(words[w],"^Fl$")) { + add("\\fB\\-" words[++w] "\\fP") + if(!nospace&&match(words[w+1],"^[\\.,]")) + nospace=1 + } else if(match(words[w],"^Ar$")) { + add("\\fI") + if(w==nwords) + add("file ...\\fP") + else { + add(words[++w] "\\fP") + while(match(words[w+1],"^\\|$")) + add(OFS words[++w] " \\fI" words[++w] "\\fP") + } + if(!nospace&&match(words[w+1],"^[\\.,]")) + nospace=1 + } else if(match(words[w],"^Cm$")) { + add("\\fB" words[++w] "\\fP") + while(w") + if(option) + add("]") + if(ext&&!extopt&&!match(line," $")) + add(OFS) + if(!ext&&!extopt&&length(line)) { + print line + prenl=0 + line="" + } +} diff -ruN --exclude CVS ssh-openbsd-2003091600/misc.c openssh-3.7p1/misc.c --- ssh-openbsd-2003091600/misc.c 2003-05-13 13:34:30.000000000 +1000 +++ openssh-3.7p1/misc.c 2003-08-25 11:16:21.000000000 +1000 @@ -152,9 +152,15 @@ 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; diff -ruN --exclude CVS ssh-openbsd-2003091600/mkinstalldirs openssh-3.7p1/mkinstalldirs --- ssh-openbsd-2003091600/mkinstalldirs 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/mkinstalldirs 2000-05-20 15:33:45.000000000 +1000 @@ -0,0 +1,40 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +# $Id: mkinstalldirs,v 1.1 2000/05/20 05:33:45 damien 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 -ruN --exclude CVS ssh-openbsd-2003091600/moduli openssh-3.7p1/moduli --- ssh-openbsd-2003091600/moduli 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/moduli 2001-09-25 13:06:19.000000000 +1000 @@ -0,0 +1,158 @@ +# $OpenBSD: moduli,v 1.1 2001/06/22 22:07:54 provos Exp $ + +# Time Type Tests Tries Size Generator Modulus +20010328182134 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF5449C221CB +20010328182222 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF5449C95A43 +20010328182256 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF5449CC8CFB +20010328182409 2 6 100 1023 5 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF5449D9BDB7 +20010328182628 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF5449FB6EF3 +20010328182708 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544A000153 +20010328182758 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544A06E9EB +20010328182946 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544A1F2C93 +20010328183015 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544A206ADB +20010328183112 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544A2A109B +20010328183143 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544A2BC1BB +20010328183301 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544A3ADCEB +20010328183532 2 6 100 1023 5 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544A5E8BAF +20010328183646 2 6 100 1023 5 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544A6D54D7 +20010328183712 2 6 100 1023 5 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544A6EC46F +20010328184223 2 6 100 1023 5 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544AB8626F +20010328184337 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544AC7DC73 +20010328184634 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544AEFF073 +20010328184714 2 6 100 1023 5 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544AF594FF +20010328184807 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544AFEEC53 +20010328184910 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544B0B3513 +20010328185030 2 6 100 1023 5 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544B165707 +20010328185334 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544B3A9673 +20010328185423 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544B426623 +20010328185451 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544B4427DB +20010328185637 2 6 100 1023 5 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544B5E3FC7 +20010328185720 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544B65964B +20010328185757 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544B6A9373 +20010328185844 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544B7203B3 +20010328185933 2 6 100 1023 5 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544B7A9FFF +20010328190006 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544B7DAAD3 +20010328190054 2 6 100 1023 5 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544B855C2F +20010328190139 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544B8C53EB +20010328190304 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544B9F26C3 +20010328190329 2 6 100 1023 5 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544BA00697 +20010328190412 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544BA54313 +20010328190506 2 6 100 1023 5 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544BAEEF27 +20010328190550 2 6 100 1023 2 DCFAC4EFE89F5B082962AB9A67E8D63E84FA491E5D3874978815868595469163DA0661E6208A8C2CD4F83893B53864ADFD2154E8D8EFA146BAD808562E4BF6C90348FD79EEB3387D93FC7943BC450BA55399BA3CF3DFBD0D4E71800007B0E9D5F12E7A2CB7EA4E49812E715F8DC570C478DC2DEB1C49B0AE87A5DF544BB5CE0B +20010328200734 2 6 100 1534 5 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC33395187 +20010328201124 2 6 100 1534 2 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC334ED15B +20010328201358 2 6 100 1534 5 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC3359FC07 +20010328201537 2 6 100 1534 2 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC335F7A83 +20010328201829 2 6 100 1534 2 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC336D1433 +20010328202120 2 6 100 1534 2 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC337B253B +20010328202848 2 6 100 1534 5 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC33A3D43F +20010328203335 2 6 100 1534 2 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC33BF24A3 +20010328204332 2 6 100 1534 2 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC34011B8B +20010328204443 2 6 100 1534 5 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC3402A92F +20010328204617 2 6 100 1534 2 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC3406D343 +20010328205458 2 6 100 1534 2 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC3436FA2B +20010328210413 2 6 100 1534 2 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC3471CF1B +20010328213513 2 6 100 1534 5 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC352AF5EF +20010328215014 2 6 100 1534 2 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC358CC3CB +20010328215520 2 6 100 1534 5 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC35A9B7FF +20010328215733 2 6 100 1534 5 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC35B2927F +20010328220114 2 6 100 1534 2 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC35C47323 +20010328220334 2 6 100 1534 2 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC35CFA9C3 +20010328220653 2 6 100 1534 5 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC35E0BB37 +20010328220915 2 6 100 1534 2 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC35E9CC23 +20010328221256 2 6 100 1534 5 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC35FD7D67 +20010328221457 2 6 100 1534 2 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC36052CCB +20010328222639 2 6 100 1534 5 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC364A1E07 +20010328224126 2 6 100 1534 5 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC36AD5557 +20010328225125 2 6 100 1534 5 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC36EE57BF +20010328225751 2 6 100 1534 2 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC3716A70B +20010328225943 2 6 100 1534 2 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC371D010B +20010328230054 2 6 100 1534 5 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC371EB5C7 +20010328230301 2 6 100 1534 2 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC37275F4B +20010328230628 2 6 100 1534 2 6DFD16D9669EDAF42EF5D4EED82AA84B0541DEC2045B6AF55021A184F32BCADE614A114137022C9A8B41C09AFC38199E7305864F70A8708F37FC2127264ECF4FA32391F243CC62B89602D3813082679E5BDF496BA9DFA4C818AD21EC261B6F11841E6F2DE1574CE95095841DAF052868CCD5E9BFCA543E0934B50A76A598E693136DE2D479AEF3785D97BAFF4FB85AB8D46DA424C4CC5E11ABCAF718837E16350982BF8A27728318EC02C71ED164F57CDB121B72614B7B7C406613EC3738C3F3 +20010329000424 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853ACAACAB +20010329001637 2 6 100 2046 5 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853AE5BE0F +20010329002229 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853AEDE2D3 +20010329003652 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853B0F32CB +20010329005040 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853B30E503 +20010329014643 2 6 100 2046 5 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853BC9AF57 +20010329021950 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853C205263 +20010329023256 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853C3F2E53 +20010329031049 2 6 100 2046 5 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853CA28BBF +20010329032045 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853CB81103 +20010329052113 2 6 100 2046 5 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853DF13B47 +20010329052449 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853DF3ED53 +20010329060404 2 6 100 2046 5 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853E5D25E7 +20010329062856 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853E9CF013 +20010329063152 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853E9E1CEB +20010329070601 2 6 100 2046 5 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853EF58B7F +20010329071302 2 6 100 2046 5 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853F017697 +20010329072011 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853F0E72D3 +20010329072445 2 6 100 2046 5 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853F14CE17 +20010329073641 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853F2EEBA3 +20010329075209 2 6 100 2046 5 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853F52E927 +20010329080750 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853F776F8B +20010329084002 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853FC98043 +20010329084744 2 6 100 2046 5 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853FD7EAAF +20010329090209 2 6 100 2046 5 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993853FF9AF5F +20010329093527 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC3499385404E330B +20010329094652 2 6 100 2046 5 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC349938540672D1F +20010329103445 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC349938540E4B213 +20010329111418 2 6 100 2046 5 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC34993854144947F +20010329112031 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC3499385414F223B +20010329112413 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC349938541522073 +20010329114209 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC3499385417C8E53 +20010329125026 2 6 100 2046 2 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC3499385422E41AB +20010329132045 2 6 100 2046 5 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC3499385427DD3FF +20010329134105 2 6 100 2046 5 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC349938542AFA2D7 +20010329134914 2 6 100 2046 5 7ED0888B660A818F15E5F76A7F2BF10C99D74129DA04446C60116C9C800501060B8AFF075DCE0C08CEFDF695440E6F16FCCDB06359D080EF62D6485CBAEB94B92BE771D535B4EA9C5D14D84CD7649E25C7CFEA2C914486CC2BFDE77C4C0DF1D6DDED65FEE2F53A7FA690AFE38EE00C154FBAEFF935466B176CB0AED02458A552929F4EA7FC3E6F9F758DE7F22CC1F49641F492820441BDC109F0CE18F883FC93EA9AC4C1432682BA1C5B67BED8C861152A5F952A8CDCF1BCE02B8D93E80C113CE9FE2E4ACA49B2978B99A8C5FA231A77F5E7C604D44C7C6EA98D561294D4F7AB061432CAB8BBDCEC3659DE64F65265E6B9FC5F46879BB17CC349938542C04A37 +20010403222140 2 6 100 3190 5 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B0AB16DAF +20010403225231 2 6 100 3190 5 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B0AC56CFF +20010404053436 2 6 100 3190 5 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B0C2F4B7F +20010404092851 2 6 100 3190 5 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B0D04E7F7 +20010404093943 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B0D07794B +20010404102659 2 6 100 3190 5 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B0D2BE8CF +20010404112553 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B0D5D012B +20010404174625 2 6 100 3190 5 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B0EA59E17 +20010404184645 2 6 100 3190 5 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B0ED6DA4F +20010404193402 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B0EFB39B3 +20010404230716 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B0FB07C1B +20010405044433 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B10DD9FC3 +20010405053429 2 6 100 3190 5 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B11038737 +20010405062826 2 6 100 3190 5 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B112E24E7 +20010405092601 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B11C9E9FB +20010405113007 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B123803EB +20010405122212 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B12612ED3 +20010405182035 2 6 100 3190 5 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B13A25087 +20010405210758 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B142C4E23 +20010405220222 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B145878F3 +20010406020130 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B152AF6AB +20010406053538 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B15E78C8B +20010406073014 2 6 100 3190 5 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B1649BFEF +20010406074100 2 6 100 3190 5 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B164D4E3F +20010406103625 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B16E07B33 +20010406131946 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B17706243 +20010406170234 2 6 100 3190 5 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B182FD957 +20010406182949 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B18768903 +20010406203157 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B18DCFC3B +20010407022825 2 6 100 3190 5 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B1A1AF797 +20010407071024 2 6 100 3190 5 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B1B1551E7 +20010407112402 2 6 100 3190 5 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B1BF78EC7 +20010407123215 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B1C30021B +20010407161504 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B1CF27743 +20010407171629 2 6 100 3190 5 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B1D25FAD7 +20010407191502 2 6 100 3190 2 669BA3ED661F226A090BE5644A2BB4209371B78FC3E6848A095821993F59084CA5EE12052F977D01F0666F03F6573B199DFEC9AB94588C2C60DE3B3E7CF5094587919FCC3FB40A61C261E891A0F91D9FFC8F30CA12CF809DD8290DD786FA8B041FFAC5793C38F38757EA6790472AC2692185B554B0046E8C065C983C0ACC8D2F85AB4BEDF7CE233009218C9691FE44261580D4149F1D4471B0B5DF79E224252474EBC3B7B5490950BB438BF498E79F8794498B3A3B5FBB42829C3BBEA4067F28C23BE40377B986BD5443CCCF02405B8CCCAA09E8179F0168D4969994171A6AD98F81015BC84E10A44E1EFD2E0862C5D1AAFE99014715A36800DBD9A6C51C0226CC82A651DAE4F73D54C4D103C13D1C15CF8CCA67D5CB39F03C66F3B7467F8FFDCC5074CD0C1B2538FBF956971BF39314CEDD20E1B10DE16D86E10BE7FA5B1A706AEB4C356F49807A22072CD00559AF0A863788956651919E26A315EAD1D26E7C98FC4CFA35A0F04DD400A2991A1FFE5B271FEDE54375896A29F968BE1D511BA466A92AC3E3772709FC815B1D8C2753 +20010420002705 2 6 100 4094 2 65B5B9F5ECFADB4CCB38D1BC894302E95B4843290F1A7A40579DF3E2FF98C1D3DA9F210857C784433DF32ADF9E0C80121211690E1FFB41B8DB4E86AFE388A09C9BB2C98EDC581C2E65D57F61BB920C3D1B7B058B5FADFF65D607DAFF443B8BA1ACE1A3A7B16EA0713F62537C6689E3C4A0F61198F3B054FCF140CFADD8622C0E7621998331E59DA6F72E9D608D0E58F526E95F485C7CA30A416617DA3CCFF722BB82362606283D054B34B83ECDB4C91BAB835944010EBE5E9FA7B016ED89891DD553CC71B5CF76EDB2A184B377F670D6AF191763EEFD175E48EA37EE18B9E44E2D017D845C444C8111816819866E490B52F7F879A0C6F401CF7859674F93E304365F4E8CB8C312EFB725732A46D7CF0C9D2939AEE25F428CEFC90959DBF8ADD612F343EF9BFCA2FBA61BD4BF93E1E54626D227FDA812E18D071579AB4EEAC9901DAB183BCB0D9F48732D92CE66B386EAE5D8212C9FD156DC3F09B171B5603E17A468D244F3B6880EBCDA189BA9E23E4A4C6C2995ACF264F8CE9D54B27316343C0BC19221F75E6A2AC68011741695E599F73460B7A042E0461DB189CDCE223B40336BF2251AE3B363159960C9F63B47EFC43790D474DABB9A686DAF21E0DD76533749FCA9F144FA9C243CEF1364C79D981ED81DC4635C73B7F8908BA190AA920ED370F815BC2F9B3D28ED87BE34A01498836222C17B70C246C03CA1C10C1E08F3 +20010420005243 2 6 100 4094 2 65B5B9F5ECFADB4CCB38D1BC894302E95B4843290F1A7A40579DF3E2FF98C1D3DA9F210857C784433DF32ADF9E0C80121211690E1FFB41B8DB4E86AFE388A09C9BB2C98EDC581C2E65D57F61BB920C3D1B7B058B5FADFF65D607DAFF443B8BA1ACE1A3A7B16EA0713F62537C6689E3C4A0F61198F3B054FCF140CFADD8622C0E7621998331E59DA6F72E9D608D0E58F526E95F485C7CA30A416617DA3CCFF722BB82362606283D054B34B83ECDB4C91BAB835944010EBE5E9FA7B016ED89891DD553CC71B5CF76EDB2A184B377F670D6AF191763EEFD175E48EA37EE18B9E44E2D017D845C444C8111816819866E490B52F7F879A0C6F401CF7859674F93E304365F4E8CB8C312EFB725732A46D7CF0C9D2939AEE25F428CEFC90959DBF8ADD612F343EF9BFCA2FBA61BD4BF93E1E54626D227FDA812E18D071579AB4EEAC9901DAB183BCB0D9F48732D92CE66B386EAE5D8212C9FD156DC3F09B171B5603E17A468D244F3B6880EBCDA189BA9E23E4A4C6C2995ACF264F8CE9D54B27316343C0BC19221F75E6A2AC68011741695E599F73460B7A042E0461DB189CDCE223B40336BF2251AE3B363159960C9F63B47EFC43790D474DABB9A686DAF21E0DD76533749FCA9F144FA9C243CEF1364C79D981ED81DC4635C73B7F8908BA190AA920ED370F815BC2F9B3D28ED87BE34A01498836222C17B70C246C03CA1C10C219FB3 +20010420035225 2 6 100 4094 5 65B5B9F5ECFADB4CCB38D1BC894302E95B4843290F1A7A40579DF3E2FF98C1D3DA9F210857C784433DF32ADF9E0C80121211690E1FFB41B8DB4E86AFE388A09C9BB2C98EDC581C2E65D57F61BB920C3D1B7B058B5FADFF65D607DAFF443B8BA1ACE1A3A7B16EA0713F62537C6689E3C4A0F61198F3B054FCF140CFADD8622C0E7621998331E59DA6F72E9D608D0E58F526E95F485C7CA30A416617DA3CCFF722BB82362606283D054B34B83ECDB4C91BAB835944010EBE5E9FA7B016ED89891DD553CC71B5CF76EDB2A184B377F670D6AF191763EEFD175E48EA37EE18B9E44E2D017D845C444C8111816819866E490B52F7F879A0C6F401CF7859674F93E304365F4E8CB8C312EFB725732A46D7CF0C9D2939AEE25F428CEFC90959DBF8ADD612F343EF9BFCA2FBA61BD4BF93E1E54626D227FDA812E18D071579AB4EEAC9901DAB183BCB0D9F48732D92CE66B386EAE5D8212C9FD156DC3F09B171B5603E17A468D244F3B6880EBCDA189BA9E23E4A4C6C2995ACF264F8CE9D54B27316343C0BC19221F75E6A2AC68011741695E599F73460B7A042E0461DB189CDCE223B40336BF2251AE3B363159960C9F63B47EFC43790D474DABB9A686DAF21E0DD76533749FCA9F144FA9C243CEF1364C79D981ED81DC4635C73B7F8908BA190AA920ED370F815BC2F9B3D28ED87BE34A01498836222C17B70C246C03CA1C10C660B3F +20010420145749 2 6 100 4094 2 65B5B9F5ECFADB4CCB38D1BC894302E95B4843290F1A7A40579DF3E2FF98C1D3DA9F210857C784433DF32ADF9E0C80121211690E1FFB41B8DB4E86AFE388A09C9BB2C98EDC581C2E65D57F61BB920C3D1B7B058B5FADFF65D607DAFF443B8BA1ACE1A3A7B16EA0713F62537C6689E3C4A0F61198F3B054FCF140CFADD8622C0E7621998331E59DA6F72E9D608D0E58F526E95F485C7CA30A416617DA3CCFF722BB82362606283D054B34B83ECDB4C91BAB835944010EBE5E9FA7B016ED89891DD553CC71B5CF76EDB2A184B377F670D6AF191763EEFD175E48EA37EE18B9E44E2D017D845C444C8111816819866E490B52F7F879A0C6F401CF7859674F93E304365F4E8CB8C312EFB725732A46D7CF0C9D2939AEE25F428CEFC90959DBF8ADD612F343EF9BFCA2FBA61BD4BF93E1E54626D227FDA812E18D071579AB4EEAC9901DAB183BCB0D9F48732D92CE66B386EAE5D8212C9FD156DC3F09B171B5603E17A468D244F3B6880EBCDA189BA9E23E4A4C6C2995ACF264F8CE9D54B27316343C0BC19221F75E6A2AC68011741695E599F73460B7A042E0461DB189CDCE223B40336BF2251AE3B363159960C9F63B47EFC43790D474DABB9A686DAF21E0DD76533749FCA9F144FA9C243CEF1364C79D981ED81DC4635C73B7F8908BA190AA920ED370F815BC2F9B3D28ED87BE34A01498836222C17B70C246C03CA1C10D741313 +20010420205718 2 6 100 4094 2 65B5B9F5ECFADB4CCB38D1BC894302E95B4843290F1A7A40579DF3E2FF98C1D3DA9F210857C784433DF32ADF9E0C80121211690E1FFB41B8DB4E86AFE388A09C9BB2C98EDC581C2E65D57F61BB920C3D1B7B058B5FADFF65D607DAFF443B8BA1ACE1A3A7B16EA0713F62537C6689E3C4A0F61198F3B054FCF140CFADD8622C0E7621998331E59DA6F72E9D608D0E58F526E95F485C7CA30A416617DA3CCFF722BB82362606283D054B34B83ECDB4C91BAB835944010EBE5E9FA7B016ED89891DD553CC71B5CF76EDB2A184B377F670D6AF191763EEFD175E48EA37EE18B9E44E2D017D845C444C8111816819866E490B52F7F879A0C6F401CF7859674F93E304365F4E8CB8C312EFB725732A46D7CF0C9D2939AEE25F428CEFC90959DBF8ADD612F343EF9BFCA2FBA61BD4BF93E1E54626D227FDA812E18D071579AB4EEAC9901DAB183BCB0D9F48732D92CE66B386EAE5D8212C9FD156DC3F09B171B5603E17A468D244F3B6880EBCDA189BA9E23E4A4C6C2995ACF264F8CE9D54B27316343C0BC19221F75E6A2AC68011741695E599F73460B7A042E0461DB189CDCE223B40336BF2251AE3B363159960C9F63B47EFC43790D474DABB9A686DAF21E0DD76533749FCA9F144FA9C243CEF1364C79D981ED81DC4635C73B7F8908BA190AA920ED370F815BC2F9B3D28ED87BE34A01498836222C17B70C246C03CA1C10DD41193 +20010420232458 2 6 100 4094 5 65B5B9F5ECFADB4CCB38D1BC894302E95B4843290F1A7A40579DF3E2FF98C1D3DA9F210857C784433DF32ADF9E0C80121211690E1FFB41B8DB4E86AFE388A09C9BB2C98EDC581C2E65D57F61BB920C3D1B7B058B5FADFF65D607DAFF443B8BA1ACE1A3A7B16EA0713F62537C6689E3C4A0F61198F3B054FCF140CFADD8622C0E7621998331E59DA6F72E9D608D0E58F526E95F485C7CA30A416617DA3CCFF722BB82362606283D054B34B83ECDB4C91BAB835944010EBE5E9FA7B016ED89891DD553CC71B5CF76EDB2A184B377F670D6AF191763EEFD175E48EA37EE18B9E44E2D017D845C444C8111816819866E490B52F7F879A0C6F401CF7859674F93E304365F4E8CB8C312EFB725732A46D7CF0C9D2939AEE25F428CEFC90959DBF8ADD612F343EF9BFCA2FBA61BD4BF93E1E54626D227FDA812E18D071579AB4EEAC9901DAB183BCB0D9F48732D92CE66B386EAE5D8212C9FD156DC3F09B171B5603E17A468D244F3B6880EBCDA189BA9E23E4A4C6C2995ACF264F8CE9D54B27316343C0BC19221F75E6A2AC68011741695E599F73460B7A042E0461DB189CDCE223B40336BF2251AE3B363159960C9F63B47EFC43790D474DABB9A686DAF21E0DD76533749FCA9F144FA9C243CEF1364C79D981ED81DC4635C73B7F8908BA190AA920ED370F815BC2F9B3D28ED87BE34A01498836222C17B70C246C03CA1C10E0AB4EF +20010421003952 2 6 100 4094 5 65B5B9F5ECFADB4CCB38D1BC894302E95B4843290F1A7A40579DF3E2FF98C1D3DA9F210857C784433DF32ADF9E0C80121211690E1FFB41B8DB4E86AFE388A09C9BB2C98EDC581C2E65D57F61BB920C3D1B7B058B5FADFF65D607DAFF443B8BA1ACE1A3A7B16EA0713F62537C6689E3C4A0F61198F3B054FCF140CFADD8622C0E7621998331E59DA6F72E9D608D0E58F526E95F485C7CA30A416617DA3CCFF722BB82362606283D054B34B83ECDB4C91BAB835944010EBE5E9FA7B016ED89891DD553CC71B5CF76EDB2A184B377F670D6AF191763EEFD175E48EA37EE18B9E44E2D017D845C444C8111816819866E490B52F7F879A0C6F401CF7859674F93E304365F4E8CB8C312EFB725732A46D7CF0C9D2939AEE25F428CEFC90959DBF8ADD612F343EF9BFCA2FBA61BD4BF93E1E54626D227FDA812E18D071579AB4EEAC9901DAB183BCB0D9F48732D92CE66B386EAE5D8212C9FD156DC3F09B171B5603E17A468D244F3B6880EBCDA189BA9E23E4A4C6C2995ACF264F8CE9D54B27316343C0BC19221F75E6A2AC68011741695E599F73460B7A042E0461DB189CDCE223B40336BF2251AE3B363159960C9F63B47EFC43790D474DABB9A686DAF21E0DD76533749FCA9F144FA9C243CEF1364C79D981ED81DC4635C73B7F8908BA190AA920ED370F815BC2F9B3D28ED87BE34A01498836222C17B70C246C03CA1C10E22F857 +20010421013245 2 6 100 4094 2 65B5B9F5ECFADB4CCB38D1BC894302E95B4843290F1A7A40579DF3E2FF98C1D3DA9F210857C784433DF32ADF9E0C80121211690E1FFB41B8DB4E86AFE388A09C9BB2C98EDC581C2E65D57F61BB920C3D1B7B058B5FADFF65D607DAFF443B8BA1ACE1A3A7B16EA0713F62537C6689E3C4A0F61198F3B054FCF140CFADD8622C0E7621998331E59DA6F72E9D608D0E58F526E95F485C7CA30A416617DA3CCFF722BB82362606283D054B34B83ECDB4C91BAB835944010EBE5E9FA7B016ED89891DD553CC71B5CF76EDB2A184B377F670D6AF191763EEFD175E48EA37EE18B9E44E2D017D845C444C8111816819866E490B52F7F879A0C6F401CF7859674F93E304365F4E8CB8C312EFB725732A46D7CF0C9D2939AEE25F428CEFC90959DBF8ADD612F343EF9BFCA2FBA61BD4BF93E1E54626D227FDA812E18D071579AB4EEAC9901DAB183BCB0D9F48732D92CE66B386EAE5D8212C9FD156DC3F09B171B5603E17A468D244F3B6880EBCDA189BA9E23E4A4C6C2995ACF264F8CE9D54B27316343C0BC19221F75E6A2AC68011741695E599F73460B7A042E0461DB189CDCE223B40336BF2251AE3B363159960C9F63B47EFC43790D474DABB9A686DAF21E0DD76533749FCA9F144FA9C243CEF1364C79D981ED81DC4635C73B7F8908BA190AA920ED370F815BC2F9B3D28ED87BE34A01498836222C17B70C246C03CA1C10E31828B +20010421085157 2 6 100 4094 2 65B5B9F5ECFADB4CCB38D1BC894302E95B4843290F1A7A40579DF3E2FF98C1D3DA9F210857C784433DF32ADF9E0C80121211690E1FFB41B8DB4E86AFE388A09C9BB2C98EDC581C2E65D57F61BB920C3D1B7B058B5FADFF65D607DAFF443B8BA1ACE1A3A7B16EA0713F62537C6689E3C4A0F61198F3B054FCF140CFADD8622C0E7621998331E59DA6F72E9D608D0E58F526E95F485C7CA30A416617DA3CCFF722BB82362606283D054B34B83ECDB4C91BAB835944010EBE5E9FA7B016ED89891DD553CC71B5CF76EDB2A184B377F670D6AF191763EEFD175E48EA37EE18B9E44E2D017D845C444C8111816819866E490B52F7F879A0C6F401CF7859674F93E304365F4E8CB8C312EFB725732A46D7CF0C9D2939AEE25F428CEFC90959DBF8ADD612F343EF9BFCA2FBA61BD4BF93E1E54626D227FDA812E18D071579AB4EEAC9901DAB183BCB0D9F48732D92CE66B386EAE5D8212C9FD156DC3F09B171B5603E17A468D244F3B6880EBCDA189BA9E23E4A4C6C2995ACF264F8CE9D54B27316343C0BC19221F75E6A2AC68011741695E599F73460B7A042E0461DB189CDCE223B40336BF2251AE3B363159960C9F63B47EFC43790D474DABB9A686DAF21E0DD76533749FCA9F144FA9C243CEF1364C79D981ED81DC4635C73B7F8908BA190AA920ED370F815BC2F9B3D28ED87BE34A01498836222C17B70C246C03CA1C10EE28B2B +20010421092617 2 6 100 4094 2 65B5B9F5ECFADB4CCB38D1BC894302E95B4843290F1A7A40579DF3E2FF98C1D3DA9F210857C784433DF32ADF9E0C80121211690E1FFB41B8DB4E86AFE388A09C9BB2C98EDC581C2E65D57F61BB920C3D1B7B058B5FADFF65D607DAFF443B8BA1ACE1A3A7B16EA0713F62537C6689E3C4A0F61198F3B054FCF140CFADD8622C0E7621998331E59DA6F72E9D608D0E58F526E95F485C7CA30A416617DA3CCFF722BB82362606283D054B34B83ECDB4C91BAB835944010EBE5E9FA7B016ED89891DD553CC71B5CF76EDB2A184B377F670D6AF191763EEFD175E48EA37EE18B9E44E2D017D845C444C8111816819866E490B52F7F879A0C6F401CF7859674F93E304365F4E8CB8C312EFB725732A46D7CF0C9D2939AEE25F428CEFC90959DBF8ADD612F343EF9BFCA2FBA61BD4BF93E1E54626D227FDA812E18D071579AB4EEAC9901DAB183BCB0D9F48732D92CE66B386EAE5D8212C9FD156DC3F09B171B5603E17A468D244F3B6880EBCDA189BA9E23E4A4C6C2995ACF264F8CE9D54B27316343C0BC19221F75E6A2AC68011741695E599F73460B7A042E0461DB189CDCE223B40336BF2251AE3B363159960C9F63B47EFC43790D474DABB9A686DAF21E0DD76533749FCA9F144FA9C243CEF1364C79D981ED81DC4635C73B7F8908BA190AA920ED370F815BC2F9B3D28ED87BE34A01498836222C17B70C246C03CA1C10EE97A3B +20010421135621 2 6 100 4094 2 65B5B9F5ECFADB4CCB38D1BC894302E95B4843290F1A7A40579DF3E2FF98C1D3DA9F210857C784433DF32ADF9E0C80121211690E1FFB41B8DB4E86AFE388A09C9BB2C98EDC581C2E65D57F61BB920C3D1B7B058B5FADFF65D607DAFF443B8BA1ACE1A3A7B16EA0713F62537C6689E3C4A0F61198F3B054FCF140CFADD8622C0E7621998331E59DA6F72E9D608D0E58F526E95F485C7CA30A416617DA3CCFF722BB82362606283D054B34B83ECDB4C91BAB835944010EBE5E9FA7B016ED89891DD553CC71B5CF76EDB2A184B377F670D6AF191763EEFD175E48EA37EE18B9E44E2D017D845C444C8111816819866E490B52F7F879A0C6F401CF7859674F93E304365F4E8CB8C312EFB725732A46D7CF0C9D2939AEE25F428CEFC90959DBF8ADD612F343EF9BFCA2FBA61BD4BF93E1E54626D227FDA812E18D071579AB4EEAC9901DAB183BCB0D9F48732D92CE66B386EAE5D8212C9FD156DC3F09B171B5603E17A468D244F3B6880EBCDA189BA9E23E4A4C6C2995ACF264F8CE9D54B27316343C0BC19221F75E6A2AC68011741695E599F73460B7A042E0461DB189CDCE223B40336BF2251AE3B363159960C9F63B47EFC43790D474DABB9A686DAF21E0DD76533749FCA9F144FA9C243CEF1364C79D981ED81DC4635C73B7F8908BA190AA920ED370F815BC2F9B3D28ED87BE34A01498836222C17B70C246C03CA1C10F52C463 +20010422012438 2 6 100 4094 2 65B5B9F5ECFADB4CCB38D1BC894302E95B4843290F1A7A40579DF3E2FF98C1D3DA9F210857C784433DF32ADF9E0C80121211690E1FFB41B8DB4E86AFE388A09C9BB2C98EDC581C2E65D57F61BB920C3D1B7B058B5FADFF65D607DAFF443B8BA1ACE1A3A7B16EA0713F62537C6689E3C4A0F61198F3B054FCF140CFADD8622C0E7621998331E59DA6F72E9D608D0E58F526E95F485C7CA30A416617DA3CCFF722BB82362606283D054B34B83ECDB4C91BAB835944010EBE5E9FA7B016ED89891DD553CC71B5CF76EDB2A184B377F670D6AF191763EEFD175E48EA37EE18B9E44E2D017D845C444C8111816819866E490B52F7F879A0C6F401CF7859674F93E304365F4E8CB8C312EFB725732A46D7CF0C9D2939AEE25F428CEFC90959DBF8ADD612F343EF9BFCA2FBA61BD4BF93E1E54626D227FDA812E18D071579AB4EEAC9901DAB183BCB0D9F48732D92CE66B386EAE5D8212C9FD156DC3F09B171B5603E17A468D244F3B6880EBCDA189BA9E23E4A4C6C2995ACF264F8CE9D54B27316343C0BC19221F75E6A2AC68011741695E599F73460B7A042E0461DB189CDCE223B40336BF2251AE3B363159960C9F63B47EFC43790D474DABB9A686DAF21E0DD76533749FCA9F144FA9C243CEF1364C79D981ED81DC4635C73B7F8908BA190AA920ED370F815BC2F9B3D28ED87BE34A01498836222C17B70C246C03CA1C110627AF3 +20010422042530 2 6 100 4094 2 65B5B9F5ECFADB4CCB38D1BC894302E95B4843290F1A7A40579DF3E2FF98C1D3DA9F210857C784433DF32ADF9E0C80121211690E1FFB41B8DB4E86AFE388A09C9BB2C98EDC581C2E65D57F61BB920C3D1B7B058B5FADFF65D607DAFF443B8BA1ACE1A3A7B16EA0713F62537C6689E3C4A0F61198F3B054FCF140CFADD8622C0E7621998331E59DA6F72E9D608D0E58F526E95F485C7CA30A416617DA3CCFF722BB82362606283D054B34B83ECDB4C91BAB835944010EBE5E9FA7B016ED89891DD553CC71B5CF76EDB2A184B377F670D6AF191763EEFD175E48EA37EE18B9E44E2D017D845C444C8111816819866E490B52F7F879A0C6F401CF7859674F93E304365F4E8CB8C312EFB725732A46D7CF0C9D2939AEE25F428CEFC90959DBF8ADD612F343EF9BFCA2FBA61BD4BF93E1E54626D227FDA812E18D071579AB4EEAC9901DAB183BCB0D9F48732D92CE66B386EAE5D8212C9FD156DC3F09B171B5603E17A468D244F3B6880EBCDA189BA9E23E4A4C6C2995ACF264F8CE9D54B27316343C0BC19221F75E6A2AC68011741695E599F73460B7A042E0461DB189CDCE223B40336BF2251AE3B363159960C9F63B47EFC43790D474DABB9A686DAF21E0DD76533749FCA9F144FA9C243CEF1364C79D981ED81DC4635C73B7F8908BA190AA920ED370F815BC2F9B3D28ED87BE34A01498836222C17B70C246C03CA1C110A793B3 +20010422163438 2 6 100 4094 5 65B5B9F5ECFADB4CCB38D1BC894302E95B4843290F1A7A40579DF3E2FF98C1D3DA9F210857C784433DF32ADF9E0C80121211690E1FFB41B8DB4E86AFE388A09C9BB2C98EDC581C2E65D57F61BB920C3D1B7B058B5FADFF65D607DAFF443B8BA1ACE1A3A7B16EA0713F62537C6689E3C4A0F61198F3B054FCF140CFADD8622C0E7621998331E59DA6F72E9D608D0E58F526E95F485C7CA30A416617DA3CCFF722BB82362606283D054B34B83ECDB4C91BAB835944010EBE5E9FA7B016ED89891DD553CC71B5CF76EDB2A184B377F670D6AF191763EEFD175E48EA37EE18B9E44E2D017D845C444C8111816819866E490B52F7F879A0C6F401CF7859674F93E304365F4E8CB8C312EFB725732A46D7CF0C9D2939AEE25F428CEFC90959DBF8ADD612F343EF9BFCA2FBA61BD4BF93E1E54626D227FDA812E18D071579AB4EEAC9901DAB183BCB0D9F48732D92CE66B386EAE5D8212C9FD156DC3F09B171B5603E17A468D244F3B6880EBCDA189BA9E23E4A4C6C2995ACF264F8CE9D54B27316343C0BC19221F75E6A2AC68011741695E599F73460B7A042E0461DB189CDCE223B40336BF2251AE3B363159960C9F63B47EFC43790D474DABB9A686DAF21E0DD76533749FCA9F144FA9C243CEF1364C79D981ED81DC4635C73B7F8908BA190AA920ED370F815BC2F9B3D28ED87BE34A01498836222C17B70C246C03CA1C111D2A227 diff -ruN --exclude CVS ssh-openbsd-2003091600/monitor.c openssh-3.7p1/monitor.c --- ssh-openbsd-2003091600/monitor.c 2003-09-03 12:07:14.000000000 +1000 +++ openssh-3.7p1/monitor.c 2003-09-03 07:32:46.000000000 +1000 @@ -121,6 +121,15 @@ int mm_answer_sesskey(int, Buffer *); int mm_answer_sessid(int, Buffer *); +#ifdef USE_PAM +int mm_answer_pam_start(int, Buffer *); +int mm_answer_pam_account(int, Buffer *); +int mm_answer_pam_init_ctx(int, Buffer *); +int mm_answer_pam_query(int, Buffer *); +int mm_answer_pam_respond(int, Buffer *); +int mm_answer_pam_free_ctx(int, Buffer *); +#endif + #ifdef GSSAPI int mm_answer_gss_setup_ctx(int, Buffer *); int mm_answer_gss_accept_ctx(int, Buffer *); @@ -162,6 +171,14 @@ {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 BSD_AUTH {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery}, {MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH,mm_answer_bsdauthrespond}, @@ -206,6 +223,14 @@ {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 {0, 0, NULL} }; @@ -279,6 +304,18 @@ 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) { + 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) { @@ -541,7 +578,9 @@ 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); @@ -558,6 +597,10 @@ 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); } @@ -733,6 +776,141 @@ } #endif +#ifdef USE_PAM +int +mm_answer_pam_start(int socket, Buffer *m) +{ + char *user; + + if (!options.use_pam) + fatal("UsePAM not set, but ended up in %s anyway", __func__); + + user = buffer_get_string(m, NULL); + + start_pam(user); + + xfree(user); + + monitor_permit(mon_dispatch, MONITOR_REQ_PAM_ACCOUNT, 1); + + return (0); +} + +int +mm_answer_pam_account(int socket, 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); + + mm_request_send(socket, MONITOR_ANS_PAM_ACCOUNT, m); + + return (ret); +} + +static void *sshpam_ctxt, *sshpam_authok; +extern KbdintDevice sshpam_device; + +int +mm_answer_pam_init_ctx(int socket, 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(socket, MONITOR_ANS_PAM_INIT_CTX, m); + return (0); +} + +int +mm_answer_pam_query(int socket, Buffer *m) +{ + char *name, *info, **prompts; + u_int num, *echo_on; + int i, 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); + mm_request_send(socket, MONITOR_ANS_PAM_QUERY, m); + return (0); +} + +int +mm_answer_pam_respond(int socket, Buffer *m) +{ + char **resp; + u_int num; + int i, ret; + + debug3("%s", __func__); + sshpam_authok = NULL; + num = buffer_get_int(m); + if (num > 0) { + resp = xmalloc(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(socket, 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 socket, Buffer *m) +{ + + debug3("%s", __func__); + (sshpam_device.free_ctx)(sshpam_ctxt); + buffer_clear(m); + mm_request_send(socket, MONITOR_ANS_PAM_FREE_CTX, m); + return (sshpam_authok == sshpam_ctxt); +} +#endif + static void mm_append_debug(Buffer *m) { @@ -1509,8 +1687,13 @@ static void monitor_socketpair(int *pair) { +#ifdef HAVE_SOCKETPAIR if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) fatal("%s: socketpair", __func__); +#else + fatal("%s: UsePrivilegeSeparation=yes not supported", + __func__); +#endif FD_CLOSEONEXEC(pair[0]); FD_CLOSEONEXEC(pair[1]); } diff -ruN --exclude CVS ssh-openbsd-2003091600/.#monitor.c.1.34 openssh-3.7p1/.#monitor.c.1.34 --- ssh-openbsd-2003091600/.#monitor.c.1.34 2003-04-29 19:36:44.000000000 +1000 +++ openssh-3.7p1/.#monitor.c.1.34 1970-01-01 10:00:00.000000000 +1000 @@ -1,1610 +0,0 @@ -/* - * Copyright 2002 Niels Provos - * Copyright 2002 Markus Friedl - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "includes.h" -RCSID("$OpenBSD: monitor.c,v 1.34 2003/03/23 19:02:00 markus Exp $"); - -#include - -#ifdef SKEY -#include -#endif - -#include "ssh.h" -#include "auth.h" -#include "kex.h" -#include "dh.h" -#include "zlib.h" -#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" -#include "monitor_wrap.h" -#include "monitor_fdpass.h" -#include "xmalloc.h" -#include "misc.h" -#include "buffer.h" -#include "bufaux.h" -#include "compat.h" -#include "ssh2.h" -#include "mpaux.h" - -/* 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 input, output; -extern Buffer auth_debug; -extern int auth_debug_init; - -/* 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; -} child_state; - -/* Functions on the montior that answer unprivileged requests */ - -int mm_answer_moduli(int, Buffer *); -int mm_answer_sign(int, Buffer *); -int mm_answer_pwnamallow(int, Buffer *); -int mm_answer_auth2_read_banner(int, Buffer *); -int mm_answer_authserv(int, Buffer *); -int mm_answer_authpassword(int, Buffer *); -int mm_answer_bsdauthquery(int, Buffer *); -int mm_answer_bsdauthrespond(int, Buffer *); -int mm_answer_skeyquery(int, Buffer *); -int mm_answer_skeyrespond(int, Buffer *); -int mm_answer_keyallowed(int, Buffer *); -int mm_answer_keyverify(int, Buffer *); -int mm_answer_pty(int, Buffer *); -int mm_answer_pty_cleanup(int, Buffer *); -int mm_answer_term(int, Buffer *); -int mm_answer_rsa_keyallowed(int, Buffer *); -int mm_answer_rsa_challenge(int, Buffer *); -int mm_answer_rsa_response(int, Buffer *); -int mm_answer_sesskey(int, Buffer *); -int mm_answer_sessid(int, Buffer *); - -#ifdef KRB4 -int mm_answer_krb4(int, Buffer *); -#endif -#ifdef KRB5 -int mm_answer_krb5(int, Buffer *); -#endif - -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 int session_id2_len = 0; -static u_char *session_id2 = NULL; - -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_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 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}, - {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}, - {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, mm_answer_rsa_keyallowed}, - {MONITOR_REQ_KEYALLOWED, MON_ISAUTH, 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 KRB4 - {MONITOR_REQ_KRB4, MON_ONCE|MON_AUTH, mm_answer_krb4}, -#endif -#ifdef KRB5 - {MONITOR_REQ_KRB5, MON_ONCE|MON_AUTH, mm_answer_krb5}, -#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}, - {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++; - } -} - -Authctxt * -monitor_child_preauth(struct monitor *pmonitor) -{ - struct mon_table *ent; - int authenticated = 0; - - debug3("preauth child monitor started"); - - 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); - } - - authctxt = authctxt_new(); - - /* The first few requests do not require asynchronous access */ - while (!authenticated) { - authenticated = monitor_read(pmonitor, mon_dispatch, &ent); - 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; - } - - if (ent->flags & MON_AUTHDECIDE) { - auth_log(authctxt, authenticated, auth_method, - compat20 ? " ssh2" : ""); - if (!authenticated) - authctxt->failures++; - } - } - - if (!authctxt->valid) - fatal("%s: authenticated invalid user", __func__); - - debug("%s: %s has been authenticated by privileged process", - __func__, authctxt->user); - - mm_get_keystate(pmonitor); - - return (authctxt); -} - -void -monitor_child_postauth(struct monitor *pmonitor) -{ - if (compat20) { - mon_dispatch = mon_dispatch_postauth20; - - /* Permit requests for moduli and signatures */ - monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); - monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); - monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); - - } else { - mon_dispatch = mon_dispatch_postauth15; - monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); - } - if (!no_pty_flag) { - monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); - monitor_permit(mon_dispatch, MONITOR_REQ_PTYCLEANUP, 1); - } - - for (;;) - monitor_read(pmonitor, mon_dispatch, NULL); -} - -void -monitor_sync(struct monitor *pmonitor) -{ - if (options.compression) { - /* The member allocation is not visible, so sync it */ - mm_share_sync(&pmonitor->m_zlib, &pmonitor->m_zback); - } -} - -int -monitor_read(struct monitor *pmonitor, struct mon_table *ent, - struct mon_table **pent) -{ - Buffer m; - int ret; - u_char type; - - 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 || - memcmp(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 socket, 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(socket, MONITOR_ANS_MODULI, m); - return (0); -} - -int -mm_answer_sign(int socket, 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); - - if (datlen != 20) - 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(socket, 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 socket, Buffer *m) -{ - char *login; - struct passwd *pwent; - int allowed = 0; - - debug3("%s", __func__); - - if (authctxt->attempt++ != 0) - fatal("%s: multiple attempts for getpwnam", __func__); - - login = buffer_get_string(m, NULL); - - pwent = getpwnamallow(login); - - authctxt->user = xstrdup(login); - setproctitle("%s [priv]", pwent ? login : "unknown"); - xfree(login); - - buffer_clear(m); - - if (pwent == NULL) { - buffer_put_char(m, 0); - 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); - buffer_put_cstring(m, pwent->pw_class); - buffer_put_cstring(m, pwent->pw_dir); - buffer_put_cstring(m, pwent->pw_shell); - - out: - debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed); - mm_request_send(socket, 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); - } - - - return (0); -} - -int mm_answer_auth2_read_banner(int socket, Buffer *m) -{ - char *banner; - - buffer_clear(m); - banner = auth2_read_banner(); - buffer_put_cstring(m, banner != NULL ? banner : ""); - mm_request_send(socket, MONITOR_ANS_AUTH2_READ_BANNER, m); - - if (banner != NULL) - xfree(banner); - - return (0); -} - -int -mm_answer_authserv(int socket, 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 socket, 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) && authctxt->valid; - 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(socket, 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 socket, 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(socket, MONITOR_ANS_BSDAUTHQUERY, m); - - if (success) { - xfree(name); - xfree(infotxt); - xfree(prompts); - xfree(echo_on); - } - - return (0); -} - -int -mm_answer_bsdauthrespond(int socket, 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(socket, MONITOR_ANS_BSDAUTHRESPOND, m); - - auth_method = "bsdauth"; - - return (authok != 0); -} -#endif - -#ifdef SKEY -int -mm_answer_skeyquery(int socket, Buffer *m) -{ - struct skey skey; - char challenge[1024]; - u_int success; - - success = skeychallenge(&skey, authctxt->user, 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(socket, MONITOR_ANS_SKEYQUERY, m); - - return (0); -} - -int -mm_answer_skeyrespond(int socket, 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(socket, MONITOR_ANS_SKEYRESPOND, m); - - auth_method = "skey"; - - return (authok != 0); -} -#endif - -static void -mm_append_debug(Buffer *m) -{ - if (auth_debug_init && buffer_len(&auth_debug)) { - debug3("%s: Appending debug messages for child", __func__); - buffer_append(m, buffer_ptr(&auth_debug), - buffer_len(&auth_debug)); - buffer_clear(&auth_debug); - } -} - -int -mm_answer_keyallowed(int socket, 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->pw != NULL) { - switch(type) { - case MM_USERKEY: - allowed = options.pubkey_authentication && - user_key_allowed(authctxt->pw, key); - break; - case MM_HOSTKEY: - allowed = options.hostbased_authentication && - hostbased_key_allowed(authctxt->pw, - cuser, chost, key); - break; - case MM_RSAHOSTKEY: - key->type = KEY_RSA1; /* XXX */ - allowed = options.rhosts_rsa_authentication && - auth_rhosts_rsa_key_allowed(authctxt->pw, - cuser, chost, key); - 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; - } - - debug3("%s: key %p is %s", - __func__, key, allowed ? "allowed" : "disallowed"); - - buffer_clear(m); - buffer_put_int(m, allowed); - buffer_put_int(m, forced_command != NULL); - - mm_append_debug(m); - - mm_request_send(socket, 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) || - (memcmp(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) || - (memcmp(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) { - log("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) || - (memcmp(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) { - log("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 socket, 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 ? "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(socket, MONITOR_ANS_KEYVERIFY, m); - - return (verified); -} - -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)); - fatal_cleanup(); - } - } - /* 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.verify_reverse_mapping), - (struct sockaddr *)&from, fromlen); -} - -static void -mm_session_close(Session *s) -{ - debug3("%s: session %d pid %d", __func__, s->self, s->pid); - if (s->ttyfd != -1) { - debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd); - fatal_remove_cleanup(session_pty_cleanup2, (void *)s); - session_pty_cleanup2(s); - } - s->used = 0; -} - -int -mm_answer_pty(int socket, 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; - fatal_add_cleanup(session_pty_cleanup2, (void *)s); - pty_setowner(authctxt->pw, s->tty); - - buffer_put_int(m, 1); - buffer_put_cstring(m, s->tty); - mm_request_send(socket, MONITOR_ANS_PTY, m); - - mm_send_fd(socket, s->ptyfd); - mm_send_fd(socket, s->ttyfd); - - /* 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); - - /* 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(socket, MONITOR_ANS_PTY, m); - return (0); -} - -int -mm_answer_pty_cleanup(int socket, 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 socket, Buffer *m) -{ - BIGNUM *p; - int rsafail; - - /* Turn off permissions */ - monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 1); - - 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(socket, 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 socket, 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 socket, Buffer *m) -{ - BIGNUM *client_n; - Key *key = NULL; - u_char *blob = NULL; - u_int blen = 0; - int allowed = 0; - - debug3("%s entering", __func__); - - 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_append_debug(m); - - mm_request_send(socket, 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 socket, 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 (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(socket, 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 socket, 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(socket, MONITOR_ANS_RSARESPONSE, m); - - return (success); -} - -#ifdef KRB4 -int -mm_answer_krb4(int socket, Buffer *m) -{ - KTEXT_ST auth, reply; - char *client, *p; - int success; - u_int alen; - - reply.length = auth.length = 0; - - p = buffer_get_string(m, &alen); - if (alen >= MAX_KTXT_LEN) - fatal("%s: auth too large", __func__); - memcpy(auth.dat, p, alen); - auth.length = alen; - memset(p, 0, alen); - xfree(p); - - success = options.kerberos_authentication && - authctxt->valid && - auth_krb4(authctxt, &auth, &client, &reply); - - memset(auth.dat, 0, alen); - buffer_clear(m); - buffer_put_int(m, success); - - if (success) { - buffer_put_cstring(m, client); - buffer_put_string(m, reply.dat, reply.length); - if (client) - xfree(client); - if (reply.length) - memset(reply.dat, 0, reply.length); - } - - debug3("%s: sending result %d", __func__, success); - mm_request_send(socket, MONITOR_ANS_KRB4, m); - - auth_method = "kerberos"; - - /* Causes monitor loop to terminate if authenticated */ - return (success); -} -#endif - -#ifdef KRB5 -int -mm_answer_krb5(int socket, Buffer *m) -{ - krb5_data tkt, reply; - char *client_user; - u_int len; - int success; - - /* use temporary var to avoid size issues on 64bit arch */ - tkt.data = buffer_get_string(m, &len); - tkt.length = len; - - success = options.kerberos_authentication && - authctxt->valid && - auth_krb5(authctxt, &tkt, &client_user, &reply); - - if (tkt.length) - xfree(tkt.data); - - buffer_clear(m); - buffer_put_int(m, success); - - if (success) { - buffer_put_cstring(m, client_user); - buffer_put_string(m, reply.data, reply.length); - if (client_user) - xfree(client_user); - if (reply.length) - xfree(reply.data); - } - mm_request_send(socket, MONITOR_ANS_KRB5, m); - - return success; -} -#endif - -int -mm_answer_term(int socket, 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); - - while (waitpid(pmonitor->m_pid, &status, 0) == -1) - if (errno != EINTR) - exit(1); - - res = WIFEXITED(status) ? WEXITSTATUS(status) : 1; - - /* Terminate process */ - exit (res); -} - -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(&input); - buffer_append(&input, child_state.input, child_state.ilen); - memset(child_state.input, 0, child_state.ilen); - xfree(child_state.input); - - buffer_clear(&output); - buffer_append(&output, child_state.output, child_state.olen); - memset(child_state.output, 0, child_state.olen); - xfree(child_state.output); -} - -static Kex * -mm_get_kex(Buffer *m) -{ - Kex *kex; - void *blob; - u_int bloblen; - - kex = xmalloc(sizeof(*kex)); - memset(kex, 0, sizeof(*kex)); - kex->session_id = buffer_get_string(m, &kex->session_id_len); - if ((session_id2 == NULL) || - (kex->session_id_len != session_id2_len) || - (memcmp(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_GEX_SHA1] = kexgex_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_key=&get_hostkey_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; - - 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 */ - packet_set_seqnr(MODE_OUT, buffer_get_int(&m)); - packet_set_seqnr(MODE_IN, buffer_get_int(&m)); - - 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); - - 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, 1) == -1) \ - fatal("fcntl(%d, F_SETFD)", x); \ -} while (0) - -static void -monitor_socketpair(int *pair) -{ - if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) - fatal("%s: socketpair", __func__); - FD_CLOSEONEXEC(pair[0]); - FD_CLOSEONEXEC(pair[1]); -} - -#define MM_MEMSIZE 65536 - -struct monitor * -monitor_init(void) -{ - struct monitor *mon; - int pair[2]; - - mon = xmalloc(sizeof(*mon)); - - monitor_socketpair(pair); - - mon->m_recvfd = pair[0]; - mon->m_sendfd = pair[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) -{ - int pair[2]; - - monitor_socketpair(pair); - - mon->m_recvfd = pair[0]; - mon->m_sendfd = pair[1]; -} diff -ruN --exclude CVS ssh-openbsd-2003091600/.#monitor.c.1.38 openssh-3.7p1/.#monitor.c.1.38 --- ssh-openbsd-2003091600/.#monitor.c.1.38 2003-05-13 13:34:30.000000000 +1000 +++ openssh-3.7p1/.#monitor.c.1.38 1970-01-01 10:00:00.000000000 +1000 @@ -1,1618 +0,0 @@ -/* - * Copyright 2002 Niels Provos - * Copyright 2002 Markus Friedl - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "includes.h" -RCSID("$OpenBSD: monitor.c,v 1.38 2003/04/08 20:21:28 itojun Exp $"); - -#include - -#ifdef SKEY -#include -#endif - -#include "ssh.h" -#include "auth.h" -#include "kex.h" -#include "dh.h" -#include "zlib.h" -#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" -#include "monitor_wrap.h" -#include "monitor_fdpass.h" -#include "xmalloc.h" -#include "misc.h" -#include "buffer.h" -#include "bufaux.h" -#include "compat.h" -#include "ssh2.h" -#include "mpaux.h" - -/* 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 input, output; -extern Buffer auth_debug; -extern int auth_debug_init; - -/* 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; -} child_state; - -/* Functions on the montior that answer unprivileged requests */ - -int mm_answer_moduli(int, Buffer *); -int mm_answer_sign(int, Buffer *); -int mm_answer_pwnamallow(int, Buffer *); -int mm_answer_auth2_read_banner(int, Buffer *); -int mm_answer_authserv(int, Buffer *); -int mm_answer_authpassword(int, Buffer *); -int mm_answer_bsdauthquery(int, Buffer *); -int mm_answer_bsdauthrespond(int, Buffer *); -int mm_answer_skeyquery(int, Buffer *); -int mm_answer_skeyrespond(int, Buffer *); -int mm_answer_keyallowed(int, Buffer *); -int mm_answer_keyverify(int, Buffer *); -int mm_answer_pty(int, Buffer *); -int mm_answer_pty_cleanup(int, Buffer *); -int mm_answer_term(int, Buffer *); -int mm_answer_rsa_keyallowed(int, Buffer *); -int mm_answer_rsa_challenge(int, Buffer *); -int mm_answer_rsa_response(int, Buffer *); -int mm_answer_sesskey(int, Buffer *); -int mm_answer_sessid(int, Buffer *); - -#ifdef KRB4 -int mm_answer_krb4(int, Buffer *); -#endif -#ifdef KRB5 -int mm_answer_krb5(int, Buffer *); -#endif - -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 int session_id2_len = 0; -static u_char *session_id2 = NULL; - -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_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 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}, - {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}, - {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, mm_answer_rsa_keyallowed}, - {MONITOR_REQ_KEYALLOWED, MON_ISAUTH, 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 KRB4 - {MONITOR_REQ_KRB4, MON_ONCE|MON_AUTH, mm_answer_krb4}, -#endif -#ifdef KRB5 - {MONITOR_REQ_KRB5, MON_ONCE|MON_AUTH, mm_answer_krb5}, -#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}, - {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++; - } -} - -Authctxt * -monitor_child_preauth(struct monitor *pmonitor) -{ - struct mon_table *ent; - int authenticated = 0; - - debug3("preauth child monitor started"); - - 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); - } - - authctxt = authctxt_new(); - - /* The first few requests do not require asynchronous access */ - while (!authenticated) { - authenticated = monitor_read(pmonitor, mon_dispatch, &ent); - 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; - } - - if (ent->flags & MON_AUTHDECIDE) { - auth_log(authctxt, authenticated, auth_method, - compat20 ? " ssh2" : ""); - if (!authenticated) - authctxt->failures++; - } - } - - if (!authctxt->valid) - fatal("%s: authenticated invalid user", __func__); - - debug("%s: %s has been authenticated by privileged process", - __func__, authctxt->user); - - mm_get_keystate(pmonitor); - - return (authctxt); -} - -void -monitor_child_postauth(struct monitor *pmonitor) -{ - if (compat20) { - mon_dispatch = mon_dispatch_postauth20; - - /* Permit requests for moduli and signatures */ - monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); - monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); - monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); - - } else { - mon_dispatch = mon_dispatch_postauth15; - monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); - } - if (!no_pty_flag) { - monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); - monitor_permit(mon_dispatch, MONITOR_REQ_PTYCLEANUP, 1); - } - - for (;;) - monitor_read(pmonitor, mon_dispatch, NULL); -} - -void -monitor_sync(struct monitor *pmonitor) -{ - if (options.compression) { - /* The member allocation is not visible, so sync it */ - mm_share_sync(&pmonitor->m_zlib, &pmonitor->m_zback); - } -} - -int -monitor_read(struct monitor *pmonitor, struct mon_table *ent, - struct mon_table **pent) -{ - Buffer m; - int ret; - u_char type; - - 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 || - memcmp(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 socket, 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(socket, MONITOR_ANS_MODULI, m); - return (0); -} - -int -mm_answer_sign(int socket, 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); - - if (datlen != 20) - 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(socket, 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 socket, Buffer *m) -{ - char *login; - struct passwd *pwent; - int allowed = 0; - - debug3("%s", __func__); - - if (authctxt->attempt++ != 0) - fatal("%s: multiple attempts for getpwnam", __func__); - - login = buffer_get_string(m, NULL); - - pwent = getpwnamallow(login); - - authctxt->user = xstrdup(login); - setproctitle("%s [priv]", pwent ? login : "unknown"); - xfree(login); - - buffer_clear(m); - - if (pwent == NULL) { - buffer_put_char(m, 0); - 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); - buffer_put_cstring(m, pwent->pw_class); - buffer_put_cstring(m, pwent->pw_dir); - buffer_put_cstring(m, pwent->pw_shell); - - out: - debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed); - mm_request_send(socket, 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); - } - - - return (0); -} - -int mm_answer_auth2_read_banner(int socket, Buffer *m) -{ - char *banner; - - buffer_clear(m); - banner = auth2_read_banner(); - buffer_put_cstring(m, banner != NULL ? banner : ""); - mm_request_send(socket, MONITOR_ANS_AUTH2_READ_BANNER, m); - - if (banner != NULL) - xfree(banner); - - return (0); -} - -int -mm_answer_authserv(int socket, 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 socket, 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) && authctxt->valid; - 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(socket, 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 socket, 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(socket, MONITOR_ANS_BSDAUTHQUERY, m); - - if (success) { - xfree(name); - xfree(infotxt); - xfree(prompts); - xfree(echo_on); - } - - return (0); -} - -int -mm_answer_bsdauthrespond(int socket, 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(socket, MONITOR_ANS_BSDAUTHRESPOND, m); - - auth_method = "bsdauth"; - - return (authok != 0); -} -#endif - -#ifdef SKEY -int -mm_answer_skeyquery(int socket, Buffer *m) -{ - struct skey skey; - char challenge[1024]; - u_int success; - - success = skeychallenge(&skey, authctxt->user, 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(socket, MONITOR_ANS_SKEYQUERY, m); - - return (0); -} - -int -mm_answer_skeyrespond(int socket, 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(socket, MONITOR_ANS_SKEYRESPOND, m); - - auth_method = "skey"; - - return (authok != 0); -} -#endif - -static void -mm_append_debug(Buffer *m) -{ - if (auth_debug_init && buffer_len(&auth_debug)) { - debug3("%s: Appending debug messages for child", __func__); - buffer_append(m, buffer_ptr(&auth_debug), - buffer_len(&auth_debug)); - buffer_clear(&auth_debug); - } -} - -int -mm_answer_keyallowed(int socket, 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->pw != NULL) { - switch(type) { - case MM_USERKEY: - allowed = options.pubkey_authentication && - user_key_allowed(authctxt->pw, key); - break; - case MM_HOSTKEY: - allowed = options.hostbased_authentication && - hostbased_key_allowed(authctxt->pw, - cuser, chost, key); - break; - case MM_RSAHOSTKEY: - key->type = KEY_RSA1; /* XXX */ - allowed = options.rhosts_rsa_authentication && - auth_rhosts_rsa_key_allowed(authctxt->pw, - cuser, chost, key); - 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; - } - - debug3("%s: key %p is %s", - __func__, key, allowed ? "allowed" : "disallowed"); - - buffer_clear(m); - buffer_put_int(m, allowed); - buffer_put_int(m, forced_command != NULL); - - mm_append_debug(m); - - mm_request_send(socket, 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) || - (memcmp(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) || - (memcmp(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) || - (memcmp(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 socket, 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 ? "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(socket, MONITOR_ANS_KEYVERIFY, m); - - return (verified); -} - -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)); - fatal_cleanup(); - } - } - /* 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.verify_reverse_mapping), - (struct sockaddr *)&from, fromlen); -} - -static void -mm_session_close(Session *s) -{ - debug3("%s: session %d pid %d", __func__, s->self, s->pid); - if (s->ttyfd != -1) { - debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd); - fatal_remove_cleanup(session_pty_cleanup2, (void *)s); - session_pty_cleanup2(s); - } - s->used = 0; -} - -int -mm_answer_pty(int socket, 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; - fatal_add_cleanup(session_pty_cleanup2, (void *)s); - pty_setowner(authctxt->pw, s->tty); - - buffer_put_int(m, 1); - buffer_put_cstring(m, s->tty); - mm_request_send(socket, MONITOR_ANS_PTY, m); - - mm_send_fd(socket, s->ptyfd); - mm_send_fd(socket, s->ttyfd); - - /* 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); - - /* 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(socket, MONITOR_ANS_PTY, m); - return (0); -} - -int -mm_answer_pty_cleanup(int socket, 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 socket, Buffer *m) -{ - BIGNUM *p; - int rsafail; - - /* Turn off permissions */ - monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 1); - - 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(socket, 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 socket, 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 socket, Buffer *m) -{ - BIGNUM *client_n; - Key *key = NULL; - u_char *blob = NULL; - u_int blen = 0; - int allowed = 0; - - debug3("%s entering", __func__); - - 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_append_debug(m); - - mm_request_send(socket, 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 socket, 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 (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(socket, 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 socket, 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(socket, MONITOR_ANS_RSARESPONSE, m); - - return (success); -} - -#ifdef KRB4 -int -mm_answer_krb4(int socket, Buffer *m) -{ - KTEXT_ST auth, reply; - char *client, *p; - int success; - u_int alen; - - reply.length = auth.length = 0; - - p = buffer_get_string(m, &alen); - if (alen >= MAX_KTXT_LEN) - fatal("%s: auth too large", __func__); - memcpy(auth.dat, p, alen); - auth.length = alen; - memset(p, 0, alen); - xfree(p); - - success = options.kerberos_authentication && - authctxt->valid && - auth_krb4(authctxt, &auth, &client, &reply); - - memset(auth.dat, 0, alen); - buffer_clear(m); - buffer_put_int(m, success); - - if (success) { - buffer_put_cstring(m, client); - buffer_put_string(m, reply.dat, reply.length); - if (client) - xfree(client); - if (reply.length) - memset(reply.dat, 0, reply.length); - } - - debug3("%s: sending result %d", __func__, success); - mm_request_send(socket, MONITOR_ANS_KRB4, m); - - auth_method = "kerberos"; - - /* Causes monitor loop to terminate if authenticated */ - return (success); -} -#endif - -#ifdef KRB5 -int -mm_answer_krb5(int socket, Buffer *m) -{ - krb5_data tkt, reply; - char *client_user; - u_int len; - int success; - - /* use temporary var to avoid size issues on 64bit arch */ - tkt.data = buffer_get_string(m, &len); - tkt.length = len; - - success = options.kerberos_authentication && - authctxt->valid && - auth_krb5(authctxt, &tkt, &client_user, &reply); - - if (tkt.length) - xfree(tkt.data); - - buffer_clear(m); - buffer_put_int(m, success); - - if (success) { - buffer_put_cstring(m, client_user); - buffer_put_string(m, reply.data, reply.length); - if (client_user) - xfree(client_user); - if (reply.length) - xfree(reply.data); - } - mm_request_send(socket, MONITOR_ANS_KRB5, m); - - return success; -} -#endif - -int -mm_answer_term(int socket, 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); - - while (waitpid(pmonitor->m_pid, &status, 0) == -1) - if (errno != EINTR) - exit(1); - - res = WIFEXITED(status) ? WEXITSTATUS(status) : 1; - - /* Terminate process */ - exit (res); -} - -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(&input); - buffer_append(&input, child_state.input, child_state.ilen); - memset(child_state.input, 0, child_state.ilen); - xfree(child_state.input); - - buffer_clear(&output); - buffer_append(&output, child_state.output, child_state.olen); - memset(child_state.output, 0, child_state.olen); - xfree(child_state.output); -} - -static Kex * -mm_get_kex(Buffer *m) -{ - Kex *kex; - void *blob; - u_int bloblen; - - kex = xmalloc(sizeof(*kex)); - memset(kex, 0, sizeof(*kex)); - kex->session_id = buffer_get_string(m, &kex->session_id_len); - if ((session_id2 == NULL) || - (kex->session_id_len != session_id2_len) || - (memcmp(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_GEX_SHA1] = kexgex_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_key=&get_hostkey_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; - - 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); - packet_set_state(MODE_OUT, seqnr, blocks, packets); - seqnr = buffer_get_int(&m); - blocks = buffer_get_int64(&m); - packets = buffer_get_int(&m); - packet_set_state(MODE_IN, seqnr, blocks, packets); - - 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); - - 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, 1) == -1) \ - fatal("fcntl(%d, F_SETFD)", x); \ -} while (0) - -static void -monitor_socketpair(int *pair) -{ - if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) - fatal("%s: socketpair", __func__); - FD_CLOSEONEXEC(pair[0]); - FD_CLOSEONEXEC(pair[1]); -} - -#define MM_MEMSIZE 65536 - -struct monitor * -monitor_init(void) -{ - struct monitor *mon; - int pair[2]; - - mon = xmalloc(sizeof(*mon)); - - monitor_socketpair(pair); - - mon->m_recvfd = pair[0]; - mon->m_sendfd = pair[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) -{ - int pair[2]; - - monitor_socketpair(pair); - - mon->m_recvfd = pair[0]; - mon->m_sendfd = pair[1]; -} diff -ruN --exclude CVS ssh-openbsd-2003091600/monitor_fdpass.c openssh-3.7p1/monitor_fdpass.c --- ssh-openbsd-2003091600/monitor_fdpass.c 2003-03-26 16:04:04.000000000 +1100 +++ openssh-3.7p1/monitor_fdpass.c 2003-05-02 20:48:21.000000000 +1000 @@ -34,14 +34,21 @@ void mm_send_fd(int socket, int fd) { +#if defined(HAVE_SENDMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR)) struct msghdr msg; - char tmp[CMSG_SPACE(sizeof(int))]; - struct cmsghdr *cmsg; struct iovec vec; char ch = '\0'; ssize_t n; +#ifndef HAVE_ACCRIGHTS_IN_MSGHDR + char tmp[CMSG_SPACE(sizeof(int))]; + struct cmsghdr *cmsg; +#endif 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)tmp; msg.msg_controllen = CMSG_LEN(sizeof(int)); cmsg = CMSG_FIRSTHDR(&msg); @@ -49,6 +56,7 @@ cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_type = SCM_RIGHTS; *(int *)CMSG_DATA(cmsg) = fd; +#endif vec.iov_base = &ch; vec.iov_len = 1; @@ -61,26 +69,38 @@ if (n != 1) fatal("%s: sendmsg: expected sent 1 got %ld", __func__, (long)n); +#else + fatal("%s: UsePrivilegeSeparation=yes not supported", + __func__); +#endif } int mm_receive_fd(int socket) { +#if defined(HAVE_RECVMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR)) struct msghdr msg; - char tmp[CMSG_SPACE(sizeof(int))]; - struct cmsghdr *cmsg; struct iovec vec; ssize_t n; char ch; int fd; +#ifndef HAVE_ACCRIGHTS_IN_MSGHDR + char tmp[CMSG_SPACE(sizeof(int))]; + struct cmsghdr *cmsg; +#endif 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 = tmp; msg.msg_controllen = sizeof(tmp); +#endif if ((n = recvmsg(socket, &msg, 0)) == -1) fatal("%s: recvmsg: %s", __func__, strerror(errno)); @@ -88,10 +108,21 @@ fatal("%s: recvmsg: expected received 1 got %ld", __func__, (long)n); +#ifdef HAVE_ACCRIGHTS_IN_MSGHDR + if (msg.msg_accrightslen != sizeof(fd)) + fatal("%s: no fd", __func__); +#else cmsg = CMSG_FIRSTHDR(&msg); +#ifndef BROKEN_CMSG_TYPE if (cmsg->cmsg_type != SCM_RIGHTS) fatal("%s: expected type %d got %d", __func__, SCM_RIGHTS, cmsg->cmsg_type); +#endif fd = (*(int *)CMSG_DATA(cmsg)); +#endif return fd; +#else + fatal("%s: UsePrivilegeSeparation=yes not supported", + __func__); +#endif } diff -ruN --exclude CVS ssh-openbsd-2003091600/monitor.h openssh-3.7p1/monitor.h --- ssh-openbsd-2003091600/monitor.h 2003-09-03 12:07:14.000000000 +1000 +++ openssh-3.7p1/monitor.h 2003-09-02 22:51:17.000000000 +1000 @@ -52,6 +52,12 @@ MONITOR_REQ_GSSSETUP, MONITOR_ANS_GSSSETUP, MONITOR_REQ_GSSSTEP, MONITOR_ANS_GSSSTEP, MONITOR_REQ_GSSUSEROK, MONITOR_ANS_GSSUSEROK, + 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_TERM }; diff -ruN --exclude CVS ssh-openbsd-2003091600/monitor_mm.c openssh-3.7p1/monitor_mm.c --- ssh-openbsd-2003091600/monitor_mm.c 2003-03-26 16:04:04.000000000 +1100 +++ openssh-3.7p1/monitor_mm.c 2003-08-30 02:59:52.000000000 +1000 @@ -26,7 +26,9 @@ #include "includes.h" RCSID("$OpenBSD: monitor_mm.c,v 1.8 2002/08/02 14:43:15 millert Exp $"); +#ifdef HAVE_SYS_MMAN_H #include +#endif #include "ssh.h" #include "xmalloc.h" @@ -89,8 +91,7 @@ */ mm->mmalloc = mmalloc; - address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_ANON|MAP_SHARED, - -1, 0); + address = xmmap(size); if (address == MAP_FAILED) fatal("mmap(%lu): %s", (u_long)size, strerror(errno)); @@ -130,9 +131,14 @@ 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 diff -ruN --exclude CVS ssh-openbsd-2003091600/monitor_mm.h openssh-3.7p1/monitor_mm.h --- ssh-openbsd-2003091600/monitor_mm.h 2003-03-26 16:04:04.000000000 +1100 +++ openssh-3.7p1/monitor_mm.h 2002-09-12 10:43:31.000000000 +1000 @@ -27,7 +27,7 @@ #ifndef _MM_H_ #define _MM_H_ -#include +#include "openbsd-compat/sys-tree.h" struct mm_share { RB_ENTRY(mm_share) next; diff -ruN --exclude CVS ssh-openbsd-2003091600/monitor_wrap.c openssh-3.7p1/monitor_wrap.c --- ssh-openbsd-2003091600/monitor_wrap.c 2003-09-03 12:07:14.000000000 +1000 +++ openssh-3.7p1/monitor_wrap.c 2003-09-02 22:51:17.000000000 +1000 @@ -47,6 +47,7 @@ #include "atomicio.h" #include "monitor_fdpass.h" #include "getput.h" +#include "servconf.h" #include "auth.h" #include "channels.h" @@ -63,6 +64,7 @@ extern z_stream outgoing_stream; extern struct monitor *pmonitor; extern Buffer input, output; +extern ServerOptions options; void mm_request_send(int socket, enum monitor_reqtype type, Buffer *m) @@ -202,7 +204,9 @@ pw->pw_name = buffer_get_string(&m, NULL); pw->pw_passwd = buffer_get_string(&m, NULL); pw->pw_gecos = buffer_get_string(&m, NULL); +#ifdef HAVE_PW_CLASS_IN_PASSWD pw->pw_class = buffer_get_string(&m, NULL); +#endif pw->pw_dir = buffer_get_string(&m, NULL); pw->pw_shell = buffer_get_string(&m, NULL); buffer_free(&m); @@ -664,6 +668,131 @@ s->ttyfd = -1; } +#ifdef USE_PAM +void +mm_start_pam(char *user) +{ + Buffer m; + + debug3("%s entering", __func__); + if (!options.use_pam) + fatal("UsePAM=no, but ended up in %s anyway", __func__); + + buffer_init(&m); + buffer_put_cstring(&m, user); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_START, &m); + + buffer_free(&m); +} + +u_int +mm_do_pam_account(void) +{ + Buffer m; + u_int ret; + + debug3("%s entering", __func__); + if (!options.use_pam) + fatal("UsePAM=no, but ended up in %s anyway", __func__); + + buffer_init(&m); + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_ACCOUNT, &m); + + mm_request_receive_expect(pmonitor->m_recvfd, + MONITOR_ANS_PAM_ACCOUNT, &m); + ret = buffer_get_int(&m); + + buffer_free(&m); + + debug3("%s returning %d", __func__, ret); + + return (ret); +} + +void * +mm_sshpam_init_ctx(Authctxt *authctxt) +{ + Buffer m; + int success; + + debug3("%s", __func__); + buffer_init(&m); + buffer_put_cstring(&m, authctxt->user); + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_INIT_CTX, &m); + debug3("%s: waiting for MONITOR_ANS_PAM_INIT_CTX", __func__); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_INIT_CTX, &m); + success = buffer_get_int(&m); + if (success == 0) { + debug3("%s: pam_init_ctx failed", __func__); + buffer_free(&m); + return (NULL); + } + buffer_free(&m); + return (authctxt); +} + +int +mm_sshpam_query(void *ctx, char **name, char **info, + u_int *num, char ***prompts, u_int **echo_on) +{ + Buffer m; + int i, ret; + + debug3("%s", __func__); + buffer_init(&m); + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_QUERY, &m); + debug3("%s: waiting for MONITOR_ANS_PAM_QUERY", __func__); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_QUERY, &m); + ret = buffer_get_int(&m); + debug3("%s: pam_query returned %d", __func__, ret); + *name = buffer_get_string(&m, NULL); + *info = buffer_get_string(&m, NULL); + *num = buffer_get_int(&m); + *prompts = xmalloc((*num + 1) * sizeof(char *)); + *echo_on = xmalloc((*num + 1) * sizeof(u_int)); + for (i = 0; i < *num; ++i) { + (*prompts)[i] = buffer_get_string(&m, NULL); + (*echo_on)[i] = buffer_get_int(&m); + } + buffer_free(&m); + return (ret); +} + +int +mm_sshpam_respond(void *ctx, u_int num, char **resp) +{ + Buffer m; + int i, ret; + + debug3("%s", __func__); + buffer_init(&m); + buffer_put_int(&m, num); + for (i = 0; i < num; ++i) + buffer_put_cstring(&m, resp[i]); + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_RESPOND, &m); + debug3("%s: waiting for MONITOR_ANS_PAM_RESPOND", __func__); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_RESPOND, &m); + ret = buffer_get_int(&m); + debug3("%s: pam_respond returned %d", __func__, ret); + buffer_free(&m); + return (ret); +} + +void +mm_sshpam_free_ctx(void *ctxtp) +{ + Buffer m; + + debug3("%s", __func__); + buffer_init(&m); + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_FREE_CTX, &m); + debug3("%s: waiting for MONITOR_ANS_PAM_FREE_CTX", __func__); + mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_FREE_CTX, &m); + buffer_free(&m); +} +#endif /* USE_PAM */ + /* Request process termination */ void diff -ruN --exclude CVS ssh-openbsd-2003091600/monitor_wrap.h openssh-3.7p1/monitor_wrap.h --- ssh-openbsd-2003091600/monitor_wrap.h 2003-09-03 12:07:14.000000000 +1000 +++ openssh-3.7p1/monitor_wrap.h 2003-09-02 22:51:17.000000000 +1000 @@ -63,6 +63,15 @@ int mm_ssh_gssapi_userok(char *user); #endif +#ifdef USE_PAM +void mm_start_pam(char *); +u_int mm_do_pam_account(void); +void *mm_sshpam_init_ctx(struct Authctxt *); +int mm_sshpam_query(void *, char **, char **, u_int *, char ***, u_int **); +int mm_sshpam_respond(void *, u_int, char **); +void mm_sshpam_free_ctx(void *); +#endif + void mm_terminate(void); int mm_pty_allocate(int *, int *, char *, int); void mm_session_pty_cleanup2(void *); diff -ruN --exclude CVS ssh-openbsd-2003091600/nchan.c openssh-3.7p1/nchan.c --- ssh-openbsd-2003091600/nchan.c 2003-09-03 12:07:14.000000000 +1000 +++ openssh-3.7p1/nchan.c 2003-09-02 22:52:31.000000000 +1000 @@ -463,7 +463,13 @@ return; debug2("channel %d: close_read", c->self); if (c->sock != -1) { - if (shutdown(c->sock, SHUT_RD) < 0) + /* + * shutdown(sock, SHUT_READ) may return ENOTCONN if the + * write side has been closed already. (bug on Linux) + * HP-UX may return ENOTCONN also. + */ + if (shutdown(c->sock, SHUT_RD) < 0 + && errno != ENOTCONN) error("channel %d: chan_shutdown_read: " "shutdown() failed for fd%d [i%d o%d]: %.100s", c->self, c->sock, c->istate, c->ostate, diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/base64.c openssh-3.7p1/openbsd-compat/base64.c --- ssh-openbsd-2003091600/openbsd-compat/base64.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/base64.c 2003-02-24 15:45:43.000000000 +1100 @@ -0,0 +1,322 @@ +/* $OpenBSD: base64.c,v 1.4 2002/01/02 23:00:10 deraadt Exp $ */ + +/* + * Copyright (c) 1996 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +/* + * Portions Copyright (c) 1995 by International Business Machines, Inc. + * + * International Business Machines, Inc. (hereinafter called IBM) grants + * permission under its copyrights to use, copy, modify, and distribute this + * Software with or without fee, provided that the above copyright notice and + * all paragraphs of this notice appear in all copies, and that the name of IBM + * not be used in connection with the marketing of any product incorporating + * the Software or modifications thereof, without specific, written prior + * permission. + * + * To the extent it has a right to do so, IBM grants an immunity from suit + * under its patents, if any, for the use, sale or manufacture of products to + * the extent that such products are used for performing Domain Name System + * dynamic updates in TCP/IP networks by means of the Software. No immunity is + * granted for any product per se or for any other function of any product. + * + * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, + * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN + * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +#include "includes.h" + +#if (!defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP)) || (!defined(HAVE_B64_PTON) && !defined(HAVE___B64_PTON)) + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "base64.h" + +/* XXX abort illegal in library */ +#define Assert(Cond) if (!(Cond)) abort() + +static const char Base64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static const char Pad64 = '='; + +/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt) + The following encoding technique is taken from RFC 1521 by Borenstein + and Freed. It is reproduced here in a slightly edited form for + convenience. + + A 65-character subset of US-ASCII is used, enabling 6 bits to be + represented per printable character. (The extra 65th character, "=", + is used to signify a special processing function.) + + The encoding process represents 24-bit groups of input bits as output + strings of 4 encoded characters. Proceeding from left to right, a + 24-bit input group is formed by concatenating 3 8-bit input groups. + These 24 bits are then treated as 4 concatenated 6-bit groups, each + of which is translated into a single digit in the base64 alphabet. + + Each 6-bit group is used as an index into an array of 64 printable + characters. The character referenced by the index is placed in the + output string. + + Table 1: The Base64 Alphabet + + Value Encoding Value Encoding Value Encoding Value Encoding + 0 A 17 R 34 i 51 z + 1 B 18 S 35 j 52 0 + 2 C 19 T 36 k 53 1 + 3 D 20 U 37 l 54 2 + 4 E 21 V 38 m 55 3 + 5 F 22 W 39 n 56 4 + 6 G 23 X 40 o 57 5 + 7 H 24 Y 41 p 58 6 + 8 I 25 Z 42 q 59 7 + 9 J 26 a 43 r 60 8 + 10 K 27 b 44 s 61 9 + 11 L 28 c 45 t 62 + + 12 M 29 d 46 u 63 / + 13 N 30 e 47 v + 14 O 31 f 48 w (pad) = + 15 P 32 g 49 x + 16 Q 33 h 50 y + + Special processing is performed if fewer than 24 bits are available + at the end of the data being encoded. A full encoding quantum is + always completed at the end of a quantity. When fewer than 24 input + bits are available in an input group, zero bits are added (on the + right) to form an integral number of 6-bit groups. Padding at the + end of the data is performed using the '=' character. + + Since all base64 input is an integral number of octets, only the + ------------------------------------------------- + following cases can arise: + + (1) the final quantum of encoding input is an integral + multiple of 24 bits; here, the final unit of encoded + output will be an integral multiple of 4 characters + with no "=" padding, + (2) the final quantum of encoding input is exactly 8 bits; + here, the final unit of encoded output will be two + characters followed by two "=" padding characters, or + (3) the final quantum of encoding input is exactly 16 bits; + here, the final unit of encoded output will be three + characters followed by one "=" padding character. + */ + +#if !defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP) +int +b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize) +{ + size_t datalength = 0; + u_char input[3]; + u_char output[4]; + int i; + + while (2 < srclength) { + input[0] = *src++; + input[1] = *src++; + input[2] = *src++; + srclength -= 3; + + output[0] = input[0] >> 2; + output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); + output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + output[3] = input[2] & 0x3f; + Assert(output[0] < 64); + Assert(output[1] < 64); + Assert(output[2] < 64); + Assert(output[3] < 64); + + if (datalength + 4 > targsize) + return (-1); + target[datalength++] = Base64[output[0]]; + target[datalength++] = Base64[output[1]]; + target[datalength++] = Base64[output[2]]; + target[datalength++] = Base64[output[3]]; + } + + /* Now we worry about padding. */ + if (0 != srclength) { + /* Get what's left. */ + input[0] = input[1] = input[2] = '\0'; + for (i = 0; i < srclength; i++) + input[i] = *src++; + + output[0] = input[0] >> 2; + output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); + output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + Assert(output[0] < 64); + Assert(output[1] < 64); + Assert(output[2] < 64); + + if (datalength + 4 > targsize) + return (-1); + target[datalength++] = Base64[output[0]]; + target[datalength++] = Base64[output[1]]; + if (srclength == 1) + target[datalength++] = Pad64; + else + target[datalength++] = Base64[output[2]]; + target[datalength++] = Pad64; + } + if (datalength >= targsize) + return (-1); + target[datalength] = '\0'; /* Returned value doesn't count \0. */ + return (datalength); +} +#endif /* !defined(HAVE_B64_NTOP) && !defined(HAVE___B64_NTOP) */ + +#if !defined(HAVE_B64_PTON) && !defined(HAVE___B64_PTON) + +/* skips all whitespace anywhere. + converts characters, four at a time, starting at (or after) + src from base - 64 numbers into three 8 bit bytes in the target area. + it returns the number of data bytes stored at the target, or -1 on error. + */ + +int +b64_pton(char const *src, u_char *target, size_t targsize) +{ + int tarindex, state, ch; + char *pos; + + state = 0; + tarindex = 0; + + while ((ch = *src++) != '\0') { + if (isspace(ch)) /* Skip whitespace anywhere. */ + continue; + + if (ch == Pad64) + break; + + pos = strchr(Base64, ch); + if (pos == 0) /* A non-base64 character. */ + return (-1); + + switch (state) { + case 0: + if (target) { + if (tarindex >= targsize) + return (-1); + target[tarindex] = (pos - Base64) << 2; + } + state = 1; + break; + case 1: + if (target) { + if (tarindex + 1 >= targsize) + return (-1); + target[tarindex] |= (pos - Base64) >> 4; + target[tarindex+1] = ((pos - Base64) & 0x0f) + << 4 ; + } + tarindex++; + state = 2; + break; + case 2: + if (target) { + if (tarindex + 1 >= targsize) + return (-1); + target[tarindex] |= (pos - Base64) >> 2; + target[tarindex+1] = ((pos - Base64) & 0x03) + << 6; + } + tarindex++; + state = 3; + break; + case 3: + if (target) { + if (tarindex >= targsize) + return (-1); + target[tarindex] |= (pos - Base64); + } + tarindex++; + state = 0; + break; + } + } + + /* + * We are done decoding Base-64 chars. Let's see if we ended + * on a byte boundary, and/or with erroneous trailing characters. + */ + + if (ch == Pad64) { /* We got a pad char. */ + ch = *src++; /* Skip it, get next. */ + switch (state) { + case 0: /* Invalid = in first position */ + case 1: /* Invalid = in second position */ + return (-1); + + case 2: /* Valid, means one byte of info */ + /* Skip any number of spaces. */ + for (; ch != '\0'; ch = *src++) + if (!isspace(ch)) + break; + /* Make sure there is another trailing = sign. */ + if (ch != Pad64) + return (-1); + ch = *src++; /* Skip the = */ + /* Fall through to "single trailing =" case. */ + /* FALLTHROUGH */ + + case 3: /* Valid, means two bytes of info */ + /* + * We know this char is an =. Is there anything but + * whitespace after it? + */ + for (; ch != '\0'; ch = *src++) + if (!isspace(ch)) + return (-1); + + /* + * Now make sure for cases 2 and 3 that the "extra" + * bits that slopped past the last full byte were + * zeros. If we don't check them, they become a + * subliminal channel. + */ + if (target && target[tarindex] != 0) + return (-1); + } + } else { + /* + * We ended by seeing the end of the string. Make sure we + * have no partial bytes lying around. + */ + if (state != 0) + return (-1); + } + + return (tarindex); +} + +#endif /* !defined(HAVE_B64_PTON) && !defined(HAVE___B64_PTON) */ +#endif diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/base64.h openssh-3.7p1/openbsd-compat/base64.h --- ssh-openbsd-2003091600/openbsd-compat/base64.h 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/base64.h 2003-08-30 02:59:52.000000000 +1000 @@ -0,0 +1,65 @@ +/* $Id: base64.h,v 1.6 2003/08/29 16:59:52 mouring Exp $ */ + +/* + * Copyright (c) 1996 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +/* + * Portions Copyright (c) 1995 by International Business Machines, Inc. + * + * International Business Machines, Inc. (hereinafter called IBM) grants + * permission under its copyrights to use, copy, modify, and distribute this + * Software with or without fee, provided that the above copyright notice and + * all paragraphs of this notice appear in all copies, and that the name of IBM + * not be used in connection with the marketing of any product incorporating + * the Software or modifications thereof, without specific, written prior + * permission. + * + * To the extent it has a right to do so, IBM grants an immunity from suit + * under its patents, if any, for the use, sale or manufacture of products to + * the extent that such products are used for performing Domain Name System + * dynamic updates in TCP/IP networks by means of the Software. No immunity is + * granted for any product per se or for any other function of any product. + * + * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, + * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN + * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +#ifndef _BSD_BASE64_H +#define _BSD_BASE64_H + +#include "includes.h" + +#ifndef HAVE___B64_NTOP +# ifndef HAVE_B64_NTOP +int b64_ntop(u_char const *src, size_t srclength, char *target, + size_t targsize); +# endif /* !HAVE_B64_NTOP */ +# define __b64_ntop(a,b,c,d) b64_ntop(a,b,c,d) +#endif /* HAVE___B64_NTOP */ + +#ifndef HAVE___B64_PTON +# ifndef HAVE_B64_PTON +int b64_pton(char const *src, u_char *target, size_t targsize); +# endif /* !HAVE_B64_PTON */ +# define __b64_pton(a,b,c) b64_pton(a,b,c) +#endif /* HAVE___B64_PTON */ + +#endif /* _BSD_BASE64_H */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/basename.c openssh-3.7p1/openbsd-compat/basename.c --- ssh-openbsd-2003091600/openbsd-compat/basename.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/basename.c 2003-08-25 11:10:51.000000000 +1000 @@ -0,0 +1,62 @@ +/* $OpenBSD: basename.c,v 1.11 2003/06/17 21:56:23 millert Exp $ */ + +/* + * Copyright (c) 1997 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" +#ifndef HAVE_BASENAME + +#ifndef lint +static char rcsid[] = "$OpenBSD: basename.c,v 1.11 2003/06/17 21:56:23 millert Exp $"; +#endif /* not lint */ + +char * +basename(const char *path) +{ + static char bname[MAXPATHLEN]; + register const char *endp, *startp; + + /* Empty or NULL string gets treated as "." */ + if (path == NULL || *path == '\0') { + (void)strlcpy(bname, ".", sizeof bname); + return(bname); + } + + /* Strip trailing slashes */ + endp = path + strlen(path) - 1; + while (endp > path && *endp == '/') + endp--; + + /* All slashes become "/" */ + if (endp == path && *endp == '/') { + (void)strlcpy(bname, "/", sizeof bname); + return(bname); + } + + /* Find the start of the base */ + startp = endp; + while (startp > path && *(startp - 1) != '/') + startp--; + + if (endp - startp + 2 > sizeof(bname)) { + errno = ENAMETOOLONG; + return(NULL); + } + strlcpy(bname, startp, endp - startp + 2); + return(bname); +} + +#endif /* !defined(HAVE_BASENAME) */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/bindresvport.c openssh-3.7p1/openbsd-compat/bindresvport.c --- ssh-openbsd-2003091600/openbsd-compat/bindresvport.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/bindresvport.c 2003-06-02 18:59:08.000000000 +1000 @@ -0,0 +1,112 @@ +/* This file has be substantially modified from the original OpenBSD source */ + +/* $OpenBSD: bindresvport.c,v 1.15 2003/05/20 22:42:35 deraadt Exp $ */ + +/* + * Copyright 1996, Jason Downs. All rights reserved. + * Copyright 1998, Theo de Raadt. All rights reserved. + * Copyright 2000, Damien Miller. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#ifndef HAVE_BINDRESVPORT_SA + +#include "includes.h" + +#define STARTPORT 600 +#define ENDPORT (IPPORT_RESERVED - 1) +#define NPORTS (ENDPORT - STARTPORT + 1) + +/* + * Bind a socket to a privileged IP port + */ +int +bindresvport_sa(sd, sa) + int sd; + struct sockaddr *sa; +{ + int error, af; + struct sockaddr_storage myaddr; + struct sockaddr_in *sin; + struct sockaddr_in6 *sin6; + u_int16_t *portp; + u_int16_t port; + socklen_t salen; + int i; + + if (sa == NULL) { + memset(&myaddr, 0, sizeof(myaddr)); + sa = (struct sockaddr *)&myaddr; + + if (getsockname(sd, sa, &salen) == -1) + return -1; /* errno is correctly set */ + + af = sa->sa_family; + memset(&myaddr, 0, salen); + } else + af = sa->sa_family; + + if (af == AF_INET) { + sin = (struct sockaddr_in *)sa; + salen = sizeof(struct sockaddr_in); + portp = &sin->sin_port; + } else if (af == AF_INET6) { + sin6 = (struct sockaddr_in6 *)sa; + salen = sizeof(struct sockaddr_in6); + portp = &sin6->sin6_port; + } else { + errno = EPFNOSUPPORT; + return (-1); + } + sa->sa_family = af; + + port = ntohs(*portp); + if (port == 0) + port = (arc4random() % NPORTS) + STARTPORT; + + /* Avoid warning */ + error = -1; + + for(i = 0; i < NPORTS; i++) { + *portp = htons(port); + + error = bind(sd, sa, salen); + + /* Terminate on success */ + if (error == 0) + break; + + /* Terminate on errors, except "address already in use" */ + if ((error < 0) && !((errno == EADDRINUSE) || (errno == EINVAL))) + break; + + port++; + if (port > ENDPORT) + port = STARTPORT; + } + + return (error); +} + +#endif /* HAVE_BINDRESVPORT_SA */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/bsd-arc4random.c openssh-3.7p1/openbsd-compat/bsd-arc4random.c --- ssh-openbsd-2003091600/openbsd-compat/bsd-arc4random.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/bsd-arc4random.c 2003-05-19 00:13:38.000000000 +1000 @@ -0,0 +1,78 @@ +/* + * 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. + */ + +#include "includes.h" +#include "log.h" + +RCSID("$Id: bsd-arc4random.c,v 1.7 2003/05/18 14:13:38 djm Exp $"); + +#ifndef HAVE_ARC4RANDOM + +#include +#include +#include + +/* Size of key to use */ +#define SEED_SIZE 20 + +/* Number of bytes to reseed after */ +#define REKEY_BYTES (1 << 24) + +static int rc4_ready = 0; +static RC4_KEY rc4; + +unsigned int arc4random(void) +{ + unsigned int r = 0; + static int first_time = 1; + + if (rc4_ready <= 0) { + if (first_time) + seed_rng(); + first_time = 0; + arc4random_stir(); + } + + RC4(&rc4, sizeof(r), (unsigned char *)&r, (unsigned char *)&r); + + rc4_ready -= sizeof(r); + + return(r); +} + +void arc4random_stir(void) +{ + unsigned char rand_buf[SEED_SIZE]; + + memset(&rc4, 0, sizeof(rc4)); + if (RAND_bytes(rand_buf, sizeof(rand_buf)) <= 0) + fatal("Couldn't obtain random bytes (error %ld)", + ERR_get_error()); + RC4_set_key(&rc4, sizeof(rand_buf), rand_buf); + RC4(&rc4, sizeof(rand_buf), rand_buf, rand_buf); + memset(rand_buf, 0, sizeof(rand_buf)); + + rc4_ready = REKEY_BYTES; +} +#endif /* !HAVE_ARC4RANDOM */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/bsd-cray.c openssh-3.7p1/openbsd-compat/bsd-cray.c --- ssh-openbsd-2003091600/openbsd-compat/bsd-cray.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/bsd-cray.c 2003-06-03 12:45:27.000000000 +1000 @@ -0,0 +1,781 @@ +/* + * $Id: bsd-cray.c,v 1.12 2003/06/03 02:45:27 dtucker Exp $ + * + * bsd-cray.c + * + * Copyright (c) 2002, Cray Inc. (Wendy Palm ) + * Significant portions provided by + * Wayne Schroeder, SDSC + * William Jones, UTexas + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Created: Apr 22 16.34:00 2002 wp + * + * This file contains functions required for proper execution + * on UNICOS systems. + * + */ +#ifdef _UNICOS + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ssh.h" +#include "log.h" +#include "servconf.h" +#include "bsd-cray.h" + +#define MAXACID 80 + +extern ServerOptions options; + +char cray_tmpdir[TPATHSIZ + 1]; /* job TMPDIR path */ + +struct sysv sysv; /* system security structure */ +struct usrv usrv; /* user security structure */ + +/* + * Functions. + */ +void cray_retain_utmp(struct utmp *, int); +void cray_delete_tmpdir(char *, int, uid_t); +void cray_init_job(struct passwd *); +void cray_set_tmpdir(struct utmp *); +void cray_login_failure(char *, int); +int cray_setup(uid_t, char *, const char *); +int cray_access_denied(char *); + +void +cray_login_failure(char *username, int errcode) +{ + struct udb *ueptr; /* UDB pointer for username */ + ia_failure_t fsent; /* ia_failure structure */ + ia_failure_ret_t fret; /* ia_failure return stuff */ + struct jtab jtab; /* job table structure */ + int jid = 0; /* job id */ + + if ((jid = getjtab(&jtab)) < 0) + debug("cray_login_failure(): getjtab error"); + + getsysudb(); + if ((ueptr = getudbnam(username)) == UDB_NULL) + debug("cray_login_failure(): getudbname() returned NULL"); + endudb(); + + memset(&fsent, '\0', sizeof(fsent)); + fsent.revision = 0; + fsent.uname = username; + fsent.host = (char *)get_canonical_hostname(options.use_dns); + fsent.ttyn = "sshd"; + fsent.caller = IA_SSHD; + fsent.flags = IA_INTERACTIVE; + fsent.ueptr = ueptr; + fsent.jid = jid; + fsent.errcode = errcode; + fsent.pwdp = NULL; + fsent.exitcode = 0; /* dont exit in ia_failure() */ + + fret.revision = 0; + fret.normal = 0; + + /* + * Call ia_failure because of an login failure. + */ + ia_failure(&fsent, &fret); +} + +/* + * Cray access denied + */ +int +cray_access_denied(char *username) +{ + struct udb *ueptr; /* UDB pointer for username */ + int errcode; /* IA errorcode */ + + errcode = 0; + getsysudb(); + if ((ueptr = getudbnam(username)) == UDB_NULL) + debug("cray_login_failure(): getudbname() returned NULL"); + endudb(); + + if (ueptr != NULL && ueptr->ue_disabled) + errcode = IA_DISABLED; + if (errcode) + cray_login_failure(username, errcode); + + return (errcode); +} + +/* + * record_failed_login: generic "login failed" interface function + */ +void +record_failed_login(const char *user, const char *ttyname) +{ + cray_login_failure((char *)user, IA_UDBERR); +} + +int +cray_setup (uid_t uid, char *username, const char *command) +{ + extern struct udb *getudb(); + extern char *setlimits(); + + int err; /* error return */ + time_t system_time; /* current system clock */ + time_t expiration_time; /* password expiration time */ + int maxattempts; /* maximum no. of failed login attempts */ + int SecureSys; /* unicos security flag */ + int minslevel = 0; /* system minimum security level */ + int i, j; + int valid_acct = -1; /* flag for reading valid acct */ + char acct_name[MAXACID] = { "" }; /* used to read acct name */ + struct jtab jtab; /* Job table struct */ + struct udb ue; /* udb entry for logging-in user */ + struct udb *up; /* pointer to UDB entry */ + struct secstat secinfo; /* file security attributes */ + struct servprov init_info; /* used for sesscntl() call */ + int jid; /* job ID */ + int pid; /* process ID */ + char *sr; /* status return from setlimits() */ + char *ttyn = NULL; /* ttyname or command name*/ + char hostname[MAXHOSTNAMELEN]; + /* passwd stuff for ia_user */ + passwd_t pwdacm, pwddialup, pwdudb, pwdwal, pwddce; + ia_user_ret_t uret; /* stuff returned from ia_user */ + ia_user_t usent /* ia_user main structure */ + int ia_rcode; /* ia_user return code */ + ia_failure_t fsent; /* ia_failure structure */ + ia_failure_ret_t fret; /* ia_failure return stuff */ + ia_success_t ssent; /* ia_success structure */ + ia_success_ret_t sret; /* ia_success return stuff */ + int ia_mlsrcode; /* ia_mlsuser return code */ + int secstatrc; /* [f]secstat return code */ + + if (SecureSys = (int)sysconf(_SC_CRAY_SECURE_SYS)) { + getsysv(&sysv, sizeof(struct sysv)); + minslevel = sysv.sy_minlvl; + if (getusrv(&usrv) < 0) + fatal("getusrv() failed, errno = %d", errno); + } + hostname[0] = '\0'; + strlcpy(hostname, + (char *)get_canonical_hostname(options.use_dns), + MAXHOSTNAMELEN); + /* + * Fetch user's UDB entry. + */ + getsysudb(); + if ((up = getudbnam(username)) == UDB_NULL) + fatal("cannot fetch user's UDB entry"); + + /* + * Prevent any possible fudging so perform a data + * safety check and compare the supplied uid against + * the udb's uid. + */ + if (up->ue_uid != uid) + fatal("IA uid missmatch"); + endudb(); + + if ((jid = getjtab(&jtab)) < 0) { + debug("getjtab"); + return(-1); + } + pid = getpid(); + ttyn = ttyname(0); + if (SecureSys) { + if (ttyn != NULL) + secstatrc = secstat(ttyn, &secinfo); + else + secstatrc = fsecstat(1, &secinfo); + + if (secstatrc == 0) + debug("[f]secstat() successful"); + else + fatal("[f]secstat() error, rc = %d", secstatrc); + } + if ((ttyn == NULL) && ((char *)command != NULL)) + ttyn = (char *)command; + /* + * Initialize all structures to call ia_user + */ + usent.revision = 0; + usent.uname = username; + usent.host = hostname; + usent.ttyn = ttyn; + usent.caller = IA_SSHD; + usent.pswdlist = &pwdacm; + usent.ueptr = &ue; + usent.flags = IA_INTERACTIVE | IA_FFLAG; + pwdacm.atype = IA_SECURID; + pwdacm.pwdp = NULL; + pwdacm.next = &pwdudb; + + pwdudb.atype = IA_UDB; + pwdudb.pwdp = NULL; + pwdudb.next = &pwddce; + + pwddce.atype = IA_DCE; + pwddce.pwdp = NULL; + pwddce.next = &pwddialup; + + pwddialup.atype = IA_DIALUP; + pwddialup.pwdp = NULL; + /* pwddialup.next = &pwdwal; */ + pwddialup.next = NULL; + + pwdwal.atype = IA_WAL; + pwdwal.pwdp = NULL; + pwdwal.next = NULL; + + uret.revision = 0; + uret.pswd = NULL; + uret.normal = 0; + + ia_rcode = ia_user(&usent, &uret); + switch (ia_rcode) { + /* + * These are acceptable return codes from ia_user() + */ + case IA_UDBWEEK: /* Password Expires in 1 week */ + expiration_time = ue.ue_pwage.time + ue.ue_pwage.maxage; + printf ("WARNING - your current password will expire %s\n", + ctime((const time_t *)&expiration_time)); + break; + case IA_UDBEXPIRED: + if (ttyname(0) != NULL) { + /* Force a password change */ + printf("Your password has expired; Choose a new one.\n"); + execl("/bin/passwd", "passwd", username, 0); + exit(9); + } + break; + case IA_NORMAL: /* Normal Return Code */ + break; + case IA_BACKDOOR: + /* XXX: can we memset it to zero here so save some of this */ + strlcpy(ue.ue_name, "root", sizeof(ue.ue_name)); + strlcpy(ue.ue_dir, "/", sizeof(ue.ue_dir)); + strlcpy(ue.ue_shell, "/bin/sh", sizeof(ue.ue_shell)); + + ue.ue_passwd[0] = '\0'; + ue.ue_age[0] = '\0'; + ue.ue_comment[0] = '\0'; + ue.ue_loghost[0] = '\0'; + ue.ue_logline[0] = '\0'; + + ue.ue_uid = -1; + ue.ue_nice[UDBRC_INTER] = 0; + + for (i = 0; i < MAXVIDS; i++) + ue.ue_gids[i] = 0; + + ue.ue_logfails = 0; + ue.ue_minlvl = ue.ue_maxlvl = ue.ue_deflvl = minslevel; + ue.ue_defcomps = 0; + ue.ue_comparts = 0; + ue.ue_permits = 0; + ue.ue_trap = 0; + ue.ue_disabled = 0; + ue.ue_logtime = 0; + break; + case IA_CONSOLE: /* Superuser not from Console */ + case IA_TRUSTED: /* Trusted user */ + if (options.permit_root_login > PERMIT_NO) + break; /* Accept root login */ + default: + /* + * These are failed return codes from ia_user() + */ + switch (ia_rcode) + { + case IA_BADAUTH: + printf("Bad authorization, access denied.\n"); + break; + case IA_DISABLED: + printf("Your login has been disabled. Contact the system "); + printf("administrator for assistance.\n"); + break; + case IA_GETSYSV: + printf("getsysv() failed - errno = %d\n", errno); + break; + case IA_MAXLOGS: + printf("Maximum number of failed login attempts exceeded.\n"); + printf("Access denied.\n"); + break; + case IA_UDBPWDNULL: + if (SecureSys) + printf("NULL Password not allowed on MLS systems.\n"); + break; + default: + break; + } + + /* + * Authentication failed. + */ + printf("sshd: Login incorrect, (0%o)\n", + ia_rcode-IA_ERRORCODE); + + /* + * Initialize structure for ia_failure + * which will exit. + */ + fsent.revision = 0; + fsent.uname = username; + fsent.host = hostname; + fsent.ttyn = ttyn; + fsent.caller = IA_SSHD; + fsent.flags = IA_INTERACTIVE; + fsent.ueptr = &ue; + fsent.jid = jid; + fsent.errcode = ia_rcode; + fsent.pwdp = uret.pswd; + fsent.exitcode = 1; + + fret.revision = 0; + fret.normal = 0; + + /* + * Call ia_failure because of an IA failure. + * There is no return because ia_failure exits. + */ + ia_failure(&fsent, &fret); + + exit(1); + } + + ia_mlsrcode = IA_NORMAL; + if (SecureSys) { + debug("calling ia_mlsuser()"); + ia_mlsrcode = ia_mlsuser(&ue, &secinfo, &usrv, NULL, 0); + } + if (ia_mlsrcode != IA_NORMAL) { + printf("sshd: Login incorrect, (0%o)\n", + ia_mlsrcode-IA_ERRORCODE); + /* + * Initialize structure for ia_failure + * which will exit. + */ + fsent.revision = 0; + fsent.uname = username; + fsent.host = hostname; + fsent.ttyn = ttyn; + fsent.caller = IA_SSHD; + fsent.flags = IA_INTERACTIVE; + fsent.ueptr = &ue; + fsent.jid = jid; + fsent.errcode = ia_mlsrcode; + fsent.pwdp = uret.pswd; + fsent.exitcode = 1; + fret.revision = 0; + fret.normal = 0; + + /* + * Call ia_failure because of an IA failure. + * There is no return because ia_failure exits. + */ + ia_failure(&fsent,&fret); + exit(1); + } + + /* Provide login status information */ + if (options.print_lastlog && ue.ue_logtime != 0) { + printf("Last successful login was : %.*s ", 19, + (char *)ctime(&ue.ue_logtime)); + + if (*ue.ue_loghost != '\0') { + printf("from %.*s\n", sizeof(ue.ue_loghost), + ue.ue_loghost); + } else { + printf("on %.*s\n", sizeof(ue.ue_logline), + ue.ue_logline); + } + + if (SecureSys && (ue.ue_logfails != 0)) { + printf(" followed by %d failed attempts\n", + ue.ue_logfails); + } + } + + /* + * Call ia_success to process successful I/A. + */ + ssent.revision = 0; + ssent.uname = username; + ssent.host = hostname; + ssent.ttyn = ttyn; + ssent.caller = IA_SSHD; + ssent.flags = IA_INTERACTIVE; + ssent.ueptr = &ue; + ssent.jid = jid; + ssent.errcode = ia_rcode; + ssent.us = NULL; + ssent.time = 1; /* Set ue_logtime */ + + sret.revision = 0; + sret.normal = 0; + + ia_success(&ssent, &sret); + + /* + * Query for account, iff > 1 valid acid & askacid permbit + */ + if (((ue.ue_permbits & PERMBITS_ACCTID) || + (ue.ue_acids[0] >= 0) && (ue.ue_acids[1] >= 0)) && + ue.ue_permbits & PERMBITS_ASKACID) { + if (ttyname(0) != NULL) { + debug("cray_setup: ttyname true case, %.100s", ttyname); + while (valid_acct == -1) { + printf("Account (? for available accounts)" + " [%s]: ", acid2nam(ue.ue_acids[0])); + fgets(acct_name, MAXACID, stdin); + switch (acct_name[0]) { + case EOF: + exit(0); + break; + case '\0': + valid_acct = ue.ue_acids[0]; + strlcpy(acct_name, acid2nam(valid_acct), MAXACID); + break; + case '?': + /* Print the list 3 wide */ + for (i = 0, j = 0; i < MAXVIDS; i++) { + if (ue.ue_acids[i] == -1) { + printf("\n"); + break; + } + if (++j == 4) { + j = 1; + printf("\n"); + } + printf(" %s", + acid2nam(ue.ue_acids[i])); + } + if (ue.ue_permbits & PERMBITS_ACCTID) { + printf("\"acctid\" permbit also allows" + " you to select any valid " + "account name.\n"); + } + printf("\n"); + break; + default: + valid_acct = nam2acid(acct_name); + if (valid_acct == -1) { + printf( + "Account id not found for" + " account name \"%s\"\n\n", + acct_name); + break; + } + /* + * If an account was given, search the user's + * acids array to verify they can use this account. + */ + if ((valid_acct != -1) && + !(ue.ue_permbits & PERMBITS_ACCTID)) { + for (i = 0; i < MAXVIDS; i++) { + if (ue.ue_acids[i] == -1) + break; + if (valid_acct == ue.ue_acids[i]) + break; + } + if (i == MAXVIDS || + ue.ue_acids[i] == -1) { + fprintf(stderr, "Cannot set" + " account name to " + "\"%s\", permission " + "denied\n\n", acct_name); + valid_acct = -1; + } + } + } + } else { + /* + * The client isn't connected to a terminal and can't + * respond to an acid prompt. Use default acid. + */ + debug("cray_setup: ttyname false case, %.100s", + ttyname); + valid_acct = ue.ue_acids[0]; + } + } else { + /* + * The user doesn't have the askacid permbit set or + * only has one valid account to use. + */ + valid_acct = ue.ue_acids[0]; + } + if (acctid(0, valid_acct) < 0) { + printf ("Bad account id: %d\n", valid_acct); + exit(1); + } + + /* + * Now set shares, quotas, limits, including CPU time for the + * (interactive) job and process, and set up permissions + * (for chown etc), etc. + */ + if (setshares(ue.ue_uid, valid_acct, printf, 0, 0)) { + printf("Unable to give %d shares to <%s>(%d/%d)\n", + ue.ue_shares, ue.ue_name, ue.ue_uid, valid_acct); + exit(1); + } + + sr = setlimits(username, C_PROC, pid, UDBRC_INTER); + if (sr != NULL) { + debug("%.200s", sr); + exit(1); + } + sr = setlimits(username, C_JOB, jid, UDBRC_INTER); + if (sr != NULL) { + debug("%.200s", sr); + exit(1); + } + /* + * Place the service provider information into + * the session table (Unicos) or job table (Unicos/mk). + * There exist double defines for the job/session table in + * unicos/mk (jtab.h) so no need for a compile time switch. + */ + memset(&init_info, '\0', sizeof(init_info)); + init_info.s_sessinit.si_id = URM_SPT_LOGIN; + init_info.s_sessinit.si_pid = getpid(); + init_info.s_sessinit.si_sid = jid; + sesscntl(0, S_SETSERVPO, (int)&init_info); + + /* + * Set user and controlling tty security attributes. + */ + if (SecureSys) { + if (setusrv(&usrv) == -1) { + debug("setusrv() failed, errno = %d",errno); + exit(1); + } + } + + return (0); +} + +/* + * The rc.* and /etc/sdaemon methods of starting a program on unicos/unicosmk + * can have pal privileges that sshd can inherit which + * could allow a user to su to root with out a password. + * This subroutine clears all privileges. + */ +void +drop_cray_privs() +{ +#if defined(_SC_CRAY_PRIV_SU) + priv_proc_t *privstate; + int result; + extern int priv_set_proc(); + extern priv_proc_t *priv_init_proc(); + + /* + * If ether of theses two flags are not set + * then don't allow this version of ssh to run. + */ + if (!sysconf(_SC_CRAY_PRIV_SU)) + fatal("Not PRIV_SU system."); + if (!sysconf(_SC_CRAY_POSIX_PRIV)) + fatal("Not POSIX_PRIV."); + + debug("Setting MLS labels.");; + + if (sysconf(_SC_CRAY_SECURE_MAC)) { + usrv.sv_minlvl = SYSLOW; + usrv.sv_actlvl = SYSHIGH; + usrv.sv_maxlvl = SYSHIGH; + } else { + usrv.sv_minlvl = sysv.sy_minlvl; + usrv.sv_actlvl = sysv.sy_minlvl; + usrv.sv_maxlvl = sysv.sy_maxlvl; + } + usrv.sv_actcmp = 0; + usrv.sv_valcmp = sysv.sy_valcmp; + + usrv.sv_intcat = TFM_SYSTEM; + usrv.sv_valcat |= (TFM_SYSTEM | TFM_SYSFILE); + + if (setusrv(&usrv) < 0) { + fatal("%s(%d): setusrv(): %s", __FILE__, __LINE__, + strerror(errno)); + } + + if ((privstate = priv_init_proc()) != NULL) { + result = priv_set_proc(privstate); + if (result != 0 ) { + fatal("%s(%d): priv_set_proc(): %s", + __FILE__, __LINE__, strerror(errno)); + } + priv_free_proc(privstate); + } + debug ("Privileges should be cleared..."); +#else + /* XXX: do this differently */ +# error Cray systems must be run with _SC_CRAY_PRIV_SU on! +#endif +} + + +/* + * Retain utmp/wtmp information - used by cray accounting. + */ +void +cray_retain_utmp(struct utmp *ut, int pid) +{ + int fd; + struct utmp utmp; + + if ((fd = open(UTMP_FILE, O_RDONLY)) != -1) { + /* XXX use atomicio */ + while (read(fd, (char *)&utmp, sizeof(utmp)) == sizeof(utmp)) { + if (pid == utmp.ut_pid) { + ut->ut_jid = utmp.ut_jid; + strncpy(ut->ut_tpath, utmp.ut_tpath, sizeof(utmp.ut_tpath)); + strncpy(ut->ut_host, utmp.ut_host, sizeof(utmp.ut_host)); + strncpy(ut->ut_name, utmp.ut_name, sizeof(utmp.ut_name)); + break; + } + } + close(fd); + } else + fatal("Unable to open utmp file"); +} + +/* + * tmpdir support. + */ + +/* + * find and delete jobs tmpdir. + */ +void +cray_delete_tmpdir(char *login, int jid, uid_t uid) +{ + static char jtmp[TPATHSIZ]; + struct stat statbuf; + int child, c, wstat; + + for (c = 'a'; c <= 'z'; c++) { + snprintf(jtmp, TPATHSIZ, "%s/jtmp.%06d%c", JTMPDIR, jid, c); + if (stat(jtmp, &statbuf) == 0 && statbuf.st_uid == uid) + break; + } + + if (c > 'z') + return; + + if ((child = fork()) == 0) { + execl(CLEANTMPCMD, CLEANTMPCMD, login, jtmp, (char *)NULL); + fatal("cray_delete_tmpdir: execl of CLEANTMPCMD failed"); + } + + while (waitpid(child, &wstat, 0) == -1 && errno == EINTR) + ; +} + +/* + * Remove tmpdir on job termination. + */ +void +cray_job_termination_handler(int sig) +{ + int jid; + char *login = NULL; + struct jtab jtab; + + debug("received signal %d",sig); + + if ((jid = waitjob(&jtab)) == -1 || + (login = uid2nam(jtab.j_uid)) == NULL) + return; + + cray_delete_tmpdir(login, jid, jtab.j_uid); +} + +/* + * Set job id and create tmpdir directory. + */ +void +cray_init_job(struct passwd *pw) +{ + int jid; + int c; + + jid = setjob(pw->pw_uid, WJSIGNAL); + if (jid < 0) + fatal("System call setjob failure"); + + for (c = 'a'; c <= 'z'; c++) { + snprintf(cray_tmpdir, TPATHSIZ, "%s/jtmp.%06d%c", JTMPDIR, jid, c); + if (mkdir(cray_tmpdir, JTMPMODE) != 0) + continue; + if (chown(cray_tmpdir, pw->pw_uid, pw->pw_gid) != 0) { + rmdir(cray_tmpdir); + continue; + } + break; + } + + if (c > 'z') + cray_tmpdir[0] = '\0'; +} + +void +cray_set_tmpdir(struct utmp *ut) +{ + int jid; + struct jtab jbuf; + + if ((jid = getjtab(&jbuf)) < 0) + return; + + /* + * Set jid and tmpdir in utmp record. + */ + ut->ut_jid = jid; + strncpy(ut->ut_tpath, cray_tmpdir, TPATHSIZ); +} +#endif diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/bsd-cray.h openssh-3.7p1/openbsd-compat/bsd-cray.h --- ssh-openbsd-2003091600/openbsd-compat/bsd-cray.h 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/bsd-cray.h 2003-08-30 02:59:52.000000000 +1000 @@ -0,0 +1,62 @@ +/* $Id: bsd-cray.h,v 1.10 2003/08/29 16:59:52 mouring Exp $ */ + +/* + * Copyright (c) 2002, Cray Inc. (Wendy Palm ) + * Significant portions provided by + * Wayne Schroeder, SDSC + * William Jones, UTexas + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Created: Apr 22 16.34:00 2002 wp + * + * This file contains functions required for proper execution + * on UNICOS systems. + * + */ + +#ifndef _BSD_CRAY_H +#define _BSD_CRAY_H + +#ifdef _UNICOS + +void cray_init_job(struct passwd *); +void cray_job_termination_handler(int); +void cray_login_failure(char *, int ); +int cray_access_denied(char *); +#define CUSTOM_FAILED_LOGIN 1 +void record_failed_login(const char *, const char *); +extern char cray_tmpdir[]; + +#ifndef IA_SSHD +# define IA_SSHD IA_LOGIN +#endif +#ifndef MAXHOSTNAMELEN +# define MAXHOSTNAMELEN 64 +#endif +#ifndef _CRAYT3E +# include +# define TIOCGPGRP (tIOC|20) +#endif + +#endif /* UNICOS */ + +#endif /* _BSD_CRAY_H */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/bsd-cygwin_util.c openssh-3.7p1/openbsd-compat/bsd-cygwin_util.c --- ssh-openbsd-2003091600/openbsd-compat/bsd-cygwin_util.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/bsd-cygwin_util.c 2003-08-07 16:23:43.000000000 +1000 @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2000, 2001, Corinna Vinschen + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Created: Sat Sep 02 12:17:00 2000 cv + * + * This file contains functions for forcing opened file descriptors to + * binary mode on Windows systems. + */ + +#include "includes.h" + +RCSID("$Id: bsd-cygwin_util.c,v 1.11 2003/08/07 06:23:43 dtucker Exp $"); + +#ifdef HAVE_CYGWIN + +#include +#include +#include +#include +#include +#define is_winnt (GetVersion() < 0x80000000) + +#define ntsec_on(c) ((c) && strstr((c),"ntsec") && !strstr((c),"nontsec")) +#define ntsec_off(c) ((c) && strstr((c),"nontsec")) +#define ntea_on(c) ((c) && strstr((c),"ntea") && !strstr((c),"nontea")) + +#if defined(open) && open == binary_open +# undef open +#endif +#if defined(pipe) && open == binary_pipe +# undef pipe +#endif + +int +binary_open(const char *filename, int flags, ...) +{ + va_list ap; + mode_t mode; + + va_start(ap, flags); + mode = va_arg(ap, mode_t); + va_end(ap); + return (open(filename, flags | O_BINARY, mode)); +} + +int +binary_pipe(int fd[2]) +{ + int ret = pipe(fd); + + if (!ret) { + setmode(fd[0], O_BINARY); + setmode(fd[1], O_BINARY); + } + return (ret); +} + +#define HAS_CREATE_TOKEN 1 +#define HAS_NTSEC_BY_DEFAULT 2 + +static int +has_capability(int what) +{ + static int inited; + static int has_create_token; + static int has_ntsec_by_default; + + /* + * has_capability() basically calls uname() and checks if + * specific capabilities of Cygwin can be evaluated from that. + * This simplifies the calling functions which only have to ask + * for a capability using has_capability() instead of having + * to figure that out by themselves. + */ + if (!inited) { + struct utsname uts; + char *c; + + if (!uname(&uts)) { + int major_high = 0, major_low = 0, minor = 0; + int api_major_version = 0, api_minor_version = 0; + char *c; + + sscanf(uts.release, "%d.%d.%d", &major_high, + &major_low, &minor); + if ((c = strchr(uts.release, '(')) != NULL) { + sscanf(c + 1, "%d.%d", &api_major_version, + &api_minor_version); + } + if (major_high > 1 || + (major_high == 1 && (major_low > 3 || + (major_low == 3 && minor >= 2)))) + has_create_token = 1; + if (api_major_version > 0 || api_minor_version >= 56) + has_ntsec_by_default = 1; + inited = 1; + } + } + switch (what) { + case HAS_CREATE_TOKEN: + return (has_create_token); + case HAS_NTSEC_BY_DEFAULT: + return (has_ntsec_by_default); + } + return (0); +} + +int +check_nt_auth(int pwd_authenticated, struct passwd *pw) +{ + /* + * The only authentication which is able to change the user + * context on NT systems is the password authentication. So + * we deny all requsts for changing the user context if another + * authentication method is used. + * + * This doesn't apply to Cygwin versions >= 1.3.2 anymore which + * uses the undocumented NtCreateToken() call to create a user + * token if the process has the appropriate privileges and if + * CYGWIN ntsec setting is on. + */ + static int has_create_token = -1; + + if (pw == NULL) + return 0; + if (is_winnt) { + if (has_create_token < 0) { + char *cygwin = getenv("CYGWIN"); + + has_create_token = 0; + if (has_capability(HAS_CREATE_TOKEN) && + (ntsec_on(cygwin) || + (has_capability(HAS_NTSEC_BY_DEFAULT) && + !ntsec_off(cygwin)))) + has_create_token = 1; + } + if (has_create_token < 1 && + !pwd_authenticated && geteuid() != pw->pw_uid) + return (0); + } + return (1); +} + +int +check_ntsec(const char *filename) +{ + char *cygwin; + int allow_ntea = 0, allow_ntsec = 0; + struct statfs fsstat; + + /* Windows 95/98/ME don't support file system security at all. */ + if (!is_winnt) + return (0); + + /* Evaluate current CYGWIN settings. */ + cygwin = getenv("CYGWIN"); + allow_ntea = ntea_on(cygwin); + allow_ntsec = ntsec_on(cygwin) || + (has_capability(HAS_NTSEC_BY_DEFAULT) && !ntsec_off(cygwin)); + + /* + * `ntea' is an emulation of POSIX attributes. It doesn't support + * real file level security as ntsec on NTFS file systems does + * but it supports FAT filesystems. `ntea' is minimum requirement + * for security checks. + */ + if (allow_ntea) + return (1); + + /* + * Retrieve file system flags. In Cygwin, file system flags are + * copied to f_type which has no meaning in Win32 itself. + */ + if (statfs(filename, &fsstat)) + return (1); + + /* + * Only file systems supporting ACLs are able to set permissions. + * `ntsec' is the setting in Cygwin which switches using of NTFS + * ACLs to support POSIX permissions on files. + */ + if (fsstat.f_type & FS_PERSISTENT_ACLS) + return (allow_ntsec); + + return (0); +} + +void +register_9x_service(void) +{ + HINSTANCE kerneldll; + DWORD (*RegisterServiceProcess)(DWORD, DWORD); + + /* The service register mechanism in 9x/Me is pretty different from + * NT/2K/XP. In NT/2K/XP we're using a special service starter + * application to register and control sshd as service. This method + * doesn't play nicely with 9x/Me. For that reason we register here + * as service when running under 9x/Me. This function is only called + * by the child sshd when it's going to daemonize. + */ + if (is_winnt) + return; + if (!(kerneldll = LoadLibrary("KERNEL32.DLL"))) + return; + if (!(RegisterServiceProcess = (DWORD (*)(DWORD, DWORD)) + GetProcAddress(kerneldll, "RegisterServiceProcess"))) + return; + RegisterServiceProcess(0, 1); +} + +#endif /* HAVE_CYGWIN */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/bsd-cygwin_util.h openssh-3.7p1/openbsd-compat/bsd-cygwin_util.h --- ssh-openbsd-2003091600/openbsd-compat/bsd-cygwin_util.h 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/bsd-cygwin_util.h 2003-08-07 16:28:16.000000000 +1000 @@ -0,0 +1,55 @@ +/* $Id: bsd-cygwin_util.h,v 1.10 2003/08/07 06:28:16 dtucker Exp $ */ + +/* + * Copyright (c) 2000, 2001, Corinna Vinschen + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Created: Sat Sep 02 12:17:00 2000 cv + * + * This file contains functions for forcing opened file descriptors to + * binary mode on Windows systems. + */ + +#ifndef _BSD_CYGWIN_UTIL_H +#define _BSD_CYGWIN_UTIL_H + +#ifdef HAVE_CYGWIN + +#undef ERROR +#define is_winnt (GetVersion() < 0x80000000) + +#include +#include +#include + +int binary_open(const char *, int , ...); +int binary_pipe(int fd[2]); +int check_nt_auth(int, struct passwd *); +int check_ntsec(const char *); +void register_9x_service(void); + +#define open binary_open +#define pipe binary_pipe + +#endif /* HAVE_CYGWIN */ + +#endif /* _BSD_CYGWIN_UTIL_H */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/bsd-getpeereid.c openssh-3.7p1/openbsd-compat/bsd-getpeereid.c --- ssh-openbsd-2003091600/openbsd-compat/bsd-getpeereid.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/bsd-getpeereid.c 2003-03-25 09:07:52.000000000 +1100 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 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. + */ + +#include "includes.h" + +RCSID("$Id: bsd-getpeereid.c,v 1.2 2003/03/24 22:07:52 djm Exp $"); + +#if !defined(HAVE_GETPEEREID) + +#if defined(SO_PEERCRED) +int +getpeereid(int s, uid_t *euid, gid_t *gid) +{ + struct ucred cred; + socklen_t len = sizeof(cred); + + if (getsockopt(s, SOL_SOCKET, SO_PEERCRED, &cred, &len) < 0) + return (-1); + *euid = cred.uid; + *gid = cred.gid; + + return (0); +} +#else +int +getpeereid(int s, uid_t *euid, gid_t *gid) +{ + *euid = geteuid(); + *gid = getgid(); + + return (0); +} +#endif /* defined(SO_PEERCRED) */ + +#endif /* !defined(HAVE_GETPEEREID) */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/bsd-misc.c openssh-3.7p1/openbsd-compat/bsd-misc.c --- ssh-openbsd-2003091600/openbsd-compat/bsd-misc.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/bsd-misc.c 2003-08-25 11:16:21.000000000 +1000 @@ -0,0 +1,228 @@ +/* + * 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. + */ + +#include "includes.h" +#include "xmalloc.h" + +RCSID("$Id: bsd-misc.c,v 1.19 2003/08/25 01:16:21 mouring Exp $"); + +/* + * NB. duplicate __progname in case it is an alias for argv[0] + * Otherwise it may get clobbered by setproctitle() + */ +char *ssh_get_progname(char *argv0) +{ +#ifdef HAVE___PROGNAME + extern char *__progname; + + return xstrdup(__progname); +#else + char *p; + + if (argv0 == NULL) + return ("unknown"); /* XXX */ + p = strrchr(argv0, '/'); + if (p == NULL) + p = argv0; + else + p++; + + return (xstrdup(p)); +#endif +} + +#ifndef HAVE_SETLOGIN +int setlogin(const char *name) +{ + return (0); +} +#endif /* !HAVE_SETLOGIN */ + +#ifndef HAVE_INNETGR +int innetgr(const char *netgroup, const char *host, + const char *user, const char *domain) +{ + return (0); +} +#endif /* HAVE_INNETGR */ + +#if !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) +int seteuid(uid_t euid) +{ + return (setreuid(-1, euid)); +} +#endif /* !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) */ + +#if !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) +int setegid(uid_t egid) +{ + return(setresgid(-1, egid, -1)); +} +#endif /* !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) */ + +#if !defined(HAVE_STRERROR) && defined(HAVE_SYS_ERRLIST) && defined(HAVE_SYS_NERR) +const char *strerror(int e) +{ + extern int sys_nerr; + extern char *sys_errlist[]; + + if ((e >= 0) && (e < sys_nerr)) + return (sys_errlist[e]); + + return ("unlisted error"); +} +#endif + +#ifndef HAVE_UTIMES +int utimes(char *filename, struct timeval *tvp) +{ + struct utimbuf ub; + + ub.actime = tvp[0].tv_sec; + ub.modtime = tvp[1].tv_sec; + + return (utime(filename, &ub)); +} +#endif + +#ifndef HAVE_TRUNCATE +int truncate(const char *path, off_t length) +{ + int fd, ret, saverrno; + + fd = open(path, O_WRONLY); + if (fd < 0) + return (-1); + + ret = ftruncate(fd, length); + saverrno = errno; + close(fd); + if (ret == -1) + errno = saverrno; + + return(ret); +} +#endif /* HAVE_TRUNCATE */ + +#if !defined(HAVE_SETGROUPS) && defined(SETGROUPS_NOOP) +/* + * Cygwin setgroups should be a noop. + */ +int +setgroups(size_t size, const gid_t *list) +{ + return (0); +} +#endif + +#if !defined(HAVE_NANOSLEEP) && !defined(HAVE_NSLEEP) +int nanosleep(const struct timespec *req, struct timespec *rem) +{ + int rc, saverrno; + extern int errno; + struct timeval tstart, tstop, tremain, time2wait; + + TIMESPEC_TO_TIMEVAL(&time2wait, req) + (void) gettimeofday(&tstart, NULL); + rc = select(0, NULL, NULL, NULL, &time2wait); + if (rc == -1) { + saverrno = errno; + (void) gettimeofday (&tstop, NULL); + errno = saverrno; + tremain.tv_sec = time2wait.tv_sec - + (tstop.tv_sec - tstart.tv_sec); + tremain.tv_usec = time2wait.tv_usec - + (tstop.tv_usec - tstart.tv_usec); + tremain.tv_sec += tremain.tv_usec / 1000000L; + tremain.tv_usec %= 1000000L; + } else { + tremain.tv_sec = 0; + tremain.tv_usec = 0; + } + TIMEVAL_TO_TIMESPEC(&tremain, rem) + + return(rc); +} + +#endif + +#ifndef HAVE_TCGETPGRP +pid_t +tcgetpgrp(int fd) +{ + int ctty_pgrp; + + if (ioctl(fd, TIOCGPGRP, &ctty_pgrp) == -1) + return(-1); + else + return(ctty_pgrp); +} +#endif /* HAVE_TCGETPGRP */ + +#ifndef HAVE_TCSENDBREAK +int +tcsendbreak(int fd, int duration) +{ +# if defined(TIOCSBRK) && defined(TIOCCBRK) + struct timeval sleepytime; + + sleepytime.tv_sec = 0; + sleepytime.tv_usec = 400000; + if (ioctl(fd, TIOCSBRK, 0) == -1) + return (-1); + (void)select(0, 0, 0, 0, &sleepytime); + if (ioctl(fd, TIOCCBRK, 0) == -1) + return (-1); + return (0); +# else + return -1; +# endif +} +#endif /* HAVE_TCSENDBREAK */ + +mysig_t +mysignal(int sig, mysig_t act) +{ +#ifdef HAVE_SIGACTION + struct sigaction sa, osa; + + if (sigaction(sig, NULL, &osa) == -1) + return (mysig_t) -1; + if (osa.sa_handler != act) { + memset(&sa, 0, sizeof(sa)); + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; +#ifdef SA_INTERRUPT + if (sig == SIGALRM) + sa.sa_flags |= SA_INTERRUPT; +#endif + sa.sa_handler = act; + if (sigaction(sig, &sa, NULL) == -1) + return (mysig_t) -1; + } + return (osa.sa_handler); +#else + return (signal(sig, act)); +#endif +} diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/bsd-misc.h openssh-3.7p1/openbsd-compat/bsd-misc.h --- ssh-openbsd-2003091600/openbsd-compat/bsd-misc.h 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/bsd-misc.h 2003-08-30 02:59:52.000000000 +1000 @@ -0,0 +1,106 @@ +/* $Id: bsd-misc.h,v 1.13 2003/08/29 16:59:52 mouring Exp $ */ + +/* + * 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 _BSD_MISC_H +#define _BSD_MISC_H + +#include "includes.h" + +char *ssh_get_progname(char *); + +#ifndef HAVE_SETSID +#define setsid() setpgrp(0, getpid()) +#endif /* !HAVE_SETSID */ + +#ifndef HAVE_SETENV +int setenv(const char *, const char *, int); +#endif /* !HAVE_SETENV */ + +#ifndef HAVE_SETLOGIN +int setlogin(const char *); +#endif /* !HAVE_SETLOGIN */ + +#ifndef HAVE_INNETGR +int innetgr(const char *, const char *, const char *, const char *); +#endif /* HAVE_INNETGR */ + +#if !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) +int seteuid(uid_t); +#endif /* !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) */ + +#if !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) +int setegid(uid_t); +#endif /* !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) */ + +#if !defined(HAVE_STRERROR) && defined(HAVE_SYS_ERRLIST) && defined(HAVE_SYS_NERR) +const char *strerror(int); +#endif + + +#ifndef HAVE_UTIMES +#ifndef HAVE_STRUCT_TIMEVAL +struct timeval { + long tv_sec; + long tv_usec; +} +#endif /* HAVE_STRUCT_TIMEVAL */ + +int utimes(char *, struct timeval *); +#endif /* HAVE_UTIMES */ + +#ifndef HAVE_TRUNCATE +int truncate (const char *, off_t); +#endif /* HAVE_TRUNCATE */ + +#if !defined(HAVE_SETGROUPS) && defined(SETGROUPS_NOOP) +int setgroups(size_t, const gid_t *); +#endif + +#if !defined(HAVE_NANOSLEEP) && !defined(HAVE_NSLEEP) +#ifndef HAVE_STRUCT_TIMESPEC +struct timespec { + time_t tv_sec; + long tv_nsec; +}; +#endif +int nanosleep(const struct timespec *, struct timespec *); +#endif + +#ifndef HAVE_TCGETPGRP +pid_t tcgetpgrp(int); +#endif + +#ifndef HAVE_TCSENDBREAK +int tcsendbreak(int, int); +#endif + +/* wrapper for signal interface */ +typedef void (*mysig_t)(int); +mysig_t mysignal(int sig, mysig_t act); + +#define signal(a,b) mysignal(a,b) + +#endif /* _BSD_MISC_H */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/bsd-nextstep.c openssh-3.7p1/openbsd-compat/bsd-nextstep.c --- ssh-openbsd-2003091600/openbsd-compat/bsd-nextstep.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/bsd-nextstep.c 2003-06-01 13:23:57.000000000 +1000 @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2000,2001 Ben Lindstrom. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +RCSID("$Id: bsd-nextstep.c,v 1.6 2003/06/01 03:23:57 mouring Exp $"); + +#ifdef HAVE_NEXT +#include +#include +#include "bsd-nextstep.h" + +pid_t +posix_wait(int *status) +{ + union wait statusp; + pid_t wait_pid; + + #undef wait /* Use NeXT's wait() function */ + wait_pid = wait(&statusp); + if (status) + *status = (int) statusp.w_status; + + return (wait_pid); +} + +int +tcgetattr(int fd, struct termios *t) +{ + return (ioctl(fd, TIOCGETA, t)); +} + +int +tcsetattr(int fd, int opt, const struct termios *t) +{ + struct termios localterm; + + if (opt & TCSASOFT) { + localterm = *t; + localterm.c_cflag |= CIGNORE; + t = &localterm; + } + switch (opt & ~TCSASOFT) { + case TCSANOW: + return (ioctl(fd, TIOCSETA, t)); + case TCSADRAIN: + return (ioctl(fd, TIOCSETAW, t)); + case TCSAFLUSH: + return (ioctl(fd, TIOCSETAF, t)); + default: + errno = EINVAL; + return (-1); + } +} + +int tcsetpgrp(int fd, pid_t pgrp) +{ + return (ioctl(fd, TIOCSPGRP, &pgrp)); +} + +speed_t cfgetospeed(const struct termios *t) +{ + return (t->c_ospeed); +} + +speed_t cfgetispeed(const struct termios *t) +{ + return (t->c_ispeed); +} + +int +cfsetospeed(struct termios *t,int speed) +{ + t->c_ospeed = speed; + return (0); +} + +int +cfsetispeed(struct termios *t, int speed) +{ + t->c_ispeed = speed; + return (0); +} +#endif /* HAVE_NEXT */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/bsd-nextstep.h openssh-3.7p1/openbsd-compat/bsd-nextstep.h --- ssh-openbsd-2003091600/openbsd-compat/bsd-nextstep.h 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/bsd-nextstep.h 2003-08-30 02:59:52.000000000 +1000 @@ -0,0 +1,59 @@ +/* $Id: bsd-nextstep.h,v 1.9 2003/08/29 16:59:52 mouring Exp $ */ + +/* + * Copyright (c) 2000,2001 Ben Lindstrom. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef _NEXT_POSIX_H +#define _NEXT_POSIX_H + +#ifdef HAVE_NEXT +#include + +/* NGROUPS_MAX is behind -lposix. Use the BSD version which is NGROUPS */ +#undef NGROUPS_MAX +#define NGROUPS_MAX NGROUPS + +/* NeXT's readdir() is BSD (struct direct) not POSIX (struct dirent) */ +#define dirent direct + +/* Swap out NeXT's BSD wait() for a more POSIX complient one */ +pid_t posix_wait(int *); +#define wait(a) posix_wait(a) + +/* #ifdef wrapped functions that need defining for clean compiling */ +pid_t getppid(void); +void vhangup(void); +int innetgr(const char *, const char *, const char *, const char *); + +/* TERMCAP */ +int tcgetattr(int, struct termios *); +int tcsetattr(int, int, const struct termios *); +int tcsetpgrp(int, pid_t); +speed_t cfgetospeed(const struct termios *); +speed_t cfgetispeed(const struct termios *); +int cfsetospeed(struct termios *, int); +int cfsetispeed(struct termios *, int); +#endif /* HAVE_NEXT */ +#endif /* _NEXT_POSIX_H */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/bsd-snprintf.c openssh-3.7p1/openbsd-compat/bsd-snprintf.c --- ssh-openbsd-2003091600/openbsd-compat/bsd-snprintf.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/bsd-snprintf.c 2003-05-19 00:13:39.000000000 +1000 @@ -0,0 +1,652 @@ +/* + * Copyright Patrick Powell 1995 + * This code is based on code written by Patrick Powell (papowell@astart.com) + * It may be used for any purpose as long as this notice remains intact + * on all source code distributions + */ + +/************************************************************** + * Original: + * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 + * A bombproof version of doprnt (dopr) included. + * Sigh. This sort of thing is always nasty do deal with. Note that + * the version here does not include floating point... + * + * snprintf() is used instead of sprintf() as it does limit checks + * for string length. This covers a nasty loophole. + * + * The other functions are there to prevent NULL pointers from + * causing nast effects. + * + * More Recently: + * Brandon Long 9/15/96 for mutt 0.43 + * This was ugly. It is still ugly. I opted out of floating point + * numbers, but the formatter understands just about everything + * from the normal C string format, at least as far as I can tell from + * the Solaris 2.5 printf(3S) man page. + * + * Brandon Long 10/22/97 for mutt 0.87.1 + * Ok, added some minimal floating point support, which means this + * probably requires libm on most operating systems. Don't yet + * support the exponent (e,E) and sigfig (g,G). Also, fmtint() + * was pretty badly broken, it just wasn't being exercised in ways + * which showed it, so that's been fixed. Also, formated the code + * to mutt conventions, and removed dead code left over from the + * original. Also, there is now a builtin-test, just compile with: + * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm + * and run snprintf for results. + * + * Thomas Roessler 01/27/98 for mutt 0.89i + * The PGP code was using unsigned hexadecimal formats. + * Unfortunately, unsigned formats simply didn't work. + * + * Michael Elkins 03/05/98 for mutt 0.90.8 + * The original code assumed that both snprintf() and vsnprintf() were + * missing. Some systems only have snprintf() but not vsnprintf(), so + * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF. + * + * Ben Lindstrom 09/27/00 for OpenSSH + * Welcome to the world of %lld and %qd support. With other + * long long support. This is needed for sftp-server to work + * right. + * + * Ben Lindstrom 02/12/01 for OpenSSH + * Removed all hint of VARARGS stuff and banished it to the void, + * and did a bit of KNF style work to make things a bit more + * acceptable. Consider stealing from mutt or enlightenment. + **************************************************************/ + +#include "includes.h" + +RCSID("$Id: bsd-snprintf.c,v 1.7 2003/05/18 14:13:39 djm Exp $"); + +#if defined(BROKEN_SNPRINTF) /* For those with broken snprintf() */ +# undef HAVE_SNPRINTF +# undef HAVE_VSNPRINTF +#endif + +#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) + +static void +dopr(char *buffer, size_t maxlen, const char *format, va_list args); + +static void +fmtstr(char *buffer, size_t *currlen, size_t maxlen, char *value, int flags, + int min, int max); + +static void +fmtint(char *buffer, size_t *currlen, size_t maxlen, long value, int base, + int min, int max, int flags); + +static void +fmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue, + int min, int max, int flags); + +static void +dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c); + +/* + * dopr(): poor man's version of doprintf + */ + +/* format read states */ +#define DP_S_DEFAULT 0 +#define DP_S_FLAGS 1 +#define DP_S_MIN 2 +#define DP_S_DOT 3 +#define DP_S_MAX 4 +#define DP_S_MOD 5 +#define DP_S_CONV 6 +#define DP_S_DONE 7 + +/* format flags - Bits */ +#define DP_F_MINUS (1 << 0) +#define DP_F_PLUS (1 << 1) +#define DP_F_SPACE (1 << 2) +#define DP_F_NUM (1 << 3) +#define DP_F_ZERO (1 << 4) +#define DP_F_UP (1 << 5) +#define DP_F_UNSIGNED (1 << 6) + +/* Conversion Flags */ +#define DP_C_SHORT 1 +#define DP_C_LONG 2 +#define DP_C_LDOUBLE 3 +#define DP_C_LONG_LONG 4 + +#define char_to_int(p) (p - '0') +#define abs_val(p) (p < 0 ? -p : p) + + +static void +dopr(char *buffer, size_t maxlen, const char *format, va_list args) +{ + char *strvalue, ch; + long value; + long double fvalue; + int min = 0, max = -1, state = DP_S_DEFAULT, flags = 0, cflags = 0; + size_t currlen = 0; + + ch = *format++; + + while (state != DP_S_DONE) { + if ((ch == '\0') || (currlen >= maxlen)) + state = DP_S_DONE; + + switch(state) { + case DP_S_DEFAULT: + if (ch == '%') + state = DP_S_FLAGS; + else + dopr_outch(buffer, &currlen, maxlen, ch); + ch = *format++; + break; + case DP_S_FLAGS: + switch (ch) { + case '-': + flags |= DP_F_MINUS; + ch = *format++; + break; + case '+': + flags |= DP_F_PLUS; + ch = *format++; + break; + case ' ': + flags |= DP_F_SPACE; + ch = *format++; + break; + case '#': + flags |= DP_F_NUM; + ch = *format++; + break; + case '0': + flags |= DP_F_ZERO; + ch = *format++; + break; + default: + state = DP_S_MIN; + break; + } + break; + case DP_S_MIN: + if (isdigit((unsigned char)ch)) { + min = 10 * min + char_to_int (ch); + ch = *format++; + } else if (ch == '*') { + min = va_arg (args, int); + ch = *format++; + state = DP_S_DOT; + } else + state = DP_S_DOT; + break; + case DP_S_DOT: + if (ch == '.') { + state = DP_S_MAX; + ch = *format++; + } else + state = DP_S_MOD; + break; + case DP_S_MAX: + if (isdigit((unsigned char)ch)) { + if (max < 0) + max = 0; + max = 10 * max + char_to_int(ch); + ch = *format++; + } else if (ch == '*') { + max = va_arg (args, int); + ch = *format++; + state = DP_S_MOD; + } else + state = DP_S_MOD; + break; + case DP_S_MOD: + switch (ch) { + case 'h': + cflags = DP_C_SHORT; + ch = *format++; + break; + case 'l': + cflags = DP_C_LONG; + ch = *format++; + if (ch == 'l') { + cflags = DP_C_LONG_LONG; + ch = *format++; + } + break; + case 'q': + cflags = DP_C_LONG_LONG; + ch = *format++; + break; + case 'L': + cflags = DP_C_LDOUBLE; + ch = *format++; + break; + default: + break; + } + state = DP_S_CONV; + break; + case DP_S_CONV: + switch (ch) { + case 'd': + case 'i': + if (cflags == DP_C_SHORT) + value = va_arg(args, int); + else if (cflags == DP_C_LONG) + value = va_arg(args, long int); + else if (cflags == DP_C_LONG_LONG) + value = va_arg (args, long long); + else + value = va_arg (args, int); + fmtint(buffer, &currlen, maxlen, value, 10, min, max, flags); + break; + case 'o': + flags |= DP_F_UNSIGNED; + if (cflags == DP_C_SHORT) + value = va_arg(args, unsigned int); + else if (cflags == DP_C_LONG) + value = va_arg(args, unsigned long int); + else if (cflags == DP_C_LONG_LONG) + value = va_arg(args, unsigned long long); + else + value = va_arg(args, unsigned int); + fmtint(buffer, &currlen, maxlen, value, 8, min, max, flags); + break; + case 'u': + flags |= DP_F_UNSIGNED; + if (cflags == DP_C_SHORT) + value = va_arg(args, unsigned int); + else if (cflags == DP_C_LONG) + value = va_arg(args, unsigned long int); + else if (cflags == DP_C_LONG_LONG) + value = va_arg(args, unsigned long long); + else + value = va_arg(args, unsigned int); + fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); + break; + case 'X': + flags |= DP_F_UP; + case 'x': + flags |= DP_F_UNSIGNED; + if (cflags == DP_C_SHORT) + value = va_arg(args, unsigned int); + else if (cflags == DP_C_LONG) + value = va_arg(args, unsigned long int); + else if (cflags == DP_C_LONG_LONG) + value = va_arg(args, unsigned long long); + else + value = va_arg(args, unsigned int); + fmtint(buffer, &currlen, maxlen, value, 16, min, max, flags); + break; + case 'f': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg(args, long double); + else + fvalue = va_arg(args, double); + /* um, floating point? */ + fmtfp(buffer, &currlen, maxlen, fvalue, min, max, flags); + break; + case 'E': + flags |= DP_F_UP; + case 'e': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg(args, long double); + else + fvalue = va_arg(args, double); + break; + case 'G': + flags |= DP_F_UP; + case 'g': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg(args, long double); + else + fvalue = va_arg(args, double); + break; + case 'c': + dopr_outch(buffer, &currlen, maxlen, va_arg(args, int)); + break; + case 's': + strvalue = va_arg(args, char *); + if (max < 0) + max = maxlen; /* ie, no max */ + fmtstr(buffer, &currlen, maxlen, strvalue, flags, min, max); + break; + case 'p': + strvalue = va_arg(args, void *); + fmtint(buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags); + break; + case 'n': + if (cflags == DP_C_SHORT) { + short int *num; + num = va_arg(args, short int *); + *num = currlen; + } else if (cflags == DP_C_LONG) { + long int *num; + num = va_arg(args, long int *); + *num = currlen; + } else if (cflags == DP_C_LONG_LONG) { + long long *num; + num = va_arg(args, long long *); + *num = currlen; + } else { + int *num; + num = va_arg(args, int *); + *num = currlen; + } + break; + case '%': + dopr_outch(buffer, &currlen, maxlen, ch); + break; + case 'w': /* not supported yet, treat as next char */ + ch = *format++; + break; + default: /* Unknown, skip */ + break; + } + ch = *format++; + state = DP_S_DEFAULT; + flags = cflags = min = 0; + max = -1; + break; + case DP_S_DONE: + break; + default: /* hmm? */ + break; /* some picky compilers need this */ + } + } + if (currlen < maxlen - 1) + buffer[currlen] = '\0'; + else + buffer[maxlen - 1] = '\0'; +} + +static void +fmtstr(char *buffer, size_t *currlen, size_t maxlen, + char *value, int flags, int min, int max) +{ + int cnt = 0, padlen, strln; /* amount to pad */ + + if (value == 0) + value = ""; + + for (strln = 0; value[strln]; ++strln); /* strlen */ + padlen = min - strln; + if (padlen < 0) + padlen = 0; + if (flags & DP_F_MINUS) + padlen = -padlen; /* Left Justify */ + + while ((padlen > 0) && (cnt < max)) { + dopr_outch(buffer, currlen, maxlen, ' '); + --padlen; + ++cnt; + } + while (*value && (cnt < max)) { + dopr_outch(buffer, currlen, maxlen, *value++); + ++cnt; + } + while ((padlen < 0) && (cnt < max)) { + dopr_outch(buffer, currlen, maxlen, ' '); + ++padlen; + ++cnt; + } +} + +/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */ + +static void +fmtint(char *buffer, size_t *currlen, size_t maxlen, + long value, int base, int min, int max, int flags) +{ + unsigned long uvalue; + char convert[20]; + int signvalue = 0, place = 0, caps = 0; + int spadlen = 0; /* amount to space pad */ + int zpadlen = 0; /* amount to zero pad */ + + if (max < 0) + max = 0; + + uvalue = value; + + if (!(flags & DP_F_UNSIGNED)) { + if (value < 0) { + signvalue = '-'; + uvalue = -value; + } else if (flags & DP_F_PLUS) /* Do a sign (+/i) */ + signvalue = '+'; + else if (flags & DP_F_SPACE) + signvalue = ' '; + } + + if (flags & DP_F_UP) + caps = 1; /* Should characters be upper case? */ + do { + convert[place++] = + (caps ? "0123456789ABCDEF" : "0123456789abcdef") + [uvalue % (unsigned)base]; + uvalue = (uvalue / (unsigned)base ); + } while (uvalue && (place < 20)); + if (place == 20) + place--; + convert[place] = 0; + + zpadlen = max - place; + spadlen = min - MAX (max, place) - (signvalue ? 1 : 0); + if (zpadlen < 0) + zpadlen = 0; + if (spadlen < 0) + spadlen = 0; + if (flags & DP_F_ZERO) { + zpadlen = MAX(zpadlen, spadlen); + spadlen = 0; + } + if (flags & DP_F_MINUS) + spadlen = -spadlen; /* Left Justifty */ + + /* Spaces */ + while (spadlen > 0) { + dopr_outch(buffer, currlen, maxlen, ' '); + --spadlen; + } + + /* Sign */ + if (signvalue) + dopr_outch(buffer, currlen, maxlen, signvalue); + + /* Zeros */ + if (zpadlen > 0) { + while (zpadlen > 0) { + dopr_outch(buffer, currlen, maxlen, '0'); + --zpadlen; + } + } + + /* Digits */ + while (place > 0) + dopr_outch(buffer, currlen, maxlen, convert[--place]); + + /* Left Justified spaces */ + while (spadlen < 0) { + dopr_outch (buffer, currlen, maxlen, ' '); + ++spadlen; + } +} + +static long double +pow10(int exp) +{ + long double result = 1; + + while (exp) { + result *= 10; + exp--; + } + + return result; +} + +static long +round(long double value) +{ + long intpart = value; + + value -= intpart; + if (value >= 0.5) + intpart++; + + return intpart; +} + +static void +fmtfp(char *buffer, size_t *currlen, size_t maxlen, long double fvalue, + int min, int max, int flags) +{ + char iconvert[20], fconvert[20]; + int signvalue = 0, iplace = 0, fplace = 0; + int padlen = 0; /* amount to pad */ + int zpadlen = 0, caps = 0; + long intpart, fracpart; + long double ufvalue; + + /* + * AIX manpage says the default is 0, but Solaris says the default + * is 6, and sprintf on AIX defaults to 6 + */ + if (max < 0) + max = 6; + + ufvalue = abs_val(fvalue); + + if (fvalue < 0) + signvalue = '-'; + else if (flags & DP_F_PLUS) /* Do a sign (+/i) */ + signvalue = '+'; + else if (flags & DP_F_SPACE) + signvalue = ' '; + + intpart = ufvalue; + + /* + * Sorry, we only support 9 digits past the decimal because of our + * conversion method + */ + if (max > 9) + max = 9; + + /* We "cheat" by converting the fractional part to integer by + * multiplying by a factor of 10 + */ + fracpart = round((pow10 (max)) * (ufvalue - intpart)); + + if (fracpart >= pow10 (max)) { + intpart++; + fracpart -= pow10 (max); + } + + /* Convert integer part */ + do { + iconvert[iplace++] = + (caps ? "0123456789ABCDEF" : "0123456789abcdef") + [intpart % 10]; + intpart = (intpart / 10); + } while(intpart && (iplace < 20)); + if (iplace == 20) + iplace--; + iconvert[iplace] = 0; + + /* Convert fractional part */ + do { + fconvert[fplace++] = + (caps ? "0123456789ABCDEF" : "0123456789abcdef") + [fracpart % 10]; + fracpart = (fracpart / 10); + } while(fracpart && (fplace < 20)); + if (fplace == 20) + fplace--; + fconvert[fplace] = 0; + + /* -1 for decimal point, another -1 if we are printing a sign */ + padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); + zpadlen = max - fplace; + if (zpadlen < 0) + zpadlen = 0; + if (padlen < 0) + padlen = 0; + if (flags & DP_F_MINUS) + padlen = -padlen; /* Left Justifty */ + + if ((flags & DP_F_ZERO) && (padlen > 0)) { + if (signvalue) { + dopr_outch(buffer, currlen, maxlen, signvalue); + --padlen; + signvalue = 0; + } + while (padlen > 0) { + dopr_outch(buffer, currlen, maxlen, '0'); + --padlen; + } + } + while (padlen > 0) { + dopr_outch(buffer, currlen, maxlen, ' '); + --padlen; + } + if (signvalue) + dopr_outch(buffer, currlen, maxlen, signvalue); + + while (iplace > 0) + dopr_outch(buffer, currlen, maxlen, iconvert[--iplace]); + + /* + * Decimal point. This should probably use locale to find the + * correct char to print out. + */ + dopr_outch(buffer, currlen, maxlen, '.'); + + while (fplace > 0) + dopr_outch(buffer, currlen, maxlen, fconvert[--fplace]); + + while (zpadlen > 0) { + dopr_outch(buffer, currlen, maxlen, '0'); + --zpadlen; + } + + while (padlen < 0) { + dopr_outch(buffer, currlen, maxlen, ' '); + ++padlen; + } +} + +static void +dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c) +{ + if (*currlen < maxlen) + buffer[(*currlen)++] = c; +} +#endif /* !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) */ + +#ifndef HAVE_VSNPRINTF +int +vsnprintf(char *str, size_t count, const char *fmt, va_list args) +{ + str[0] = 0; + dopr(str, count, fmt, args); + + return(strlen(str)); +} +#endif /* !HAVE_VSNPRINTF */ + +#ifndef HAVE_SNPRINTF +int +snprintf(char *str,size_t count,const char *fmt,...) +{ + va_list ap; + + va_start(ap, fmt); + (void) vsnprintf(str, count, fmt, ap); + va_end(ap); + + return(strlen(str)); +} + +#endif /* !HAVE_SNPRINTF */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/bsd-waitpid.c openssh-3.7p1/openbsd-compat/bsd-waitpid.c --- ssh-openbsd-2003091600/openbsd-compat/bsd-waitpid.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/bsd-waitpid.c 2003-06-01 13:23:57.000000000 +1000 @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2000 Ben Lindstrom. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +RCSID("$Id: bsd-waitpid.c,v 1.5 2003/06/01 03:23:57 mouring Exp $"); + +#ifndef HAVE_WAITPID +#include +#include +#include "bsd-waitpid.h" + +pid_t +waitpid(int pid, int *stat_loc, int options) +{ + union wait statusp; + pid_t wait_pid; + + if (pid <= 0) { + if (pid != -1) { + errno = EINVAL; + return (-1); + } + /* wait4() wants pid=0 for indiscriminate wait. */ + pid = 0; + } + wait_pid = wait4(pid, &statusp, options, NULL); + if (stat_loc) + *stat_loc = (int) statusp.w_status; + + return (wait_pid); +} + +#endif /* !HAVE_WAITPID */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/bsd-waitpid.h openssh-3.7p1/openbsd-compat/bsd-waitpid.h --- ssh-openbsd-2003091600/openbsd-compat/bsd-waitpid.h 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/bsd-waitpid.h 2003-08-30 02:59:52.000000000 +1000 @@ -0,0 +1,51 @@ +/* $Id: bsd-waitpid.h,v 1.5 2003/08/29 16:59:52 mouring Exp $ */ + +/* + * Copyright (c) 2000 Ben Lindstrom. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef _BSD_WAITPID_H +#define _BSD_WAITPID_H + +#ifndef HAVE_WAITPID +/* Clean out any potental issues */ +#undef WIFEXITED +#undef WIFSTOPPED +#undef WIFSIGNALED + +/* Define required functions to mimic a POSIX look and feel */ +#define _W_INT(w) (*(int*)&(w)) /* convert union wait to int */ +#define WIFEXITED(w) (!((_W_INT(w)) & 0377)) +#define WIFSTOPPED(w) ((_W_INT(w)) & 0100) +#define WIFSIGNALED(w) (!WIFEXITED(w) && !WIFSTOPPED(w)) +#define WEXITSTATUS(w) (int)(WIFEXITED(w) ? ((_W_INT(w) >> 8) & 0377) : -1) +#define WTERMSIG(w) (int)(WIFSIGNALED(w) ? (_W_INT(w) & 0177) : -1) +#define WCOREFLAG 0x80 +#define WCOREDUMP(w) ((_W_INT(w)) & WCOREFLAG) + +/* Prototype */ +pid_t waitpid(int, int *, int); + +#endif /* !HAVE_WAITPID */ +#endif /* _BSD_WAITPID_H */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/.cvsignore openssh-3.7p1/openbsd-compat/.cvsignore --- ssh-openbsd-2003091600/openbsd-compat/.cvsignore 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/.cvsignore 2001-04-30 13:55:39.000000000 +1000 @@ -0,0 +1 @@ +Makefile diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/daemon.c openssh-3.7p1/openbsd-compat/daemon.c --- ssh-openbsd-2003091600/openbsd-compat/daemon.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/daemon.c 2003-08-25 11:10:51.000000000 +1000 @@ -0,0 +1,79 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "includes.h" + +#ifndef HAVE_DAEMON + +#if defined(LIBC_SCCS) && !defined(lint) +static char rcsid[] = "$OpenBSD: daemon.c,v 1.5 2003/07/15 17:32:41 deraadt Exp $"; +#endif /* LIBC_SCCS and not lint */ + +int +daemon(int nochdir, int noclose) +{ + int fd; + + switch (fork()) { + case -1: + return (-1); + case 0: +#ifdef HAVE_CYGWIN + register_9x_service(); +#endif + break; + default: +#ifdef HAVE_CYGWIN + /* + * This sleep avoids a race condition which kills the + * child process if parent is started by a NT/W2K service. + */ + sleep(1); +#endif + _exit(0); + } + + if (setsid() == -1) + return (-1); + + if (!nochdir) + (void)chdir("/"); + + if (!noclose && (fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { + (void)dup2(fd, STDIN_FILENO); + (void)dup2(fd, STDOUT_FILENO); + (void)dup2(fd, STDERR_FILENO); + if (fd > 2) + (void)close (fd); + } + return (0); +} + +#endif /* !HAVE_DAEMON */ + diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/dirname.c openssh-3.7p1/openbsd-compat/dirname.c --- ssh-openbsd-2003091600/openbsd-compat/dirname.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/dirname.c 2003-08-25 11:10:51.000000000 +1000 @@ -0,0 +1,68 @@ +/* $OpenBSD: dirname.c,v 1.10 2003/06/17 21:56:23 millert Exp $ */ + +/* + * Copyright (c) 1997 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" +#ifndef HAVE_DIRNAME + +#ifndef lint +static char rcsid[] = "$OpenBSD: dirname.c,v 1.10 2003/06/17 21:56:23 millert Exp $"; +#endif /* not lint */ + +#include +#include +#include + +char * +dirname(const char *path) +{ + static char bname[MAXPATHLEN]; + register const char *endp; + + /* Empty or NULL string gets treated as "." */ + if (path == NULL || *path == '\0') { + (void)strlcpy(bname, ".", sizeof bname); + return(bname); + } + + /* Strip trailing slashes */ + endp = path + strlen(path) - 1; + while (endp > path && *endp == '/') + endp--; + + /* Find the start of the dir */ + while (endp > path && *endp != '/') + endp--; + + /* Either the dir is "/" or there are no slashes */ + if (endp == path) { + (void)strlcpy(bname, *endp == '/' ? "/" : ".", sizeof bname); + return(bname); + } else { + do { + endp--; + } while (endp > path && *endp == '/'); + } + + if (endp - path + 2 > sizeof(bname)) { + errno = ENAMETOOLONG; + return(NULL); + } + strlcpy(bname, path, endp - path + 2); + return(bname); +} +#endif diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/fake-rfc2553.c openssh-3.7p1/openbsd-compat/fake-rfc2553.c --- ssh-openbsd-2003091600/openbsd-compat/fake-rfc2553.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/fake-rfc2553.c 2003-06-14 08:43:23.000000000 +1000 @@ -0,0 +1,220 @@ +/* + * Copyright (C) 2000-2003 Damien Miller. All rights reserved. + * Copyright (C) 1999 WIDE Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Pseudo-implementation of RFC2553 name / address resolution functions + * + * But these functions are not implemented correctly. The minimum subset + * is implemented for ssh use only. For example, this routine assumes + * that ai_family is AF_INET. Don't use it for another purpose. + */ + +#include "includes.h" + +RCSID("$Id: fake-rfc2553.c,v 1.4 2003/06/13 22:43:23 djm Exp $"); + +#ifndef HAVE_GETNAMEINFO +int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, + size_t hostlen, char *serv, size_t servlen, int flags) +{ + struct sockaddr_in *sin = (struct sockaddr_in *)sa; + struct hostent *hp; + char tmpserv[16]; + + if (serv != NULL) { + snprintf(tmpserv, sizeof(tmpserv), "%d", ntohs(sin->sin_port)); + if (strlcpy(serv, tmpserv, servlen) >= servlen) + return (EAI_MEMORY); + } + + if (host != NULL) { + if (flags & NI_NUMERICHOST) { + if (strlcpy(host, inet_ntoa(sin->sin_addr), + hostlen) >= hostlen) + return (EAI_MEMORY); + else + return (0); + } else { + hp = gethostbyaddr((char *)&sin->sin_addr, + sizeof(struct in_addr), AF_INET); + if (hp == NULL) + return (EAI_NODATA); + + if (strlcpy(host, hp->h_name, hostlen) >= hostlen) + return (EAI_MEMORY); + else + return (0); + } + } + return (0); +} +#endif /* !HAVE_GETNAMEINFO */ + +#ifndef HAVE_GAI_STRERROR +char * +gai_strerror(int err) +{ + switch (err) { + case EAI_NODATA: + return ("no address associated with name"); + case EAI_MEMORY: + return ("memory allocation failure."); + case EAI_NONAME: + return ("nodename nor servname provided, or not known"); + default: + return ("unknown/invalid error."); + } +} +#endif /* !HAVE_GAI_STRERROR */ + +#ifndef HAVE_FREEADDRINFO +void +freeaddrinfo(struct addrinfo *ai) +{ + struct addrinfo *next; + + for(; ai != NULL;) { + next = ai->ai_next; + free(ai); + ai = next; + } +} +#endif /* !HAVE_FREEADDRINFO */ + +#ifndef HAVE_GETADDRINFO +static struct +addrinfo *malloc_ai(int port, u_long addr, const struct addrinfo *hints) +{ + struct addrinfo *ai; + + ai = malloc(sizeof(*ai) + sizeof(struct sockaddr_in)); + if (ai == NULL) + return (NULL); + + memset(ai, '\0', sizeof(*ai) + sizeof(struct sockaddr_in)); + + ai->ai_addr = (struct sockaddr *)(ai + 1); + /* XXX -- ssh doesn't use sa_len */ + ai->ai_addrlen = sizeof(struct sockaddr_in); + ai->ai_addr->sa_family = ai->ai_family = AF_INET; + + ((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port; + ((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr; + + /* XXX: the following is not generally correct, but does what we want */ + if (hints->ai_socktype) + ai->ai_socktype = hints->ai_socktype; + else + ai->ai_socktype = SOCK_STREAM; + + if (hints->ai_protocol) + ai->ai_protocol = hints->ai_protocol; + + return (ai); +} + +int +getaddrinfo(const char *hostname, const char *servname, + const struct addrinfo *hints, struct addrinfo **res) +{ + struct hostent *hp; + struct servent *sp; + struct in_addr in; + int i; + long int port; + u_long addr; + + port = 0; + if (servname != NULL) { + char *cp; + + port = strtol(servname, &cp, 10); + if (port > 0 && port <= 65535 && *cp == '\0') + port = htons(port); + else if ((sp = getservbyname(servname, NULL)) != NULL) + port = sp->s_port; + else + port = 0; + } + + if (hints && hints->ai_flags & AI_PASSIVE) { + addr = htonl(0x00000000); + if (hostname && inet_aton(hostname, &in) != 0) + addr = in.s_addr; + *res = malloc_ai(port, addr, hints); + if (*res == NULL) + return (EAI_MEMORY); + return (0); + } + + if (!hostname) { + *res = malloc_ai(port, htonl(0x7f000001), hints); + if (*res == NULL) + return (EAI_MEMORY); + return (0); + } + + if (inet_aton(hostname, &in)) { + *res = malloc_ai(port, in.s_addr, hints); + if (*res == NULL) + return (EAI_MEMORY); + return (0); + } + + /* Don't try DNS if AI_NUMERICHOST is set */ + if (hints && hints->ai_flags & AI_NUMERICHOST) + return (EAI_NONAME); + + hp = gethostbyname(hostname); + if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) { + struct addrinfo *cur, *prev; + + cur = prev = *res = NULL; + for (i = 0; hp->h_addr_list[i]; i++) { + struct in_addr *in = (struct in_addr *)hp->h_addr_list[i]; + + cur = malloc_ai(port, in->s_addr, hints); + if (cur == NULL) { + if (*res != NULL) + freeaddrinfo(*res); + return (EAI_MEMORY); + } + if (prev) + prev->ai_next = cur; + else + *res = cur; + + prev = cur; + } + return (0); + } + + return (EAI_NODATA); +} +#endif /* !HAVE_GETADDRINFO */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/fake-rfc2553.h openssh-3.7p1/openbsd-compat/fake-rfc2553.h --- ssh-openbsd-2003091600/openbsd-compat/fake-rfc2553.h 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/fake-rfc2553.h 2003-08-30 02:59:52.000000000 +1000 @@ -0,0 +1,154 @@ +/* $Id: fake-rfc2553.h,v 1.6 2003/08/29 16:59:52 mouring Exp $ */ + +/* + * Copyright (C) 2000-2003 Damien Miller. All rights reserved. + * Copyright (C) 1999 WIDE Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Pseudo-implementation of RFC2553 name / address resolution functions + * + * But these functions are not implemented correctly. The minimum subset + * is implemented for ssh use only. For example, this routine assumes + * that ai_family is AF_INET. Don't use it for another purpose. + */ + +#ifndef _FAKE_RFC2553_H +#define _FAKE_RFC2553_H + +#include "includes.h" +#include "sys/types.h" + +/* + * First, socket and INET6 related definitions + */ +#ifndef HAVE_STRUCT_SOCKADDR_STORAGE +# define _SS_MAXSIZE 128 /* Implementation specific max size */ +# define _SS_PADSIZE (_SS_MAXSIZE - sizeof (struct sockaddr)) +struct sockaddr_storage { + struct sockaddr ss_sa; + char __ss_pad2[_SS_PADSIZE]; +}; +# define ss_family ss_sa.sa_family +#endif /* !HAVE_STRUCT_SOCKADDR_STORAGE */ + +#ifndef IN6_IS_ADDR_LOOPBACK +# define IN6_IS_ADDR_LOOPBACK(a) \ + (((u_int32_t *)(a))[0] == 0 && ((u_int32_t *)(a))[1] == 0 && \ + ((u_int32_t *)(a))[2] == 0 && ((u_int32_t *)(a))[3] == htonl(1)) +#endif /* !IN6_IS_ADDR_LOOPBACK */ + +#ifndef HAVE_STRUCT_IN6_ADDR +struct in6_addr { + u_int8_t s6_addr[16]; +}; +#endif /* !HAVE_STRUCT_IN6_ADDR */ + +#ifndef HAVE_STRUCT_SOCKADDR_IN6 +struct sockaddr_in6 { + unsigned short sin6_family; + u_int16_t sin6_port; + u_int32_t sin6_flowinfo; + struct in6_addr sin6_addr; +}; +#endif /* !HAVE_STRUCT_SOCKADDR_IN6 */ + +#ifndef AF_INET6 +/* Define it to something that should never appear */ +#define AF_INET6 AF_MAX +#endif + +/* + * Next, RFC2553 name / address resolution API + */ + +#ifndef NI_NUMERICHOST +# define NI_NUMERICHOST (1) +#endif +#ifndef NI_NAMEREQD +# define NI_NAMEREQD (1<<1) +#endif +#ifndef NI_NUMERICSERV +# define NI_NUMERICSERV (1<<2) +#endif + +#ifndef AI_PASSIVE +# define AI_PASSIVE (1) +#endif +#ifndef AI_CANONNAME +# define AI_CANONNAME (1<<1) +#endif +#ifndef AI_NUMERICHOST +# define AI_NUMERICHOST (1<<2) +#endif + +#ifndef NI_MAXSERV +# define NI_MAXSERV 32 +#endif /* !NI_MAXSERV */ +#ifndef NI_MAXHOST +# define NI_MAXHOST 1025 +#endif /* !NI_MAXHOST */ + +#ifndef EAI_NODATA +# define EAI_NODATA 1 +# define EAI_MEMORY 2 +# define EAI_NONAME 3 +#endif + +#ifndef HAVE_STRUCT_ADDRINFO +struct addrinfo { + int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ + int ai_family; /* PF_xxx */ + int ai_socktype; /* SOCK_xxx */ + int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ + size_t ai_addrlen; /* length of ai_addr */ + char *ai_canonname; /* canonical name for hostname */ + struct sockaddr *ai_addr; /* binary address */ + struct addrinfo *ai_next; /* next structure in linked list */ +}; +#endif /* !HAVE_STRUCT_ADDRINFO */ + +#ifndef HAVE_GETADDRINFO +int getaddrinfo(const char *, const char *, + const struct addrinfo *, struct addrinfo **); +#endif /* !HAVE_GETADDRINFO */ + +#ifndef HAVE_GAI_STRERROR +char *gai_strerror(int); +#endif /* !HAVE_GAI_STRERROR */ + +#ifndef HAVE_FREEADDRINFO +void freeaddrinfo(struct addrinfo *); +#endif /* !HAVE_FREEADDRINFO */ + +#ifndef HAVE_GETNAMEINFO +int getnameinfo(const struct sockaddr *, size_t, char *, size_t, + char *, size_t, int); +#endif /* !HAVE_GETNAMEINFO */ + +#endif /* !_FAKE_RFC2553_H */ + diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/getcwd.c openssh-3.7p1/openbsd-compat/getcwd.c --- ssh-openbsd-2003091600/openbsd-compat/getcwd.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/getcwd.c 2003-08-25 11:10:51.000000000 +1000 @@ -0,0 +1,240 @@ +/* + * Copyright (c) 1989, 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "includes.h" + +#if !defined(HAVE_GETCWD) + +#if defined(LIBC_SCCS) && !defined(lint) +static char rcsid[] = "$OpenBSD: getcwd.c,v 1.9 2003/06/11 21:03:10 deraadt Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "includes.h" + +#define ISDOT(dp) \ + (dp->d_name[0] == '.' && (dp->d_name[1] == '\0' || \ + (dp->d_name[1] == '.' && dp->d_name[2] == '\0'))) + +char * +getcwd(char *pt, size_t size) +{ + register struct dirent *dp; + register DIR *dir = NULL; + register dev_t dev; + register ino_t ino; + register int first; + register char *bpt, *bup; + struct stat s; + dev_t root_dev; + ino_t root_ino; + size_t ptsize, upsize; + int save_errno; + char *ept, *eup, *up; + + /* + * If no buffer specified by the user, allocate one as necessary. + * If a buffer is specified, the size has to be non-zero. The path + * is built from the end of the buffer backwards. + */ + if (pt) { + ptsize = 0; + if (!size) { + errno = EINVAL; + return (NULL); + } + ept = pt + size; + } else { + if ((pt = malloc(ptsize = 1024 - 4)) == NULL) + return (NULL); + ept = pt + ptsize; + } + bpt = ept - 1; + *bpt = '\0'; + + /* + * Allocate bytes (1024 - malloc space) for the string of "../"'s. + * Should always be enough (it's 340 levels). If it's not, allocate + * as necessary. Special * case the first stat, it's ".", not "..". + */ + if ((up = malloc(upsize = 1024 - 4)) == NULL) + goto err; + eup = up + MAXPATHLEN; + bup = up; + up[0] = '.'; + up[1] = '\0'; + + /* Save root values, so know when to stop. */ + if (stat("/", &s)) + goto err; + root_dev = s.st_dev; + root_ino = s.st_ino; + + errno = 0; /* XXX readdir has no error return. */ + + for (first = 1;; first = 0) { + /* Stat the current level. */ + if (lstat(up, &s)) + goto err; + + /* Save current node values. */ + ino = s.st_ino; + dev = s.st_dev; + + /* Check for reaching root. */ + if (root_dev == dev && root_ino == ino) { + *--bpt = '/'; + /* + * It's unclear that it's a requirement to copy the + * path to the beginning of the buffer, but it's always + * been that way and stuff would probably break. + */ + memmove(pt, bpt, ept - bpt); + free(up); + return (pt); + } + + /* + * Build pointer to the parent directory, allocating memory + * as necessary. Max length is 3 for "../", the largest + * possible component name, plus a trailing NUL. + */ + if (bup + 3 + MAXNAMLEN + 1 >= eup) { + char *nup; + + if ((nup = realloc(up, upsize *= 2)) == NULL) + goto err; + up = nup; + bup = up; + eup = up + upsize; + } + *bup++ = '.'; + *bup++ = '.'; + *bup = '\0'; + + /* Open and stat parent directory. + * RACE?? - replaced fstat(dirfd(dir), &s) w/ lstat(up,&s) + */ + if (!(dir = opendir(up)) || lstat(up,&s)) + goto err; + + /* Add trailing slash for next directory. */ + *bup++ = '/'; + + /* + * If it's a mount point, have to stat each element because + * the inode number in the directory is for the entry in the + * parent directory, not the inode number of the mounted file. + */ + save_errno = 0; + if (s.st_dev == dev) { + for (;;) { + if (!(dp = readdir(dir))) + goto notfound; + if (dp->d_fileno == ino) + break; + } + } else + for (;;) { + if (!(dp = readdir(dir))) + goto notfound; + if (ISDOT(dp)) + continue; + memmove(bup, dp->d_name, dp->d_namlen + 1); + + /* Save the first error for later. */ + if (lstat(up, &s)) { + if (!save_errno) + save_errno = errno; + errno = 0; + continue; + } + if (s.st_dev == dev && s.st_ino == ino) + break; + } + + /* + * Check for length of the current name, preceding slash, + * leading slash. + */ + if (bpt - pt < dp->d_namlen + (first ? 1 : 2)) { + size_t len, off; + char *npt; + + if (!ptsize) { + errno = ERANGE; + goto err; + } + off = bpt - pt; + len = ept - bpt; + if ((npt = realloc(pt, ptsize *= 2)) == NULL) + goto err; + pt = npt; + bpt = pt + off; + ept = pt + ptsize; + memmove(ept - len, bpt, len); + bpt = ept - len; + } + if (!first) + *--bpt = '/'; + bpt -= dp->d_namlen; + memmove(bpt, dp->d_name, dp->d_namlen); + (void)closedir(dir); + + /* Truncate any file name. */ + *bup = '\0'; + } + +notfound: + /* + * If readdir set errno, use it, not any saved error; otherwise, + * didn't find the current directory in its parent directory, set + * errno to ENOENT. + */ + if (!errno) + errno = save_errno ? save_errno : ENOENT; + /* FALLTHROUGH */ +err: + if (ptsize) + free(pt); + if (up) + free(up); + if (dir) + (void)closedir(dir); + return (NULL); +} + +#endif /* !defined(HAVE_GETCWD) */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/getgrouplist.c openssh-3.7p1/openbsd-compat/getgrouplist.c --- ssh-openbsd-2003091600/openbsd-compat/getgrouplist.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/getgrouplist.c 2003-08-25 11:10:52.000000000 +1000 @@ -0,0 +1,100 @@ +/* + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "includes.h" + +#ifndef HAVE_GETGROUPLIST + +#if defined(LIBC_SCCS) && !defined(lint) +static char rcsid[] = "$OpenBSD: getgrouplist.c,v 1.9 2003/06/25 21:16:47 deraadt Exp $"; +#endif /* LIBC_SCCS and not lint */ + +/* + * get credential + */ +#include +#include +#include +#include + +int +getgrouplist(uname, agroup, groups, grpcnt) + const char *uname; + gid_t agroup; + register gid_t *groups; + int *grpcnt; +{ + register struct group *grp; + register int i, ngroups; + int ret, maxgroups; + int bail; + + ret = 0; + ngroups = 0; + maxgroups = *grpcnt; + + /* + * install primary group + */ + if (ngroups >= maxgroups) { + *grpcnt = ngroups; + return (-1); + } + groups[ngroups++] = agroup; + + /* + * Scan the group file to find additional groups. + */ + setgrent(); + while ((grp = getgrent())) { + if (grp->gr_gid == agroup) + continue; + for (bail = 0, i = 0; bail == 0 && i < ngroups; i++) + if (groups[i] == grp->gr_gid) + bail = 1; + if (bail) + continue; + for (i = 0; grp->gr_mem[i]; i++) { + if (!strcmp(grp->gr_mem[i], uname)) { + if (ngroups >= maxgroups) { + ret = -1; + goto out; + } + groups[ngroups++] = grp->gr_gid; + break; + } + } + } +out: + endgrent(); + *grpcnt = ngroups; + return (ret); +} + +#endif /* HAVE_GETGROUPLIST */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/getopt.c openssh-3.7p1/openbsd-compat/getopt.c --- ssh-openbsd-2003091600/openbsd-compat/getopt.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/getopt.c 2003-06-03 12:12:51.000000000 +1000 @@ -0,0 +1,121 @@ +/* + * Copyright (c) 1987, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "includes.h" +#if !defined(HAVE_GETOPT) || !defined(HAVE_GETOPT_OPTRESET) + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: getopt.c,v 1.5 2003/06/02 20:18:37 millert Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include + +int BSDopterr = 1, /* if error message should be printed */ + BSDoptind = 1, /* index into parent argv vector */ + BSDoptopt, /* character checked for validity */ + BSDoptreset; /* reset getopt */ +char *BSDoptarg; /* argument associated with option */ + +#define BADCH (int)'?' +#define BADARG (int)':' +#define EMSG "" + +/* + * getopt -- + * Parse argc/argv argument vector. + */ +int +BSDgetopt(nargc, nargv, ostr) + int nargc; + char * const *nargv; + const char *ostr; +{ + extern char *__progname; + static char *place = EMSG; /* option letter processing */ + char *oli; /* option letter list index */ + + if (ostr == NULL) + return (-1); + + if (BSDoptreset || !*place) { /* update scanning pointer */ + BSDoptreset = 0; + if (BSDoptind >= nargc || *(place = nargv[BSDoptind]) != '-') { + place = EMSG; + return (-1); + } + if (place[1] && *++place == '-') { /* found "--" */ + ++BSDoptind; + place = EMSG; + return (-1); + } + } /* option letter okay? */ + if ((BSDoptopt = (int)*place++) == (int)':' || + !(oli = strchr(ostr, BSDoptopt))) { + /* + * if the user didn't specify '-' as an option, + * assume it means -1. + */ + if (BSDoptopt == (int)'-') + return (-1); + if (!*place) + ++BSDoptind; + if (BSDopterr && *ostr != ':') + (void)fprintf(stderr, + "%s: illegal option -- %c\n", __progname, BSDoptopt); + return (BADCH); + } + if (*++oli != ':') { /* don't need argument */ + BSDoptarg = NULL; + if (!*place) + ++BSDoptind; + } + else { /* need an argument */ + if (*place) /* no white space */ + BSDoptarg = place; + else if (nargc <= ++BSDoptind) { /* no arg */ + place = EMSG; + if (*ostr == ':') + return (BADARG); + if (BSDopterr) + (void)fprintf(stderr, + "%s: option requires an argument -- %c\n", + __progname, BSDoptopt); + return (BADCH); + } + else /* white space */ + BSDoptarg = nargv[BSDoptind]; + place = EMSG; + ++BSDoptind; + } + return (BSDoptopt); /* dump back option letter */ +} + +#endif /* !defined(HAVE_GETOPT) || !defined(HAVE_OPTRESET) */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/getrrsetbyname.c openssh-3.7p1/openbsd-compat/getrrsetbyname.c --- ssh-openbsd-2003091600/openbsd-compat/getrrsetbyname.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/getrrsetbyname.c 2003-09-09 07:35:17.000000000 +1000 @@ -0,0 +1,578 @@ +/* $OpenBSD: getrrsetbyname.c,v 1.7 2003/03/07 07:34:14 itojun Exp $ */ + +/* + * Copyright (c) 2001 Jakob Schlyter. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Portions Copyright (c) 1999-2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#if defined(DNS) && !defined(HAVE_GETRRSETBYNAME) + +#include "getrrsetbyname.h" + +/* #include "thread_private.h" */ + +#define ANSWER_BUFFER_SIZE 1024*64 + +struct dns_query { + char *name; + u_int16_t type; + u_int16_t class; + struct dns_query *next; +}; + +struct dns_rr { + char *name; + u_int16_t type; + u_int16_t class; + u_int16_t ttl; + u_int16_t size; + void *rdata; + struct dns_rr *next; +}; + +struct dns_response { + HEADER header; + struct dns_query *query; + struct dns_rr *answer; + struct dns_rr *authority; + struct dns_rr *additional; +}; + +static struct dns_response *parse_dns_response(const u_char *, int); +static struct dns_query *parse_dns_qsection(const u_char *, int, + const u_char **, int); +static struct dns_rr *parse_dns_rrsection(const u_char *, int, const u_char **, + int); + +static void free_dns_query(struct dns_query *); +static void free_dns_rr(struct dns_rr *); +static void free_dns_response(struct dns_response *); + +static int count_dns_rr(struct dns_rr *, u_int16_t, u_int16_t); + +/* + * Inline versions of get/put short/long. Pointer is advanced. + * + * These macros demonstrate the property of C whereby it can be + * portable or it can be elegant but rarely both. + */ + +#ifndef INT32SZ +# define INT32SZ 4 +#endif +#ifndef INT16SZ +# define INT16SZ 2 +#endif + +#ifndef GETSHORT +#define GETSHORT(s, cp) { \ + register u_char *t_cp = (u_char *)(cp); \ + (s) = ((u_int16_t)t_cp[0] << 8) \ + | ((u_int16_t)t_cp[1]) \ + ; \ + (cp) += INT16SZ; \ +} +#endif + +#ifndef GETLONG +#define GETLONG(l, cp) { \ + register u_char *t_cp = (u_char *)(cp); \ + (l) = ((u_int32_t)t_cp[0] << 24) \ + | ((u_int32_t)t_cp[1] << 16) \ + | ((u_int32_t)t_cp[2] << 8) \ + | ((u_int32_t)t_cp[3]) \ + ; \ + (cp) += INT32SZ; \ +} +#endif + +/* + * Routines to insert/extract short/long's. + */ + +#ifndef HAVE__GETSHORT +static u_int16_t +_getshort(msgp) + register const u_char *msgp; +{ + register u_int16_t u; + + GETSHORT(u, msgp); + return (u); +} +#endif + +#ifndef HAVE__GETLONG +static u_int32_t +_getlong(msgp) + register const u_char *msgp; +{ + register u_int32_t u; + + GETLONG(u, msgp); + return (u); +} +#endif + +int +getrrsetbyname(const char *hostname, unsigned int rdclass, + unsigned int rdtype, unsigned int flags, + struct rrsetinfo **res) +{ + struct __res_state *_resp = &_res; + int result; + struct rrsetinfo *rrset = NULL; + struct dns_response *response; + struct dns_rr *rr; + struct rdatainfo *rdata; + int length; + unsigned int index_ans, index_sig; + u_char answer[ANSWER_BUFFER_SIZE]; + + /* check for invalid class and type */ + if (rdclass > 0xffff || rdtype > 0xffff) { + result = ERRSET_INVAL; + goto fail; + } + + /* don't allow queries of class or type ANY */ + if (rdclass == 0xff || rdtype == 0xff) { + result = ERRSET_INVAL; + goto fail; + } + + /* don't allow flags yet, unimplemented */ + if (flags) { + result = ERRSET_INVAL; + goto fail; + } + + /* initialize resolver */ + if ((_resp->options & RES_INIT) == 0 && res_init() == -1) { + result = ERRSET_FAIL; + goto fail; + } + +#ifdef DEBUG + _resp->options |= RES_DEBUG; +#endif /* DEBUG */ + +#ifdef RES_USE_DNSSEC + /* turn on DNSSEC if EDNS0 is configured */ + if (_resp->options & RES_USE_EDNS0) + _resp->options |= RES_USE_DNSSEC; +#endif /* RES_USE_DNSEC */ + + /* make query */ + length = res_query(hostname, (signed int) rdclass, (signed int) rdtype, + answer, sizeof(answer)); + if (length < 0) { + switch(h_errno) { + case HOST_NOT_FOUND: + result = ERRSET_NONAME; + goto fail; + case NO_DATA: + result = ERRSET_NODATA; + goto fail; + default: + result = ERRSET_FAIL; + goto fail; + } + } + + /* parse result */ + response = parse_dns_response(answer, length); + if (response == NULL) { + result = ERRSET_FAIL; + goto fail; + } + + if (response->header.qdcount != 1) { + result = ERRSET_FAIL; + goto fail; + } + + /* initialize rrset */ + rrset = calloc(1, sizeof(struct rrsetinfo)); + if (rrset == NULL) { + result = ERRSET_NOMEMORY; + goto fail; + } + rrset->rri_rdclass = response->query->class; + rrset->rri_rdtype = response->query->type; + rrset->rri_ttl = response->answer->ttl; + rrset->rri_nrdatas = response->header.ancount; + +#ifdef HAVE_HEADER_AD + /* check for authenticated data */ + if (response->header.ad == 1) + rrset->rri_flags |= RRSET_VALIDATED; +#endif + + /* copy name from answer section */ + length = strlen(response->answer->name); + rrset->rri_name = malloc(length + 1); + if (rrset->rri_name == NULL) { + result = ERRSET_NOMEMORY; + goto fail; + } + strlcpy(rrset->rri_name, response->answer->name, length + 1); + + /* count answers */ + rrset->rri_nrdatas = count_dns_rr(response->answer, rrset->rri_rdclass, + rrset->rri_rdtype); + rrset->rri_nsigs = count_dns_rr(response->answer, rrset->rri_rdclass, + T_SIG); + + /* allocate memory for answers */ + rrset->rri_rdatas = calloc(rrset->rri_nrdatas, + sizeof(struct rdatainfo)); + if (rrset->rri_rdatas == NULL) { + result = ERRSET_NOMEMORY; + goto fail; + } + + /* allocate memory for signatures */ + rrset->rri_sigs = calloc(rrset->rri_nsigs, sizeof(struct rdatainfo)); + if (rrset->rri_sigs == NULL) { + result = ERRSET_NOMEMORY; + goto fail; + } + + /* copy answers & signatures */ + for (rr = response->answer, index_ans = 0, index_sig = 0; + rr; rr = rr->next) { + + rdata = NULL; + + if (rr->class == rrset->rri_rdclass && + rr->type == rrset->rri_rdtype) + rdata = &rrset->rri_rdatas[index_ans++]; + + if (rr->class == rrset->rri_rdclass && + rr->type == T_SIG) + rdata = &rrset->rri_sigs[index_sig++]; + + if (rdata) { + rdata->rdi_length = rr->size; + rdata->rdi_data = malloc(rr->size); + + if (rdata->rdi_data == NULL) { + result = ERRSET_NOMEMORY; + goto fail; + } + memcpy(rdata->rdi_data, rr->rdata, rr->size); + } + } + + *res = rrset; + return (ERRSET_SUCCESS); + +fail: + if (rrset != NULL) + freerrset(rrset); + return (result); +} + +void +freerrset(struct rrsetinfo *rrset) +{ + u_int16_t i; + + if (rrset == NULL) + return; + + if (rrset->rri_rdatas) { + for (i = 0; i < rrset->rri_nrdatas; i++) { + if (rrset->rri_rdatas[i].rdi_data == NULL) + break; + free(rrset->rri_rdatas[i].rdi_data); + } + free(rrset->rri_rdatas); + } + + if (rrset->rri_sigs) { + for (i = 0; i < rrset->rri_nsigs; i++) { + if (rrset->rri_sigs[i].rdi_data == NULL) + break; + free(rrset->rri_sigs[i].rdi_data); + } + free(rrset->rri_sigs); + } + + if (rrset->rri_name) + free(rrset->rri_name); + free(rrset); +} + +/* + * DNS response parsing routines + */ +static struct dns_response * +parse_dns_response(const u_char *answer, int size) +{ + struct dns_response *resp; + const u_char *cp; + + /* allocate memory for the response */ + resp = calloc(1, sizeof(*resp)); + if (resp == NULL) + return (NULL); + + /* initialize current pointer */ + cp = answer; + + /* copy header */ + memcpy(&resp->header, cp, HFIXEDSZ); + cp += HFIXEDSZ; + + /* fix header byte order */ + resp->header.qdcount = ntohs(resp->header.qdcount); + resp->header.ancount = ntohs(resp->header.ancount); + resp->header.nscount = ntohs(resp->header.nscount); + resp->header.arcount = ntohs(resp->header.arcount); + + /* there must be at least one query */ + if (resp->header.qdcount < 1) { + free_dns_response(resp); + return (NULL); + } + + /* parse query section */ + resp->query = parse_dns_qsection(answer, size, &cp, + resp->header.qdcount); + if (resp->header.qdcount && resp->query == NULL) { + free_dns_response(resp); + return (NULL); + } + + /* parse answer section */ + resp->answer = parse_dns_rrsection(answer, size, &cp, + resp->header.ancount); + if (resp->header.ancount && resp->answer == NULL) { + free_dns_response(resp); + return (NULL); + } + + /* parse authority section */ + resp->authority = parse_dns_rrsection(answer, size, &cp, + resp->header.nscount); + if (resp->header.nscount && resp->authority == NULL) { + free_dns_response(resp); + return (NULL); + } + + /* parse additional section */ + resp->additional = parse_dns_rrsection(answer, size, &cp, + resp->header.arcount); + if (resp->header.arcount && resp->additional == NULL) { + free_dns_response(resp); + return (NULL); + } + + return (resp); +} + +static struct dns_query * +parse_dns_qsection(const u_char *answer, int size, const u_char **cp, int count) +{ + struct dns_query *head, *curr, *prev; + int i, length; + char name[MAXDNAME]; + + for (i = 1, head = NULL, prev = NULL; i <= count; i++, prev = curr) { + + /* allocate and initialize struct */ + curr = calloc(1, sizeof(struct dns_query)); + if (curr == NULL) { + free_dns_query(head); + return (NULL); + } + if (head == NULL) + head = curr; + if (prev != NULL) + prev->next = curr; + + /* name */ + length = dn_expand(answer, answer + size, *cp, name, + sizeof(name)); + if (length < 0) { + free_dns_query(head); + return (NULL); + } + curr->name = strdup(name); + if (curr->name == NULL) { + free_dns_query(head); + return (NULL); + } + *cp += length; + + /* type */ + curr->type = _getshort(*cp); + *cp += INT16SZ; + + /* class */ + curr->class = _getshort(*cp); + *cp += INT16SZ; + } + + return (head); +} + +static struct dns_rr * +parse_dns_rrsection(const u_char *answer, int size, const u_char **cp, int count) +{ + struct dns_rr *head, *curr, *prev; + int i, length; + char name[MAXDNAME]; + + for (i = 1, head = NULL, prev = NULL; i <= count; i++, prev = curr) { + + /* allocate and initialize struct */ + curr = calloc(1, sizeof(struct dns_rr)); + if (curr == NULL) { + free_dns_rr(head); + return (NULL); + } + if (head == NULL) + head = curr; + if (prev != NULL) + prev->next = curr; + + /* name */ + length = dn_expand(answer, answer + size, *cp, name, + sizeof(name)); + if (length < 0) { + free_dns_rr(head); + return (NULL); + } + curr->name = strdup(name); + if (curr->name == NULL) { + free_dns_rr(head); + return (NULL); + } + *cp += length; + + /* type */ + curr->type = _getshort(*cp); + *cp += INT16SZ; + + /* class */ + curr->class = _getshort(*cp); + *cp += INT16SZ; + + /* ttl */ + curr->ttl = _getlong(*cp); + *cp += INT32SZ; + + /* rdata size */ + curr->size = _getshort(*cp); + *cp += INT16SZ; + + /* rdata itself */ + curr->rdata = malloc(curr->size); + if (curr->rdata == NULL) { + free_dns_rr(head); + return (NULL); + } + memcpy(curr->rdata, *cp, curr->size); + *cp += curr->size; + } + + return (head); +} + +static void +free_dns_query(struct dns_query *p) +{ + if (p == NULL) + return; + + if (p->name) + free(p->name); + free_dns_query(p->next); + free(p); +} + +static void +free_dns_rr(struct dns_rr *p) +{ + if (p == NULL) + return; + + if (p->name) + free(p->name); + if (p->rdata) + free(p->rdata); + free_dns_rr(p->next); + free(p); +} + +static void +free_dns_response(struct dns_response *p) +{ + if (p == NULL) + return; + + free_dns_query(p->query); + free_dns_rr(p->answer); + free_dns_rr(p->authority); + free_dns_rr(p->additional); + free(p); +} + +static int +count_dns_rr(struct dns_rr *p, u_int16_t class, u_int16_t type) +{ + int n = 0; + + while(p) { + if (p->class == class && p->type == type) + n++; + p = p->next; + } + + return (n); +} + +#endif /* defined(DNS) && !defined(HAVE_GETRRSETBYNAME) */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/getrrsetbyname.h openssh-3.7p1/openbsd-compat/getrrsetbyname.h --- ssh-openbsd-2003091600/openbsd-compat/getrrsetbyname.h 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/getrrsetbyname.h 2003-08-30 02:59:52.000000000 +1000 @@ -0,0 +1,100 @@ +/* $OpenBSD: getrrsetbyname.c,v 1.4 2001/08/16 18:16:43 ho Exp $ */ + +/* + * Copyright (c) 2001 Jakob Schlyter. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Portions Copyright (c) 1999-2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _GETRRSETBYNAME_H +#define _GETRRSETBYNAME_H + +#include "includes.h" + +#if defined(DNS) && !defined(HAVE_GETRRSETBYNAME) + +#include +#include +#include +#include +#include + +/* + * Flags for getrrsetbyname() + */ +#ifndef RRSET_VALIDATED +# define RRSET_VALIDATED 1 +#endif + +/* + * Return codes for getrrsetbyname() + */ +#ifndef ERRSET_SUCCESS +# define ERRSET_SUCCESS 0 +# define ERRSET_NOMEMORY 1 +# define ERRSET_FAIL 2 +# define ERRSET_INVAL 3 +# define ERRSET_NONAME 4 +# define ERRSET_NODATA 5 +#endif + +struct rdatainfo { + unsigned int rdi_length; /* length of data */ + unsigned char *rdi_data; /* record data */ +}; + +struct rrsetinfo { + unsigned int rri_flags; /* RRSET_VALIDATED ... */ + unsigned int rri_rdclass; /* class number */ + unsigned int rri_rdtype; /* RR type number */ + unsigned int rri_ttl; /* time to live */ + unsigned int rri_nrdatas; /* size of rdatas array */ + unsigned int rri_nsigs; /* size of sigs array */ + char *rri_name; /* canonical name */ + struct rdatainfo *rri_rdatas; /* individual records */ + struct rdatainfo *rri_sigs; /* individual signatures */ +}; + +int getrrsetbyname(const char *, unsigned int, unsigned int, unsigned int, struct rrsetinfo **); +void freerrset(struct rrsetinfo *); + +#endif /* defined(DNS) && !defined(HAVE_GETRRSETBYNAME) */ + +#endif /* _GETRRSETBYNAME_H */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/glob.c openssh-3.7p1/openbsd-compat/glob.c --- ssh-openbsd-2003091600/openbsd-compat/glob.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/glob.c 2003-08-25 11:10:52.000000000 +1000 @@ -0,0 +1,912 @@ +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Guido van Rossum. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "includes.h" +#include + +static long +get_arg_max(void) +{ +#ifdef ARG_MAX + return(ARG_MAX); +#elif defined(HAVE_SYSCONF) && defined(_SC_ARG_MAX) + return(sysconf(_SC_ARG_MAX)); +#else + return(256); /* XXX: arbitrary */ +#endif +} + +#if !defined(HAVE_GLOB) || !defined(GLOB_HAS_ALTDIRFUNC) || \ + !defined(GLOB_HAS_GL_MATCHC) + +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)glob.c 8.3 (Berkeley) 10/13/93"; +#else +static char rcsid[] = "$OpenBSD: glob.c,v 1.22 2003/06/25 21:16:47 deraadt Exp $"; +#endif +#endif /* LIBC_SCCS and not lint */ + +/* + * glob(3) -- a superset of the one defined in POSIX 1003.2. + * + * The [!...] convention to negate a range is supported (SysV, Posix, ksh). + * + * Optional extra services, controlled by flags not defined by POSIX: + * + * GLOB_QUOTE: + * Escaping convention: \ inhibits any special meaning the following + * character might have (except \ at end of string is retained). + * GLOB_MAGCHAR: + * Set in gl_flags if pattern contained a globbing character. + * GLOB_NOMAGIC: + * Same as GLOB_NOCHECK, but it will only append pattern if it did + * not contain any magic characters. [Used in csh style globbing] + * GLOB_ALTDIRFUNC: + * Use alternately specified directory access functions. + * GLOB_TILDE: + * expand ~user/foo to the /home/dir/of/user/foo + * GLOB_BRACE: + * expand {1,2}{a,b} to 1a 1b 2a 2b + * gl_matchc: + * Number of matches in the current invocation of glob. + */ + + +#define DOLLAR '$' +#define DOT '.' +#define EOS '\0' +#define LBRACKET '[' +#define NOT '!' +#define QUESTION '?' +#define QUOTE '\\' +#define RANGE '-' +#define RBRACKET ']' +#define SEP '/' +#define STAR '*' +#undef TILDE /* Some platforms may already define it */ +#define TILDE '~' +#define UNDERSCORE '_' +#define LBRACE '{' +#define RBRACE '}' +#define SLASH '/' +#define COMMA ',' + +#ifndef DEBUG + +#define M_QUOTE 0x8000 +#define M_PROTECT 0x4000 +#define M_MASK 0xffff +#define M_ASCII 0x00ff + +typedef u_short Char; + +#else + +#define M_QUOTE 0x80 +#define M_PROTECT 0x40 +#define M_MASK 0xff +#define M_ASCII 0x7f + +typedef char Char; + +#endif + + +#define CHAR(c) ((Char)((c)&M_ASCII)) +#define META(c) ((Char)((c)|M_QUOTE)) +#define M_ALL META('*') +#define M_END META(']') +#define M_NOT META('!') +#define M_ONE META('?') +#define M_RNG META('-') +#define M_SET META('[') +#define ismeta(c) (((c)&M_QUOTE) != 0) + + +static int compare(const void *, const void *); +static int g_Ctoc(const Char *, char *, u_int); +static int g_lstat(Char *, struct stat *, glob_t *); +static DIR *g_opendir(Char *, glob_t *); +static Char *g_strchr(Char *, int); +static int g_stat(Char *, struct stat *, glob_t *); +static int glob0(const Char *, glob_t *); +static int glob1(Char *, Char *, glob_t *, size_t *); +static int glob2(Char *, Char *, Char *, Char *, Char *, Char *, + glob_t *, size_t *); +static int glob3(Char *, Char *, Char *, Char *, Char *, Char *, + Char *, Char *, glob_t *, size_t *); +static int globextend(const Char *, glob_t *, size_t *); +static const Char * + globtilde(const Char *, Char *, size_t, glob_t *); +static int globexp1(const Char *, glob_t *); +static int globexp2(const Char *, const Char *, glob_t *, int *); +static int match(Char *, Char *, Char *); +#ifdef DEBUG +static void qprintf(const char *, Char *); +#endif + +int +glob(pattern, flags, errfunc, pglob) + const char *pattern; + int flags, (*errfunc)(const char *, int); + glob_t *pglob; +{ + const u_char *patnext; + int c; + Char *bufnext, *bufend, patbuf[MAXPATHLEN]; + + patnext = (u_char *) pattern; + if (!(flags & GLOB_APPEND)) { + pglob->gl_pathc = 0; + pglob->gl_pathv = NULL; + if (!(flags & GLOB_DOOFFS)) + pglob->gl_offs = 0; + } + pglob->gl_flags = flags & ~GLOB_MAGCHAR; + pglob->gl_errfunc = errfunc; + pglob->gl_matchc = 0; + + bufnext = patbuf; + bufend = bufnext + MAXPATHLEN - 1; + if (flags & GLOB_NOESCAPE) + while (bufnext < bufend && (c = *patnext++) != EOS) + *bufnext++ = c; + else { + /* Protect the quoted characters. */ + while (bufnext < bufend && (c = *patnext++) != EOS) + if (c == QUOTE) { + if ((c = *patnext++) == EOS) { + c = QUOTE; + --patnext; + } + *bufnext++ = c | M_PROTECT; + } else + *bufnext++ = c; + } + *bufnext = EOS; + + if (flags & GLOB_BRACE) + return globexp1(patbuf, pglob); + else + return glob0(patbuf, pglob); +} + +/* + * Expand recursively a glob {} pattern. When there is no more expansion + * invoke the standard globbing routine to glob the rest of the magic + * characters + */ +static int +globexp1(pattern, pglob) + const Char *pattern; + glob_t *pglob; +{ + const Char* ptr = pattern; + int rv; + + /* Protect a single {}, for find(1), like csh */ + if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS) + return glob0(pattern, pglob); + + while ((ptr = (const Char *) g_strchr((Char *) ptr, LBRACE)) != NULL) + if (!globexp2(ptr, pattern, pglob, &rv)) + return rv; + + return glob0(pattern, pglob); +} + + +/* + * Recursive brace globbing helper. Tries to expand a single brace. + * If it succeeds then it invokes globexp1 with the new pattern. + * If it fails then it tries to glob the rest of the pattern and returns. + */ +static int +globexp2(ptr, pattern, pglob, rv) + const Char *ptr, *pattern; + glob_t *pglob; + int *rv; +{ + int i; + Char *lm, *ls; + const Char *pe, *pm, *pl; + Char patbuf[MAXPATHLEN]; + + /* copy part up to the brace */ + for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++) + ; + *lm = EOS; + ls = lm; + + /* Find the balanced brace */ + for (i = 0, pe = ++ptr; *pe; pe++) + if (*pe == LBRACKET) { + /* Ignore everything between [] */ + for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++) + ; + if (*pe == EOS) { + /* + * We could not find a matching RBRACKET. + * Ignore and just look for RBRACE + */ + pe = pm; + } + } else if (*pe == LBRACE) + i++; + else if (*pe == RBRACE) { + if (i == 0) + break; + i--; + } + + /* Non matching braces; just glob the pattern */ + if (i != 0 || *pe == EOS) { + *rv = glob0(patbuf, pglob); + return 0; + } + + for (i = 0, pl = pm = ptr; pm <= pe; pm++) { + switch (*pm) { + case LBRACKET: + /* Ignore everything between [] */ + for (pl = pm++; *pm != RBRACKET && *pm != EOS; pm++) + ; + if (*pm == EOS) { + /* + * We could not find a matching RBRACKET. + * Ignore and just look for RBRACE + */ + pm = pl; + } + break; + + case LBRACE: + i++; + break; + + case RBRACE: + if (i) { + i--; + break; + } + /* FALLTHROUGH */ + case COMMA: + if (i && *pm == COMMA) + break; + else { + /* Append the current string */ + for (lm = ls; (pl < pm); *lm++ = *pl++) + ; + + /* + * Append the rest of the pattern after the + * closing brace + */ + for (pl = pe + 1; (*lm++ = *pl++) != EOS; ) + ; + + /* Expand the current pattern */ +#ifdef DEBUG + qprintf("globexp2:", patbuf); +#endif + *rv = globexp1(patbuf, pglob); + + /* move after the comma, to the next string */ + pl = pm + 1; + } + break; + + default: + break; + } + } + *rv = 0; + return 0; +} + + + +/* + * expand tilde from the passwd file. + */ +static const Char * +globtilde(pattern, patbuf, patbuf_len, pglob) + const Char *pattern; + Char *patbuf; + size_t patbuf_len; + glob_t *pglob; +{ + struct passwd *pwd; + char *h; + const Char *p; + Char *b, *eb; + + if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE)) + return pattern; + + /* Copy up to the end of the string or / */ + eb = &patbuf[patbuf_len - 1]; + for (p = pattern + 1, h = (char *) patbuf; + h < (char *)eb && *p && *p != SLASH; *h++ = *p++) + ; + + *h = EOS; + +#if 0 + if (h == (char *)eb) + return what; +#endif + + if (((char *) patbuf)[0] == EOS) { + /* + * handle a plain ~ or ~/ by expanding $HOME + * first and then trying the password file + */ +#if 0 + if (issetugid() != 0 || (h = getenv("HOME")) == NULL) { +#endif + if ((getuid() != geteuid()) || (h = getenv("HOME")) == NULL) { + if ((pwd = getpwuid(getuid())) == NULL) + return pattern; + else + h = pwd->pw_dir; + } + } else { + /* + * Expand a ~user + */ + if ((pwd = getpwnam((char*) patbuf)) == NULL) + return pattern; + else + h = pwd->pw_dir; + } + + /* Copy the home directory */ + for (b = patbuf; b < eb && *h; *b++ = *h++) + ; + + /* Append the rest of the pattern */ + while (b < eb && (*b++ = *p++) != EOS) + ; + *b = EOS; + + return patbuf; +} + + +/* + * The main glob() routine: compiles the pattern (optionally processing + * quotes), calls glob1() to do the real pattern matching, and finally + * sorts the list (unless unsorted operation is requested). Returns 0 + * if things went well, nonzero if errors occurred. It is not an error + * to find no matches. + */ +static int +glob0(pattern, pglob) + const Char *pattern; + glob_t *pglob; +{ + const Char *qpatnext; + int c, err, oldpathc; + Char *bufnext, patbuf[MAXPATHLEN]; + size_t limit = 0; + + qpatnext = globtilde(pattern, patbuf, MAXPATHLEN, pglob); + oldpathc = pglob->gl_pathc; + bufnext = patbuf; + + /* We don't need to check for buffer overflow any more. */ + while ((c = *qpatnext++) != EOS) { + switch (c) { + case LBRACKET: + c = *qpatnext; + if (c == NOT) + ++qpatnext; + if (*qpatnext == EOS || + g_strchr((Char *) qpatnext+1, RBRACKET) == NULL) { + *bufnext++ = LBRACKET; + if (c == NOT) + --qpatnext; + break; + } + *bufnext++ = M_SET; + if (c == NOT) + *bufnext++ = M_NOT; + c = *qpatnext++; + do { + *bufnext++ = CHAR(c); + if (*qpatnext == RANGE && + (c = qpatnext[1]) != RBRACKET) { + *bufnext++ = M_RNG; + *bufnext++ = CHAR(c); + qpatnext += 2; + } + } while ((c = *qpatnext++) != RBRACKET); + pglob->gl_flags |= GLOB_MAGCHAR; + *bufnext++ = M_END; + break; + case QUESTION: + pglob->gl_flags |= GLOB_MAGCHAR; + *bufnext++ = M_ONE; + break; + case STAR: + pglob->gl_flags |= GLOB_MAGCHAR; + /* collapse adjacent stars to one, + * to avoid exponential behavior + */ + if (bufnext == patbuf || bufnext[-1] != M_ALL) + *bufnext++ = M_ALL; + break; + default: + *bufnext++ = CHAR(c); + break; + } + } + *bufnext = EOS; +#ifdef DEBUG + qprintf("glob0:", patbuf); +#endif + + if ((err = glob1(patbuf, patbuf+MAXPATHLEN-1, pglob, &limit)) != 0) + return(err); + + /* + * If there was no match we are going to append the pattern + * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified + * and the pattern did not contain any magic characters + * GLOB_NOMAGIC is there just for compatibility with csh. + */ + if (pglob->gl_pathc == oldpathc) { + if ((pglob->gl_flags & GLOB_NOCHECK) || + ((pglob->gl_flags & GLOB_NOMAGIC) && + !(pglob->gl_flags & GLOB_MAGCHAR))) + return(globextend(pattern, pglob, &limit)); + else + return(GLOB_NOMATCH); + } + if (!(pglob->gl_flags & GLOB_NOSORT)) + qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, + pglob->gl_pathc - oldpathc, sizeof(char *), compare); + return(0); +} + +static int +compare(p, q) + const void *p, *q; +{ + return(strcmp(*(char **)p, *(char **)q)); +} + +static int +glob1(pattern, pattern_last, pglob, limitp) + Char *pattern, *pattern_last; + glob_t *pglob; + size_t *limitp; +{ + Char pathbuf[MAXPATHLEN]; + + /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */ + if (*pattern == EOS) + return(0); + return(glob2(pathbuf, pathbuf+MAXPATHLEN-1, + pathbuf, pathbuf+MAXPATHLEN-1, + pattern, pattern_last, pglob, limitp)); +} + +/* + * The functions glob2 and glob3 are mutually recursive; there is one level + * of recursion for each segment in the pattern that contains one or more + * meta characters. + */ +static int +glob2(pathbuf, pathbuf_last, pathend, pathend_last, pattern, + pattern_last, pglob, limitp) + Char *pathbuf, *pathbuf_last, *pathend, *pathend_last; + Char *pattern, *pattern_last; + glob_t *pglob; + size_t *limitp; +{ + struct stat sb; + Char *p, *q; + int anymeta; + + /* + * Loop over pattern segments until end of pattern or until + * segment with meta character found. + */ + for (anymeta = 0;;) { + if (*pattern == EOS) { /* End of pattern? */ + *pathend = EOS; + if (g_lstat(pathbuf, &sb, pglob)) + return(0); + + if (((pglob->gl_flags & GLOB_MARK) && + pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) || + (S_ISLNK(sb.st_mode) && + (g_stat(pathbuf, &sb, pglob) == 0) && + S_ISDIR(sb.st_mode)))) { + if (pathend+1 > pathend_last) + return (1); + *pathend++ = SEP; + *pathend = EOS; + } + ++pglob->gl_matchc; + return(globextend(pathbuf, pglob, limitp)); + } + + /* Find end of next segment, copy tentatively to pathend. */ + q = pathend; + p = pattern; + while (*p != EOS && *p != SEP) { + if (ismeta(*p)) + anymeta = 1; + if (q+1 > pathend_last) + return (1); + *q++ = *p++; + } + + if (!anymeta) { /* No expansion, do next segment. */ + pathend = q; + pattern = p; + while (*pattern == SEP) { + if (pathend+1 > pathend_last) + return (1); + *pathend++ = *pattern++; + } + } else + /* Need expansion, recurse. */ + return(glob3(pathbuf, pathbuf_last, pathend, + pathend_last, pattern, pattern_last, + p, pattern_last, pglob, limitp)); + } + /* NOTREACHED */ +} + +static int +glob3(pathbuf, pathbuf_last, pathend, pathend_last, pattern, pattern_last, + restpattern, restpattern_last, pglob, limitp) + Char *pathbuf, *pathbuf_last, *pathend, *pathend_last; + Char *pattern, *pattern_last, *restpattern, *restpattern_last; + glob_t *pglob; + size_t *limitp; +{ + register struct dirent *dp; + DIR *dirp; + int err; + char buf[MAXPATHLEN]; + + /* + * The readdirfunc declaration can't be prototyped, because it is + * assigned, below, to two functions which are prototyped in glob.h + * and dirent.h as taking pointers to differently typed opaque + * structures. + */ + struct dirent *(*readdirfunc)(void *); + + if (pathend > pathend_last) + return (1); + *pathend = EOS; + errno = 0; + + if ((dirp = g_opendir(pathbuf, pglob)) == NULL) { + /* TODO: don't call for ENOENT or ENOTDIR? */ + if (pglob->gl_errfunc) { + if (g_Ctoc(pathbuf, buf, sizeof(buf))) + return(GLOB_ABORTED); + if (pglob->gl_errfunc(buf, errno) || + pglob->gl_flags & GLOB_ERR) + return(GLOB_ABORTED); + } + return(0); + } + + err = 0; + + /* Search directory for matching names. */ + if (pglob->gl_flags & GLOB_ALTDIRFUNC) + readdirfunc = pglob->gl_readdir; + else + readdirfunc = (struct dirent *(*)(void *))readdir; + while ((dp = (*readdirfunc)(dirp))) { + register u_char *sc; + register Char *dc; + + /* Initial DOT must be matched literally. */ + if (dp->d_name[0] == DOT && *pattern != DOT) + continue; + dc = pathend; + sc = (u_char *) dp->d_name; + while (dc < pathend_last && (*dc++ = *sc++) != EOS) + ; + if (dc >= pathend_last) { + *dc = EOS; + err = 1; + break; + } + + if (!match(pathend, pattern, restpattern)) { + *pathend = EOS; + continue; + } + err = glob2(pathbuf, pathbuf_last, --dc, pathend_last, + restpattern, restpattern_last, pglob, limitp); + if (err) + break; + } + + if (pglob->gl_flags & GLOB_ALTDIRFUNC) + (*pglob->gl_closedir)(dirp); + else + closedir(dirp); + return(err); +} + + +/* + * Extend the gl_pathv member of a glob_t structure to accommodate a new item, + * add the new item, and update gl_pathc. + * + * This assumes the BSD realloc, which only copies the block when its size + * crosses a power-of-two boundary; for v7 realloc, this would cause quadratic + * behavior. + * + * Return 0 if new item added, error code if memory couldn't be allocated. + * + * Invariant of the glob_t structure: + * Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and + * gl_pathv points to (gl_offs + gl_pathc + 1) items. + */ +static int +globextend(path, pglob, limitp) + const Char *path; + glob_t *pglob; + size_t *limitp; +{ + register char **pathv; + register int i; + u_int newsize, len; + char *copy; + const Char *p; + + newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs); + pathv = pglob->gl_pathv ? realloc((char *)pglob->gl_pathv, newsize) : + malloc(newsize); + if (pathv == NULL) { + if (pglob->gl_pathv) { + free(pglob->gl_pathv); + pglob->gl_pathv = NULL; + } + return(GLOB_NOSPACE); + } + + if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) { + /* first time around -- clear initial gl_offs items */ + pathv += pglob->gl_offs; + for (i = pglob->gl_offs; --i >= 0; ) + *--pathv = NULL; + } + pglob->gl_pathv = pathv; + + for (p = path; *p++;) + ; + len = (size_t)(p - path); + *limitp += len; + if ((copy = malloc(len)) != NULL) { + if (g_Ctoc(path, copy, len)) { + free(copy); + return(GLOB_NOSPACE); + } + pathv[pglob->gl_offs + pglob->gl_pathc++] = copy; + } + pathv[pglob->gl_offs + pglob->gl_pathc] = NULL; + + if ((pglob->gl_flags & GLOB_LIMIT) && + newsize + *limitp >= (u_int) get_arg_max()) { + errno = 0; + return(GLOB_NOSPACE); + } + + return(copy == NULL ? GLOB_NOSPACE : 0); +} + + +/* + * pattern matching function for filenames. Each occurrence of the * + * pattern causes a recursion level. + */ +static int +match(name, pat, patend) + register Char *name, *pat, *patend; +{ + int ok, negate_range; + Char c, k; + + while (pat < patend) { + c = *pat++; + switch (c & M_MASK) { + case M_ALL: + if (pat == patend) + return(1); + do + if (match(name, pat, patend)) + return(1); + while (*name++ != EOS) + ; + return(0); + case M_ONE: + if (*name++ == EOS) + return(0); + break; + case M_SET: + ok = 0; + if ((k = *name++) == EOS) + return(0); + if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS) + ++pat; + while (((c = *pat++) & M_MASK) != M_END) + if ((*pat & M_MASK) == M_RNG) { + if (c <= k && k <= pat[1]) + ok = 1; + pat += 2; + } else if (c == k) + ok = 1; + if (ok == negate_range) + return(0); + break; + default: + if (*name++ != c) + return(0); + break; + } + } + return(*name == EOS); +} + +/* Free allocated data belonging to a glob_t structure. */ +void +globfree(pglob) + glob_t *pglob; +{ + register int i; + register char **pp; + + if (pglob->gl_pathv != NULL) { + pp = pglob->gl_pathv + pglob->gl_offs; + for (i = pglob->gl_pathc; i--; ++pp) + if (*pp) + free(*pp); + free(pglob->gl_pathv); + pglob->gl_pathv = NULL; + } +} + +static DIR * +g_opendir(str, pglob) + register Char *str; + glob_t *pglob; +{ + char buf[MAXPATHLEN]; + + if (!*str) + strlcpy(buf, ".", sizeof buf); + else { + if (g_Ctoc(str, buf, sizeof(buf))) + return(NULL); + } + + if (pglob->gl_flags & GLOB_ALTDIRFUNC) + return((*pglob->gl_opendir)(buf)); + + return(opendir(buf)); +} + +static int +g_lstat(fn, sb, pglob) + register Char *fn; + struct stat *sb; + glob_t *pglob; +{ + char buf[MAXPATHLEN]; + + if (g_Ctoc(fn, buf, sizeof(buf))) + return(-1); + if (pglob->gl_flags & GLOB_ALTDIRFUNC) + return((*pglob->gl_lstat)(buf, sb)); + return(lstat(buf, sb)); +} + +static int +g_stat(fn, sb, pglob) + register Char *fn; + struct stat *sb; + glob_t *pglob; +{ + char buf[MAXPATHLEN]; + + if (g_Ctoc(fn, buf, sizeof(buf))) + return(-1); + if (pglob->gl_flags & GLOB_ALTDIRFUNC) + return((*pglob->gl_stat)(buf, sb)); + return(stat(buf, sb)); +} + +static Char * +g_strchr(str, ch) + Char *str; + int ch; +{ + do { + if (*str == ch) + return (str); + } while (*str++); + return (NULL); +} + +static int +g_Ctoc(str, buf, len) + register const Char *str; + char *buf; + u_int len; +{ + + while (len--) { + if ((*buf++ = *str++) == EOS) + return (0); + } + return (1); +} + +#ifdef DEBUG +static void +qprintf(str, s) + const char *str; + register Char *s; +{ + register Char *p; + + (void)printf("%s:\n", str); + for (p = s; *p; p++) + (void)printf("%c", CHAR(*p)); + (void)printf("\n"); + for (p = s; *p; p++) + (void)printf("%c", *p & M_PROTECT ? '"' : ' '); + (void)printf("\n"); + for (p = s; *p; p++) + (void)printf("%c", ismeta(*p) ? '_' : ' '); + (void)printf("\n"); +} +#endif + +#endif /* !defined(HAVE_GLOB) || !defined(GLOB_HAS_ALTDIRFUNC) || + !defined(GLOB_HAS_GL_MATCHC) */ + diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/glob.h openssh-3.7p1/openbsd-compat/glob.h --- ssh-openbsd-2003091600/openbsd-compat/glob.h 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/glob.h 2003-06-03 12:12:51.000000000 +1000 @@ -0,0 +1,97 @@ +/* $OpenBSD: glob.h,v 1.8 2003/06/02 19:34:12 millert Exp $ */ +/* $NetBSD: glob.h,v 1.5 1994/10/26 00:55:56 cgd Exp $ */ + +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Guido van Rossum. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)glob.h 8.1 (Berkeley) 6/2/93 + */ + +#if !defined(HAVE_GLOB_H) || !defined(GLOB_HAS_ALTDIRFUNC) || \ + !defined(GLOB_HAS_GL_MATCHC) + +#ifndef _GLOB_H_ +#define _GLOB_H_ + +struct stat; +typedef struct { + int gl_pathc; /* Count of total paths so far. */ + int gl_matchc; /* Count of paths matching pattern. */ + int gl_offs; /* Reserved at beginning of gl_pathv. */ + int gl_flags; /* Copy of flags parameter to glob. */ + char **gl_pathv; /* List of paths matching pattern. */ + /* Copy of errfunc parameter to glob. */ + int (*gl_errfunc)(const char *, int); + + /* + * Alternate filesystem access methods for glob; replacement + * versions of closedir(3), readdir(3), opendir(3), stat(2) + * and lstat(2). + */ + void (*gl_closedir)(void *); + struct dirent *(*gl_readdir)(void *); + void *(*gl_opendir)(const char *); + int (*gl_lstat)(const char *, struct stat *); + int (*gl_stat)(const char *, struct stat *); +} glob_t; + +/* Flags */ +#define GLOB_APPEND 0x0001 /* Append to output from previous call. */ +#define GLOB_DOOFFS 0x0002 /* Use gl_offs. */ +#define GLOB_ERR 0x0004 /* Return on error. */ +#define GLOB_MARK 0x0008 /* Append / to matching directories. */ +#define GLOB_NOCHECK 0x0010 /* Return pattern itself if nothing matches. */ +#define GLOB_NOSORT 0x0020 /* Don't sort. */ + +#define GLOB_ALTDIRFUNC 0x0040 /* Use alternately specified directory funcs. */ +#define GLOB_BRACE 0x0080 /* Expand braces ala csh. */ +#define GLOB_MAGCHAR 0x0100 /* Pattern had globbing characters. */ +#define GLOB_NOMAGIC 0x0200 /* GLOB_NOCHECK without magic chars (csh). */ +#define GLOB_QUOTE 0x0400 /* Quote special chars with \. */ +#define GLOB_TILDE 0x0800 /* Expand tilde names from the passwd file. */ +#define GLOB_NOESCAPE 0x1000 /* Disable backslash escaping. */ +#define GLOB_LIMIT 0x2000 /* Limit pattern match output to ARG_MAX */ + +/* Error values returned by glob(3) */ +#define GLOB_NOSPACE (-1) /* Malloc call failed. */ +#define GLOB_ABORTED (-2) /* Unignored error. */ +#define GLOB_NOMATCH (-3) /* No match and GLOB_NOCHECK not set. */ +#define GLOB_NOSYS (-4) /* Function not supported. */ +#define GLOB_ABEND GLOB_ABORTED + +int glob(const char *, int, int (*)(const char *, int), glob_t *); +void globfree(glob_t *); + +#endif /* !_GLOB_H_ */ + +#endif /* !defined(HAVE_GLOB_H) || !defined(GLOB_HAS_ALTDIRFUNC) || + !defined(GLOB_HAS_GL_MATCHC */ + diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/inet_aton.c openssh-3.7p1/openbsd-compat/inet_aton.c --- ssh-openbsd-2003091600/openbsd-compat/inet_aton.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/inet_aton.c 2003-06-03 12:12:51.000000000 +1000 @@ -0,0 +1,187 @@ +/* $OpenBSD: inet_addr.c,v 1.7 2003/06/02 20:18:35 millert Exp $ */ + +/* + * Copyright (c) 1983, 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * - + * Portions Copyright (c) 1993 by Digital Equipment Corporation. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies, and that + * the name of Digital Equipment Corporation not be used in advertising or + * publicity pertaining to distribution of the document or software without + * specific, written prior permission. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT + * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * - + * --Copyright-- + */ + +#include "includes.h" + +#if !defined(HAVE_INET_ATON) + +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93"; +static char rcsid[] = "$From: inet_addr.c,v 8.5 1996/08/05 08:31:35 vixie Exp $"; +#else +static char rcsid[] = "$OpenBSD: inet_addr.c,v 1.7 2003/06/02 20:18:35 millert Exp $"; +#endif +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include + +#if 0 +/* + * Ascii internet address interpretation routine. + * The value returned is in network order. + */ +in_addr_t +inet_addr(cp) + register const char *cp; +{ + struct in_addr val; + + if (inet_aton(cp, &val)) + return (val.s_addr); + return (INADDR_NONE); +} +#endif + +/* + * Check whether "cp" is a valid ascii representation + * of an Internet address and convert to a binary address. + * Returns 1 if the address is valid, 0 if not. + * This replaces inet_addr, the return value from which + * cannot distinguish between failure and a local broadcast address. + */ +int +inet_aton(const char *cp, struct in_addr *addr) +{ + register u_int32_t val; + register int base, n; + register char c; + unsigned int parts[4]; + register unsigned int *pp = parts; + + c = *cp; + for (;;) { + /* + * Collect number up to ``.''. + * Values are specified as for C: + * 0x=hex, 0=octal, isdigit=decimal. + */ + if (!isdigit(c)) + return (0); + val = 0; base = 10; + if (c == '0') { + c = *++cp; + if (c == 'x' || c == 'X') + base = 16, c = *++cp; + else + base = 8; + } + for (;;) { + if (isascii(c) && isdigit(c)) { + val = (val * base) + (c - '0'); + c = *++cp; + } else if (base == 16 && isascii(c) && isxdigit(c)) { + val = (val << 4) | + (c + 10 - (islower(c) ? 'a' : 'A')); + c = *++cp; + } else + break; + } + if (c == '.') { + /* + * Internet format: + * a.b.c.d + * a.b.c (with c treated as 16 bits) + * a.b (with b treated as 24 bits) + */ + if (pp >= parts + 3) + return (0); + *pp++ = val; + c = *++cp; + } else + break; + } + /* + * Check for trailing characters. + */ + if (c != '\0' && (!isascii(c) || !isspace(c))) + return (0); + /* + * Concoct the address according to + * the number of parts specified. + */ + n = pp - parts + 1; + switch (n) { + + case 0: + return (0); /* initial nondigit */ + + case 1: /* a -- 32 bits */ + break; + + case 2: /* a.b -- 8.24 bits */ + if ((val > 0xffffff) || (parts[0] > 0xff)) + return (0); + val |= parts[0] << 24; + break; + + case 3: /* a.b.c -- 8.8.16 bits */ + if ((val > 0xffff) || (parts[0] > 0xff) || (parts[1] > 0xff)) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16); + break; + + case 4: /* a.b.c.d -- 8.8.8.8 bits */ + if ((val > 0xff) || (parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff)) + return (0); + val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); + break; + } + if (addr) + addr->s_addr = htonl(val); + return (1); +} + +#endif /* !defined(HAVE_INET_ATON) */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/inet_ntoa.c openssh-3.7p1/openbsd-compat/inet_ntoa.c --- ssh-openbsd-2003091600/openbsd-compat/inet_ntoa.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/inet_ntoa.c 2003-06-03 12:12:51.000000000 +1000 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "includes.h" + +#if defined(BROKEN_INET_NTOA) || !defined(HAVE_INET_NTOA) + +#if defined(LIBC_SCCS) && !defined(lint) +static char rcsid[] = "$OpenBSD: inet_ntoa.c,v 1.4 2003/06/02 20:18:35 millert Exp $"; +#endif /* LIBC_SCCS and not lint */ + +/* + * Convert network-format internet address + * to base 256 d.d.d.d representation. + */ +#include +#include +#include +#include +#include "inet_ntoa.h" + +char *inet_ntoa(struct in_addr in) +{ + static char b[18]; + register char *p; + + p = (char *)∈ +#define UC(b) (((int)b)&0xff) + (void)snprintf(b, sizeof(b), + "%u.%u.%u.%u", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3])); + return (b); +} + +#endif /* defined(BROKEN_INET_NTOA) || !defined(HAVE_INET_NTOA) */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/inet_ntop.c openssh-3.7p1/openbsd-compat/inet_ntop.c --- ssh-openbsd-2003091600/openbsd-compat/inet_ntop.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/inet_ntop.c 2003-06-05 18:52:48.000000000 +1000 @@ -0,0 +1,229 @@ +/* $OpenBSD: inet_ntop.c,v 1.5 2002/08/23 16:27:31 itojun Exp $ */ + +/* Copyright (c) 1996 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#include "includes.h" + +#ifndef HAVE_INET_NTOP + +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 +static char rcsid[] = "$From: inet_ntop.c,v 8.7 1996/08/05 08:41:18 vixie Exp $"; +#else +static char rcsid[] = "$OpenBSD: inet_ntop.c,v 1.5 2002/08/23 16:27:31 itojun Exp $"; +#endif +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#ifndef HAVE_CYGWIN +#include +#endif +#include +#include +#include + +#ifndef IN6ADDRSZ +#define IN6ADDRSZ 16 /* IPv6 T_AAAA */ +#endif + +#ifndef INT16SZ +#define INT16SZ 2 /* for systems without 16-bit ints */ +#endif + +/* + * WARNING: Don't even consider trying to compile this on a system where + * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. + */ + +static const char *inet_ntop4(const u_char *src, char *dst, size_t size); +static const char *inet_ntop6(const u_char *src, char *dst, size_t size); + +/* char * + * inet_ntop(af, src, dst, size) + * convert a network format address to presentation format. + * return: + * pointer to presentation format address (`dst'), or NULL (see errno). + * author: + * Paul Vixie, 1996. + */ +const char * +inet_ntop(af, src, dst, size) + int af; + const void *src; + char *dst; + size_t size; +{ + switch (af) { + case AF_INET: + return (inet_ntop4(src, dst, size)); + case AF_INET6: + return (inet_ntop6(src, dst, size)); + default: + errno = EAFNOSUPPORT; + return (NULL); + } + /* NOTREACHED */ +} + +/* const char * + * inet_ntop4(src, dst, size) + * format an IPv4 address, more or less like inet_ntoa() + * return: + * `dst' (as a const) + * notes: + * (1) uses no statics + * (2) takes a u_char* not an in_addr as input + * author: + * Paul Vixie, 1996. + */ +static const char * +inet_ntop4(src, dst, size) + const u_char *src; + char *dst; + size_t size; +{ + static const char fmt[] = "%u.%u.%u.%u"; + char tmp[sizeof "255.255.255.255"]; + int l; + + l = snprintf(tmp, size, fmt, src[0], src[1], src[2], src[3]); + if (l <= 0 || l >= size) { + errno = ENOSPC; + return (NULL); + } + strlcpy(dst, tmp, size); + return (dst); +} + +/* const char * + * inet_ntop6(src, dst, size) + * convert IPv6 binary address into presentation (printable) format + * author: + * Paul Vixie, 1996. + */ +static const char * +inet_ntop6(src, dst, size) + const u_char *src; + char *dst; + size_t size; +{ + /* + * Note that int32_t and int16_t need only be "at least" large enough + * to contain a value of the specified size. On some systems, like + * Crays, there is no such thing as an integer variable with 16 bits. + * Keep this in mind if you think this function should have been coded + * to use pointer overlays. All the world's not a VAX. + */ + char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"]; + char *tp, *ep; + struct { int base, len; } best, cur; + u_int words[IN6ADDRSZ / INT16SZ]; + int i; + int advance; + + /* + * Preprocess: + * Copy the input (bytewise) array into a wordwise array. + * Find the longest run of 0x00's in src[] for :: shorthanding. + */ + memset(words, '\0', sizeof words); + for (i = 0; i < IN6ADDRSZ; i++) + words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); + best.base = -1; + cur.base = -1; + for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { + if (words[i] == 0) { + if (cur.base == -1) + cur.base = i, cur.len = 1; + else + cur.len++; + } else { + if (cur.base != -1) { + if (best.base == -1 || cur.len > best.len) + best = cur; + cur.base = -1; + } + } + } + if (cur.base != -1) { + if (best.base == -1 || cur.len > best.len) + best = cur; + } + if (best.base != -1 && best.len < 2) + best.base = -1; + + /* + * Format the result. + */ + tp = tmp; + ep = tmp + sizeof(tmp); + for (i = 0; i < (IN6ADDRSZ / INT16SZ) && tp < ep; i++) { + /* Are we inside the best run of 0x00's? */ + if (best.base != -1 && i >= best.base && + i < (best.base + best.len)) { + if (i == best.base) { + if (tp + 1 >= ep) + return (NULL); + *tp++ = ':'; + } + continue; + } + /* Are we following an initial run of 0x00s or any real hex? */ + if (i != 0) { + if (tp + 1 >= ep) + return (NULL); + *tp++ = ':'; + } + /* Is this address an encapsulated IPv4? */ + if (i == 6 && best.base == 0 && + (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { + if (!inet_ntop4(src+12, tp, (size_t)(ep - tp))) + return (NULL); + tp += strlen(tp); + break; + } + advance = snprintf(tp, ep - tp, "%x", words[i]); + if (advance <= 0 || advance >= ep - tp) + return (NULL); + tp += advance; + } + /* Was it a trailing run of 0x00's? */ + if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) { + if (tp + 1 >= ep) + return (NULL); + *tp++ = ':'; + } + if (tp + 1 >= ep) + return (NULL); + *tp++ = '\0'; + + /* + * Check for overflow, copy, and we're done. + */ + if ((size_t)(tp - tmp) > size) { + errno = ENOSPC; + return (NULL); + } + strlcpy(dst, tmp, size); + return (dst); +} + +#endif /* !HAVE_INET_NTOP */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/Makefile.in openssh-3.7p1/openbsd-compat/Makefile.in --- ssh-openbsd-2003091600/openbsd-compat/Makefile.in 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/Makefile.in 2003-07-24 16:52:14.000000000 +1000 @@ -0,0 +1,42 @@ +# $Id: Makefile.in,v 1.28 2003/07/24 06:52:14 mouring Exp $ + +sysconfdir=@sysconfdir@ +piddir=@piddir@ +srcdir=@srcdir@ +top_srcdir=@top_srcdir@ + +VPATH=@srcdir@ +CC=@CC@ +LD=@LD@ +CFLAGS=@CFLAGS@ +CPPFLAGS=-I. -I.. -I$(srcdir) -I$(srcdir)/.. @CPPFLAGS@ @DEFS@ +LIBS=@LIBS@ +AR=@AR@ +RANLIB=@RANLIB@ +INSTALL=@INSTALL@ +LDFLAGS=-L. @LDFLAGS@ + +OPENBSD=base64.o basename.o bindresvport.o daemon.o dirname.o getcwd.o getgrouplist.o getopt.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sigact.o strlcat.o strlcpy.o strmode.o strsep.o vis.o + +COMPAT=bsd-arc4random.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o bsd-misc.o bsd-nextstep.o bsd-snprintf.o bsd-waitpid.o fake-rfc2553.o xmmap.o xcrypt.o + +PORTS=port-irix.o port-aix.o + +.c.o: + $(CC) $(CFLAGS) $(CPPFLAGS) -c $< + +all: libopenbsd-compat.a + +$(COMPAT): ../config.h +$(OPENBSD): ../config.h +$(PORTS): ../config.h + +libopenbsd-compat.a: $(COMPAT) $(OPENBSD) $(PORTS) + $(AR) rv $@ $(COMPAT) $(OPENBSD) $(PORTS) + $(RANLIB) $@ + +clean: + rm -f *.o *.a core + +distclean: clean + rm -f Makefile *~ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/mktemp.c openssh-3.7p1/openbsd-compat/mktemp.c --- ssh-openbsd-2003091600/openbsd-compat/mktemp.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/mktemp.c 2003-06-03 12:12:51.000000000 +1000 @@ -0,0 +1,180 @@ +/* THIS FILE HAS BEEN MODIFIED FROM THE ORIGINAL OPENBSD SOURCE */ +/* Changes: Removed mktemp */ + +/* + * Copyright (c) 1987, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "includes.h" + +#if !defined(HAVE_MKDTEMP) || defined(HAVE_STRICT_MKSTEMP) + +#if defined(LIBC_SCCS) && !defined(lint) +static char rcsid[] = "$OpenBSD: mktemp.c,v 1.17 2003/06/02 20:18:37 millert Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#ifdef HAVE_CYGWIN +#define open binary_open +extern int binary_open(); +#endif + +static int _gettemp(char *, int *, int, int); + +int +mkstemps(path, slen) + char *path; + int slen; +{ + int fd; + + return (_gettemp(path, &fd, 0, slen) ? fd : -1); +} + +int +mkstemp(path) + char *path; +{ + int fd; + + return (_gettemp(path, &fd, 0, 0) ? fd : -1); +} + +char * +mkdtemp(path) + char *path; +{ + return(_gettemp(path, (int *)NULL, 1, 0) ? path : (char *)NULL); +} + +static int +_gettemp(path, doopen, domkdir, slen) + char *path; + register int *doopen; + int domkdir; + int slen; +{ + register char *start, *trv, *suffp; + struct stat sbuf; + int rval; + pid_t pid; + + if (doopen && domkdir) { + errno = EINVAL; + return(0); + } + + for (trv = path; *trv; ++trv) + ; + trv -= slen; + suffp = trv; + --trv; + if (trv < path) { + errno = EINVAL; + return (0); + } + pid = getpid(); + while (trv >= path && *trv == 'X' && pid != 0) { + *trv-- = (pid % 10) + '0'; + pid /= 10; + } + while (trv >= path && *trv == 'X') { + char c; + + pid = (arc4random() & 0xffff) % (26+26); + if (pid < 26) + c = pid + 'A'; + else + c = (pid - 26) + 'a'; + *trv-- = c; + } + start = trv + 1; + + /* + * check the target directory; if you have six X's and it + * doesn't exist this runs for a *very* long time. + */ + if (doopen || domkdir) { + for (;; --trv) { + if (trv <= path) + break; + if (*trv == '/') { + *trv = '\0'; + rval = stat(path, &sbuf); + *trv = '/'; + if (rval != 0) + return(0); + if (!S_ISDIR(sbuf.st_mode)) { + errno = ENOTDIR; + return(0); + } + break; + } + } + } + + for (;;) { + if (doopen) { + if ((*doopen = + open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0) + return(1); + if (errno != EEXIST) + return(0); + } else if (domkdir) { + if (mkdir(path, 0700) == 0) + return(1); + if (errno != EEXIST) + return(0); + } else if (lstat(path, &sbuf)) + return(errno == ENOENT ? 1 : 0); + + /* tricky little algorithm for backward compatibility */ + for (trv = start;;) { + if (!*trv) + return (0); + if (*trv == 'Z') { + if (trv == suffp) + return (0); + *trv++ = 'a'; + } else { + if (isdigit(*trv)) + *trv = 'a'; + else if (*trv == 'z') /* inc from z to A */ + *trv = 'A'; + else { + if (trv == suffp) + return (0); + ++*trv; + } + break; + } + } + } + /*NOTREACHED*/ +} + +#endif /* !defined(HAVE_MKDTEMP) || defined(HAVE_STRICT_MKSTEMP) */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/openbsd-compat.h openssh-3.7p1/openbsd-compat/openbsd-compat.h --- ssh-openbsd-2003091600/openbsd-compat/openbsd-compat.h 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/openbsd-compat.h 2003-08-30 02:59:52.000000000 +1000 @@ -0,0 +1,168 @@ +/* $Id: openbsd-compat.h,v 1.24 2003/08/29 16:59:52 mouring Exp $ */ + +/* + * Copyright (c) 1999-2003 Damien Miller. All rights reserved. + * Copyright (c) 2003 Ben Lindstrom. All rights reserved. + * Copyright (c) 2002 Tim Rice. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _OPENBSD_COMPAT_H +#define _OPENBSD_COMPAT_H + +#include "includes.h" + +/* OpenBSD function replacements */ +#include "base64.h" +#include "sigact.h" +#include "glob.h" +#include "readpassphrase.h" +#include "vis.h" +#include "getrrsetbyname.h" + + +#ifndef HAVE_BASENAME +char *basename(const char *path); +#endif + +#ifndef HAVE_BINDRESVPORT_SA +int bindresvport_sa(int sd, struct sockaddr *sa); +#endif + +#ifndef HAVE_GETCWD +char *getcwd(char *pt, size_t size); +#endif + +#if !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) +char *realpath(const char *path, char *resolved); +#endif + +#ifndef HAVE_RRESVPORT_AF +int rresvport_af(int *alport, sa_family_t af); +#endif + +#ifndef HAVE_STRLCPY +/* #include XXX Still needed? */ +size_t strlcpy(char *dst, const char *src, size_t siz); +#endif + +#ifndef HAVE_STRLCAT +/* #include XXX Still needed? */ +size_t strlcat(char *dst, const char *src, size_t siz); +#endif + +#ifndef HAVE_SETENV +int setenv(register const char *name, register const char *value, int rewrite); +#endif + +#ifndef HAVE_STRMODE +void strmode(int mode, char *p); +#endif + +#if !defined(HAVE_MKDTEMP) || defined(HAVE_STRICT_MKSTEMP) +int mkstemps(char *path, int slen); +int mkstemp(char *path); +char *mkdtemp(char *path); +#endif + +#ifndef HAVE_DAEMON +int daemon(int nochdir, int noclose); +#endif + +#ifndef HAVE_DIRNAME +char *dirname(const char *path); +#endif + +#if defined(BROKEN_INET_NTOA) || !defined(HAVE_INET_NTOA) +char *inet_ntoa(struct in_addr in); +#endif + +#ifndef HAVE_INET_NTOP +const char *inet_ntop(int af, const void *src, char *dst, size_t size); +#endif + +#ifndef HAVE_INET_ATON +int inet_aton(const char *cp, struct in_addr *addr); +#endif + +#ifndef HAVE_STRSEP +char *strsep(char **stringp, const char *delim); +#endif + +#ifndef HAVE_SETPROCTITLE +void setproctitle(const char *fmt, ...); +void compat_init_setproctitle(int argc, char *argv[]); +#endif + +#ifndef HAVE_GETGROUPLIST +/* #include XXXX Still needed ? */ +int getgrouplist(const char *, gid_t, gid_t *, int *); +#endif + +#if !defined(HAVE_GETOPT) || !defined(HAVE_GETOPT_OPTRESET) +int BSDgetopt(int argc, char * const *argv, const char *opts); +#endif + + +/* Home grown routines */ +#include "bsd-misc.h" +#include "bsd-waitpid.h" + +/*#include XXX Still needed? * For uid_t, gid_t * */ + +#ifndef HAVE_GETPEEREID +int getpeereid(int , uid_t *, gid_t *); +#endif + +#ifndef HAVE_ARC4RANDOM +unsigned int arc4random(void); +void arc4random_stir(void); +#endif /* !HAVE_ARC4RANDOM */ + + + + +/* #include XXX needed? For size_t */ + +#ifndef HAVE_SNPRINTF +int snprintf(char *, size_t, const char *, ...); +#endif + +#ifndef HAVE_VSNPRINTF +int vsnprintf(char *, size_t, const char *, va_list); +#endif + +void *xmmap(size_t size); +char *xcrypt(const char *password, const char *salt); +char *shadow_pw(struct passwd *pw); + + +/* rfc2553 socket API replacements */ +#include "fake-rfc2553.h" + +/* Routines for a single OS platform */ +#include "bsd-cray.h" +#include "bsd-cygwin_util.h" +#include "port-irix.h" +#include "port-aix.h" + +#endif /* _OPENBSD_COMPAT_H */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/port-aix.c openssh-3.7p1/openbsd-compat/port-aix.c --- ssh-openbsd-2003091600/openbsd-compat/port-aix.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/port-aix.c 2003-07-14 16:41:55.000000000 +1000 @@ -0,0 +1,141 @@ +/* + * + * Copyright (c) 2001 Gert Doering. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR 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 "ssh.h" +#include "log.h" +#include "servconf.h" + +#ifdef _AIX + +#include +#include <../xmalloc.h> +#include "port-aix.h" + +extern ServerOptions options; + +/* + * AIX has a "usrinfo" area where logname and other stuff is stored - + * a few applications actually use this and die if it's not set + * + * NOTE: TTY= should be set, but since no one uses it and it's hard to + * acquire due to privsep code. We will just drop support. + */ +void +aix_usrinfo(struct passwd *pw) +{ + u_int i; + size_t len; + char *cp; + + len = sizeof("LOGNAME= NAME= ") + (2 * strlen(pw->pw_name)); + cp = xmalloc(len); + + i = snprintf(cp, len, "LOGNAME=%s%cNAME=%s%c", pw->pw_name, '\0', + pw->pw_name, '\0'); + if (usrinfo(SETUINFO, cp, i) == -1) + fatal("Couldn't set usrinfo: %s", strerror(errno)); + debug3("AIX/UsrInfo: set len %d", i); + + xfree(cp); +} + +#ifdef WITH_AIXAUTHENTICATE +/* + * Remove embedded newlines in string (if any). + * Used before logging messages returned by AIX authentication functions + * so the message is logged on one line. + */ +void +aix_remove_embedded_newlines(char *p) +{ + if (p == NULL) + return; + + for (; *p; p++) { + if (*p == '\n') + *p = ' '; + } + /* Remove trailing whitespace */ + if (*--p == ' ') + *p = '\0'; +} +#endif /* WITH_AIXAUTHENTICATE */ + +# ifdef CUSTOM_FAILED_LOGIN +/* + * record_failed_login: generic "login failed" interface function + */ +void +record_failed_login(const char *user, const char *ttyname) +{ + char *hostname = get_canonical_hostname(options.use_dns); + + if (geteuid() != 0) + return; + + aix_setauthdb(user); +# ifdef AIX_LOGINFAILED_4ARG + loginfailed((char *)user, hostname, (char *)ttyname, AUDIT_FAIL_AUTH); +# else + loginfailed((char *)user, hostname, (char *)ttyname); +# endif +} + +/* + * If we have setauthdb, retrieve the password registry for the user's + * account then feed it to setauthdb. This may load registry-specific method + * code. If we don't have setauthdb or have already called it this is a no-op. + */ +void +aix_setauthdb(const char *user) +{ +# ifdef HAVE_SETAUTHDB + static char *registry = NULL; + + if (registry != NULL) /* have already done setauthdb */ + return; + + if (setuserdb(S_READ) == -1) { + debug3("%s: Could not open userdb to read", __func__); + return; + } + + if (getuserattr((char *)user, S_REGISTRY, ®istry, SEC_CHAR) == 0) { + if (setauthdb(registry, NULL) == 0) + debug3("%s: AIX/setauthdb set registry %s", __func__, + registry); + else + debug3("%s: AIX/setauthdb set registry %s failed: %s", + __func__, registry, strerror(errno)); + } else + debug3("%s: Could not read S_REGISTRY for user: %s", __func__, + strerror(errno)); + enduserdb(); +# endif +} +# endif /* CUSTOM_FAILED_LOGIN */ +#endif /* _AIX */ + diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/port-aix.h openssh-3.7p1/openbsd-compat/port-aix.h --- ssh-openbsd-2003091600/openbsd-compat/port-aix.h 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/port-aix.h 2003-08-30 02:59:52.000000000 +1000 @@ -0,0 +1,62 @@ +/* $Id: port-aix.h,v 1.14 2003/08/29 16:59:52 mouring Exp $ */ + +/* + * + * Copyright (c) 2001 Gert Doering. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef _AIX + +#ifdef WITH_AIXAUTHENTICATE +# include +# include +# include +# ifdef HAVE_SYS_AUDIT_H +# include +# endif +#endif + +/* Some versions define r_type in the above headers, which causes a conflict */ +#ifdef r_type +# undef r_type +#endif + +/* AIX 4.2.x doesn't have nanosleep but does have nsleep which is equivalent */ +#if !defined(HAVE_NANOSLEEP) && defined(HAVE_NSLEEP) +# define nanosleep(a,b) nsleep(a,b) +#endif + +/* For struct timespec on AIX 4.2.x */ +#ifdef HAVE_SYS_TIMERS_H +# include +#endif + +#ifdef WITH_AIXAUTHENTICATE +# define CUSTOM_FAILED_LOGIN 1 +void record_failed_login(const char *, const char *); +void aix_setauthdb(const char *); +#endif + +void aix_usrinfo(struct passwd *); +void aix_remove_embedded_newlines(char *); +#endif /* _AIX */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/port-irix.c openssh-3.7p1/openbsd-compat/port-irix.c --- ssh-openbsd-2003091600/openbsd-compat/port-irix.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/port-irix.c 2003-06-01 13:23:57.000000000 +1000 @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2000 Denis Parker. All rights reserved. + * Copyright (c) 2000 Michael Stone. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#if defined(WITH_IRIX_PROJECT) || \ + defined(WITH_IRIX_JOBS) || \ + defined(WITH_IRIX_ARRAY) + +#ifdef WITH_IRIX_PROJECT +# include +#endif /* WITH_IRIX_PROJECT */ +#ifdef WITH_IRIX_JOBS +# include +#endif +#ifdef WITH_IRIX_AUDIT +# include +#endif /* WITH_IRIX_AUDIT */ + +void +irix_setusercontext(struct passwd *pw) +{ +#ifdef WITH_IRIX_PROJECT + prid_t projid; +#endif +#ifdef WITH_IRIX_JOBS + jid_t jid = 0; +#elif defined(WITH_IRIX_ARRAY) + int jid = 0; +#endif + +#ifdef WITH_IRIX_JOBS + jid = jlimit_startjob(pw->pw_name, pw->pw_uid, "interactive"); + if (jid == -1) + fatal("Failed to create job container: %.100s", + strerror(errno)); +#endif /* WITH_IRIX_JOBS */ +#ifdef WITH_IRIX_ARRAY + /* initialize array session */ + if (jid == 0 && newarraysess() != 0) + fatal("Failed to set up new array session: %.100s", + strerror(errno)); +#endif /* WITH_IRIX_ARRAY */ +#ifdef WITH_IRIX_PROJECT + /* initialize irix project info */ + if ((projid = getdfltprojuser(pw->pw_name)) == -1) { + debug("Failed to get project id, using projid 0"); + projid = 0; + } + if (setprid(projid)) + fatal("Failed to initialize project %d for %s: %.100s", + (int)projid, pw->pw_name, strerror(errno)); +#endif /* WITH_IRIX_PROJECT */ +#ifdef WITH_IRIX_AUDIT + if (sysconf(_SC_AUDIT)) { + debug("Setting sat id to %d", (int) pw->pw_uid); + if (satsetid(pw->pw_uid)) + debug("error setting satid: %.100s", strerror(errno)); + } +#endif /* WITH_IRIX_AUDIT */ +} + + +#endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/port-irix.h openssh-3.7p1/openbsd-compat/port-irix.h --- ssh-openbsd-2003091600/openbsd-compat/port-irix.h 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/port-irix.h 2003-08-30 02:59:52.000000000 +1000 @@ -0,0 +1,39 @@ +/* $Id: port-irix.h,v 1.4 2003/08/29 16:59:52 mouring Exp $ */ + +/* + * Copyright (c) 2000 Denis Parker. All rights reserved. + * Copyright (c) 2000 Michael Stone. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _PORT_IRIX_H +#define _PORT_IRIX_H + +#if defined(WITH_IRIX_PROJECT) || \ + defined(WITH_IRIX_JOBS) || \ + defined(WITH_IRIX_ARRAY) + +void irix_setusercontext(struct passwd *pw); + +#endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */ + +#endif /* ! _PORT_IRIX_H */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/readpassphrase.c openssh-3.7p1/openbsd-compat/readpassphrase.c --- ssh-openbsd-2003091600/openbsd-compat/readpassphrase.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/readpassphrase.c 2003-08-25 11:10:52.000000000 +1000 @@ -0,0 +1,184 @@ +/* $OpenBSD: readpassphrase.c,v 1.16 2003/06/17 21:56:23 millert Exp $ */ + +/* + * Copyright (c) 2000-2002 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Sponsored in part by the Defense Advanced Research Projects + * Agency (DARPA) and Air Force Research Laboratory, Air Force + * Materiel Command, USAF, under agreement number F39502-99-1-0512. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static const char rcsid[] = "$OpenBSD: readpassphrase.c,v 1.16 2003/06/17 21:56:23 millert Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include "includes.h" + +#ifndef HAVE_READPASSPHRASE + +#include +#include + +#ifdef TCSASOFT +# define _T_FLUSH (TCSAFLUSH|TCSASOFT) +#else +# define _T_FLUSH (TCSAFLUSH) +#endif + +/* SunOS 4.x which lacks _POSIX_VDISABLE, but has VDISABLE */ +#if !defined(_POSIX_VDISABLE) && defined(VDISABLE) +# define _POSIX_VDISABLE VDISABLE +#endif + +static volatile sig_atomic_t signo; + +static void handler(int); + +char * +readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags) +{ + ssize_t nr; + int input, output, save_errno; + char ch, *p, *end; + struct termios term, oterm; + struct sigaction sa, savealrm, saveint, savehup, savequit, saveterm; + struct sigaction savetstp, savettin, savettou, savepipe; + + /* I suppose we could alloc on demand in this case (XXX). */ + if (bufsiz == 0) { + errno = EINVAL; + return(NULL); + } + +restart: + signo = 0; + /* + * Read and write to /dev/tty if available. If not, read from + * stdin and write to stderr unless a tty is required. + */ + if ((flags & RPP_STDIN) || + (input = output = open(_PATH_TTY, O_RDWR)) == -1) { + if (flags & RPP_REQUIRE_TTY) { + errno = ENOTTY; + return(NULL); + } + input = STDIN_FILENO; + output = STDERR_FILENO; + } + + /* + * Catch signals that would otherwise cause the user to end + * up with echo turned off in the shell. Don't worry about + * things like SIGXCPU and SIGVTALRM for now. + */ + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; /* don't restart system calls */ + sa.sa_handler = handler; + (void)sigaction(SIGALRM, &sa, &savealrm); + (void)sigaction(SIGHUP, &sa, &savehup); + (void)sigaction(SIGINT, &sa, &saveint); + (void)sigaction(SIGPIPE, &sa, &savepipe); + (void)sigaction(SIGQUIT, &sa, &savequit); + (void)sigaction(SIGTERM, &sa, &saveterm); + (void)sigaction(SIGTSTP, &sa, &savetstp); + (void)sigaction(SIGTTIN, &sa, &savettin); + (void)sigaction(SIGTTOU, &sa, &savettou); + + /* Turn off echo if possible. */ + if (input != STDIN_FILENO && tcgetattr(input, &oterm) == 0) { + memcpy(&term, &oterm, sizeof(term)); + if (!(flags & RPP_ECHO_ON)) + term.c_lflag &= ~(ECHO | ECHONL); +#ifdef VSTATUS + if (term.c_cc[VSTATUS] != _POSIX_VDISABLE) + term.c_cc[VSTATUS] = _POSIX_VDISABLE; +#endif + (void)tcsetattr(input, _T_FLUSH, &term); + } else { + memset(&term, 0, sizeof(term)); + term.c_lflag |= ECHO; + memset(&oterm, 0, sizeof(oterm)); + oterm.c_lflag |= ECHO; + } + + if (!(flags & RPP_STDIN)) + (void)write(output, prompt, strlen(prompt)); + end = buf + bufsiz - 1; + for (p = buf; (nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r';) { + if (p < end) { + if ((flags & RPP_SEVENBIT)) + ch &= 0x7f; + if (isalpha(ch)) { + if ((flags & RPP_FORCELOWER)) + ch = tolower(ch); + if ((flags & RPP_FORCEUPPER)) + ch = toupper(ch); + } + *p++ = ch; + } + } + *p = '\0'; + save_errno = errno; + if (!(term.c_lflag & ECHO)) + (void)write(output, "\n", 1); + + /* Restore old terminal settings and signals. */ + if (memcmp(&term, &oterm, sizeof(term)) != 0) + (void)tcsetattr(input, _T_FLUSH, &oterm); + (void)sigaction(SIGALRM, &savealrm, NULL); + (void)sigaction(SIGHUP, &savehup, NULL); + (void)sigaction(SIGINT, &saveint, NULL); + (void)sigaction(SIGQUIT, &savequit, NULL); + (void)sigaction(SIGPIPE, &savepipe, NULL); + (void)sigaction(SIGTERM, &saveterm, NULL); + (void)sigaction(SIGTSTP, &savetstp, NULL); + (void)sigaction(SIGTTIN, &savettin, NULL); + if (input != STDIN_FILENO) + (void)close(input); + + /* + * If we were interrupted by a signal, resend it to ourselves + * now that we have restored the signal handlers. + */ + if (signo) { + kill(getpid(), signo); + switch (signo) { + case SIGTSTP: + case SIGTTIN: + case SIGTTOU: + goto restart; + } + } + + errno = save_errno; + return(nr == -1 ? NULL : buf); +} + +#if 0 +char * +getpass(const char *prompt) +{ + static char buf[_PASSWORD_LEN + 1]; + + return(readpassphrase(prompt, buf, sizeof(buf), RPP_ECHO_OFF)); +} +#endif + +static void handler(int s) +{ + + signo = s; +} +#endif /* HAVE_READPASSPHRASE */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/readpassphrase.h openssh-3.7p1/openbsd-compat/readpassphrase.h --- ssh-openbsd-2003091600/openbsd-compat/readpassphrase.h 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/readpassphrase.h 2002-09-11 10:29:14.000000000 +1000 @@ -0,0 +1,49 @@ +/* $OpenBSD: readpassphrase.h,v 1.3 2002/06/28 12:32:22 millert Exp $ */ + +/* + * Copyright (c) 2000 Todd C. 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. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 _READPASSPHRASE_H_ +#define _READPASSPHRASE_H_ + +#include "includes.h" + +#ifndef HAVE_READPASSPHRASE + +#define RPP_ECHO_OFF 0x00 /* Turn off echo (default). */ +#define RPP_ECHO_ON 0x01 /* Leave echo on. */ +#define RPP_REQUIRE_TTY 0x02 /* Fail if there is no tty. */ +#define RPP_FORCELOWER 0x04 /* Force input to lower case. */ +#define RPP_FORCEUPPER 0x08 /* Force input to upper case. */ +#define RPP_SEVENBIT 0x10 /* Strip the high bit from input. */ +#define RPP_STDIN 0x20 /* Read from stdin, not /dev/tty */ + +char * readpassphrase(const char *, char *, size_t, int); + +#endif /* HAVE_READPASSPHRASE */ + +#endif /* !_READPASSPHRASE_H_ */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/realpath.c openssh-3.7p1/openbsd-compat/realpath.c --- ssh-openbsd-2003091600/openbsd-compat/realpath.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/realpath.c 2003-08-25 11:10:52.000000000 +1000 @@ -0,0 +1,169 @@ +/* + * Copyright (c) 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "includes.h" + +#if !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: realpath.c,v 1.10 2003/08/01 21:04:59 millert Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include + +#include +#include +#include +#include +#include + +/* + * MAXSYMLINKS + */ +#ifndef MAXSYMLINKS +#define MAXSYMLINKS 5 +#endif + +/* + * char *realpath(const char *path, char resolved_path[MAXPATHLEN]); + * + * Find the real name of path, by removing all ".", ".." and symlink + * components. Returns (resolved) on success, or (NULL) on failure, + * in which case the path which caused trouble is left in (resolved). + */ +char * +realpath(const char *path, char *resolved) +{ + struct stat sb; + int fd, n, needslash, serrno = 0; + char *p, *q, wbuf[MAXPATHLEN], start[MAXPATHLEN]; + int symlinks = 0; + + /* Save the starting point. */ + getcwd(start,MAXPATHLEN); + if ((fd = open(".", O_RDONLY)) < 0) { + (void)strlcpy(resolved, ".", MAXPATHLEN); + return (NULL); + } + close(fd); + + /* Convert "." -> "" to optimize away a needless lstat() and chdir() */ + if (path[0] == '.' && path[1] == '\0') + path = ""; + + /* + * Find the dirname and basename from the path to be resolved. + * Change directory to the dirname component. + * lstat the basename part. + * if it is a symlink, read in the value and loop. + * if it is a directory, then change to that directory. + * get the current directory name and append the basename. + */ + strlcpy(resolved, path, MAXPATHLEN); +loop: + q = strrchr(resolved, '/'); + if (q != NULL) { + p = q + 1; + if (q == resolved) + q = "/"; + else { + do { + --q; + } while (q > resolved && *q == '/'); + q[1] = '\0'; + q = resolved; + } + if (chdir(q) < 0) + goto err1; + } else + p = resolved; + + /* Deal with the last component. */ + if (*p != '\0' && lstat(p, &sb) == 0) { + if (S_ISLNK(sb.st_mode)) { + if (++symlinks > MAXSYMLINKS) { + serrno = ELOOP; + goto err1; + } + n = readlink(p, resolved, MAXPATHLEN-1); + if (n < 0) + goto err1; + resolved[n] = '\0'; + goto loop; + } + if (S_ISDIR(sb.st_mode)) { + if (chdir(p) < 0) + goto err1; + p = ""; + } + } + + /* + * Save the last component name and get the full pathname of + * the current directory. + */ + (void)strlcpy(wbuf, p, sizeof wbuf); + if (getcwd(resolved, MAXPATHLEN) == 0) + goto err1; + + /* + * Join the two strings together, ensuring that the right thing + * happens if the last component is empty, or the dirname is root. + */ + if (resolved[0] == '/' && resolved[1] == '\0') + needslash = 0; + else + needslash = 1; + + if (*wbuf) { + if (strlen(resolved) + strlen(wbuf) + needslash >= MAXPATHLEN) { + serrno = ENAMETOOLONG; + goto err1; + } + if (needslash == 0) + strlcat(resolved, "/", MAXPATHLEN); + strlcat(resolved, wbuf, MAXPATHLEN); + } + + /* Go back to where we came from. */ + if (chdir(start) < 0) { + serrno = errno; + goto err2; + } + return (resolved); + +err1: chdir(start); +err2: errno = serrno; + return (NULL); +} +#endif /* !defined(HAVE_REALPATH) || defined(BROKEN_REALPATH) */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/rresvport.c openssh-3.7p1/openbsd-compat/rresvport.c --- ssh-openbsd-2003091600/openbsd-compat/rresvport.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/rresvport.c 2003-06-03 12:12:51.000000000 +1000 @@ -0,0 +1,101 @@ +/* + * Copyright (c) 1995, 1996, 1998 Theo de Raadt. All rights reserved. + * Copyright (c) 1983, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "includes.h" + +#ifndef HAVE_RRESVPORT_AF + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: rresvport.c,v 1.6 2003/06/03 02:11:35 deraadt Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include "includes.h" + +#if 0 +int +rresvport(alport) + int *alport; +{ + return rresvport_af(alport, AF_INET); +} +#endif + +int +rresvport_af(int *alport, sa_family_t af) +{ + struct sockaddr_storage ss; + struct sockaddr *sa; + u_int16_t *portp; + int s; + socklen_t salen; + + memset(&ss, '\0', sizeof ss); + sa = (struct sockaddr *)&ss; + + switch (af) { + case AF_INET: + salen = sizeof(struct sockaddr_in); + portp = &((struct sockaddr_in *)sa)->sin_port; + break; + case AF_INET6: + salen = sizeof(struct sockaddr_in6); + portp = &((struct sockaddr_in6 *)sa)->sin6_port; + break; + default: + errno = EPFNOSUPPORT; + return (-1); + } + sa->sa_family = af; + + s = socket(af, SOCK_STREAM, 0); + if (s < 0) + return (-1); + + *portp = htons(*alport); + if (*alport < IPPORT_RESERVED - 1) { + if (bind(s, sa, salen) >= 0) + return (s); + if (errno != EADDRINUSE) { + (void)close(s); + return (-1); + } + } + + *portp = 0; + sa->sa_family = af; + if (bindresvport_sa(s, sa) == -1) { + (void)close(s); + return (-1); + } + *alport = ntohs(*portp); + return (s); +} + +#endif /* HAVE_RRESVPORT_AF */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/setenv.c openssh-3.7p1/openbsd-compat/setenv.c --- ssh-openbsd-2003091600/openbsd-compat/setenv.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/setenv.c 2003-06-03 12:12:51.000000000 +1000 @@ -0,0 +1,159 @@ +/* + * Copyright (c) 1987 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "includes.h" +#ifndef HAVE_SETENV + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: setenv.c,v 1.6 2003/06/02 20:18:38 millert Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include + +char *__findenv(const char *name, int *offset); + +/* + * __findenv -- + * Returns pointer to value associated with name, if any, else NULL. + * Sets offset to be the offset of the name/value combination in the + * environmental array, for use by setenv(3) and unsetenv(3). + * Explicitly removes '=' in argument name. + * + * This routine *should* be a static; don't use it. + */ +char * +__findenv(name, offset) + register const char *name; + int *offset; +{ + extern char **environ; + register int len, i; + register const char *np; + register char **p, *cp; + + if (name == NULL || environ == NULL) + return (NULL); + for (np = name; *np && *np != '='; ++np) + ; + len = np - name; + for (p = environ; (cp = *p) != NULL; ++p) { + for (np = name, i = len; i && *cp; i--) + if (*cp++ != *np++) + break; + if (i == 0 && *cp++ == '=') { + *offset = p - environ; + return (cp); + } + } + return (NULL); +} + +/* + * setenv -- + * Set the value of the environmental variable "name" to be + * "value". If rewrite is set, replace any current value. + */ +int +setenv(name, value, rewrite) + register const char *name; + register const char *value; + int rewrite; +{ + extern char **environ; + static int alloced; /* if allocated space before */ + register char *C; + int l_value, offset; + + if (*value == '=') /* no `=' in value */ + ++value; + l_value = strlen(value); + if ((C = __findenv(name, &offset))) { /* find if already exists */ + if (!rewrite) + return (0); + if (strlen(C) >= l_value) { /* old larger; copy over */ + while ((*C++ = *value++)) + ; + return (0); + } + } else { /* create new slot */ + register int cnt; + register char **P; + + for (P = environ, cnt = 0; *P; ++P, ++cnt); + if (alloced) { /* just increase size */ + P = (char **)realloc((void *)environ, + (size_t)(sizeof(char *) * (cnt + 2))); + if (!P) + return (-1); + environ = P; + } + else { /* get new space */ + alloced = 1; /* copy old entries into it */ + P = (char **)malloc((size_t)(sizeof(char *) * + (cnt + 2))); + if (!P) + return (-1); + memmove(P, environ, cnt * sizeof(char *)); + environ = P; + } + environ[cnt + 1] = NULL; + offset = cnt; + } + for (C = (char *)name; *C && *C != '='; ++C); /* no `=' in name */ + if (!(environ[offset] = /* name + `=' + value */ + malloc((size_t)((int)(C - name) + l_value + 2)))) + return (-1); + for (C = environ[offset]; (*C = *name++) && *C != '='; ++C) + ; + for (*C++ = '='; (*C++ = *value++); ) + ; + return (0); +} + +/* + * unsetenv(name) -- + * Delete environmental variable "name". + */ +void +unsetenv(name) + const char *name; +{ + extern char **environ; + register char **P; + int offset; + char *__findenv(); + + while (__findenv(name, &offset)) /* if set multiple times */ + for (P = &environ[offset];; ++P) + if (!(*P = *(P + 1))) + break; +} + +#endif /* HAVE_SETENV */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/setproctitle.c openssh-3.7p1/openbsd-compat/setproctitle.c --- ssh-openbsd-2003091600/openbsd-compat/setproctitle.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/setproctitle.c 2003-06-22 18:32:10.000000000 +1000 @@ -0,0 +1,157 @@ +/* Based on conf.c from UCB sendmail 8.8.8 */ + +/* + * Copyright 2003 Damien Miller + * Copyright (c) 1983, 1995-1997 Eric P. Allman + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "includes.h" + +#ifndef HAVE_SETPROCTITLE + +#include +#ifdef HAVE_SYS_PSTAT_H +#include +#endif + +#define SPT_NONE 0 /* don't use it at all */ +#define SPT_PSTAT 1 /* cover argv with title information */ +#define SPT_REUSEARGV 2 /* use pstat(PSTAT_SETCMD, ...) */ + +#ifndef SPT_TYPE +# define SPT_TYPE SPT_NONE +#endif + +#ifndef SPT_PADCHAR +# define SPT_PADCHAR '\0' +#endif + +#if SPT_TYPE == SPT_REUSEARGV +static char *argv_start = NULL; +static size_t argv_env_len = 0; +#endif + +#endif /* HAVE_SETPROCTITLE */ + +void +compat_init_setproctitle(int argc, char *argv[]) +{ +#if defined(SPT_TYPE) && SPT_TYPE == SPT_REUSEARGV + extern char **environ; + char *lastargv = NULL; + char **envp = environ; + int i; + + /* + * NB: This assumes that argv has already been copied out of the + * way. This is true for sshd, but may not be true for other + * programs. Beware. + */ + + if (argc == 0 || argv[0] == NULL) + return; + + /* Fail if we can't allocate room for the new environment */ + for (i = 0; envp[i] != NULL; i++) + ; + if ((environ = malloc(sizeof(*environ) * (i + 1))) == NULL) { + environ = envp; /* put it back */ + return; + } + + /* + * Find the last argv string or environment variable within + * our process memory area. + */ + for (i = 0; i < argc; i++) { + if (lastargv == NULL || lastargv + 1 == argv[i]) + lastargv = argv[i] + strlen(argv[i]); + } + for (i = 0; envp[i] != NULL; i++) { + if (lastargv + 1 == envp[i]) + lastargv = envp[i] + strlen(envp[i]); + } + + argv[1] = NULL; + argv_start = argv[0]; + argv_env_len = lastargv - argv[0] - 1; + + /* + * Copy environment + * XXX - will truncate env on strdup fail + */ + for (i = 0; envp[i] != NULL; i++) + environ[i] = strdup(envp[i]); + environ[i] = NULL; +#endif /* SPT_REUSEARGV */ +} + +#ifndef HAVE_SETPROCTITLE +void +setproctitle(const char *fmt, ...) +{ +#if SPT_TYPE != SPT_NONE + va_list ap; + char buf[1024]; + size_t len; + extern char *__progname; +#if SPT_TYPE == SPT_PSTAT + union pstun pst; +#endif + +#if SPT_TYPE == SPT_REUSEARGV + if (argv_env_len <= 0) + return; +#endif + + strlcpy(buf, __progname, sizeof(buf)); + + va_start(ap, fmt); + if (fmt != NULL) { + len = strlcat(buf, ": ", sizeof(buf)); + if (len < sizeof(buf)) + vsnprintf(buf + len, sizeof(buf) - len , fmt, ap); + } + va_end(ap); + +#if SPT_TYPE == SPT_PSTAT + pst.pst_command = buf; + pstat(PSTAT_SETCMD, pst, strlen(buf), 0, 0); +#elif SPT_TYPE == SPT_REUSEARGV +/* debug("setproctitle: copy \"%s\" into len %d", + buf, argv_env_len); */ + len = strlcpy(argv_start, buf, argv_env_len); + for(; len < argv_env_len; len++) + argv_start[len] = SPT_PADCHAR; +#endif + +#endif /* SPT_NONE */ +} + +#endif /* HAVE_SETPROCTITLE */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/sigact.c openssh-3.7p1/openbsd-compat/sigact.c --- ssh-openbsd-2003091600/openbsd-compat/sigact.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/sigact.c 2002-06-28 04:23:22.000000000 +1000 @@ -0,0 +1,102 @@ +/* $OpenBSD: sigaction.c,v 1.3 1999/06/27 08:14:21 millert Exp $ */ + +/**************************************************************************** + * Copyright (c) 1998 Free Software Foundation, Inc. * + * * + * Permission is hereby granted, free of charge, to any person obtaining a * + * copy of this software and associated documentation files (the * + * "Software"), to deal in the Software without restriction, including * + * without limitation the rights to use, copy, modify, merge, publish, * + * distribute, distribute with modifications, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the Software is * + * furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included * + * in all copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * + * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + * * + * Except as contained in this notice, the name(s) of the above copyright * + * holders shall not be used in advertising or otherwise to promote the * + * sale, use or other dealings in this Software without prior written * + * authorization. * + ****************************************************************************/ + +/**************************************************************************** + * Author: Zeyd M. Ben-Halim 1992,1995 * + * and: Eric S. Raymond * + ****************************************************************************/ + +#include "includes.h" +#include +#include "sigact.h" + +/* This file provides sigaction() emulation using sigvec() */ +/* Use only if this is non POSIX system */ + +#if !HAVE_SIGACTION && HAVE_SIGVEC + +int +sigaction(int sig, struct sigaction *sigact, struct sigaction *osigact) +{ + return sigvec(sig, &(sigact->sv), &(osigact->sv)); +} + +int +sigemptyset (sigset_t * mask) +{ + *mask = 0; + return 0; +} + +int +sigprocmask (int mode, sigset_t * mask, sigset_t * omask) +{ + sigset_t current = sigsetmask(0); + + if (omask) *omask = current; + + if (mode==SIG_BLOCK) + current |= *mask; + else if (mode==SIG_UNBLOCK) + current &= ~*mask; + else if (mode==SIG_SETMASK) + current = *mask; + + sigsetmask(current); + return 0; +} + +int +sigsuspend (sigset_t * mask) +{ + return sigpause(*mask); +} + +int +sigdelset (sigset_t * mask, int sig) +{ + *mask &= ~sigmask(sig); + return 0; +} + +int +sigaddset (sigset_t * mask, int sig) +{ + *mask |= sigmask(sig); + return 0; +} + +int +sigismember (sigset_t * mask, int sig) +{ + return (*mask & sigmask(sig)) != 0; +} + +#endif diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/sigact.h openssh-3.7p1/openbsd-compat/sigact.h --- ssh-openbsd-2003091600/openbsd-compat/sigact.h 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/sigact.h 2001-02-24 11:24:20.000000000 +1100 @@ -0,0 +1,88 @@ +/* $OpenBSD: SigAction.h,v 1.2 1999/06/27 08:15:19 millert Exp $ */ + +/**************************************************************************** + * Copyright (c) 1998 Free Software Foundation, Inc. * + * * + * Permission is hereby granted, free of charge, to any person obtaining a * + * copy of this software and associated documentation files (the * + * "Software"), to deal in the Software without restriction, including * + * without limitation the rights to use, copy, modify, merge, publish, * + * distribute, distribute with modifications, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the Software is * + * furnished to do so, subject to the following conditions: * + * * + * The above copyright notice and this permission notice shall be included * + * in all copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * + * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + * * + * Except as contained in this notice, the name(s) of the above copyright * + * holders shall not be used in advertising or otherwise to promote the * + * sale, use or other dealings in this Software without prior written * + * authorization. * + ****************************************************************************/ + +/**************************************************************************** + * Author: Zeyd M. Ben-Halim 1992,1995 * + * and: Eric S. Raymond * + ****************************************************************************/ + +/* + * $From: SigAction.h,v 1.5 1999/06/19 23:00:54 tom Exp $ + * + * This file exists to handle non-POSIX systems which don't have , + * and usually no sigaction() nor + */ + +#ifndef _SIGACTION_H +#define _SIGACTION_H + +#if !defined(HAVE_SIGACTION) && defined(HAVE_SIGVEC) + +#undef SIG_BLOCK +#define SIG_BLOCK 00 + +#undef SIG_UNBLOCK +#define SIG_UNBLOCK 01 + +#undef SIG_SETMASK +#define SIG_SETMASK 02 + +/* + * is in the Linux 1.2.8 + gcc 2.7.0 configuration, + * and is useful for testing this header file. + */ +#if HAVE_BSD_SIGNAL_H +# include +#endif + +struct sigaction +{ + struct sigvec sv; +}; + +typedef unsigned long sigset_t; + +#undef sa_mask +#define sa_mask sv.sv_mask +#undef sa_handler +#define sa_handler sv.sv_handler +#undef sa_flags +#define sa_flags sv.sv_flags + +int sigaction(int sig, struct sigaction *sigact, struct sigaction *osigact); +int sigprocmask (int how, sigset_t *mask, sigset_t *omask); +int sigemptyset (sigset_t *mask); +int sigsuspend (sigset_t *mask); +int sigdelset (sigset_t *mask, int sig); +int sigaddset (sigset_t *mask, int sig); + +#endif /* !defined(HAVE_SIGACTION) && defined(HAVE_SIGVEC) */ + +#endif /* !defined(_SIGACTION_H) */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/strlcat.c openssh-3.7p1/openbsd-compat/strlcat.c --- ssh-openbsd-2003091600/openbsd-compat/strlcat.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/strlcat.c 2003-09-02 23:33:43.000000000 +1000 @@ -0,0 +1,64 @@ +/* $OpenBSD: strlcat.c,v 1.11 2003/06/17 21:56:24 millert Exp $ */ + +/* + * Copyright (c) 1998 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" +#ifndef HAVE_STRLCAT + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: strlcat.c,v 1.11 2003/06/17 21:56:24 millert Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include + +/* + * Appends src to string dst of size siz (unlike strncat, siz is the + * full size of dst, not space left). At most siz-1 characters + * will be copied. Always NUL terminates (unless siz <= strlen(dst)). + * Returns strlen(src) + MIN(siz, strlen(initial dst)). + * If retval >= siz, truncation occurred. + */ +size_t +strlcat(char *dst, const char *src, size_t siz) +{ + register char *d = dst; + register const char *s = src; + register size_t n = siz; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end */ + while (n-- != 0 && *d != '\0') + d++; + dlen = d - dst; + n = siz - dlen; + + if (n == 0) + return(dlen + strlen(s)); + while (*s != '\0') { + if (n != 1) { + *d++ = *s; + n--; + } + s++; + } + *d = '\0'; + + return(dlen + (s - src)); /* count does not include NUL */ +} + +#endif /* !HAVE_STRLCAT */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/strlcpy.c openssh-3.7p1/openbsd-compat/strlcpy.c --- ssh-openbsd-2003091600/openbsd-compat/strlcpy.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/strlcpy.c 2003-09-02 23:33:43.000000000 +1000 @@ -0,0 +1,60 @@ +/* $OpenBSD: strlcpy.c,v 1.8 2003/06/17 21:56:24 millert Exp $ */ + +/* + * Copyright (c) 1998 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" +#ifndef HAVE_STRLCPY + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: strlcpy.c,v 1.8 2003/06/17 21:56:24 millert Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include + +/* + * Copy src to string dst of size siz. At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ +size_t +strlcpy(char *dst, const char *src, size_t siz) +{ + register char *d = dst; + register const char *s = src; + register size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0 && --n != 0) { + do { + if ((*d++ = *s++) == 0) + break; + } while (--n != 0); + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} + +#endif /* !HAVE_STRLCPY */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/strmode.c openssh-3.7p1/openbsd-compat/strmode.c --- ssh-openbsd-2003091600/openbsd-compat/strmode.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/strmode.c 2003-08-25 11:10:52.000000000 +1000 @@ -0,0 +1,154 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "includes.h" +#ifndef HAVE_STRMODE + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: strmode.c,v 1.5 2003/06/11 21:08:16 deraadt Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include + +/* XXX mode should be mode_t */ + +void +strmode(int mode, char *p) +{ + /* print type */ + switch (mode & S_IFMT) { + case S_IFDIR: /* directory */ + *p++ = 'd'; + break; + case S_IFCHR: /* character special */ + *p++ = 'c'; + break; + case S_IFBLK: /* block special */ + *p++ = 'b'; + break; + case S_IFREG: /* regular */ + *p++ = '-'; + break; + case S_IFLNK: /* symbolic link */ + *p++ = 'l'; + break; +#ifdef S_IFSOCK + case S_IFSOCK: /* socket */ + *p++ = 's'; + break; +#endif +#ifdef S_IFIFO + case S_IFIFO: /* fifo */ + *p++ = 'p'; + break; +#endif +#ifdef S_IFWHT + case S_IFWHT: /* whiteout */ + *p++ = 'w'; + break; +#endif + default: /* unknown */ + *p++ = '?'; + break; + } + /* usr */ + if (mode & S_IRUSR) + *p++ = 'r'; + else + *p++ = '-'; + if (mode & S_IWUSR) + *p++ = 'w'; + else + *p++ = '-'; + switch (mode & (S_IXUSR | S_ISUID)) { + case 0: + *p++ = '-'; + break; + case S_IXUSR: + *p++ = 'x'; + break; + case S_ISUID: + *p++ = 'S'; + break; + case S_IXUSR | S_ISUID: + *p++ = 's'; + break; + } + /* group */ + if (mode & S_IRGRP) + *p++ = 'r'; + else + *p++ = '-'; + if (mode & S_IWGRP) + *p++ = 'w'; + else + *p++ = '-'; + switch (mode & (S_IXGRP | S_ISGID)) { + case 0: + *p++ = '-'; + break; + case S_IXGRP: + *p++ = 'x'; + break; + case S_ISGID: + *p++ = 'S'; + break; + case S_IXGRP | S_ISGID: + *p++ = 's'; + break; + } + /* other */ + if (mode & S_IROTH) + *p++ = 'r'; + else + *p++ = '-'; + if (mode & S_IWOTH) + *p++ = 'w'; + else + *p++ = '-'; + switch (mode & (S_IXOTH | S_ISVTX)) { + case 0: + *p++ = '-'; + break; + case S_IXOTH: + *p++ = 'x'; + break; + case S_ISVTX: + *p++ = 'T'; + break; + case S_IXOTH | S_ISVTX: + *p++ = 't'; + break; + } + *p++ = ' '; /* will be a '+' if ACL's implemented */ + *p = '\0'; +} +#endif diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/strsep.c openssh-3.7p1/openbsd-compat/strsep.c --- ssh-openbsd-2003091600/openbsd-compat/strsep.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/strsep.c 2003-08-25 11:10:52.000000000 +1000 @@ -0,0 +1,85 @@ +/* $OpenBSD: strsep.c,v 1.5 2003/06/11 21:08:16 deraadt Exp $ */ + +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "includes.h" + +#if !defined(HAVE_STRSEP) + +#include +#include + +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)strsep.c 8.1 (Berkeley) 6/4/93"; +#else +static char *rcsid = "$OpenBSD: strsep.c,v 1.5 2003/06/11 21:08:16 deraadt Exp $"; +#endif +#endif /* LIBC_SCCS and not lint */ + +/* + * Get next token from string *stringp, where tokens are possibly-empty + * strings separated by characters from delim. + * + * Writes NULs into the string at *stringp to end tokens. + * delim need not remain constant from call to call. + * On return, *stringp points past the last NUL written (if there might + * be further tokens), or is NULL (if there are definitely no more tokens). + * + * If *stringp is NULL, strsep returns NULL. + */ +char * +strsep(char **stringp, const char *delim) +{ + char *s; + const char *spanp; + int c, sc; + char *tok; + + if ((s = *stringp) == NULL) + return (NULL); + for (tok = s;;) { + c = *s++; + spanp = delim; + do { + if ((sc = *spanp++) == c) { + if (c == 0) + s = NULL; + else + s[-1] = 0; + *stringp = s; + return (tok); + } + } while (sc != 0); + } + /* NOTREACHED */ +} + +#endif /* !defined(HAVE_STRSEP) */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/sys-queue.h openssh-3.7p1/openbsd-compat/sys-queue.h --- ssh-openbsd-2003091600/openbsd-compat/sys-queue.h 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/sys-queue.h 2003-06-03 12:12:51.000000000 +1000 @@ -0,0 +1,580 @@ +/* $OpenBSD: queue.h,v 1.23 2003/06/02 23:28:21 millert Exp $ */ +/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */ + +/* + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)queue.h 8.5 (Berkeley) 8/20/94 + */ + +#ifndef _FAKE_QUEUE_H_ +#define _FAKE_QUEUE_H_ + +/* + * Ignore all since older platforms have broken/incomplete + * that are too hard to work around. + */ +#undef SLIST_HEAD +#undef SLIST_HEAD_INITIALIZER +#undef SLIST_ENTRY +#undef SLIST_FIRST +#undef SLIST_END +#undef SLIST_EMPTY +#undef SLIST_NEXT +#undef SLIST_FOREACH +#undef SLIST_INIT +#undef SLIST_INSERT_AFTER +#undef SLIST_INSERT_HEAD +#undef SLIST_REMOVE_HEAD +#undef SLIST_REMOVE +#undef LIST_HEAD +#undef LIST_HEAD_INITIALIZER +#undef LIST_ENTRY +#undef LIST_FIRST +#undef LIST_END +#undef LIST_EMPTY +#undef LIST_NEXT +#undef LIST_FOREACH +#undef LIST_INIT +#undef LIST_INSERT_AFTER +#undef LIST_INSERT_BEFORE +#undef LIST_INSERT_HEAD +#undef LIST_REMOVE +#undef LIST_REPLACE +#undef SIMPLEQ_HEAD +#undef SIMPLEQ_HEAD_INITIALIZER +#undef SIMPLEQ_ENTRY +#undef SIMPLEQ_FIRST +#undef SIMPLEQ_END +#undef SIMPLEQ_EMPTY +#undef SIMPLEQ_NEXT +#undef SIMPLEQ_FOREACH +#undef SIMPLEQ_INIT +#undef SIMPLEQ_INSERT_HEAD +#undef SIMPLEQ_INSERT_TAIL +#undef SIMPLEQ_INSERT_AFTER +#undef SIMPLEQ_REMOVE_HEAD +#undef TAILQ_HEAD +#undef TAILQ_HEAD_INITIALIZER +#undef TAILQ_ENTRY +#undef TAILQ_FIRST +#undef TAILQ_END +#undef TAILQ_NEXT +#undef TAILQ_LAST +#undef TAILQ_PREV +#undef TAILQ_EMPTY +#undef TAILQ_FOREACH +#undef TAILQ_FOREACH_REVERSE +#undef TAILQ_INIT +#undef TAILQ_INSERT_HEAD +#undef TAILQ_INSERT_TAIL +#undef TAILQ_INSERT_AFTER +#undef TAILQ_INSERT_BEFORE +#undef TAILQ_REMOVE +#undef TAILQ_REPLACE +#undef CIRCLEQ_HEAD +#undef CIRCLEQ_HEAD_INITIALIZER +#undef CIRCLEQ_ENTRY +#undef CIRCLEQ_FIRST +#undef CIRCLEQ_LAST +#undef CIRCLEQ_END +#undef CIRCLEQ_NEXT +#undef CIRCLEQ_PREV +#undef CIRCLEQ_EMPTY +#undef CIRCLEQ_FOREACH +#undef CIRCLEQ_FOREACH_REVERSE +#undef CIRCLEQ_INIT +#undef CIRCLEQ_INSERT_AFTER +#undef CIRCLEQ_INSERT_BEFORE +#undef CIRCLEQ_INSERT_HEAD +#undef CIRCLEQ_INSERT_TAIL +#undef CIRCLEQ_REMOVE +#undef CIRCLEQ_REPLACE + +/* + * This file defines five types of data structures: singly-linked lists, + * lists, simple queues, tail queues, and circular queues. + * + * + * A singly-linked list is headed by a single forward pointer. The elements + * are singly linked for minimum space and pointer manipulation overhead at + * the expense of O(n) removal for arbitrary elements. New elements can be + * added to the list after an existing element or at the head of the list. + * Elements being removed from the head of the list should use the explicit + * macro for this purpose for optimum efficiency. A singly-linked list may + * only be traversed in the forward direction. Singly-linked lists are ideal + * for applications with large datasets and few or no removals or for + * implementing a LIFO queue. + * + * A list is headed by a single forward pointer (or an array of forward + * pointers for a hash table header). The elements are doubly linked + * so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before + * or after an existing element or at the head of the list. A list + * may only be traversed in the forward direction. + * + * A simple queue is headed by a pair of pointers, one the head of the + * list and the other to the tail of the list. The elements are singly + * linked to save space, so elements can only be removed from the + * head of the list. New elements can be added to the list before or after + * an existing element, at the head of the list, or at the end of the + * list. A simple queue may only be traversed in the forward direction. + * + * A tail queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before or + * after an existing element, at the head of the list, or at the end of + * the list. A tail queue may be traversed in either direction. + * + * A circle queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before or after + * an existing element, at the head of the list, or at the end of the list. + * A circle queue may be traversed in either direction, but has a more + * complex end of list detection. + * + * For details on the use of these macros, see the queue(3) manual page. + */ + +/* + * Singly-linked List definitions. + */ +#define SLIST_HEAD(name, type) \ +struct name { \ + struct type *slh_first; /* first element */ \ +} + +#define SLIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define SLIST_ENTRY(type) \ +struct { \ + struct type *sle_next; /* next element */ \ +} + +/* + * Singly-linked List access methods. + */ +#define SLIST_FIRST(head) ((head)->slh_first) +#define SLIST_END(head) NULL +#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head)) +#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) + +#define SLIST_FOREACH(var, head, field) \ + for((var) = SLIST_FIRST(head); \ + (var) != SLIST_END(head); \ + (var) = SLIST_NEXT(var, field)) + +/* + * Singly-linked List functions. + */ +#define SLIST_INIT(head) { \ + SLIST_FIRST(head) = SLIST_END(head); \ +} + +#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ + (elm)->field.sle_next = (slistelm)->field.sle_next; \ + (slistelm)->field.sle_next = (elm); \ +} while (0) + +#define SLIST_INSERT_HEAD(head, elm, field) do { \ + (elm)->field.sle_next = (head)->slh_first; \ + (head)->slh_first = (elm); \ +} while (0) + +#define SLIST_REMOVE_HEAD(head, field) do { \ + (head)->slh_first = (head)->slh_first->field.sle_next; \ +} while (0) + +#define SLIST_REMOVE(head, elm, type, field) do { \ + if ((head)->slh_first == (elm)) { \ + SLIST_REMOVE_HEAD((head), field); \ + } \ + else { \ + struct type *curelm = (head)->slh_first; \ + while( curelm->field.sle_next != (elm) ) \ + curelm = curelm->field.sle_next; \ + curelm->field.sle_next = \ + curelm->field.sle_next->field.sle_next; \ + } \ +} while (0) + +/* + * List definitions. + */ +#define LIST_HEAD(name, type) \ +struct name { \ + struct type *lh_first; /* first element */ \ +} + +#define LIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define LIST_ENTRY(type) \ +struct { \ + struct type *le_next; /* next element */ \ + struct type **le_prev; /* address of previous next element */ \ +} + +/* + * List access methods + */ +#define LIST_FIRST(head) ((head)->lh_first) +#define LIST_END(head) NULL +#define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head)) +#define LIST_NEXT(elm, field) ((elm)->field.le_next) + +#define LIST_FOREACH(var, head, field) \ + for((var) = LIST_FIRST(head); \ + (var)!= LIST_END(head); \ + (var) = LIST_NEXT(var, field)) + +/* + * List functions. + */ +#define LIST_INIT(head) do { \ + LIST_FIRST(head) = LIST_END(head); \ +} while (0) + +#define LIST_INSERT_AFTER(listelm, elm, field) do { \ + if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \ + (listelm)->field.le_next->field.le_prev = \ + &(elm)->field.le_next; \ + (listelm)->field.le_next = (elm); \ + (elm)->field.le_prev = &(listelm)->field.le_next; \ +} while (0) + +#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ + (elm)->field.le_prev = (listelm)->field.le_prev; \ + (elm)->field.le_next = (listelm); \ + *(listelm)->field.le_prev = (elm); \ + (listelm)->field.le_prev = &(elm)->field.le_next; \ +} while (0) + +#define LIST_INSERT_HEAD(head, elm, field) do { \ + if (((elm)->field.le_next = (head)->lh_first) != NULL) \ + (head)->lh_first->field.le_prev = &(elm)->field.le_next;\ + (head)->lh_first = (elm); \ + (elm)->field.le_prev = &(head)->lh_first; \ +} while (0) + +#define LIST_REMOVE(elm, field) do { \ + if ((elm)->field.le_next != NULL) \ + (elm)->field.le_next->field.le_prev = \ + (elm)->field.le_prev; \ + *(elm)->field.le_prev = (elm)->field.le_next; \ +} while (0) + +#define LIST_REPLACE(elm, elm2, field) do { \ + if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \ + (elm2)->field.le_next->field.le_prev = \ + &(elm2)->field.le_next; \ + (elm2)->field.le_prev = (elm)->field.le_prev; \ + *(elm2)->field.le_prev = (elm2); \ +} while (0) + +/* + * Simple queue definitions. + */ +#define SIMPLEQ_HEAD(name, type) \ +struct name { \ + struct type *sqh_first; /* first element */ \ + struct type **sqh_last; /* addr of last next element */ \ +} + +#define SIMPLEQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).sqh_first } + +#define SIMPLEQ_ENTRY(type) \ +struct { \ + struct type *sqe_next; /* next element */ \ +} + +/* + * Simple queue access methods. + */ +#define SIMPLEQ_FIRST(head) ((head)->sqh_first) +#define SIMPLEQ_END(head) NULL +#define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head)) +#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next) + +#define SIMPLEQ_FOREACH(var, head, field) \ + for((var) = SIMPLEQ_FIRST(head); \ + (var) != SIMPLEQ_END(head); \ + (var) = SIMPLEQ_NEXT(var, field)) + +/* + * Simple queue functions. + */ +#define SIMPLEQ_INIT(head) do { \ + (head)->sqh_first = NULL; \ + (head)->sqh_last = &(head)->sqh_first; \ +} while (0) + +#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \ + if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \ + (head)->sqh_last = &(elm)->field.sqe_next; \ + (head)->sqh_first = (elm); \ +} while (0) + +#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.sqe_next = NULL; \ + *(head)->sqh_last = (elm); \ + (head)->sqh_last = &(elm)->field.sqe_next; \ +} while (0) + +#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ + if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\ + (head)->sqh_last = &(elm)->field.sqe_next; \ + (listelm)->field.sqe_next = (elm); \ +} while (0) + +#define SIMPLEQ_REMOVE_HEAD(head, elm, field) do { \ + if (((head)->sqh_first = (elm)->field.sqe_next) == NULL) \ + (head)->sqh_last = &(head)->sqh_first; \ +} while (0) + +/* + * Tail queue definitions. + */ +#define TAILQ_HEAD(name, type) \ +struct name { \ + struct type *tqh_first; /* first element */ \ + struct type **tqh_last; /* addr of last next element */ \ +} + +#define TAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).tqh_first } + +#define TAILQ_ENTRY(type) \ +struct { \ + struct type *tqe_next; /* next element */ \ + struct type **tqe_prev; /* address of previous next element */ \ +} + +/* + * tail queue access methods + */ +#define TAILQ_FIRST(head) ((head)->tqh_first) +#define TAILQ_END(head) NULL +#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) +#define TAILQ_LAST(head, headname) \ + (*(((struct headname *)((head)->tqh_last))->tqh_last)) +/* XXX */ +#define TAILQ_PREV(elm, headname, field) \ + (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) +#define TAILQ_EMPTY(head) \ + (TAILQ_FIRST(head) == TAILQ_END(head)) + +#define TAILQ_FOREACH(var, head, field) \ + for((var) = TAILQ_FIRST(head); \ + (var) != TAILQ_END(head); \ + (var) = TAILQ_NEXT(var, field)) + +#define TAILQ_FOREACH_REVERSE(var, head, field, headname) \ + for((var) = TAILQ_LAST(head, headname); \ + (var) != TAILQ_END(head); \ + (var) = TAILQ_PREV(var, headname, field)) + +/* + * Tail queue functions. + */ +#define TAILQ_INIT(head) do { \ + (head)->tqh_first = NULL; \ + (head)->tqh_last = &(head)->tqh_first; \ +} while (0) + +#define TAILQ_INSERT_HEAD(head, elm, field) do { \ + if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ + (head)->tqh_first->field.tqe_prev = \ + &(elm)->field.tqe_next; \ + else \ + (head)->tqh_last = &(elm)->field.tqe_next; \ + (head)->tqh_first = (elm); \ + (elm)->field.tqe_prev = &(head)->tqh_first; \ +} while (0) + +#define TAILQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.tqe_next = NULL; \ + (elm)->field.tqe_prev = (head)->tqh_last; \ + *(head)->tqh_last = (elm); \ + (head)->tqh_last = &(elm)->field.tqe_next; \ +} while (0) + +#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ + if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\ + (elm)->field.tqe_next->field.tqe_prev = \ + &(elm)->field.tqe_next; \ + else \ + (head)->tqh_last = &(elm)->field.tqe_next; \ + (listelm)->field.tqe_next = (elm); \ + (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \ +} while (0) + +#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ + (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ + (elm)->field.tqe_next = (listelm); \ + *(listelm)->field.tqe_prev = (elm); \ + (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ +} while (0) + +#define TAILQ_REMOVE(head, elm, field) do { \ + if (((elm)->field.tqe_next) != NULL) \ + (elm)->field.tqe_next->field.tqe_prev = \ + (elm)->field.tqe_prev; \ + else \ + (head)->tqh_last = (elm)->field.tqe_prev; \ + *(elm)->field.tqe_prev = (elm)->field.tqe_next; \ +} while (0) + +#define TAILQ_REPLACE(head, elm, elm2, field) do { \ + if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \ + (elm2)->field.tqe_next->field.tqe_prev = \ + &(elm2)->field.tqe_next; \ + else \ + (head)->tqh_last = &(elm2)->field.tqe_next; \ + (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \ + *(elm2)->field.tqe_prev = (elm2); \ +} while (0) + +/* + * Circular queue definitions. + */ +#define CIRCLEQ_HEAD(name, type) \ +struct name { \ + struct type *cqh_first; /* first element */ \ + struct type *cqh_last; /* last element */ \ +} + +#define CIRCLEQ_HEAD_INITIALIZER(head) \ + { CIRCLEQ_END(&head), CIRCLEQ_END(&head) } + +#define CIRCLEQ_ENTRY(type) \ +struct { \ + struct type *cqe_next; /* next element */ \ + struct type *cqe_prev; /* previous element */ \ +} + +/* + * Circular queue access methods + */ +#define CIRCLEQ_FIRST(head) ((head)->cqh_first) +#define CIRCLEQ_LAST(head) ((head)->cqh_last) +#define CIRCLEQ_END(head) ((void *)(head)) +#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next) +#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev) +#define CIRCLEQ_EMPTY(head) \ + (CIRCLEQ_FIRST(head) == CIRCLEQ_END(head)) + +#define CIRCLEQ_FOREACH(var, head, field) \ + for((var) = CIRCLEQ_FIRST(head); \ + (var) != CIRCLEQ_END(head); \ + (var) = CIRCLEQ_NEXT(var, field)) + +#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \ + for((var) = CIRCLEQ_LAST(head); \ + (var) != CIRCLEQ_END(head); \ + (var) = CIRCLEQ_PREV(var, field)) + +/* + * Circular queue functions. + */ +#define CIRCLEQ_INIT(head) do { \ + (head)->cqh_first = CIRCLEQ_END(head); \ + (head)->cqh_last = CIRCLEQ_END(head); \ +} while (0) + +#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ + (elm)->field.cqe_next = (listelm)->field.cqe_next; \ + (elm)->field.cqe_prev = (listelm); \ + if ((listelm)->field.cqe_next == CIRCLEQ_END(head)) \ + (head)->cqh_last = (elm); \ + else \ + (listelm)->field.cqe_next->field.cqe_prev = (elm); \ + (listelm)->field.cqe_next = (elm); \ +} while (0) + +#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \ + (elm)->field.cqe_next = (listelm); \ + (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \ + if ((listelm)->field.cqe_prev == CIRCLEQ_END(head)) \ + (head)->cqh_first = (elm); \ + else \ + (listelm)->field.cqe_prev->field.cqe_next = (elm); \ + (listelm)->field.cqe_prev = (elm); \ +} while (0) + +#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \ + (elm)->field.cqe_next = (head)->cqh_first; \ + (elm)->field.cqe_prev = CIRCLEQ_END(head); \ + if ((head)->cqh_last == CIRCLEQ_END(head)) \ + (head)->cqh_last = (elm); \ + else \ + (head)->cqh_first->field.cqe_prev = (elm); \ + (head)->cqh_first = (elm); \ +} while (0) + +#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.cqe_next = CIRCLEQ_END(head); \ + (elm)->field.cqe_prev = (head)->cqh_last; \ + if ((head)->cqh_first == CIRCLEQ_END(head)) \ + (head)->cqh_first = (elm); \ + else \ + (head)->cqh_last->field.cqe_next = (elm); \ + (head)->cqh_last = (elm); \ +} while (0) + +#define CIRCLEQ_REMOVE(head, elm, field) do { \ + if ((elm)->field.cqe_next == CIRCLEQ_END(head)) \ + (head)->cqh_last = (elm)->field.cqe_prev; \ + else \ + (elm)->field.cqe_next->field.cqe_prev = \ + (elm)->field.cqe_prev; \ + if ((elm)->field.cqe_prev == CIRCLEQ_END(head)) \ + (head)->cqh_first = (elm)->field.cqe_next; \ + else \ + (elm)->field.cqe_prev->field.cqe_next = \ + (elm)->field.cqe_next; \ +} while (0) + +#define CIRCLEQ_REPLACE(head, elm, elm2, field) do { \ + if (((elm2)->field.cqe_next = (elm)->field.cqe_next) == \ + CIRCLEQ_END(head)) \ + (head).cqh_last = (elm2); \ + else \ + (elm2)->field.cqe_next->field.cqe_prev = (elm2); \ + if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) == \ + CIRCLEQ_END(head)) \ + (head).cqh_first = (elm2); \ + else \ + (elm2)->field.cqe_prev->field.cqe_next = (elm2); \ +} while (0) + +#endif /* !_FAKE_QUEUE_H_ */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/sys-tree.h openssh-3.7p1/openbsd-compat/sys-tree.h --- ssh-openbsd-2003091600/openbsd-compat/sys-tree.h 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/sys-tree.h 2003-01-08 11:16:48.000000000 +1100 @@ -0,0 +1,677 @@ +/* $OpenBSD: tree.h,v 1.7 2002/10/17 21:51:54 art Exp $ */ +/* + * Copyright 2002 Niels Provos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SYS_TREE_H_ +#define _SYS_TREE_H_ + +/* + * This file defines data structures for different types of trees: + * splay trees and red-black trees. + * + * A splay tree is a self-organizing data structure. Every operation + * on the tree causes a splay to happen. The splay moves the requested + * node to the root of the tree and partly rebalances it. + * + * This has the benefit that request locality causes faster lookups as + * the requested nodes move to the top of the tree. On the other hand, + * every lookup causes memory writes. + * + * The Balance Theorem bounds the total access time for m operations + * and n inserts on an initially empty tree as O((m + n)lg n). The + * amortized cost for a sequence of m accesses to a splay tree is O(lg n); + * + * A red-black tree is a binary search tree with the node color as an + * extra attribute. It fulfills a set of conditions: + * - every search path from the root to a leaf consists of the + * same number of black nodes, + * - each red node (except for the root) has a black parent, + * - each leaf node is black. + * + * Every operation on a red-black tree is bounded as O(lg n). + * The maximum height of a red-black tree is 2lg (n+1). + */ + +#define SPLAY_HEAD(name, type) \ +struct name { \ + struct type *sph_root; /* root of the tree */ \ +} + +#define SPLAY_INITIALIZER(root) \ + { NULL } + +#define SPLAY_INIT(root) do { \ + (root)->sph_root = NULL; \ +} while (0) + +#define SPLAY_ENTRY(type) \ +struct { \ + struct type *spe_left; /* left element */ \ + struct type *spe_right; /* right element */ \ +} + +#define SPLAY_LEFT(elm, field) (elm)->field.spe_left +#define SPLAY_RIGHT(elm, field) (elm)->field.spe_right +#define SPLAY_ROOT(head) (head)->sph_root +#define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL) + +/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */ +#define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \ + SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \ + SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ + (head)->sph_root = tmp; \ +} while (0) + +#define SPLAY_ROTATE_LEFT(head, tmp, field) do { \ + SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \ + SPLAY_LEFT(tmp, field) = (head)->sph_root; \ + (head)->sph_root = tmp; \ +} while (0) + +#define SPLAY_LINKLEFT(head, tmp, field) do { \ + SPLAY_LEFT(tmp, field) = (head)->sph_root; \ + tmp = (head)->sph_root; \ + (head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \ +} while (0) + +#define SPLAY_LINKRIGHT(head, tmp, field) do { \ + SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ + tmp = (head)->sph_root; \ + (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \ +} while (0) + +#define SPLAY_ASSEMBLE(head, node, left, right, field) do { \ + SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \ + SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\ + SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \ + SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \ +} while (0) + +/* Generates prototypes and inline functions */ + +#define SPLAY_PROTOTYPE(name, type, field, cmp) \ +void name##_SPLAY(struct name *, struct type *); \ +void name##_SPLAY_MINMAX(struct name *, int); \ +struct type *name##_SPLAY_INSERT(struct name *, struct type *); \ +struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \ + \ +/* Finds the node with the same key as elm */ \ +static __inline struct type * \ +name##_SPLAY_FIND(struct name *head, struct type *elm) \ +{ \ + if (SPLAY_EMPTY(head)) \ + return(NULL); \ + name##_SPLAY(head, elm); \ + if ((cmp)(elm, (head)->sph_root) == 0) \ + return (head->sph_root); \ + return (NULL); \ +} \ + \ +static __inline struct type * \ +name##_SPLAY_NEXT(struct name *head, struct type *elm) \ +{ \ + name##_SPLAY(head, elm); \ + if (SPLAY_RIGHT(elm, field) != NULL) { \ + elm = SPLAY_RIGHT(elm, field); \ + while (SPLAY_LEFT(elm, field) != NULL) { \ + elm = SPLAY_LEFT(elm, field); \ + } \ + } else \ + elm = NULL; \ + return (elm); \ +} \ + \ +static __inline struct type * \ +name##_SPLAY_MIN_MAX(struct name *head, int val) \ +{ \ + name##_SPLAY_MINMAX(head, val); \ + return (SPLAY_ROOT(head)); \ +} + +/* Main splay operation. + * Moves node close to the key of elm to top + */ +#define SPLAY_GENERATE(name, type, field, cmp) \ +struct type * \ +name##_SPLAY_INSERT(struct name *head, struct type *elm) \ +{ \ + if (SPLAY_EMPTY(head)) { \ + SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \ + } else { \ + int __comp; \ + name##_SPLAY(head, elm); \ + __comp = (cmp)(elm, (head)->sph_root); \ + if(__comp < 0) { \ + SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\ + SPLAY_RIGHT(elm, field) = (head)->sph_root; \ + SPLAY_LEFT((head)->sph_root, field) = NULL; \ + } else if (__comp > 0) { \ + SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\ + SPLAY_LEFT(elm, field) = (head)->sph_root; \ + SPLAY_RIGHT((head)->sph_root, field) = NULL; \ + } else \ + return ((head)->sph_root); \ + } \ + (head)->sph_root = (elm); \ + return (NULL); \ +} \ + \ +struct type * \ +name##_SPLAY_REMOVE(struct name *head, struct type *elm) \ +{ \ + struct type *__tmp; \ + if (SPLAY_EMPTY(head)) \ + return (NULL); \ + name##_SPLAY(head, elm); \ + if ((cmp)(elm, (head)->sph_root) == 0) { \ + if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \ + (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\ + } else { \ + __tmp = SPLAY_RIGHT((head)->sph_root, field); \ + (head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\ + name##_SPLAY(head, elm); \ + SPLAY_RIGHT((head)->sph_root, field) = __tmp; \ + } \ + return (elm); \ + } \ + return (NULL); \ +} \ + \ +void \ +name##_SPLAY(struct name *head, struct type *elm) \ +{ \ + struct type __node, *__left, *__right, *__tmp; \ + int __comp; \ +\ + SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\ + __left = __right = &__node; \ +\ + while ((__comp = (cmp)(elm, (head)->sph_root))) { \ + if (__comp < 0) { \ + __tmp = SPLAY_LEFT((head)->sph_root, field); \ + if (__tmp == NULL) \ + break; \ + if ((cmp)(elm, __tmp) < 0){ \ + SPLAY_ROTATE_RIGHT(head, __tmp, field); \ + if (SPLAY_LEFT((head)->sph_root, field) == NULL)\ + break; \ + } \ + SPLAY_LINKLEFT(head, __right, field); \ + } else if (__comp > 0) { \ + __tmp = SPLAY_RIGHT((head)->sph_root, field); \ + if (__tmp == NULL) \ + break; \ + if ((cmp)(elm, __tmp) > 0){ \ + SPLAY_ROTATE_LEFT(head, __tmp, field); \ + if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\ + break; \ + } \ + SPLAY_LINKRIGHT(head, __left, field); \ + } \ + } \ + SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ +} \ + \ +/* Splay with either the minimum or the maximum element \ + * Used to find minimum or maximum element in tree. \ + */ \ +void name##_SPLAY_MINMAX(struct name *head, int __comp) \ +{ \ + struct type __node, *__left, *__right, *__tmp; \ +\ + SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\ + __left = __right = &__node; \ +\ + while (1) { \ + if (__comp < 0) { \ + __tmp = SPLAY_LEFT((head)->sph_root, field); \ + if (__tmp == NULL) \ + break; \ + if (__comp < 0){ \ + SPLAY_ROTATE_RIGHT(head, __tmp, field); \ + if (SPLAY_LEFT((head)->sph_root, field) == NULL)\ + break; \ + } \ + SPLAY_LINKLEFT(head, __right, field); \ + } else if (__comp > 0) { \ + __tmp = SPLAY_RIGHT((head)->sph_root, field); \ + if (__tmp == NULL) \ + break; \ + if (__comp > 0) { \ + SPLAY_ROTATE_LEFT(head, __tmp, field); \ + if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\ + break; \ + } \ + SPLAY_LINKRIGHT(head, __left, field); \ + } \ + } \ + SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ +} + +#define SPLAY_NEGINF -1 +#define SPLAY_INF 1 + +#define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y) +#define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y) +#define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y) +#define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y) +#define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \ + : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF)) +#define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \ + : name##_SPLAY_MIN_MAX(x, SPLAY_INF)) + +#define SPLAY_FOREACH(x, name, head) \ + for ((x) = SPLAY_MIN(name, head); \ + (x) != NULL; \ + (x) = SPLAY_NEXT(name, head, x)) + +/* Macros that define a red-back tree */ +#define RB_HEAD(name, type) \ +struct name { \ + struct type *rbh_root; /* root of the tree */ \ +} + +#define RB_INITIALIZER(root) \ + { NULL } + +#define RB_INIT(root) do { \ + (root)->rbh_root = NULL; \ +} while (0) + +#define RB_BLACK 0 +#define RB_RED 1 +#define RB_ENTRY(type) \ +struct { \ + struct type *rbe_left; /* left element */ \ + struct type *rbe_right; /* right element */ \ + struct type *rbe_parent; /* parent element */ \ + int rbe_color; /* node color */ \ +} + +#define RB_LEFT(elm, field) (elm)->field.rbe_left +#define RB_RIGHT(elm, field) (elm)->field.rbe_right +#define RB_PARENT(elm, field) (elm)->field.rbe_parent +#define RB_COLOR(elm, field) (elm)->field.rbe_color +#define RB_ROOT(head) (head)->rbh_root +#define RB_EMPTY(head) (RB_ROOT(head) == NULL) + +#define RB_SET(elm, parent, field) do { \ + RB_PARENT(elm, field) = parent; \ + RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \ + RB_COLOR(elm, field) = RB_RED; \ +} while (0) + +#define RB_SET_BLACKRED(black, red, field) do { \ + RB_COLOR(black, field) = RB_BLACK; \ + RB_COLOR(red, field) = RB_RED; \ +} while (0) + +#ifndef RB_AUGMENT +#define RB_AUGMENT(x) +#endif + +#define RB_ROTATE_LEFT(head, elm, tmp, field) do { \ + (tmp) = RB_RIGHT(elm, field); \ + if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field))) { \ + RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \ + } \ + RB_AUGMENT(elm); \ + if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \ + if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ + RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ + else \ + RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ + } else \ + (head)->rbh_root = (tmp); \ + RB_LEFT(tmp, field) = (elm); \ + RB_PARENT(elm, field) = (tmp); \ + RB_AUGMENT(tmp); \ + if ((RB_PARENT(tmp, field))) \ + RB_AUGMENT(RB_PARENT(tmp, field)); \ +} while (0) + +#define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \ + (tmp) = RB_LEFT(elm, field); \ + if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field))) { \ + RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \ + } \ + RB_AUGMENT(elm); \ + if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \ + if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ + RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ + else \ + RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ + } else \ + (head)->rbh_root = (tmp); \ + RB_RIGHT(tmp, field) = (elm); \ + RB_PARENT(elm, field) = (tmp); \ + RB_AUGMENT(tmp); \ + if ((RB_PARENT(tmp, field))) \ + RB_AUGMENT(RB_PARENT(tmp, field)); \ +} while (0) + +/* Generates prototypes and inline functions */ +#define RB_PROTOTYPE(name, type, field, cmp) \ +void name##_RB_INSERT_COLOR(struct name *, struct type *); \ +void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\ +struct type *name##_RB_REMOVE(struct name *, struct type *); \ +struct type *name##_RB_INSERT(struct name *, struct type *); \ +struct type *name##_RB_FIND(struct name *, struct type *); \ +struct type *name##_RB_NEXT(struct name *, struct type *); \ +struct type *name##_RB_MINMAX(struct name *, int); \ + \ + +/* Main rb operation. + * Moves node close to the key of elm to top + */ +#define RB_GENERATE(name, type, field, cmp) \ +void \ +name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \ +{ \ + struct type *parent, *gparent, *tmp; \ + while ((parent = RB_PARENT(elm, field)) && \ + RB_COLOR(parent, field) == RB_RED) { \ + gparent = RB_PARENT(parent, field); \ + if (parent == RB_LEFT(gparent, field)) { \ + tmp = RB_RIGHT(gparent, field); \ + if (tmp && RB_COLOR(tmp, field) == RB_RED) { \ + RB_COLOR(tmp, field) = RB_BLACK; \ + RB_SET_BLACKRED(parent, gparent, field);\ + elm = gparent; \ + continue; \ + } \ + if (RB_RIGHT(parent, field) == elm) { \ + RB_ROTATE_LEFT(head, parent, tmp, field);\ + tmp = parent; \ + parent = elm; \ + elm = tmp; \ + } \ + RB_SET_BLACKRED(parent, gparent, field); \ + RB_ROTATE_RIGHT(head, gparent, tmp, field); \ + } else { \ + tmp = RB_LEFT(gparent, field); \ + if (tmp && RB_COLOR(tmp, field) == RB_RED) { \ + RB_COLOR(tmp, field) = RB_BLACK; \ + RB_SET_BLACKRED(parent, gparent, field);\ + elm = gparent; \ + continue; \ + } \ + if (RB_LEFT(parent, field) == elm) { \ + RB_ROTATE_RIGHT(head, parent, tmp, field);\ + tmp = parent; \ + parent = elm; \ + elm = tmp; \ + } \ + RB_SET_BLACKRED(parent, gparent, field); \ + RB_ROTATE_LEFT(head, gparent, tmp, field); \ + } \ + } \ + RB_COLOR(head->rbh_root, field) = RB_BLACK; \ +} \ + \ +void \ +name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \ +{ \ + struct type *tmp; \ + while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \ + elm != RB_ROOT(head)) { \ + if (RB_LEFT(parent, field) == elm) { \ + tmp = RB_RIGHT(parent, field); \ + if (RB_COLOR(tmp, field) == RB_RED) { \ + RB_SET_BLACKRED(tmp, parent, field); \ + RB_ROTATE_LEFT(head, parent, tmp, field);\ + tmp = RB_RIGHT(parent, field); \ + } \ + if ((RB_LEFT(tmp, field) == NULL || \ + RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\ + (RB_RIGHT(tmp, field) == NULL || \ + RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\ + RB_COLOR(tmp, field) = RB_RED; \ + elm = parent; \ + parent = RB_PARENT(elm, field); \ + } else { \ + if (RB_RIGHT(tmp, field) == NULL || \ + RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\ + struct type *oleft; \ + if ((oleft = RB_LEFT(tmp, field)))\ + RB_COLOR(oleft, field) = RB_BLACK;\ + RB_COLOR(tmp, field) = RB_RED; \ + RB_ROTATE_RIGHT(head, tmp, oleft, field);\ + tmp = RB_RIGHT(parent, field); \ + } \ + RB_COLOR(tmp, field) = RB_COLOR(parent, field);\ + RB_COLOR(parent, field) = RB_BLACK; \ + if (RB_RIGHT(tmp, field)) \ + RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\ + RB_ROTATE_LEFT(head, parent, tmp, field);\ + elm = RB_ROOT(head); \ + break; \ + } \ + } else { \ + tmp = RB_LEFT(parent, field); \ + if (RB_COLOR(tmp, field) == RB_RED) { \ + RB_SET_BLACKRED(tmp, parent, field); \ + RB_ROTATE_RIGHT(head, parent, tmp, field);\ + tmp = RB_LEFT(parent, field); \ + } \ + if ((RB_LEFT(tmp, field) == NULL || \ + RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\ + (RB_RIGHT(tmp, field) == NULL || \ + RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\ + RB_COLOR(tmp, field) = RB_RED; \ + elm = parent; \ + parent = RB_PARENT(elm, field); \ + } else { \ + if (RB_LEFT(tmp, field) == NULL || \ + RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\ + struct type *oright; \ + if ((oright = RB_RIGHT(tmp, field)))\ + RB_COLOR(oright, field) = RB_BLACK;\ + RB_COLOR(tmp, field) = RB_RED; \ + RB_ROTATE_LEFT(head, tmp, oright, field);\ + tmp = RB_LEFT(parent, field); \ + } \ + RB_COLOR(tmp, field) = RB_COLOR(parent, field);\ + RB_COLOR(parent, field) = RB_BLACK; \ + if (RB_LEFT(tmp, field)) \ + RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\ + RB_ROTATE_RIGHT(head, parent, tmp, field);\ + elm = RB_ROOT(head); \ + break; \ + } \ + } \ + } \ + if (elm) \ + RB_COLOR(elm, field) = RB_BLACK; \ +} \ + \ +struct type * \ +name##_RB_REMOVE(struct name *head, struct type *elm) \ +{ \ + struct type *child, *parent, *old = elm; \ + int color; \ + if (RB_LEFT(elm, field) == NULL) \ + child = RB_RIGHT(elm, field); \ + else if (RB_RIGHT(elm, field) == NULL) \ + child = RB_LEFT(elm, field); \ + else { \ + struct type *left; \ + elm = RB_RIGHT(elm, field); \ + while ((left = RB_LEFT(elm, field))) \ + elm = left; \ + child = RB_RIGHT(elm, field); \ + parent = RB_PARENT(elm, field); \ + color = RB_COLOR(elm, field); \ + if (child) \ + RB_PARENT(child, field) = parent; \ + if (parent) { \ + if (RB_LEFT(parent, field) == elm) \ + RB_LEFT(parent, field) = child; \ + else \ + RB_RIGHT(parent, field) = child; \ + RB_AUGMENT(parent); \ + } else \ + RB_ROOT(head) = child; \ + if (RB_PARENT(elm, field) == old) \ + parent = elm; \ + (elm)->field = (old)->field; \ + if (RB_PARENT(old, field)) { \ + if (RB_LEFT(RB_PARENT(old, field), field) == old)\ + RB_LEFT(RB_PARENT(old, field), field) = elm;\ + else \ + RB_RIGHT(RB_PARENT(old, field), field) = elm;\ + RB_AUGMENT(RB_PARENT(old, field)); \ + } else \ + RB_ROOT(head) = elm; \ + RB_PARENT(RB_LEFT(old, field), field) = elm; \ + if (RB_RIGHT(old, field)) \ + RB_PARENT(RB_RIGHT(old, field), field) = elm; \ + if (parent) { \ + left = parent; \ + do { \ + RB_AUGMENT(left); \ + } while ((left = RB_PARENT(left, field))); \ + } \ + goto color; \ + } \ + parent = RB_PARENT(elm, field); \ + color = RB_COLOR(elm, field); \ + if (child) \ + RB_PARENT(child, field) = parent; \ + if (parent) { \ + if (RB_LEFT(parent, field) == elm) \ + RB_LEFT(parent, field) = child; \ + else \ + RB_RIGHT(parent, field) = child; \ + RB_AUGMENT(parent); \ + } else \ + RB_ROOT(head) = child; \ +color: \ + if (color == RB_BLACK) \ + name##_RB_REMOVE_COLOR(head, parent, child); \ + return (old); \ +} \ + \ +/* Inserts a node into the RB tree */ \ +struct type * \ +name##_RB_INSERT(struct name *head, struct type *elm) \ +{ \ + struct type *tmp; \ + struct type *parent = NULL; \ + int comp = 0; \ + tmp = RB_ROOT(head); \ + while (tmp) { \ + parent = tmp; \ + comp = (cmp)(elm, parent); \ + if (comp < 0) \ + tmp = RB_LEFT(tmp, field); \ + else if (comp > 0) \ + tmp = RB_RIGHT(tmp, field); \ + else \ + return (tmp); \ + } \ + RB_SET(elm, parent, field); \ + if (parent != NULL) { \ + if (comp < 0) \ + RB_LEFT(parent, field) = elm; \ + else \ + RB_RIGHT(parent, field) = elm; \ + RB_AUGMENT(parent); \ + } else \ + RB_ROOT(head) = elm; \ + name##_RB_INSERT_COLOR(head, elm); \ + return (NULL); \ +} \ + \ +/* Finds the node with the same key as elm */ \ +struct type * \ +name##_RB_FIND(struct name *head, struct type *elm) \ +{ \ + struct type *tmp = RB_ROOT(head); \ + int comp; \ + while (tmp) { \ + comp = cmp(elm, tmp); \ + if (comp < 0) \ + tmp = RB_LEFT(tmp, field); \ + else if (comp > 0) \ + tmp = RB_RIGHT(tmp, field); \ + else \ + return (tmp); \ + } \ + return (NULL); \ +} \ + \ +struct type * \ +name##_RB_NEXT(struct name *head, struct type *elm) \ +{ \ + if (RB_RIGHT(elm, field)) { \ + elm = RB_RIGHT(elm, field); \ + while (RB_LEFT(elm, field)) \ + elm = RB_LEFT(elm, field); \ + } else { \ + if (RB_PARENT(elm, field) && \ + (elm == RB_LEFT(RB_PARENT(elm, field), field))) \ + elm = RB_PARENT(elm, field); \ + else { \ + while (RB_PARENT(elm, field) && \ + (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\ + elm = RB_PARENT(elm, field); \ + elm = RB_PARENT(elm, field); \ + } \ + } \ + return (elm); \ +} \ + \ +struct type * \ +name##_RB_MINMAX(struct name *head, int val) \ +{ \ + struct type *tmp = RB_ROOT(head); \ + struct type *parent = NULL; \ + while (tmp) { \ + parent = tmp; \ + if (val < 0) \ + tmp = RB_LEFT(tmp, field); \ + else \ + tmp = RB_RIGHT(tmp, field); \ + } \ + return (parent); \ +} + +#define RB_NEGINF -1 +#define RB_INF 1 + +#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y) +#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y) +#define RB_FIND(name, x, y) name##_RB_FIND(x, y) +#define RB_NEXT(name, x, y) name##_RB_NEXT(x, y) +#define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF) +#define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF) + +#define RB_FOREACH(x, name, head) \ + for ((x) = RB_MIN(name, head); \ + (x) != NULL; \ + (x) = name##_RB_NEXT(head, x)) + +#endif /* _SYS_TREE_H_ */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/vis.c openssh-3.7p1/openbsd-compat/vis.c --- ssh-openbsd-2003091600/openbsd-compat/vis.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/vis.c 2003-08-30 02:59:52.000000000 +1000 @@ -0,0 +1,237 @@ +/*- + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include "includes.h" +#if !defined(HAVE_STRNVIS) + +#if defined(LIBC_SCCS) && !defined(lint) +static char rcsid[] = "$OpenBSD: vis.c,v 1.12 2003/06/02 20:18:35 millert Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include + +#include "vis.h" + +#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') +#define isvisible(c) (((u_int)(c) <= UCHAR_MAX && isascii((u_char)(c)) && \ + isgraph((u_char)(c))) || \ + ((flag & VIS_SP) == 0 && (c) == ' ') || \ + ((flag & VIS_TAB) == 0 && (c) == '\t') || \ + ((flag & VIS_NL) == 0 && (c) == '\n') || \ + ((flag & VIS_SAFE) && ((c) == '\b' || \ + (c) == '\007' || (c) == '\r' || \ + isgraph((u_char)(c))))) + +/* + * vis - visually encode characters + */ +char * +vis(dst, c, flag, nextc) + register char *dst; + int c, nextc; + register int flag; +{ + if (isvisible(c)) { + *dst++ = c; + if (c == '\\' && (flag & VIS_NOSLASH) == 0) + *dst++ = '\\'; + *dst = '\0'; + return (dst); + } + + if (flag & VIS_CSTYLE) { + switch(c) { + case '\n': + *dst++ = '\\'; + *dst++ = 'n'; + goto done; + case '\r': + *dst++ = '\\'; + *dst++ = 'r'; + goto done; + case '\b': + *dst++ = '\\'; + *dst++ = 'b'; + goto done; + case '\a': + *dst++ = '\\'; + *dst++ = 'a'; + goto done; + case '\v': + *dst++ = '\\'; + *dst++ = 'v'; + goto done; + case '\t': + *dst++ = '\\'; + *dst++ = 't'; + goto done; + case '\f': + *dst++ = '\\'; + *dst++ = 'f'; + goto done; + case ' ': + *dst++ = '\\'; + *dst++ = 's'; + goto done; + case '\0': + *dst++ = '\\'; + *dst++ = '0'; + if (isoctal(nextc)) { + *dst++ = '0'; + *dst++ = '0'; + } + goto done; + } + } + if (((c & 0177) == ' ') || (flag & VIS_OCTAL)) { + *dst++ = '\\'; + *dst++ = ((u_char)c >> 6 & 07) + '0'; + *dst++ = ((u_char)c >> 3 & 07) + '0'; + *dst++ = ((u_char)c & 07) + '0'; + goto done; + } + if ((flag & VIS_NOSLASH) == 0) + *dst++ = '\\'; + if (c & 0200) { + c &= 0177; + *dst++ = 'M'; + } + if (iscntrl(c)) { + *dst++ = '^'; + if (c == 0177) + *dst++ = '?'; + else + *dst++ = c + '@'; + } else { + *dst++ = '-'; + *dst++ = c; + } +done: + *dst = '\0'; + return (dst); +} + +/* + * strvis, strnvis, strvisx - visually encode characters from src into dst + * + * Dst must be 4 times the size of src to account for possible + * expansion. The length of dst, not including the trailing NULL, + * is returned. + * + * Strnvis will write no more than siz-1 bytes (and will NULL terminate). + * The number of bytes needed to fully encode the string is returned. + * + * Strvisx encodes exactly len bytes from src into dst. + * This is useful for encoding a block of data. + */ +int +strvis(dst, src, flag) + register char *dst; + register const char *src; + int flag; +{ + register char c; + char *start; + + for (start = dst; (c = *src);) + dst = vis(dst, c, flag, *++src); + *dst = '\0'; + return (dst - start); +} + +int +strnvis(dst, src, siz, flag) + char *dst; + const char *src; + size_t siz; + int flag; +{ + char c; + char *start, *end; + char tbuf[5]; + int i; + + i = 0; + for (start = dst, end = start + siz - 1; (c = *src) && dst < end; ) { + if (isvisible(c)) { + i = 1; + *dst++ = c; + if (c == '\\' && (flag & VIS_NOSLASH) == 0) { + /* need space for the extra '\\' */ + if (dst < end) + *dst++ = '\\'; + else { + dst--; + i = 2; + break; + } + } + src++; + } else { + i = vis(tbuf, c, flag, *++src) - tbuf; + if (dst + i <= end) { + memcpy(dst, tbuf, i); + dst += i; + } else { + src--; + break; + } + } + } + if (siz > 0) + *dst = '\0'; + if (dst + i > end) { + /* adjust return value for truncation */ + while ((c = *src)) + dst += vis(tbuf, c, flag, *++src) - tbuf; + } + return (dst - start); +} + +int +strvisx(dst, src, len, flag) + register char *dst; + register const char *src; + register size_t len; + int flag; +{ + register char c; + char *start; + + for (start = dst; len > 1; len--) { + c = *src; + dst = vis(dst, c, flag, *++src); + } + if (len) + dst = vis(dst, *src, flag, '\0'); + *dst = '\0'; + return (dst - start); +} + +#endif diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/vis.h openssh-3.7p1/openbsd-compat/vis.h --- ssh-openbsd-2003091600/openbsd-compat/vis.h 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/vis.h 2003-08-30 02:59:52.000000000 +1000 @@ -0,0 +1,88 @@ +/* $OpenBSD: vis.h,v 1.6 2003/06/02 19:34:12 millert Exp $ */ +/* $NetBSD: vis.h,v 1.4 1994/10/26 00:56:41 cgd Exp $ */ + +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)vis.h 5.9 (Berkeley) 4/3/91 + */ + +#include "includes.h" +#if !defined(HAVE_STRNVIS) + +#ifndef _VIS_H_ +#define _VIS_H_ + +#include +#include + +/* + * to select alternate encoding format + */ +#define VIS_OCTAL 0x01 /* use octal \ddd format */ +#define VIS_CSTYLE 0x02 /* use \[nrft0..] where appropriate */ + +/* + * to alter set of characters encoded (default is to encode all + * non-graphic except space, tab, and newline). + */ +#define VIS_SP 0x04 /* also encode space */ +#define VIS_TAB 0x08 /* also encode tab */ +#define VIS_NL 0x10 /* also encode newline */ +#define VIS_WHITE (VIS_SP | VIS_TAB | VIS_NL) +#define VIS_SAFE 0x20 /* only encode "unsafe" characters */ + +/* + * other + */ +#define VIS_NOSLASH 0x40 /* inhibit printing '\' */ + +/* + * unvis return codes + */ +#define UNVIS_VALID 1 /* character valid */ +#define UNVIS_VALIDPUSH 2 /* character valid, push back passed char */ +#define UNVIS_NOCHAR 3 /* valid sequence, no character produced */ +#define UNVIS_SYNBAD -1 /* unrecognized escape sequence */ +#define UNVIS_ERROR -2 /* decoder in unknown state (unrecoverable) */ + +/* + * unvis flags + */ +#define UNVIS_END 1 /* no more characters */ + +char *vis(char *, int, int, int); +int strvis(char *, const char *, int); +int strnvis(char *, const char *, size_t, int); +int strvisx(char *, const char *, size_t, int); +int strunvis(char *, const char *); +int unvis(char *, char, int *, int); + +#endif /* !_VIS_H_ */ + +#endif /* !HAVE_STRNVIS */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/xcrypt.c openssh-3.7p1/openbsd-compat/xcrypt.c --- ssh-openbsd-2003091600/openbsd-compat/xcrypt.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/xcrypt.c 2003-09-07 09:43:42.000000000 +1000 @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2003 Ben Lindstrom. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#if !defined(HAVE_OSF_SIA) + +# ifdef HAVE_CRYPT_H +# include +# endif + +# ifdef __hpux +# include +# include +# endif + +# ifdef HAVE_SECUREWARE +# include +# include +# include +# endif + +# if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) +# include +# endif + +# if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) +# include +# include +# include +# endif + +# if defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) +# include "md5crypt.h" +# endif + +char * +xcrypt(const char *password, const char *salt) +{ + char *crypted; + +# ifdef HAVE_MD5_PASSWORDS + if (is_md5_salt(salt)) + crypted = md5_crypt(password, salt); + else + crypted = crypt(password, salt); +# elif defined(__hpux) && !defined(HAVE_SECUREWARE) + if (iscomsec()) + crypted = bigcrypt(password, salt); + else + crypted = crypt(password, salt); +# elif defined(HAVE_SECUREWARE) + crypted = bigcrypt(password, salt); +# else + crypted = crypt(password, salt); +# endif + + return crypted; +} + +/* + * Handle shadowed password systems in a cleaner way for portable + * version. + */ + +char * +shadow_pw(struct passwd *pw) +{ + char *pw_password = pw->pw_passwd; + +# if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) + struct spwd *spw = getspnam(pw->pw_name); + + if (spw != NULL) + pw_password = spw->sp_pwdp; +# endif +# if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) + struct passwd_adjunct *spw; + if (issecure() && (spw = getpwanam(pw->pw_name)) != NULL) + pw_password = spw->pwa_passwd; +# elif defined(HAVE_SECUREWARE) + struct pr_passwd *spw = getprpwnam(pw->pw_name); + + if (spw != NULL) + pw_password = spw->ufld.fd_encrypt; +# elif defined(__hpux) && !defined(HAVE_SECUREWARE) + struct pr_passwd *spw; + if (iscomsec() && (spw = getprpwnam(pw->pw_name)) != NULL) + pw_password = spw->ufld.fd_encrypt; +# endif + + return pw_password; +} + +#endif /* !defined(HAVE_OSF_SIA) */ diff -ruN --exclude CVS ssh-openbsd-2003091600/openbsd-compat/xmmap.c openssh-3.7p1/openbsd-compat/xmmap.c --- ssh-openbsd-2003091600/openbsd-compat/xmmap.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/openbsd-compat/xmmap.c 2003-06-02 12:25:27.000000000 +1000 @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2002 Tim Rice. All rights reserved. + * MAP_FAILED code by Solar Designer. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* $Id: xmmap.c,v 1.3 2003/06/02 02:25:27 tim Exp $ */ + +#include "includes.h" + +#ifdef HAVE_SYS_MMAN_H +#include +#endif + +#include "log.h" + +void *xmmap(size_t size) +{ + void *address; + +#ifdef HAVE_MMAP +# ifdef MAP_ANON + address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_ANON|MAP_SHARED, + -1, 0); +# else + address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_SHARED, + open("/dev/zero", O_RDWR), 0); +# endif + +#define MM_SWAP_TEMPLATE "/var/run/sshd.mm.XXXXXXXX" + if (address == MAP_FAILED) { + char tmpname[sizeof(MM_SWAP_TEMPLATE)] = MM_SWAP_TEMPLATE; + int tmpfd; + + tmpfd = mkstemp(tmpname); + if (tmpfd == -1) + fatal("mkstemp(\"%s\"): %s", + MM_SWAP_TEMPLATE, strerror(errno)); + unlink(tmpname); + ftruncate(tmpfd, size); + address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_SHARED, + tmpfd, 0); + close(tmpfd); + } + + return (address); +#else + fatal("%s: UsePrivilegeSeparation=yes and Compression=yes not supported", + __func__); +#endif /* HAVE_MMAP */ + +} + diff -ruN --exclude CVS ssh-openbsd-2003091600/packet.c openssh-3.7p1/packet.c --- ssh-openbsd-2003091600/packet.c 2003-07-30 14:56:28.000000000 +1000 +++ openssh-3.7p1/packet.c 2003-07-14 17:31:06.000000000 +1000 @@ -39,7 +39,7 @@ #include "includes.h" RCSID("$OpenBSD: packet.c,v 1.109 2003/07/10 14:42:28 markus Exp $"); -#include +#include "openbsd-compat/sys-queue.h" #include "xmalloc.h" #include "buffer.h" @@ -303,9 +303,14 @@ memset(&to, 0, sizeof(to)); if (getsockname(connection_out, (struct sockaddr *)&to, &tolen) < 0) return 0; - if (to.ss_family != AF_INET) - return 0; - return 1; + if (to.ss_family == AF_INET) + return 1; +#ifdef IPV4_IN_IPV6 + if (to.ss_family == AF_INET6 && + IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&to)->sin6_addr)) + return 1; +#endif + return 0; } /* Sets the connection into non-blocking mode. */ @@ -1398,6 +1403,8 @@ return buffer_len(&output) < 128 * 1024; } + +#if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN) static void packet_set_tos(int interactive) { @@ -1411,6 +1418,7 @@ error("setsockopt IP_TOS %d: %.100s:", tos, strerror(errno)); } +#endif /* Informs that the current session is interactive. Sets IP flags for that. */ @@ -1431,7 +1439,10 @@ return; if (interactive) set_nodelay(connection_in); +#if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN) packet_set_tos(interactive); +#endif + } /* Returns true if the current connection is interactive. */ diff -ruN --exclude CVS ssh-openbsd-2003091600/pathnames.h openssh-3.7p1/pathnames.h --- ssh-openbsd-2003091600/pathnames.h 2003-03-26 16:04:04.000000000 +1100 +++ openssh-3.7p1/pathnames.h 2002-06-07 05:57:34.000000000 +1000 @@ -13,8 +13,14 @@ */ #define ETCDIR "/etc" + +#ifndef SSHDIR #define SSHDIR ETCDIR "/ssh" +#endif + +#ifndef _PATH_SSH_PIDDIR #define _PATH_SSH_PIDDIR "/var/run" +#endif /* * System-wide file containing host keys of known hosts. This file should be @@ -33,11 +39,13 @@ #define _PATH_HOST_KEY_FILE SSHDIR "/ssh_host_key" #define _PATH_HOST_DSA_KEY_FILE SSHDIR "/ssh_host_dsa_key" #define _PATH_HOST_RSA_KEY_FILE SSHDIR "/ssh_host_rsa_key" -#define _PATH_DH_MODULI ETCDIR "/moduli" +#define _PATH_DH_MODULI SSHDIR "/moduli" /* Backwards compatibility */ -#define _PATH_DH_PRIMES ETCDIR "/primes" +#define _PATH_DH_PRIMES SSHDIR "/primes" +#ifndef _PATH_SSH_PROGRAM #define _PATH_SSH_PROGRAM "/usr/bin/ssh" +#endif /* * The process id of the daemon listening for connections is saved here to @@ -102,29 +110,60 @@ * Ssh-only version of /etc/hosts.equiv. Additionally, the daemon may use * ~/.rhosts and /etc/hosts.equiv if rhosts authentication is enabled. */ -#define _PATH_SSH_HOSTS_EQUIV ETCDIR "/shosts.equiv" +#define _PATH_SSH_HOSTS_EQUIV SSHDIR "/shosts.equiv" #define _PATH_RHOSTS_EQUIV "/etc/hosts.equiv" /* * Default location of askpass */ +#ifndef _PATH_SSH_ASKPASS_DEFAULT #define _PATH_SSH_ASKPASS_DEFAULT "/usr/X11R6/bin/ssh-askpass" +#endif /* Location of ssh-keysign for hostbased authentication */ -#define _PATH_SSH_KEY_SIGN "/usr/libexec/ssh-keysign" +#ifndef _PATH_SSH_KEY_SIGN +#define _PATH_SSH_KEY_SIGN "/usr/libexec/ssh-keysign" +#endif /* xauth for X11 forwarding */ +#ifndef _PATH_XAUTH #define _PATH_XAUTH "/usr/X11R6/bin/xauth" +#endif /* UNIX domain socket for X11 server; displaynum will replace %u */ +#ifndef _PATH_UNIX_X #define _PATH_UNIX_X "/tmp/.X11-unix/X%u" +#endif /* for scp */ +#ifndef _PATH_CP #define _PATH_CP "cp" +#endif /* for sftp */ +#ifndef _PATH_SFTP_SERVER #define _PATH_SFTP_SERVER "/usr/libexec/sftp-server" -#define _PATH_LS "ls" +#endif /* chroot directory for unprivileged user when UsePrivilegeSeparation=yes */ +#ifndef _PATH_PRIVSEP_CHROOT_DIR #define _PATH_PRIVSEP_CHROOT_DIR "/var/empty" +#endif + +#ifndef _PATH_LS +#define _PATH_LS "ls" +#endif + +/* path to login program */ +#ifndef LOGIN_PROGRAM +# ifdef LOGIN_PROGRAM_FALLBACK +# define LOGIN_PROGRAM LOGIN_PROGRAM_FALLBACK +# else +# define LOGIN_PROGRAM "/usr/bin/login" +# endif +#endif /* LOGIN_PROGRAM */ + +/* Askpass program define */ +#ifndef ASKPASS_PROGRAM +#define ASKPASS_PROGRAM "/usr/lib/ssh/ssh-askpass" +#endif /* ASKPASS_PROGRAM */ diff -ruN --exclude CVS ssh-openbsd-2003091600/progressmeter.c openssh-3.7p1/progressmeter.c --- ssh-openbsd-2003091600/progressmeter.c 2003-09-03 12:07:14.000000000 +1000 +++ openssh-3.7p1/progressmeter.c 2003-09-02 22:53:33.000000000 +1000 @@ -27,6 +27,7 @@ #include "progressmeter.h" #include "atomicio.h" +#include "misc.h" #define DEFAULT_WINSIZE 80 #define MAX_WINSIZE 512 @@ -79,8 +80,8 @@ bytes = (bytes + 512) / 1024; } snprintf(buf, size, "%3lld.%1lld%c%s", - (long long) bytes / 100, - (long long) (bytes + 5) / 10 % 10, + (int64_t) bytes / 100, + (int64_t) (bytes + 5) / 10 % 10, unit[i], i ? "B" : " "); } @@ -93,7 +94,7 @@ for (i = 0; bytes >= 10000 && unit[i] != 'T'; i++) bytes = (bytes + 512) / 1024; snprintf(buf, size, "%4lld%c%s", - (long long) bytes, + (int64_t) bytes, unit[i], i ? "B" : " "); } diff -ruN --exclude CVS ssh-openbsd-2003091600/readconf.c openssh-3.7p1/readconf.c --- ssh-openbsd-2003091600/readconf.c 2003-09-03 12:07:14.000000000 +1000 +++ openssh-3.7p1/readconf.c 2003-09-02 22:58:22.000000000 +1000 @@ -204,9 +204,11 @@ u_short host_port) { Forward *fwd; +#ifndef NO_IPPORT_RESERVED_CONCEPT extern uid_t original_real_uid; if (port < IPPORT_RESERVED && original_real_uid != 0) fatal("Privileged ports can only be forwarded by root."); +#endif if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION); fwd = &options->local_forwards[options->num_local_forwards++]; diff -ruN --exclude CVS ssh-openbsd-2003091600/README openssh-3.7p1/README --- ssh-openbsd-2003091600/README 2003-03-26 16:04:01.000000000 +1100 +++ openssh-3.7p1/README 2003-01-08 23:28:40.000000000 +1100 @@ -1,25 +1,66 @@ -This release of OpenSSH is for OpenBSD systems only. +- 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 -Please read - http://www.openssh.com/portable.html -if you want to install OpenSSH on other operating systems. - -To extract and install this release on your OpenBSD system use: - - # cd /usr/src/usr.bin - # tar xvfz .../openssh-x.y.tgz - # cd ssh - # make obj - # make cleandir - # make depend - # make - # make install - # cp ssh_config sshd_config /etc/ssh - -OpenSSH is a derivative of the original and free ssh 1.2.12 release -by Tatu Ylonen. Aaron Campbell, Bob Beck, Markus Friedl, Niels -Provos, Theo de Raadt and Dug Song removed many bugs, re-added newer -features and created OpenSSH. Markus Friedl contributed the support -for SSH protocol versions 1.5 and 2.0. +This is the port of OpenBSD's excellent OpenSSH[0] to Linux and other +Unices. -See http://www.openssh.com/ for more information. +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 (for Linux and Solaris), 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 Linux, Solaris, HP-UX, NetBSD, +Irix and AIX. Support for SCO, NeXT and other Unices is underway. +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. + +If you are a citizen of an USA-embargoed country to which export of +cryptographic products is restricted, then please refrain from sending +crypto-related code or patches to the list. We cannot accept them. +Other code contribution are accepted, but please follow the OpenBSD +style guidelines[6]. + +Please refer to the INSTALL document for information on how to install +OpenSSH on your system. There are a number of differences between this +port of OpenSSH and F-Secure SSH 1.x, please refer to the OpenSSH FAQ[7] +for details and general tips. + +Damien Miller + +Miscellania - + +This version of OpenSSH is based upon code retrieved from the OpenBSD +CVS repository which in turn was based on the last free sample +implementation released by Tatu Ylonen. + +References - + +[0] http://www.openssh.com/faq.html +[1] http://www.lothar.com/tech/crypto/ +[2] http://www.aet.tu-cottbus.de/personen/jaenicke/postfix_tls/prngd.html +[3] http://www.gzip.org/zlib/ +[4] http://www.openssl.org/ +[5] http://www.kernel.org/pub/linux/libs/pam/ (PAM is standard on Solaris + and HP-UX 11) +[6] http://www.openbsd.org/cgi-bin/man.cgi?query=style&sektion=9 +[7] http://www.openssh.com/faq.html + +$Id: README,v 1.51 2003/01/08 12:28:40 djm Exp $ diff -ruN --exclude CVS ssh-openbsd-2003091600/README.dns openssh-3.7p1/README.dns --- ssh-openbsd-2003091600/README.dns 2003-05-15 04:16:20.000000000 +1000 +++ openssh-3.7p1/README.dns 2003-05-15 13:23:36.000000000 +1000 @@ -9,10 +9,7 @@ (1) Enable DNS fingerprint support in OpenSSH -Edit /usr/src/usr.bin/ssh/Makefile.inc and uncomment the line containing - - CFLAGS+= -DDNS - + configure --with-dns (2) Generate and publish the DNS RR diff -ruN --exclude CVS ssh-openbsd-2003091600/README.privsep openssh-3.7p1/README.privsep --- ssh-openbsd-2003091600/README.privsep 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/README.privsep 2003-08-26 10:48:15.000000000 +1000 @@ -0,0 +1,64 @@ +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 Linux. +It does not function on HP-UX with a trusted system +configuration. + +On Compaq Tru64 Unix, 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.12 2003/08/26 00:48:15 djm Exp $ diff -ruN --exclude CVS ssh-openbsd-2003091600/README.smartcard openssh-3.7p1/README.smartcard --- ssh-openbsd-2003091600/README.smartcard 2003-03-26 16:04:01.000000000 +1100 +++ openssh-3.7p1/README.smartcard 2003-06-10 21:09:09.000000000 +1000 @@ -1,15 +1,15 @@ How to use smartcards with OpenSSH? OpenSSH contains experimental support for authentication using -Cyberflex smartcards and TODOS card readers. To enable this you +Cyberflex smartcards and TODOS card readers, in addition to the cards +with PKCS#15 structure supported by OpenSC. To enable this you need to: -(1) enable SMARTCARD support in OpenSSH: +Using libsectok: - $ vi /usr/src/usr.bin/ssh/Makefile.inc - and uncomment - CFLAGS+= -DSMARTCARD - LDADD+= -lsectok +(1) enable sectok support in OpenSSH: + + $ ./configure --with-sectok (2) If you have used a previous version of ssh with your card, you must remove the old applet and keys. @@ -46,15 +46,7 @@ In spite of the name, this does not generate a key. It just loads an already existing key on to the card. -(5) tell the ssh client to use the card reader: - - $ ssh -I 1 otherhost - -(6) or tell the agent (don't forget to restart) to use the smartcard: - - $ ssh-add -s 1 - -(7) Optional: If you don't want to use a card passphrase, change the +(5) Optional: If you don't want to use a card passphrase, change the acl on the private key file: $ sectok @@ -67,6 +59,34 @@ If you do this, anyone who has access to your card can assume your identity. This is not recommended. + +Using OpenSC: + +(1) install OpenSC: + + Sources and instructions are available from + http://www.opensc.org/ + +(2) enable OpenSC support in OpenSSH: + + $ ./configure --with-opensc[=/path/to/opensc] [options] + +(3) load a RSA key to the card: + + Not supported yet. + + +Common operations: + +(1) tell the ssh client to use the card reader: + + $ ssh -I 1 otherhost + +(2) or tell the agent (don't forget to restart) to use the smartcard: + + $ ssh-add -s 1 + + -markus, Tue Jul 17 23:54:51 CEST 2001 diff -ruN --exclude CVS ssh-openbsd-2003091600/readpass.c openssh-3.7p1/readpass.c --- ssh-openbsd-2003091600/readpass.c 2003-03-26 16:04:04.000000000 +1100 +++ openssh-3.7p1/readpass.c 2003-01-24 11:36:23.000000000 +1100 @@ -25,8 +25,6 @@ #include "includes.h" RCSID("$OpenBSD: readpass.c,v 1.28 2003/01/23 13:50:27 markus Exp $"); -#include - #include "xmalloc.h" #include "readpass.h" #include "pathnames.h" diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/agent-getpeereid.sh openssh-3.7p1/regress/agent-getpeereid.sh --- ssh-openbsd-2003091600/regress/agent-getpeereid.sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/agent-getpeereid.sh 2003-09-04 18:04:16.000000000 +1000 @@ -0,0 +1,40 @@ +# $OpenBSD: agent-getpeereid.sh,v 1.1 2002/12/09 16:05:02 markus Exp $ +# Placed in the Public Domain. + +tid="disallow agent attach from other uid" + +UNPRIV=nobody +ASOCK=${OBJ}/agent +SSH_AUTH_SOCK=/nonexistant + +if grep "#undef.*HAVE_GETPEEREID" ${BUILDDIR}/config.h >/dev/null 2>&1 +then + echo "skipped (not supported on this platform)" + exit 0 +fi + +trace "start agent" +eval `${SSHAGENT} -s -a ${ASOCK}` > /dev/null +r=$? +if [ $r -ne 0 ]; then + fail "could not start ssh-agent: exit code $r" +else + chmod 644 ${SSH_AUTH_SOCK} + + ssh-add -l > /dev/null 2>&1 + r=$? + if [ $r -ne 1 ]; then + fail "ssh-add failed with $r != 1" + fi + + < /dev/null sudo -S -u ${UNPRIV} ssh-add -l > /dev/null 2>&1 + r=$? + if [ $r -lt 2 ]; then + fail "ssh-add did not fail for ${UNPRIV}: $r < 2" + fi + + trace "kill agent" + ${SSHAGENT} -k > /dev/null +fi + +rm -f ${OBJ}/agent diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/agent-ptrace.sh openssh-3.7p1/regress/agent-ptrace.sh --- ssh-openbsd-2003091600/regress/agent-ptrace.sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/agent-ptrace.sh 2003-09-13 04:20:32.000000000 +1000 @@ -0,0 +1,44 @@ +# $OpenBSD: agent-ptrace.sh,v 1.1 2002/12/09 15:38:30 markus Exp $ +# Placed in the Public Domain. + +tid="disallow agent ptrace attach" + +if have_prog uname ; then + case `uname` in + Linux|HP-UX|SunOS|NetBSD|AIX|CYGWIN*) + echo "skipped (not supported on this platform)" + exit 0 + ;; + esac +fi + +if have_prog gdb ; then + : ok +else + echo "skipped (gdb not found)" + exit 0 +fi + +trace "start agent" +eval `${SSHAGENT} -s` > /dev/null +r=$? +if [ $r -ne 0 ]; then + fail "could not start ssh-agent: exit code $r" +else + # ls -l ${SSH_AUTH_SOCK} + gdb ${SSHAGENT} ${SSH_AGENT_PID} > ${OBJ}/gdb.out 2>&1 << EOF + quit +EOF + if [ $? -ne 0 ]; then + fail "gdb failed: exit code $?" + fi + grep 'ptrace: Operation not permitted.' >/dev/null ${OBJ}/gdb.out + r=$? + rm -f ${OBJ}/gdb.out + if [ $r -ne 0 ]; then + fail "ptrace succeeded?: exit code $r" + fi + + trace "kill agent" + ${SSHAGENT} -k > /dev/null +fi diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/agent.sh openssh-3.7p1/regress/agent.sh --- ssh-openbsd-2003091600/regress/agent.sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/agent.sh 2003-09-04 15:16:57.000000000 +1000 @@ -0,0 +1,75 @@ +# $OpenBSD: agent.sh,v 1.6 2002/03/15 13:08:56 markus Exp $ +# Placed in the Public Domain. + +tid="simple agent test" + +SSH_AUTH_SOCK=/nonexistant ${SSHADD} -l > /dev/null 2>&1 +if [ $? -ne 2 ]; then + fail "ssh-add -l did not fail with exit code 2" +fi + +trace "start agent" +eval `${SSHAGENT} -s` > /dev/null +r=$? +if [ $r -ne 0 ]; then + fail "could not start ssh-agent: exit code $r" +else + ${SSHADD} -l > /dev/null 2>&1 + if [ $? -ne 1 ]; then + fail "ssh-add -l did not fail with exit code 1" + fi + trace "overwrite authorized keys" + echon > $OBJ/authorized_keys_$USER + for t in rsa rsa1; do + # generate user key for agent + rm -f $OBJ/$t-agent + ${SSHKEYGEN} -q -N '' -t $t -f $OBJ/$t-agent ||\ + fail "ssh-keygen for $t-agent failed" + # add to authorized keys + cat $OBJ/$t-agent.pub >> $OBJ/authorized_keys_$USER + # add privat key to agent + ${SSHADD} $OBJ/$t-agent > /dev/null 2>&1 + if [ $? -ne 0 ]; then + fail "ssh-add did succeed exit code 0" + fi + done + ${SSHADD} -l > /dev/null 2>&1 + if [ $? -ne 0 ]; then + fail "ssh-add -l failed: exit code $?" + fi + # the same for full pubkey output + ${SSHADD} -L > /dev/null 2>&1 + if [ $? -ne 0 ]; then + fail "ssh-add -L failed: exit code $?" + fi + + trace "simple connect via agent" + for p in 1 2; do + ${SSH} -$p -F $OBJ/ssh_proxy somehost exit 5$p + if [ $? -ne 5$p ]; then + fail "ssh connect with protocol $p failed (exit code $?)" + fi + done + + trace "agent forwarding" + for p in 1 2; do + ${SSH} -A -$p -F $OBJ/ssh_proxy somehost ${SSHADD} -l > /dev/null 2>&1 + if [ $? -ne 0 ]; then + fail "ssh-add -l via agent fwd proto $p failed (exit code $?)" + fi + ${SSH} -A -$p -F $OBJ/ssh_proxy somehost \ + "${SSH} -$p -F $OBJ/ssh_proxy somehost exit 5$p" + if [ $? -ne 5$p ]; then + fail "agent fwd proto $p failed (exit code $?)" + fi + done + + trace "delete all agent keys" + ${SSHADD} -D > /dev/null 2>&1 + if [ $? -ne 0 ]; then + fail "ssh-add -D failed: exit code $?" + fi + + trace "kill agent" + ${SSHAGENT} -k > /dev/null +fi diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/agent-timeout.sh openssh-3.7p1/regress/agent-timeout.sh --- ssh-openbsd-2003091600/regress/agent-timeout.sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/agent-timeout.sh 2003-09-13 09:46:03.000000000 +1000 @@ -0,0 +1,36 @@ +# $OpenBSD: agent-timeout.sh,v 1.1 2002/06/06 00:38:40 markus Exp $ +# Placed in the Public Domain. + +tid="agent timeout test" + +SSHAGENT_TIMEOUT=10 + +trace "start agent" +eval `${SSHAGENT} -s` > /dev/null +r=$? +if [ $r -ne 0 ]; then + fail "could not start ssh-agent: exit code $r" +else + trace "add keys with timeout" + for t in rsa rsa1; do + ${SSHADD} -t ${SSHAGENT_TIMEOUT} $OBJ/$t > /dev/null 2>&1 + if [ $? -ne 0 ]; then + fail "ssh-add did succeed exit code 0" + fi + done + n=`${SSHADD} -l 2> /dev/null | wc -l` + trace "agent has $n keys" + if [ $n -ne 2 ]; then + fail "ssh-add -l did not return 2 keys: $n" + fi + trace "sleeping 2*${SSHAGENT_TIMEOUT} seconds" + sleep ${SSHAGENT_TIMEOUT} + sleep ${SSHAGENT_TIMEOUT} + ${SSHADD} -l 2> /dev/null | grep 'The agent has no identities.' >/dev/null + if [ $? -ne 0 ]; then + fail "ssh-add -l still returns keys after timeout" + fi + + trace "kill agent" + ${SSHAGENT} -k > /dev/null +fi diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/broken-pipe.sh openssh-3.7p1/regress/broken-pipe.sh --- ssh-openbsd-2003091600/regress/broken-pipe.sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/broken-pipe.sh 2002-05-01 13:17:34.000000000 +1000 @@ -0,0 +1,15 @@ +# $OpenBSD: broken-pipe.sh,v 1.4 2002/03/15 13:08:56 markus Exp $ +# Placed in the Public Domain. + +tid="broken pipe test" + +for p in 1 2; do + trace "protocol $p" + for i in 1 2 3 4; do + ${SSH} -$p -F $OBJ/ssh_config_config nexthost echo $i 2> /dev/null | true + r=$? + if [ $r -ne 0 ]; then + fail "broken pipe returns $r for protocol $p" + fi + done +done diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/bsd.regress.mk openssh-3.7p1/regress/bsd.regress.mk --- ssh-openbsd-2003091600/regress/bsd.regress.mk 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/bsd.regress.mk 2002-05-01 13:17:34.000000000 +1000 @@ -0,0 +1,79 @@ +# $OpenBSD: bsd.regress.mk,v 1.9 2002/02/17 01:10:15 marc Exp $ +# No man pages for regression tests. +NOMAN= + +# No installation. +install: + +# If REGRESSTARGETS is defined and PROG is not defined, set NOPROG +.if defined(REGRESSTARGETS) && !defined(PROG) +NOPROG= +.endif + +.include + +.MAIN: all +all: regress + +# XXX - Need full path to REGRESSLOG, otherwise there will be much pain. + +REGRESSLOG?=/dev/null +REGRESSNAME=${.CURDIR:S/${BSDSRCDIR}\/regress\///} + +.if defined(PROG) && !empty(PROG) +run-regress-${PROG}: ${PROG} + ./${PROG} +.endif + +.if !defined(REGRESSTARGETS) +REGRESSTARGETS=run-regress-${PROG} +. if defined(REGRESSSKIP) +REGRESSSKIPTARGETS=run-regress-${PROG} +. endif +.endif + +REGRESSSKIPSLOW?=no + +#.if (${REGRESSSKIPSLOW:L} == "yes") && defined(REGRESSSLOWTARGETS) + +.if (${REGRESSSKIPSLOW} == "yes") && defined(REGRESSSLOWTARGETS) +REGRESSSKIPTARGETS+=${REGRESSSLOWTARGETS} +.endif + +.if defined(REGRESSROOTTARGETS) +ROOTUSER!=id -g +SUDO?= +. if (${ROOTUSER} != 0) && empty(SUDO) +REGRESSSKIPTARGETS+=${REGRESSROOTTARGETS} +. endif +.endif + +REGRESSSKIPTARGETS?= + +regress: +.for RT in ${REGRESSTARGETS} +. if ${REGRESSSKIPTARGETS:M${RT}} + @echo -n "SKIP " >> ${REGRESSLOG} +. else +# XXX - we need a better method to see if a test fails due to timeout or just +# normal failure. +. if !defined(REGRESSMAXTIME) + @if cd ${.CURDIR} && ${MAKE} ${RT}; then \ + echo -n "SUCCESS " >> ${REGRESSLOG} ; \ + else \ + echo -n "FAIL " >> ${REGRESSLOG} ; \ + echo FAILED ; \ + fi +. else + @if cd ${.CURDIR} && (ulimit -t ${REGRESSMAXTIME} ; ${MAKE} ${RT}); then \ + echo -n "SUCCESS " >> ${REGRESSLOG} ; \ + else \ + echo -n "FAIL (possible timeout) " >> ${REGRESSLOG} ; \ + echo FAILED ; \ + fi +. endif +. endif + @echo ${REGRESSNAME}/${RT:S/^run-regress-//} >> ${REGRESSLOG} +.endfor + +.PHONY: regress diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/connect-privsep.sh openssh-3.7p1/regress/connect-privsep.sh --- ssh-openbsd-2003091600/regress/connect-privsep.sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/connect-privsep.sh 2002-05-01 13:17:34.000000000 +1000 @@ -0,0 +1,13 @@ +# $OpenBSD: connect-privsep.sh,v 1.1 2002/03/21 21:45:07 markus Exp $ +# Placed in the Public Domain. + +tid="proxy connect with privsep" + +echo 'UsePrivilegeSeparation yes' >> $OBJ/sshd_proxy + +for p in 1 2; do + ${SSH} -$p -F $OBJ/ssh_proxy 999.999.999.999 true + if [ $? -ne 0 ]; then + fail "ssh privsep+proxyconnect protocol $p failed" + fi +done diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/connect.sh openssh-3.7p1/regress/connect.sh --- ssh-openbsd-2003091600/regress/connect.sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/connect.sh 2002-05-01 13:17:34.000000000 +1000 @@ -0,0 +1,13 @@ +# $OpenBSD: connect.sh,v 1.4 2002/03/15 13:08:56 markus Exp $ +# Placed in the Public Domain. + +tid="simple connect" + +start_sshd + +for p in 1 2; do + ${SSH} -o "Protocol=$p" -F $OBJ/ssh_config somehost true + if [ $? -ne 0 ]; then + fail "ssh connect with protocol $p failed" + fi +done diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/dsa_ssh2.prv openssh-3.7p1/regress/dsa_ssh2.prv --- ssh-openbsd-2003091600/regress/dsa_ssh2.prv 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/dsa_ssh2.prv 2002-05-01 13:17:34.000000000 +1000 @@ -0,0 +1,14 @@ +---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ---- +Subject: ssh-keygen test +Comment: "1024-bit dsa, Tue Jan 08 2002 22:00:23 +0100" +P2/56wAAAgIAAAAmZGwtbW9kcHtzaWdue2RzYS1uaXN0LXNoYTF9LGRoe3BsYWlufX0AAA +AEbm9uZQAAAcQAAAHAAAAAAAAABACwUfm3AxZTut3icBmwCcD48nY64HzuELlQ+vEqjIcR +Lo49es/DQTeLNQ+kdKRCfouosGNv0WqxRtF0tUsWdXxS37oHGa4QPugBdHRd7YlZGZv8kg +x7FsoepY7v7E683/97dv2zxL3AGagTEzWr7fl0yPexAaZoDvtQrrjX44BLmwAABACWQkvv +MxnD8eFkS1konFfMJ1CkuRfTN34CBZ6dY7VTSGemy4QwtFdMKmoufD0eKgy3p5WOeWCYKt +F4FhjHKZk/aaxFjjIbtkrnlvXg64QI11dSZyBN6/ViQkHPSkUDF+A6AAEhrNbQbAFSvao1 +kTvNtPCtL0AkUIduEMzGQfLCTAAAAKDeC043YVo9Zo0zAEeIA4uZh4LBCQAAA/9aj7Y5ik +ehygJ4qTDSlVypsPuV+n59tMS0e2pfrSG87yf5r94AKBmJeho5OO6wYaXCxsVB7AFbSUD6 +75AK8mHF4v1/+7SWKk5f8xlMCMSPZ9K0+j/W1d/q2qkhnnDZolOHDomLA+U00i5ya/jnTV +zyDPWLFpWK8u3xGBPAYX324gAAAKDHFvooRnaXdZbeWGTTqmgHB1GU9A== +---- END SSH2 ENCRYPTED PRIVATE KEY ---- diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/dsa_ssh2.pub openssh-3.7p1/regress/dsa_ssh2.pub --- ssh-openbsd-2003091600/regress/dsa_ssh2.pub 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/dsa_ssh2.pub 2002-05-01 13:17:34.000000000 +1000 @@ -0,0 +1,13 @@ +---- BEGIN SSH2 PUBLIC KEY ---- +Subject: ssh-keygen test +Comment: "1024-bit dsa, Tue Jan 08 2002 22:00:23 +0100" +AAAAB3NzaC1kc3MAAACBALBR+bcDFlO63eJwGbAJwPjydjrgfO4QuVD68SqMhxEujj16z8 +NBN4s1D6R0pEJ+i6iwY2/RarFG0XS1SxZ1fFLfugcZrhA+6AF0dF3tiVkZm/ySDHsWyh6l +ju/sTrzf/3t2/bPEvcAZqBMTNavt+XTI97EBpmgO+1CuuNfjgEubAAAAFQDeC043YVo9Zo +0zAEeIA4uZh4LBCQAAAIEAlkJL7zMZw/HhZEtZKJxXzCdQpLkX0zd+AgWenWO1U0hnpsuE +MLRXTCpqLnw9HioMt6eVjnlgmCrReBYYxymZP2msRY4yG7ZK55b14OuECNdXUmcgTev1Yk +JBz0pFAxfgOgABIazW0GwBUr2qNZE7zbTwrS9AJFCHbhDMxkHywkwAAACAWo+2OYpHocoC +eKkw0pVcqbD7lfp+fbTEtHtqX60hvO8n+a/eACgZiXoaOTjusGGlwsbFQewBW0lA+u+QCv +JhxeL9f/u0lipOX/MZTAjEj2fStPo/1tXf6tqpIZ5w2aJThw6JiwPlNNIucmv4501c8gz1 +ixaVivLt8RgTwGF99uI= +---- END SSH2 PUBLIC KEY ---- diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/dynamic-forward.sh openssh-3.7p1/regress/dynamic-forward.sh --- ssh-openbsd-2003091600/regress/dynamic-forward.sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/dynamic-forward.sh 2003-09-12 15:32:17.000000000 +1000 @@ -0,0 +1,47 @@ +# $OpenBSD: dynamic-forward.sh,v 1.2 2003/07/03 08:21:46 markus Exp $ +# Placed in the Public Domain. + +tid="dynamic forwarding" + +PORT=4242 +FWDPORT=4243 +DATA=/bin/ls${EXEEXT} + +if have_prog nc && nc -h 2>&1 | grep "x proxy address" >/dev/null; then + proxycmd="nc -x 127.0.0.1:$FWDPORT -X" +elif have_prog connect; then + proxycmd="connect -S 127.0.0.1:$FWDPORT -" +else + echo "skipped (no suitable ProxyCommand found)" + exit 0 +fi +trace "will use ProxyCommand $proxycmd" + +start_sshd + +for p in 1 2; do + trace "start dynamic forwarding, fork to background" + ${SSH} -$p -F $OBJ/ssh_config -f -D $FWDPORT -q somehost \ + exec sh -c \'"echo \$\$ > $OBJ/remote_pid; exec sleep 444"\' + + for s in 4 5; do + for h in 127.0.0.1 localhost; do + trace "testing ssh protocol $p socks version $s host $h" + ${SSH} -F $OBJ/ssh_config \ + -o "ProxyCommand ${proxycmd}${s} $h $PORT" \ + somehost cat $DATA > $OBJ/ls.copy + test -f $OBJ/ls.copy || fail "failed copy $DATA" + cmp $DATA $OBJ/ls.copy || fail "corrupted copy of $DATA" + done + done + + if [ -f $OBJ/remote_pid ]; then + remote=`cat $OBJ/remote_pid` + trace "terminate remote shell, pid $remote" + if [ $remote -gt 1 ]; then + kill -HUP $remote + fi + else + fail "no pid file: $OBJ/remote_pid" + fi +done diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/exit-status.sh openssh-3.7p1/regress/exit-status.sh --- ssh-openbsd-2003091600/regress/exit-status.sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/exit-status.sh 2002-05-01 13:17:34.000000000 +1000 @@ -0,0 +1,24 @@ +# $OpenBSD: exit-status.sh,v 1.6 2002/03/15 13:08:56 markus Exp $ +# Placed in the Public Domain. + +tid="remote exit status" + +for p in 1 2; do + for s in 0 1 4 5 44; do + trace "proto $p status $s" + verbose "test $tid: proto $p status $s" + ${SSH} -$p -F $OBJ/ssh_proxy otherhost exit $s + r=$? + if [ $r -ne $s ]; then + fail "exit code mismatch for protocol $p: $r != $s" + fi + + # same with early close of stdout/err + ${SSH} -$p -F $OBJ/ssh_proxy -n otherhost \ + exec sh -c \'"sleep 2; exec > /dev/null 2>&1; sleep 3; exit $s"\' + r=$? + if [ $r -ne $s ]; then + fail "exit code (with sleep) mismatch for protocol $p: $r != $s" + fi + done +done diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/forwarding.sh openssh-3.7p1/regress/forwarding.sh --- ssh-openbsd-2003091600/regress/forwarding.sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/forwarding.sh 2003-09-07 09:28:04.000000000 +1000 @@ -0,0 +1,34 @@ +# $OpenBSD: forwarding.sh,v 1.4 2002/03/15 13:08:56 markus Exp $ +# Placed in the Public Domain. + +tid="local and remote forwarding" +DATA=/bin/ls${EXEEXT} + +start_sshd + +base=33 +last=$PORT +fwd="" +for j in 0 1 2; do + for i in 0 1 2; do + a=$base$j$i + b=`expr $a + 50` + c=$last + # fwd chain: $a -> $b -> $c + fwd="$fwd -L$a:127.0.0.1:$b -R$b:127.0.0.1:$c" + last=$a + done +done +for p in 1 2; do + q=`expr 3 - $p` + trace "start forwarding, fork to background" + ${SSH} -$p -F $OBJ/ssh_config -f $fwd somehost sleep 10 + + trace "transfer over forwarded channels and check result" + ${SSH} -$q -F $OBJ/ssh_config -p$last -o 'ConnectionAttempts=4' \ + somehost cat $DATA > $OBJ/ls.copy + test -f $OBJ/ls.copy || fail "failed copy $DATA" + cmp $DATA $OBJ/ls.copy || fail "corrupted copy of $DATA" + + sleep 10 +done diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/keygen-change.sh openssh-3.7p1/regress/keygen-change.sh --- ssh-openbsd-2003091600/regress/keygen-change.sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/keygen-change.sh 2003-01-22 17:53:17.000000000 +1100 @@ -0,0 +1,23 @@ +# $OpenBSD: keygen-change.sh,v 1.2 2002/07/16 09:15:55 markus Exp $ +# Placed in the Public Domain. + +tid="change passphrase for key" + +S1="secret1" +S2="2secret" + +for t in rsa dsa rsa1; do + # generate user key for agent + trace "generating $t key" + rm -f $OBJ/$t-key + ${SSHKEYGEN} -q -N ${S1} -t $t -f $OBJ/$t-key + if [ $? -eq 0 ]; then + ${SSHKEYGEN} -p -P ${S1} -N ${S2} -f $OBJ/$t-key > /dev/null + if [ $? -ne 0 ]; then + fail "ssh-keygen -p failed for $t-key" + fi + else + fail "ssh-keygen for $t-key failed" + fi + rm -f $OBJ/$t-key $OBJ/$t-key.pub +done diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/keyscan.sh openssh-3.7p1/regress/keyscan.sh --- ssh-openbsd-2003091600/regress/keyscan.sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/keyscan.sh 2002-05-01 13:17:34.000000000 +1000 @@ -0,0 +1,19 @@ +# $OpenBSD: keyscan.sh,v 1.3 2002/03/15 13:08:56 markus Exp $ +# Placed in the Public Domain. + +tid="keyscan" + +# remove DSA hostkey +rm -f ${OBJ}/host.dsa + +start_sshd + +for t in rsa1 rsa dsa; do + trace "keyscan type $t" + ${SSHKEYSCAN} -t $t -p $PORT 127.0.0.1 127.0.0.1 127.0.0.1 \ + > /dev/null 2>&1 + r=$? + if [ $r -ne 0 ]; then + fail "ssh-keyscan -t $t failed with: $r" + fi +done diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/Makefile openssh-3.7p1/regress/Makefile --- ssh-openbsd-2003091600/regress/Makefile 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/Makefile 2003-09-14 13:16:56.000000000 +1000 @@ -0,0 +1,86 @@ +# $OpenBSD: Makefile,v 1.24 2003/07/03 08:24:13 markus Exp $ + +REGRESS_TARGETS= t1 t2 t3 t4 t5 t6 t7 t-exec +tests: $(REGRESS_TARGETS) + +clean: + for F in $(CLEANFILES); do rm -f $(OBJ)$$F; done +distclean: clean + +LTESTS= connect \ + proxy-connect \ + connect-privsep \ + proto-version \ + proto-mismatch \ + exit-status \ + transfer \ + rekey \ + stderr-data \ + stderr-after-eof \ + broken-pipe \ + try-ciphers \ + yes-head \ + agent \ + agent-getpeereid \ + agent-timeout \ + agent-ptrace \ + keyscan \ + keygen-change \ + sftp \ + sftp-cmds \ + sftp-badcmds \ + sftp-batch \ + reconfigure \ + dynamic-forward \ + forwarding + +USER!= id -un +CLEANFILES= t2.out t6.out1 t6.out2 t7.out t7.out.pub copy.1 copy.2 \ + authorized_keys_${USER} known_hosts pidfile \ + ssh_config ssh_proxy sshd_config sshd_proxy \ + rsa.pub rsa rsa1.pub rsa1 host.rsa host.rsa1 \ + rsa-agent rsa-agent.pub rsa1-agent rsa1-agent.pub \ + ls.copy remote_pid + +#LTESTS += ssh-com ssh-com-client ssh-com-keygen ssh-com-sftp + +t1: + ssh-keygen -if ${.CURDIR}/rsa_ssh2.prv | diff - ${.CURDIR}/rsa_openssh.prv + +t2: + cat ${.CURDIR}/rsa_openssh.prv > $(OBJ)/t2.out + chmod 600 $(OBJ)/t2.out + ssh-keygen -yf $(OBJ)/t2.out | diff - ${.CURDIR}/rsa_openssh.pub + +t3: + ssh-keygen -ef ${.CURDIR}/rsa_openssh.pub >$(OBJ)/rsa_secsh.pub + ssh-keygen -if $(OBJ)/rsa_secsh.pub | diff - ${.CURDIR}/rsa_openssh.pub + rm -f ${.CURDIR}/rsa_secsh.pub + +t4: + ssh-keygen -lf ${.CURDIR}/rsa_openssh.pub |\ + awk '{print $$2}' | diff - ${.CURDIR}/t4.ok + +t5: + ssh-keygen -Bf ${.CURDIR}/rsa_openssh.pub |\ + awk '{print $$2}' | diff - ${.CURDIR}/t5.ok + +t6: + ssh-keygen -if ${.CURDIR}/dsa_ssh2.prv > $(OBJ)/t6.out1 + ssh-keygen -if ${.CURDIR}/dsa_ssh2.pub > $(OBJ)/t6.out2 + chmod 600 $(OBJ)/t6.out1 + ssh-keygen -yf $(OBJ)/t6.out1 | diff - $(OBJ)/t6.out2 + +$(OBJ)/t7.out: + ssh-keygen -q -t rsa -N '' -f $@ + +t7: $(OBJ)/t7.out + ssh-keygen -lf $(OBJ)/t7.out > /dev/null + ssh-keygen -Bf $(OBJ)/t7.out > /dev/null + +t-exec: ${LTESTS:=.sh} + @if [ "x$?" = "x" ]; then exit 0; fi; \ + for TEST in ""$?; do \ + echo "run test $${TEST}" ... 1>&2; \ + (sh ${.CURDIR}/test-exec.sh ${.OBJDIR} ${.CURDIR}/$${TEST}) || exit $$?; \ + done diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/proto-mismatch.sh openssh-3.7p1/regress/proto-mismatch.sh --- ssh-openbsd-2003091600/regress/proto-mismatch.sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/proto-mismatch.sh 2002-05-01 13:17:34.000000000 +1000 @@ -0,0 +1,19 @@ +# $OpenBSD: proto-mismatch.sh,v 1.3 2002/03/15 13:08:56 markus Exp $ +# Placed in the Public Domain. + +tid="protocol version mismatch" + +mismatch () +{ + server=$1 + client=$2 + banner=`echo ${client} | ${SSHD} -o "Protocol=${server}" -i -f ${OBJ}/sshd_proxy` + r=$? + trace "sshd prints ${banner}" + if [ $r -ne 255 ]; then + fail "sshd prints ${banner} and accepts connect with version ${client}" + fi +} + +mismatch 2 SSH-1.5-HALLO +mismatch 1 SSH-2.0-HALLO diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/proto-version.sh openssh-3.7p1/regress/proto-version.sh --- ssh-openbsd-2003091600/regress/proto-version.sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/proto-version.sh 2003-09-04 15:16:57.000000000 +1000 @@ -0,0 +1,34 @@ +# $OpenBSD: proto-version.sh,v 1.3 2002/03/15 13:08:56 markus Exp $ +# Placed in the Public Domain. + +tid="sshd version with different protocol combinations" + +# we just start sshd in inetd mode and check the banner +check_version () +{ + version=$1 + expect=$2 + banner=`echon | ${SSHD} -o "Protocol=${version}" -i -f ${OBJ}/sshd_proxy` + case ${banner} in + SSH-1.99-*) + proto=199 + ;; + SSH-2.0-*) + proto=20 + ;; + SSH-1.5-*) + proto=15 + ;; + *) + proto=0 + ;; + esac + if [ ${expect} -ne ${proto} ]; then + fail "wrong protocol version ${banner} for ${version}" + fi +} + +check_version 2,1 199 +check_version 1,2 199 +check_version 2 20 +check_version 1 15 diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/proxy-connect.sh openssh-3.7p1/regress/proxy-connect.sh --- ssh-openbsd-2003091600/regress/proxy-connect.sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/proxy-connect.sh 2003-01-22 17:53:17.000000000 +1100 @@ -0,0 +1,18 @@ +# $OpenBSD: proxy-connect.sh,v 1.5 2002/12/09 15:28:46 markus Exp $ +# Placed in the Public Domain. + +tid="proxy connect" + +for p in 1 2; do + ${SSH} -$p -F $OBJ/ssh_proxy 999.999.999.999 true + if [ $? -ne 0 ]; then + fail "ssh proxyconnect protocol $p failed" + fi + SSH_CONNECTION=`${SSH} -$p -F $OBJ/ssh_proxy 999.999.999.999 'echo $SSH_CONNECTION'` + if [ $? -ne 0 ]; then + fail "ssh proxyconnect protocol $p failed" + fi + if [ "$SSH_CONNECTION" != "UNKNOWN 65535 UNKNOWN 65535" ]; then + fail "bad SSH_CONNECTION" + fi +done diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/README.regress openssh-3.7p1/regress/README.regress --- ssh-openbsd-2003091600/regress/README.regress 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/README.regress 2003-09-04 15:39:54.000000000 +1000 @@ -0,0 +1,86 @@ +Overview. + +$ ./configure && make tests + +You'll see some progress info. A failure will cause either the make to +abort or the driver script to report a "FATAL" failure. + +The test consists of 2 parts. The first is the file-based tests which is +driven by the Makefile, and the second is a set of network or proxycommand +based tests, which are driven by a driver script (test-exec.sh) which is +called multiple times by the Makefile. + +Failures in the first part will cause the Makefile to return an error. +Failures in the second part will print a "FATAL" message for the failed +test and continue. + +OpenBSD has a system-wide regression test suite. OpenSSH Portable's test +suite is based on OpenBSD's with modifications. + + +Environment variables. + +SUDO: path to sudo command, if desired. Note that some systems (notably + systems using PAM) require sudo to execute some tests. +TEST_SSH_TRACE: set yo "yes" for verbose output from tests +TEST_SSH_QUIET: set to "yes" to suppress non-fatal output. +TEST_SSH_x: path to "ssh" command under test, where x=SSH,SSHD,SSHAGENT,SSHADD + SSHKEYGEN,SSHKEYSCAN,SFTP,SFTPSERVER +OBJ: used by test scripts to access build dir. + + +Individual tests. + +You can invoke test-exec.sh directly if you set up the path to find the +binaries under test and the test scripts themselves, for example: + +$ cd regress +$ PATH=`pwd`/..:$PATH:. sh test-exec.sh `pwd` agent-timeout.sh +ok agent timeout test + + +Files. + +test-exec.sh: the main test driver. Sets environment, creates config files +and keys and runs the specified test. + +At the time of writing, the individual tests are: +agent-timeout.sh: agent timeout test +agent.sh: simple agent test +broken-pipe.sh: broken pipe test +connect-privsep.sh: proxy connect with privsep +connect.sh: simple connect +exit-status.sh: remote exit status +forwarding.sh: local and remote forwarding +keygen-change.sh: change passphrase for key +keyscan.sh: keyscan +proto-mismatch.sh: protocol version mismatch +proto-version.sh: sshd version with different protocol combinations +proxy-connect.sh: proxy connect +sftp.sh: basic sftp put/get +ssh-com-client.sh: connect with ssh.com client +ssh-com-keygen.sh: ssh.com key import +ssh-com-sftp.sh: basic sftp put/get with ssh.com server +ssh-com.sh: connect to ssh.com server +stderr-after-eof.sh: stderr data after eof +stderr-data.sh: stderr data transfer +transfer.sh: transfer data +try-ciphers.sh: try ciphers +yes-head.sh: yes pipe head + + +Problems? + +Run the failing test with shell tracing (-x) turned on: +$ PATH=`pwd`/..:$PATH:. sh -x test-exec.sh `pwd` agent-timeout.sh + +Failed tests can be difficult to diagnose. Suggestions: +- run the individual test via ./test-exec.sh `pwd` [testname] +- set LogLevel to VERBOSE in test-exec.sh and enable syslogging of + auth.debug (eg to /var/log/authlog). + + +Known Issues. + + +$Id: README.regress,v 1.1 2003/09/04 05:39:54 dtucker Exp $ diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/reconfigure.sh openssh-3.7p1/regress/reconfigure.sh --- ssh-openbsd-2003091600/regress/reconfigure.sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/reconfigure.sh 2003-09-04 13:59:49.000000000 +1000 @@ -0,0 +1,35 @@ +# $OpenBSD: reconfigure.sh,v 1.2 2003/06/21 09:14:05 markus Exp $ +# Placed in the Public Domain. + +tid="simple connect after reconfigure" + +# we need the full path to sshd for -HUP +case $SSHD in +/*) + # full path is OK + ;; +*) + # otherwise make fully qualified + SSHD=$OBJ/$SSHD +esac + +start_sshd + +$SUDO kill -HUP `cat $PIDFILE` +sleep 1 + +trace "wait for sshd to restart" +i=0; +while [ ! -f $PIDFILE -a $i -lt 10 ]; do + i=`expr $i + 1` + sleep $i +done + +test -f $PIDFILE || fatal "sshd did not restart" + +for p in 1 2; do + ${SSH} -o "Protocol=$p" -F $OBJ/ssh_config somehost true + if [ $? -ne 0 ]; then + fail "ssh connect with protocol $p failed after reconfigure" + fi +done diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/rekey.sh openssh-3.7p1/regress/rekey.sh --- ssh-openbsd-2003091600/regress/rekey.sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/rekey.sh 2003-09-04 14:02:56.000000000 +1000 @@ -0,0 +1,31 @@ +# $OpenBSD: rekey.sh,v 1.1 2003/03/28 13:58:28 markus Exp $ +# Placed in the Public Domain. + +tid="rekey during transfer data" + +DATA=${OBJ}/data +COPY=${OBJ}/copy +LOG=${OBJ}/log + +rm -f ${COPY} ${LOG} ${DATA} +dd if=/bin/ls${EXEEXT} of=${DATA} bs=1k seek=511 count=1 > /dev/null 2>&1 + +for s in 16 1k 128k 256k; do + trace "rekeylimit ${s}" + rm -f ${COPY} + cat $DATA | \ + ${SSH} -oCompression=no -oRekeyLimit=$s \ + -v -F $OBJ/ssh_proxy somehost "cat > ${COPY}" \ + 2> ${LOG} + if [ $? -ne 0 ]; then + fail "ssh failed" + fi + cmp $DATA ${COPY} || fail "corrupted copy" + n=`grep 'NEWKEYS sent' ${LOG} | wc -l` + n=`expr $n - 1` + trace "$n rekeying(s)" + if [ $n -lt 1 ]; then + fail "no rekeying occured" + fi +done +rm -f ${COPY} ${LOG} ${DATA} diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/rsa_openssh.prv openssh-3.7p1/regress/rsa_openssh.prv --- ssh-openbsd-2003091600/regress/rsa_openssh.prv 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/rsa_openssh.prv 2002-05-01 13:17:34.000000000 +1000 @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICWgIBAAKBgQDsilwKcaKN6wSMNd1WgQ9+HRqQEkD0kCTVttrazGu0OhBU3Uko ++dFD1Ip0CxdXmN25JQWxOYF7h/Ocu8P3jzv3RTX87xKR0YzlXTLX+SLtF/ySebS3 +xWPrlfRUDhh03hR5V+8xxvvy9widPYKw/oItwGSueOsEq1LTczCDv2dAjQIDAQAB +An8nH5VzvHkMbSqJ6eOYDsVwomRvYbH5IEaYl1x6VATITNvAu9kUdQ4NsSpuMc+7 +Jj9gKZvmO1y2YCKc0P/iO+i/eV0L+yQh1Rw18jQZll+12T+LZrKRav03YNvMx0gN +wqWY48Kt6hv2/N/ebQzKRe79+D0t2cTh92hT7xENFLIBAkEBGnoGKFjAUkJCwO1V +mzpUqMHpRZVOrqP9hUmPjzNJ5oBPFGe4+h1hoSRFOAzaNuZt8ssbqaLCkzB8bfzj +qhZqAQJBANZekuUpp8iBLeLSagw5FkcPwPzq6zfExbhvsZXb8Bo/4SflNs4JHXwI +7SD9Z8aJLvM4uQ/5M70lblDMQ40i3o0CQQDIJvBYBFL5tlOgakq/O7yi+wt0L5BZ +9H79w5rCSAA0IHRoK/qI1urHiHC3f3vbbLk5UStfrqEaND/mm0shyNIBAkBLsYdC +/ctt5Bc0wUGK4Vl5bBmj9LtrrMJ4FpBpLwj/69BwCuKoK9XKZ0h73p6XHveCEGRg +PIlFX4MtaoLrwgU9AkBV2k4dgIws+X8YX65EsyyFjnlDqX4x0nSOjQB1msIKfHBr +dh5XLDBTTCxnKhMJ0Yx/opgOvf09XHBFwaQntR5i +-----END RSA PRIVATE KEY----- diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/rsa_openssh.pub openssh-3.7p1/regress/rsa_openssh.pub --- ssh-openbsd-2003091600/regress/rsa_openssh.pub 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/rsa_openssh.pub 2002-05-01 13:17:34.000000000 +1000 @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDsilwKcaKN6wSMNd1WgQ9+HRqQEkD0kCTVttrazGu0OhBU3Uko+dFD1Ip0CxdXmN25JQWxOYF7h/Ocu8P3jzv3RTX87xKR0YzlXTLX+SLtF/ySebS3xWPrlfRUDhh03hR5V+8xxvvy9widPYKw/oItwGSueOsEq1LTczCDv2dAjQ== diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/rsa_ssh2.prv openssh-3.7p1/regress/rsa_ssh2.prv --- ssh-openbsd-2003091600/regress/rsa_ssh2.prv 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/rsa_ssh2.prv 2002-05-01 13:17:34.000000000 +1000 @@ -0,0 +1,16 @@ +---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ---- +Subject: ssh-keygen test +Comment: "1024-bit rsa, Sat Jun 23 2001 12:21:26 -0400" +P2/56wAAAi4AAAA3aWYtbW9kbntzaWdue3JzYS1wa2NzMS1zaGExfSxlbmNyeXB0e3JzYS +1wa2NzMXYyLW9hZXB9fQAAAARub25lAAAB3wAAAdsAAAARAQABAAAD9icflXO8eQxtKonp +45gOxXCiZG9hsfkgRpiXXHpUBMhM28C72RR1Dg2xKm4xz7smP2Apm+Y7XLZgIpzQ/+I76L +95XQv7JCHVHDXyNBmWX7XZP4tmspFq/Tdg28zHSA3CpZjjwq3qG/b8395tDMpF7v34PS3Z +xOH3aFPvEQ0UsgEAAAQA7IpcCnGijesEjDXdVoEPfh0akBJA9JAk1bba2sxrtDoQVN1JKP +nRQ9SKdAsXV5jduSUFsTmBe4fznLvD948790U1/O8SkdGM5V0y1/ki7Rf8knm0t8Vj65X0 +VA4YdN4UeVfvMcb78vcInT2CsP6CLcBkrnjrBKtS03Mwg79nQI0AAAH/VdpOHYCMLPl/GF ++uRLMshY55Q6l+MdJ0jo0AdZrCCnxwa3YeVywwU0wsZyoTCdGMf6KYDr39PVxwRcGkJ7Ue +YgAAAgDWXpLlKafIgS3i0moMORZHD8D86us3xMW4b7GV2/AaP+En5TbOCR18CO0g/WfGiS +7zOLkP+TO9JW5QzEONIt6NAAACAQEaegYoWMBSQkLA7VWbOlSowelFlU6uo/2FSY+PM0nm +gE8UZ7j6HWGhJEU4DNo25m3yyxuposKTMHxt/OOqFmoB +---- END SSH2 ENCRYPTED PRIVATE KEY ---- +--- diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/runtests.sh openssh-3.7p1/regress/runtests.sh --- ssh-openbsd-2003091600/regress/runtests.sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/runtests.sh 2002-05-01 13:17:35.000000000 +1000 @@ -0,0 +1,13 @@ +#!/bin/sh + +TEST_SSH_SSH=../ssh +TEST_SSH_SSHD=../sshd +TEST_SSH_SSHAGENT=../ssh-agent +TEST_SSH_SSHADD=../ssh-add +TEST_SSH_SSHKEYGEN=../ssh-keygen +TEST_SSH_SSHKEYSCAN=../ssh-keyscan +TEST_SSH_SFTP=../sftp +TEST_SSH_SFTPSERVER=../sftp-server + +pmake + diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/sftp-badcmds.sh openssh-3.7p1/regress/sftp-badcmds.sh --- ssh-openbsd-2003091600/regress/sftp-badcmds.sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/sftp-badcmds.sh 2003-09-10 01:35:21.000000000 +1000 @@ -0,0 +1,78 @@ +# $OpenBSD: sftp-badcmds.sh,v 1.2 2003/05/15 04:07:12 mouring Exp $ +# Placed in the Public Domain. + +tid="sftp invalid commands" + +DATA=/bin/ls${EXEEXT} +DATA2=/bin/cat${EXEEXT} +NONEXIST=/NONEXIST.$$ +COPY=${OBJ}/copy +GLOBFILES=`(cd /bin;echo l*)` + +rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd + +rm -f ${COPY} +verbose "$tid: get nonexistent" +echo "get $NONEXIST $COPY" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "get nonexistent failed" +test -f ${COPY} && fail "existing copy after get nonexistent" + +rm -f ${COPY}.dd/* +verbose "$tid: glob get to nonexistent directory" +echo "get /bin/l* $NONEXIST" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "get nonexistent failed" +for x in $GLOBFILES; do + test -f ${COPY}.dd/$x && fail "existing copy after get nonexistent" +done + +rm -f ${COPY} +verbose "$tid: put nonexistent" +echo "put $NONEXIST $COPY" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "put nonexistent failed" +test -f ${COPY} && fail "existing copy after put nonexistent" + +rm -f ${COPY}.dd/* +verbose "$tid: glob put to nonexistent directory" +echo "put /bin/l* ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "put nonexistent failed" +for x in $GLOBFILES; do + test -f ${COPY}.dd/$x && fail "existing copy after nonexistent" +done + +rm -f ${COPY} +verbose "$tid: rename nonexistent" +echo "rename $NONEXIST ${COPY}.1" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "rename nonexist failed" +test -f ${COPY}.1 && fail "file exists after rename nonexistent" + +rm -f ${COPY} ${COPY}.1 +cp $DATA $COPY +cp $DATA2 ${COPY}.1 +verbose "$tid: rename target exists" +echo "rename $COPY ${COPY}.1" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "rename target exists failed" +test -f ${COPY} || fail "oldname missing after rename target exists" +test -f ${COPY}.1 || fail "newname missing after rename target exists" +cmp $DATA ${COPY} >/dev/null 2>&1 || fail "corrupted oldname after rename target exists" +cmp $DATA2 ${COPY}.1 >/dev/null 2>&1 || fail "corrupted newname after rename target exists" + +rm -rf ${COPY} ${COPY}.dd +cp $DATA $COPY +mkdir ${COPY}.dd +verbose "$tid: rename target exists (directory)" +echo "rename $COPY ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "rename target exists (directory) failed" +test -f ${COPY} || fail "oldname missing after rename target exists (directory)" +test -d ${COPY}.dd || fail "newname missing after rename target exists (directory)" +cmp $DATA ${COPY} >/dev/null 2>&1 || fail "corrupted oldname after rename target exists (directory)" + +rm -f ${COPY}.dd/* +rm -rf ${COPY} +cp ${DATA2} ${COPY} +verbose "$tid: glob put files to local file" +echo "put /bin/l* $COPY" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 +cmp ${DATA2} ${COPY} || fail "put successed when it should have failed" + +rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd + + diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/sftp-batch.sh openssh-3.7p1/regress/sftp-batch.sh --- ssh-openbsd-2003091600/regress/sftp-batch.sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/sftp-batch.sh 2003-09-07 09:31:02.000000000 +1000 @@ -0,0 +1,57 @@ +# $OpenBSD: sftp-batch.sh,v 1.2 2003/01/10 07:52:41 djm Exp $ +# Placed in the Public Domain. + +tid="sftp batchfile" + +DATA=/bin/ls${EXEEXT} +COPY=${OBJ}/copy +BATCH=${OBJ}/sftp-batch.tmp + +rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${BATCH}.* + +cat << EOF > ${BATCH}.pass.1 + get $DATA $COPY + put ${COPY} ${COPY}.1 + rm ${COPY} + -put ${COPY} ${COPY}.2 +EOF + +cat << EOF > ${BATCH}.pass.2 + # This is a comment + + # That was a blank line + ls +EOF + +cat << EOF > ${BATCH}.fail.1 + get $DATA $COPY + put ${COPY} ${COPY}.3 + rm ${COPY}.* + # The next command should fail + put ${COPY}.3 ${COPY}.4 +EOF + +cat << EOF > ${BATCH}.fail.2 + # The next command should fail + jajajajaja +EOF + +verbose "$tid: good commands" +${SFTP} -b ${BATCH}.pass.1 -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "good commands failed" + +verbose "$tid: bad commands" +${SFTP} -b ${BATCH}.fail.1 -P ${SFTPSERVER} >/dev/null 2>&1 \ + && fail "bad commands succeeded" + +verbose "$tid: comments and blanks" +${SFTP} -b ${BATCH}.pass.2 -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "comments & blanks failed" + +verbose "$tid: junk command" +${SFTP} -b ${BATCH}.fail.2 -P ${SFTPSERVER} >/dev/null 2>&1 \ + && fail "junk command succeeded" + +rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${BATCH}.* + + diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/sftp-cmds.sh openssh-3.7p1/regress/sftp-cmds.sh --- ssh-openbsd-2003091600/regress/sftp-cmds.sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/sftp-cmds.sh 2003-09-12 15:32:17.000000000 +1000 @@ -0,0 +1,195 @@ +# $OpenBSD: sftp-cmds.sh,v 1.5 2003/07/19 00:46:31 djm Exp $ +# Placed in the Public Domain. + +# XXX - TODO: +# - chmod / chown / chgrp +# - -p flag for get & put + +tid="sftp commands" + +DATA=/bin/ls${EXEEXT} +COPY=${OBJ}/copy +# test that these files are readable! +for i in `(cd /bin;echo l*)` +do + if [ -r $i ]; then + GLOBFILES="$GLOBFILES $i" + fi +done + +if have_prog uname +then + case `uname` in + CYGWIN*) + os=cygwin + ;; + *) + os=`uname` + ;; + esac +else + os="unknown" +fi + +# Path with embedded quote +QUOTECOPY=${COPY}".\"blah\"" +QUOTECOPY_ARG=${COPY}'.\"blah\"' + +rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${COPY}.dd2 +mkdir ${COPY}.dd + +verbose "$tid: lls" +echo "lls ${OBJ}" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "lls failed" +# XXX always successful + +verbose "$tid: ls" +echo "ls ${OBJ}" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "ls failed" +# XXX always successful + +verbose "$tid: shell" +echo "!echo hi there" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "shell failed" +# XXX always successful + +verbose "$tid: pwd" +echo "pwd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "pwd failed" +# XXX always successful + +verbose "$tid: lpwd" +echo "lpwd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "lpwd failed" +# XXX always successful + +verbose "$tid: quit" +echo "quit" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "quit failed" +# XXX always successful + +verbose "$tid: help" +echo "help" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "help failed" +# XXX always successful + +rm -f ${COPY} +verbose "$tid: get" +echo "get $DATA $COPY" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "get failed" +cmp $DATA ${COPY} || fail "corrupted copy after get" + +rm -f ${COPY}.dd/* +verbose "$tid: get to directory" +echo "get $DATA ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "get failed" +cmp $DATA ${COPY}.dd/`basename $DATA` || fail "corrupted copy after get" + +rm -f ${COPY}.dd/* +verbose "$tid: glob get to directory" +echo "get /bin/l* ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "get failed" +for x in $GLOBFILES; do + cmp /bin/$x ${COPY}.dd/$x || fail "corrupted copy after get" +done + +rm -f ${COPY}.dd/* +verbose "$tid: get to local dir" +(echo "lcd ${COPY}.dd"; echo "get $DATA" ) | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "get failed" +cmp $DATA ${COPY}.dd/`basename $DATA` || fail "corrupted copy after get" + +rm -f ${COPY}.dd/* +verbose "$tid: glob get to local dir" +(echo "lcd ${COPY}.dd"; echo "get /bin/l*") | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "get failed" +for x in $GLOBFILES; do + cmp /bin/$x ${COPY}.dd/$x || fail "corrupted copy after get" +done + +rm -f ${COPY} +verbose "$tid: put" +echo "put $DATA $COPY" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "put failed" +cmp $DATA ${COPY} || fail "corrupted copy after put" + +if [ "$os" != "cygwin" ]; then +rm -f ${QUOTECOPY} +verbose "$tid: put filename with quotes" +echo "put $DATA \"$QUOTECOPY_ARG\"" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "put failed" +cmp $DATA ${QUOTECOPY} || fail "corrupted copy after put with quotes" +fi + +rm -f ${COPY}.dd/* +verbose "$tid: put to directory" +echo "put $DATA ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "put failed" +cmp $DATA ${COPY}.dd/`basename $DATA` || fail "corrupted copy after put" + +rm -f ${COPY}.dd/* +verbose "$tid: glob put to directory" +echo "put /bin/l* ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "put failed" +for x in $GLOBFILES; do + cmp /bin/$x ${COPY}.dd/$x || fail "corrupted copy after put" +done + +rm -f ${COPY}.dd/* +verbose "$tid: put to local dir" +(echo "cd ${COPY}.dd"; echo "put $DATA") | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "put failed" +cmp $DATA ${COPY}.dd/`basename $DATA` || fail "corrupted copy after put" + +rm -f ${COPY}.dd/* +verbose "$tid: glob put to local dir" +(echo "cd ${COPY}.dd"; echo "put /bin/l*") | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "put failed" +for x in $GLOBFILES; do + cmp /bin/$x ${COPY}.dd/$x || fail "corrupted copy after put" +done + +verbose "$tid: rename" +echo "rename $COPY ${COPY}.1" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "rename failed" +test -f ${COPY}.1 || fail "missing file after rename" +cmp $DATA ${COPY}.1 >/dev/null 2>&1 || fail "corrupted copy after rename" + +verbose "$tid: rename directory" +echo "rename ${COPY}.dd ${COPY}.dd2" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "rename directory failed" +test -d ${COPY}.dd && fail "oldname exists after rename directory" +test -d ${COPY}.dd2 || fail "missing newname after rename directory" + +verbose "$tid: ln" +echo "ln ${COPY}.1 ${COPY}.2" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 || fail "ln failed" +test -h ${COPY}.2 || fail "missing file after ln" + +verbose "$tid: mkdir" +echo "mkdir ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "mkdir failed" +test -d ${COPY}.dd || fail "missing directory after mkdir" + +# XXX do more here +verbose "$tid: chdir" +echo "chdir ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "chdir failed" + +verbose "$tid: rmdir" +echo "rmdir ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "rmdir failed" +test -d ${COPY}.1 && fail "present directory after rmdir" + +verbose "$tid: lmkdir" +echo "lmkdir ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "lmkdir failed" +test -d ${COPY}.dd || fail "missing directory after lmkdir" + +# XXX do more here +verbose "$tid: lchdir" +echo "lchdir ${COPY}.dd" | ${SFTP} -P ${SFTPSERVER} >/dev/null 2>&1 \ + || fail "lchdir failed" + +rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${COPY}.dd2 + + diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/sftp.sh openssh-3.7p1/regress/sftp.sh --- ssh-openbsd-2003091600/regress/sftp.sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/sftp.sh 2003-09-04 15:00:56.000000000 +1000 @@ -0,0 +1,35 @@ +# $OpenBSD: sftp.sh,v 1.2 2002/03/27 22:39:52 markus Exp $ +# Placed in the Public Domain. + +tid="basic sftp put/get" + +DATA=/bin/ls${EXEEXT} +COPY=${OBJ}/copy + +SFTPCMDFILE=${OBJ}/batch +cat >$SFTPCMDFILE < /dev/null 2>&1 + r=$? + if [ $r -ne 0 ]; then + fail "sftp failed with $r" + else + cmp $DATA ${COPY}.1 || fail "corrupted copy after get" + cmp $DATA ${COPY}.2 || fail "corrupted copy after put" + fi + done +done +rm -f ${COPY}.1 ${COPY}.2 +rm -f $SFTPCMDFILE diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/ssh-com-client.sh openssh-3.7p1/regress/ssh-com-client.sh --- ssh-openbsd-2003091600/regress/ssh-com-client.sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/ssh-com-client.sh 2003-09-04 14:54:40.000000000 +1000 @@ -0,0 +1,131 @@ +# $OpenBSD: ssh-com-client.sh,v 1.5 2003/05/14 22:08:27 markus Exp $ +# Placed in the Public Domain. + +tid="connect with ssh.com client" + +#TEST_COMBASE=/path/to/ssh/com/binaries +if [ "X${TEST_COMBASE}" = "X" ]; then + fatal '$TEST_COMBASE is not set' +fi + +VERSIONS=" + 2.1.0 + 2.2.0 + 2.3.0 + 2.3.1 + 2.4.0 + 3.0.0 + 3.1.0 + 3.2.0 + 3.2.2 + 3.2.3 + 3.3.0" + +# 2.0.10 2.0.12 2.0.13 don't like the test setup + +# setup authorized keys +SRC=`dirname ${SCRIPT}` +cp ${SRC}/dsa_ssh2.prv ${OBJ}/id.com +chmod 600 ${OBJ}/id.com +${SSHKEYGEN} -i -f ${OBJ}/id.com > $OBJ/id.openssh +chmod 600 ${OBJ}/id.openssh +${SSHKEYGEN} -y -f ${OBJ}/id.openssh > $OBJ/authorized_keys_$USER +${SSHKEYGEN} -e -f ${OBJ}/id.openssh > $OBJ/id.com.pub +echo IdKey ${OBJ}/id.com > ${OBJ}/id.list + +# we need a DSA host key +t=dsa +rm -f ${OBJ}/$t ${OBJ}/$t.pub +${SSHKEYGEN} -q -N '' -t $t -f ${OBJ}/$t +$SUDO cp $OBJ/$t $OBJ/host.$t +echo HostKey $OBJ/host.$t >> $OBJ/sshd_config + +# add hostkeys to known hosts +mkdir -p ${OBJ}/${USER}/hostkeys +HK=${OBJ}/${USER}/hostkeys/key_${PORT}_127.0.0.1 +${SSHKEYGEN} -e -f ${OBJ}/rsa.pub > ${HK}.ssh-rsa.pub +${SSHKEYGEN} -e -f ${OBJ}/dsa.pub > ${HK}.ssh-dss.pub + +cat > ${OBJ}/ssh2_config << EOF +*: + QuietMode yes + StrictHostKeyChecking yes + Port ${PORT} + User ${USER} + Host 127.0.0.1 + IdentityFile ${OBJ}/id.list + RandomSeedFile ${OBJ}/random_seed + UserConfigDirectory ${OBJ}/%U + AuthenticationSuccessMsg no + BatchMode yes + ForwardX11 no +EOF + +# we need a real server (no ProxyConnect option) +start_sshd + +DATA=/bin/ls${EXEEXT} +COPY=${OBJ}/copy +rm -f ${COPY} + +# go for it +for v in ${VERSIONS}; do + ssh2=${TEST_COMBASE}/${v}/ssh2 + if [ ! -x ${ssh2} ]; then + continue + fi + verbose "ssh2 ${v}" + key=ssh-dss + skipcat=0 + case $v in + 2.1.*|2.3.0) + skipcat=1 + ;; + 3.0.*) + key=ssh-rsa + ;; + esac + cp ${HK}.$key.pub ${HK}.pub + + # check exit status + ${ssh2} -q -F ${OBJ}/ssh2_config somehost exit 42 + r=$? + if [ $r -ne 42 ]; then + fail "ssh2 ${v} exit code test failed (got $r, expected 42)" + fi + + # data transfer + rm -f ${COPY} + ${ssh2} -F ${OBJ}/ssh2_config somehost cat ${DATA} > ${COPY} + if [ $? -ne 0 ]; then + fail "ssh2 ${v} cat test (receive) failed" + fi + cmp ${DATA} ${COPY} || fail "ssh2 ${v} cat test (receive) data mismatch" + + # data transfer, again + if [ $skipcat -eq 0 ]; then + rm -f ${COPY} + cat ${DATA} | \ + ${ssh2} -F ${OBJ}/ssh2_config host "cat > ${COPY}" + if [ $? -ne 0 ]; then + fail "ssh2 ${v} cat test (send) failed" + fi + cmp ${DATA} ${COPY} || \ + fail "ssh2 ${v} cat test (send) data mismatch" + fi + + # no stderr after eof + rm -f ${COPY} + ${ssh2} -F ${OBJ}/ssh2_config somehost \ + exec sh -c \'"exec > /dev/null; sleep 1; echo bla 1>&2; exit 0"\' \ + 2> /dev/null + if [ $? -ne 0 ]; then + fail "ssh2 ${v} stderr test failed" + fi +done + +rm -rf ${OBJ}/${USER} +for i in ssh2_config random_seed dsa.pub dsa host.dsa \ + id.list id.com id.com.pub id.openssh; do + rm -f ${OBJ}/$i +done diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/ssh-com-keygen.sh openssh-3.7p1/regress/ssh-com-keygen.sh --- ssh-openbsd-2003091600/regress/ssh-com-keygen.sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/ssh-com-keygen.sh 2003-06-18 22:36:49.000000000 +1000 @@ -0,0 +1,71 @@ +# $OpenBSD: ssh-com-keygen.sh,v 1.3 2003/05/14 22:08:27 markus Exp $ +# Placed in the Public Domain. + +tid="ssh.com key import" + +#TEST_COMBASE=/path/to/ssh/com/binaries +if [ "X${TEST_COMBASE}" = "X" ]; then + fatal '$TEST_COMBASE is not set' +fi + +VERSIONS=" + 2.0.10 + 2.0.12 + 2.0.13 + 2.1.0 + 2.2.0 + 2.3.0 + 2.3.1 + 2.4.0 + 3.0.0 + 3.1.0 + 3.2.0 + 3.2.2 + 3.2.3 + 3.3.0" + +COMPRV=${OBJ}/comkey +COMPUB=${COMPRV}.pub +OPENSSHPRV=${OBJ}/opensshkey +OPENSSHPUB=${OPENSSHPRV}.pub + +# go for it +for v in ${VERSIONS}; do + keygen=${TEST_COMBASE}/${v}/ssh-keygen2 + if [ ! -x ${keygen} ]; then + continue + fi + types="dss" + case $v in + 2.3.1|3.*) + types="$types rsa" + ;; + esac + for t in $types; do + verbose "ssh-keygen $v/$t" + rm -f $COMPRV $COMPUB $OPENSSHPRV $OPENSSHPUB + ${keygen} -q -P -t $t ${COMPRV} > /dev/null 2>&1 + if [ $? -ne 0 ]; then + fail "${keygen} -t $t failed" + continue + fi + ${SSHKEYGEN} -if ${COMPUB} > ${OPENSSHPUB} + if [ $? -ne 0 ]; then + fail "import public key ($v/$t) failed" + continue + fi + ${SSHKEYGEN} -if ${COMPRV} > ${OPENSSHPRV} + if [ $? -ne 0 ]; then + fail "import private key ($v/$t) failed" + continue + fi + chmod 600 ${OPENSSHPRV} + ${SSHKEYGEN} -yf ${OPENSSHPRV} |\ + diff - ${OPENSSHPUB} + if [ $? -ne 0 ]; then + fail "public keys ($v/$t) differ" + fi + done +done + +rm -f $COMPRV $COMPUB $OPENSSHPRV $OPENSSHPUB diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/ssh-com-sftp.sh openssh-3.7p1/regress/ssh-com-sftp.sh --- ssh-openbsd-2003091600/regress/ssh-com-sftp.sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/ssh-com-sftp.sh 2003-09-04 15:26:57.000000000 +1000 @@ -0,0 +1,64 @@ +# $OpenBSD: ssh-com-sftp.sh,v 1.4 2003/05/14 22:08:27 markus Exp $ +# Placed in the Public Domain. + +tid="basic sftp put/get with ssh.com server" + +DATA=/bin/ls${EXEEXT} +COPY=${OBJ}/copy +SFTPCMDFILE=${OBJ}/batch + +cat >$SFTPCMDFILE < /dev/null 2>&1 + r=$? + if [ $r -ne 0 ]; then + fail "sftp failed with $r" + else + cmp $DATA ${COPY}.1 || fail "corrupted copy after get" + cmp $DATA ${COPY}.2 || fail "corrupted copy after put" + fi + done + done +done +rm -f ${COPY}.1 ${COPY}.2 +rm -f $SFTPCMDFILE diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/ssh-com.sh openssh-3.7p1/regress/ssh-com.sh --- ssh-openbsd-2003091600/regress/ssh-com.sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/ssh-com.sh 2003-09-04 15:16:57.000000000 +1000 @@ -0,0 +1,116 @@ +# $OpenBSD: ssh-com.sh,v 1.5 2003/05/14 22:08:27 markus Exp $ +# Placed in the Public Domain. + +tid="connect to ssh.com server" + +#TEST_COMBASE=/path/to/ssh/com/binaries +if [ "X${TEST_COMBASE}" = "X" ]; then + fatal '$TEST_COMBASE is not set' +fi + +VERSIONS=" + 2.0.12 + 2.0.13 + 2.1.0 + 2.2.0 + 2.3.0 + 2.4.0 + 3.0.0 + 3.1.0 + 3.2.0 + 3.2.2 + 3.2.3 + 3.3.0" +# 2.0.10 does not support UserConfigDirectory +# 2.3.1 requires a config in $HOME/.ssh2 + +SRC=`dirname ${SCRIPT}` + +# ssh.com +cat << EOF > $OBJ/sshd2_config +#*: + # Port and ListenAdress are not used. + QuietMode yes + Port 4343 + ListenAddress 127.0.0.1 + UserConfigDirectory ${OBJ}/%U + Ciphers AnyCipher + PubKeyAuthentication yes + #AllowedAuthentications publickey + AuthorizationFile authorization + HostKeyFile ${SRC}/dsa_ssh2.prv + PublicHostKeyFile ${SRC}/dsa_ssh2.pub + RandomSeedFile ${OBJ}/random_seed + MaxConnections 0 + PermitRootLogin yes + VerboseMode no + CheckMail no + Ssh1Compatibility no +EOF + +# create client config +sed "s/HostKeyAlias.*/HostKeyAlias ssh2-localhost-with-alias/" \ + < $OBJ/ssh_config > $OBJ/ssh_config_com + +# we need a DSA key for +rm -f ${OBJ}/dsa ${OBJ}/dsa.pub +${SSHKEYGEN} -q -N '' -t dsa -f ${OBJ}/dsa + +# setup userdir, try rsa first +mkdir -p ${OBJ}/${USER} +cp /dev/null ${OBJ}/${USER}/authorization +for t in rsa dsa; do + ${SSHKEYGEN} -e -f ${OBJ}/$t.pub > ${OBJ}/${USER}/$t.com + echo Key $t.com >> ${OBJ}/${USER}/authorization + echo IdentityFile ${OBJ}/$t >> ${OBJ}/ssh_config_com +done + +# convert and append DSA hostkey +( + echon 'ssh2-localhost-with-alias,127.0.0.1,::1 ' + ${SSHKEYGEN} -if ${SRC}/dsa_ssh2.pub +) >> $OBJ/known_hosts + +# go for it +for v in ${VERSIONS}; do + sshd2=${TEST_COMBASE}/${v}/sshd2 + if [ ! -x ${sshd2} ]; then + continue + fi + trace "sshd2 ${v}" + PROXY="proxycommand ${sshd2} -qif ${OBJ}/sshd2_config 2> /dev/null" + ${SSH} -qF ${OBJ}/ssh_config_com -o "${PROXY}" dummy exit 0 + if [ $? -ne 0 ]; then + fail "ssh connect to sshd2 ${v} failed" + fi + + ciphers="3des-cbc blowfish-cbc arcfour" + macs="hmac-md5" + case $v in + 2.4.*) + ciphers="$ciphers cast128-cbc" + macs="$macs hmac-sha1 hmac-sha1-96 hmac-md5-96" + ;; + 3.*) + ciphers="$ciphers aes128-cbc cast128-cbc" + macs="$macs hmac-sha1 hmac-sha1-96 hmac-md5-96" + ;; + esac + #ciphers="3des-cbc" + for m in $macs; do + for c in $ciphers; do + trace "sshd2 ${v} cipher $c mac $m" + verbose "test ${tid}: sshd2 ${v} cipher $c mac $m" + ${SSH} -c $c -m $m -qF ${OBJ}/ssh_config_com -o "${PROXY}" dummy exit 0 + if [ $? -ne 0 ]; then + fail "ssh connect to sshd2 ${v} with $c/$m failed" + fi + done + done +done + +rm -rf ${OBJ}/${USER} +for i in sshd_config_proxy ssh_config_proxy random_seed \ + sshd2_config dsa.pub dsa ssh_config_com; do + rm -f ${OBJ}/$i +done diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/stderr-after-eof.sh openssh-3.7p1/regress/stderr-after-eof.sh --- ssh-openbsd-2003091600/regress/stderr-after-eof.sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/stderr-after-eof.sh 2003-09-12 15:32:17.000000000 +1000 @@ -0,0 +1,40 @@ +# $OpenBSD: stderr-after-eof.sh,v 1.1 2002/03/23 16:38:09 markus Exp $ +# Placed in the Public Domain. + +tid="stderr data after eof" + +DATA=/etc/motd +DATA=${OBJ}/data +COPY=${OBJ}/copy + +if have_prog md5sum; then + CHECKSUM=md5sum +elif have_prog openssl; then + CHECKSUM="openssl md5" +elif have_prog cksum; then + CHECKSUM=cksum +elif have_prog sum; then + CHECKSUM=sum +else + fatal "No checksum program available, aborting $tid test" +fi + +# setup data +rm -f ${DATA} ${COPY} +cp /dev/null ${DATA} +for i in 1 2 3 4 5 6; do + (date;echo $i) | $CHECKSUM >> ${DATA} +done + +${SSH} -2 -F $OBJ/ssh_proxy otherhost \ + exec sh -c \'"exec > /dev/null; sleep 2; cat ${DATA} 1>&2 $s"\' \ + 2> ${COPY} +r=$? +if [ $r -ne 0 ]; then + fail "ssh failed with exit code $r" +fi +egrep 'Disconnecting: Received extended_data after EOF' ${COPY} && + fail "ext data received after eof" +cmp ${DATA} ${COPY} || fail "stderr corrupt" + +rm -f ${DATA} ${COPY} diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/stderr-data.sh openssh-3.7p1/regress/stderr-data.sh --- ssh-openbsd-2003091600/regress/stderr-data.sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/stderr-data.sh 2003-09-04 14:54:40.000000000 +1000 @@ -0,0 +1,33 @@ +# $OpenBSD: stderr-data.sh,v 1.2 2002/03/27 22:39:52 markus Exp $ +# Placed in the Public Domain. + +tid="stderr data transfer" + +DATA=/bin/ls${EXEEXT} +COPY=${OBJ}/copy +rm -f ${COPY} + +for n in '' -n; do +for p in 1 2; do + verbose "test $tid: proto $p ($n)" + ${SSH} $n -$p -F $OBJ/ssh_proxy otherhost \ + exec sh -c \'"exec > /dev/null; sleep 3; cat ${DATA} 1>&2 $s"\' \ + 2> ${COPY} + r=$? + if [ $r -ne 0 ]; then + fail "ssh failed with exit code $r" + fi + cmp ${DATA} ${COPY} || fail "stderr corrupt" + rm -f ${COPY} + + ${SSH} $n -$p -F $OBJ/ssh_proxy otherhost \ + exec sh -c \'"echo a; exec > /dev/null; sleep 3; cat ${DATA} 1>&2 $s"\' \ + > /dev/null 2> ${COPY} + r=$? + if [ $r -ne 0 ]; then + fail "ssh failed with exit code $r" + fi + cmp ${DATA} ${COPY} || fail "stderr corrupt" + rm -f ${COPY} +done +done diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/t4.ok openssh-3.7p1/regress/t4.ok --- ssh-openbsd-2003091600/regress/t4.ok 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/t4.ok 2002-05-01 13:17:35.000000000 +1000 @@ -0,0 +1 @@ +3b:dd:44:e9:49:18:84:95:f1:e7:33:6b:9d:93:b1:36 diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/t5.ok openssh-3.7p1/regress/t5.ok --- ssh-openbsd-2003091600/regress/t5.ok 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/t5.ok 2002-05-01 13:17:35.000000000 +1000 @@ -0,0 +1 @@ +xokes-lylis-byleh-zebib-kalus-bihas-tevah-haroz-suhar-foved-noxex diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/test-exec.sh openssh-3.7p1/regress/test-exec.sh --- ssh-openbsd-2003091600/regress/test-exec.sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/test-exec.sh 2003-09-12 15:32:17.000000000 +1000 @@ -0,0 +1,257 @@ +# $OpenBSD: test-exec.sh,v 1.14 2002/04/15 15:19:48 markus Exp $ +# Placed in the Public Domain. + +PORT=4242 +#SUDO=sudo + +if [ -x /usr/ucb/whoami ]; then + USER=`/usr/ucb/whoami` +elif whoami >/dev/null 2>&1; then + USER=`whoami` +else + USER=`id -un` +fi + +OBJ=$1 +if [ "x$OBJ" = "x" ]; then + echo '$OBJ not defined' + exit 2 +fi +if [ ! -d $OBJ ]; then + echo "not a directory: $OBJ" + exit 2 +fi +SCRIPT=$2 +if [ "x$SCRIPT" = "x" ]; then + echo '$SCRIPT not defined' + exit 2 +fi +if [ ! -f $SCRIPT ]; then + echo "not a file: $SCRIPT" + exit 2 +fi +if sh -n $SCRIPT; then + true +else + echo "syntax error in $SCRIPT" + exit 2 +fi +unset SSH_AUTH_SOCK + +# defaults +SSH=ssh +SSHD=sshd +SSHAGENT=ssh-agent +SSHADD=ssh-add +SSHKEYGEN=ssh-keygen +SSHKEYSCAN=ssh-keyscan +SFTP=sftp +SFTPSERVER=/usr/libexec/openssh/sftp-server + +if [ "x$TEST_SSH_SSH" != "x" ]; then + SSH=${TEST_SSH_SSH} +fi +if [ "x$TEST_SSH_SSHD" != "x" ]; then + SSHD=${TEST_SSH_SSHD} +fi +if [ "x$TEST_SSH_SSHAGENT" != "x" ]; then + SSHAGENT=${TEST_SSH_SSHAGENT} +fi +if [ "x$TEST_SSH_SSHADD" != "x" ]; then + SSHADD=${TEST_SSH_SSHADD} +fi +if [ "x$TEST_SSH_SSHKEYGEN" != "x" ]; then + SSHKEYGEN=${TEST_SSH_SSHKEYGEN} +fi +if [ "x$TEST_SSH_SSHKEYSCAN" != "x" ]; then + SSHKEYSCAN=${TEST_SSH_SSHKEYSCAN} +fi +if [ "x$TEST_SSH_SFTP" != "x" ]; then + SFTP=${TEST_SSH_SFTP} +fi +if [ "x$TEST_SSH_SFTPSERVER" != "x" ]; then + SFTPSERVER=${TEST_SSH_SFTPSERVER} +fi + +# these should be used in tests +export SSH SSHD SSHAGENT SSHADD SSHKEYGEN SSHKEYSCAN SFTP SFTPSERVER +#echo $SSH $SSHD $SSHAGENT $SSHADD $SSHKEYGEN $SSHKEYSCAN $SFTP $SFTPSERVER + +# helper +echon() +{ + if [ "x`echo -n`" = "x" ]; then + echo -n "$@" + elif [ "x`echo '\c'`" = "x" ]; then + echo "$@\c" + else + fatal "Don't know how to echo without newline." + fi +} + +have_prog() +{ + saved_IFS="$IFS" + IFS=":" + for i in $PATH + do + if [ -x $i/$1 ]; then + IFS="$saved_IFS" + return 0 + fi + done + IFS="$saved_IFS" + return 1 +} + +cleanup () +{ + if [ -f $PIDFILE ]; then + pid=`cat $PIDFILE` + if [ "X$pid" = "X" ]; then + echo no sshd running + else + if [ $pid -lt 2 ]; then + echo bad pid for ssd: $pid + else + $SUDO kill $pid + fi + fi + fi +} + +trace () +{ + if [ "X$TEST_SSH_TRACE" = "Xyes" ]; then + echo "$@" + fi +} + +verbose () +{ + if [ "X$TEST_SSH_QUIET" != "Xyes" ]; then + echo "$@" + fi +} + + +fail () +{ + RESULT=1 + echo "$@" +} + +fatal () +{ + echon "FATAL: " + fail "$@" + cleanup + exit $RESULT +} + +RESULT=0 +PIDFILE=$OBJ/pidfile + +trap fatal 3 2 + +# create server config +cat << EOF > $OBJ/sshd_config + Port $PORT + ListenAddress 127.0.0.1 + #ListenAddress ::1 + PidFile $PIDFILE + AuthorizedKeysFile $OBJ/authorized_keys_%u + LogLevel QUIET + StrictModes no +EOF + +# server config for proxy connects +cp $OBJ/sshd_config $OBJ/sshd_proxy + +# allow group-writable directories in proxy-mode +echo 'StrictModes no' >> $OBJ/sshd_proxy + +# create client config +cat << EOF > $OBJ/ssh_config +Host * + Hostname 127.0.0.1 + HostKeyAlias localhost-with-alias + Port $PORT + User $USER + GlobalKnownHostsFile $OBJ/known_hosts + UserKnownHostsFile $OBJ/known_hosts + RSAAuthentication yes + PubkeyAuthentication yes + ChallengeResponseAuthentication no + HostbasedAuthentication no + PasswordAuthentication no + RhostsAuthentication no + RhostsRSAAuthentication no + BatchMode yes + StrictHostKeyChecking yes +EOF + +rm -f $OBJ/known_hosts $OBJ/authorized_keys_$USER + +trace "generate keys" +for t in rsa rsa1; do + # generate user key + rm -f $OBJ/$t + ${SSHKEYGEN} -q -N '' -t $t -f $OBJ/$t ||\ + fail "ssh-keygen for $t failed" + + # known hosts file for client + ( + echon 'localhost-with-alias,127.0.0.1,::1 ' + cat $OBJ/$t.pub + ) >> $OBJ/known_hosts + + # setup authorized keys + cat $OBJ/$t.pub >> $OBJ/authorized_keys_$USER + echo IdentityFile $OBJ/$t >> $OBJ/ssh_config + + # use key as host key, too + $SUDO cp $OBJ/$t $OBJ/host.$t + echo HostKey $OBJ/host.$t >> $OBJ/sshd_config + + # don't use SUDO for proxy connect + echo HostKey $OBJ/$t >> $OBJ/sshd_proxy +done +chmod 644 $OBJ/authorized_keys_$USER + +# create a proxy version of the client config +( + cat $OBJ/ssh_config + echo proxycommand ${SUDO} ${SSHD} -i -f $OBJ/sshd_proxy +) > $OBJ/ssh_proxy + +# check proxy config +${SSHD} -t -f $OBJ/sshd_proxy || fatal "sshd_proxy broken" + +start_sshd () +{ + # start sshd + $SUDO ${SSHD} -f $OBJ/sshd_config -t || fatal "sshd_config broken" + $SUDO ${SSHD} -f $OBJ/sshd_config + + trace "wait for sshd" + i=0; + while [ ! -f $PIDFILE -a $i -lt 10 ]; do + i=`expr $i + 1` + sleep $i + done + + test -f $PIDFILE || fatal "no sshd running on port $PORT" +} + +# source test body +. $SCRIPT + +# kill sshd +cleanup +if [ $RESULT -eq 0 ]; then + verbose ok $tid +else + echo failed $tid +fi +exit $RESULT diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/transfer.sh openssh-3.7p1/regress/transfer.sh --- ssh-openbsd-2003091600/regress/transfer.sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/transfer.sh 2003-09-04 14:54:40.000000000 +1000 @@ -0,0 +1,29 @@ +# $OpenBSD: transfer.sh,v 1.1 2002/03/27 00:03:37 markus Exp $ +# Placed in the Public Domain. + +tid="transfer data" + +DATA=/bin/ls${EXEEXT} +COPY=${OBJ}/copy + +for p in 1 2; do + verbose "$tid: proto $p" + rm -f ${COPY} + ${SSH} -n -q -$p -F $OBJ/ssh_proxy somehost cat ${DATA} > ${COPY} + if [ $? -ne 0 ]; then + fail "ssh cat $DATA failed" + fi + cmp ${DATA} ${COPY} || fail "corrupted copy" + + for s in 10 100 1k 32k 64k 128k 256k; do + trace "proto $p dd-size ${s}" + rm -f ${COPY} + dd if=$DATA obs=${s} 2> /dev/null | \ + ${SSH} -q -$p -F $OBJ/ssh_proxy somehost "cat > ${COPY}" + if [ $? -ne 0 ]; then + fail "ssh cat $DATA failed" + fi + cmp $DATA ${COPY} || fail "corrupted copy" + done +done +rm -f ${COPY} diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/try-ciphers.sh openssh-3.7p1/regress/try-ciphers.sh --- ssh-openbsd-2003091600/regress/try-ciphers.sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/try-ciphers.sh 2003-06-18 22:43:13.000000000 +1000 @@ -0,0 +1,30 @@ +# $OpenBSD: try-ciphers.sh,v 1.8 2003/06/12 15:40:01 markus Exp $ +# Placed in the Public Domain. + +tid="try ciphers" + +ciphers="aes128-cbc 3des-cbc blowfish-cbc cast128-cbc arcfour + aes192-cbc aes256-cbc rijndael-cbc@lysator.liu.se + aes128-ctr aes192-ctr aes256-ctr" +macs="hmac-sha1 hmac-md5 hmac-sha1-96 hmac-md5-96" + +for c in $ciphers; do + for m in $macs; do + trace "proto 2 cipher $c mac $m" + verbose "test $tid: proto 2 cipher $c mac $m" + ${SSH} -F $OBJ/ssh_proxy -2 -m $m -c $c somehost true + if [ $? -ne 0 ]; then + fail "ssh -2 failed with mac $m cipher $c" + fi + done +done + +ciphers="3des blowfish" +for c in $ciphers; do + trace "proto 1 cipher $c" + verbose "test $tid: proto 1 cipher $c" + ${SSH} -F $OBJ/ssh_proxy -1 -c $c somehost true + if [ $? -ne 0 ]; then + fail "ssh -1 failed with cipher $c" + fi +done diff -ruN --exclude CVS ssh-openbsd-2003091600/regress/yes-head.sh openssh-3.7p1/regress/yes-head.sh --- ssh-openbsd-2003091600/regress/yes-head.sh 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/regress/yes-head.sh 2003-09-13 06:21:14.000000000 +1000 @@ -0,0 +1,15 @@ +# $OpenBSD: yes-head.sh,v 1.4 2002/03/15 13:08:56 markus Exp $ +# Placed in the Public Domain. + +tid="yes pipe head" + +for p in 1 2; do + lines=`${SSH} -$p -F $OBJ/ssh_proxy thishost 'sh -c "while true;do echo yes;done | head -2000"' | (sleep 3 ; wc -l)` + if [ $? -ne 0 ]; then + fail "yes|head test failed" + lines = 0; + fi + if [ $lines -ne 2000 ]; then + fail "yes|head returns $lines lines instead of 2000" + fi +done diff -ruN --exclude CVS ssh-openbsd-2003091600/RFC.nroff openssh-3.7p1/RFC.nroff --- ssh-openbsd-2003091600/RFC.nroff 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/RFC.nroff 2000-11-06 12:39:34.000000000 +1100 @@ -0,0 +1,1780 @@ +.\" -*- nroff -*- +.\" +.\" $OpenBSD: RFC.nroff,v 1.2 2000/10/16 09:38:44 djm Exp $ +.\" +.pl 10.0i +.po 0 +.ll 7.2i +.lt 7.2i +.nr LL 7.2i +.nr LT 7.2i +.ds LF Ylonen +.ds RF FORMFEED[Page %] +.ds CF +.ds LH Internet-Draft +.ds RH 15 November 1995 +.ds CH SSH (Secure Shell) Remote Login Protocol +.na +.hy 0 +.in 0 +Network Working Group T. Ylonen +Internet-Draft Helsinki University of Technology +draft-ylonen-ssh-protocol-00.txt 15 November 1995 +Expires: 15 May 1996 + +.in 3 + +.ce +The SSH (Secure Shell) Remote Login Protocol + +.ti 0 +Status of This Memo + +This document is an Internet-Draft. Internet-Drafts are working +documents of the Internet Engineering Task Force (IETF), its areas, +and its working groups. Note that other groups may also distribute +working documents as Internet-Drafts. + +Internet-Drafts are draft documents valid for a maximum of six +months and may be updated, replaced, or obsoleted by other docu- +ments at any time. It is inappropriate to use Internet-Drafts as +reference material or to cite them other than as ``work in pro- +gress.'' + +To learn the current status of any Internet-Draft, please check the +``1id-abstracts.txt'' listing contained in the Internet- Drafts Shadow +Directories on ftp.is.co.za (Africa), nic.nordu.net (Europe), +munnari.oz.au (Pacific Rim), ds.internic.net (US East Coast), or +ftp.isi.edu (US West Coast). + +The distribution of this memo is unlimited. + +.ti 0 +Introduction + +SSH (Secure Shell) is a program to log into another computer over a +network, to execute commands in a remote machine, and to move files +from one machine to another. It provides strong authentication and +secure communications over insecure networks. Its features include +the following: +.IP o +Closes several security holes (e.g., IP, routing, and DNS spoofing). +New authentication methods: .rhosts together with RSA [RSA] based host +authentication, and pure RSA authentication. +.IP o +All communications are automatically and transparently encrypted. +Encryption is also used to protect integrity. +.IP o +X11 connection forwarding provides secure X11 sessions. +.IP o +Arbitrary TCP/IP ports can be redirected over the encrypted channel +in both directions. +.IP o +Client RSA-authenticates the server machine in the beginning of every +connection to prevent trojan horses (by routing or DNS spoofing) and +man-in-the-middle attacks, and the server RSA-authenticates the client +machine before accepting .rhosts or /etc/hosts.equiv authentication +(to prevent DNS, routing, or IP spoofing). +.IP o +An authentication agent, running in the user's local workstation or +laptop, can be used to hold the user's RSA authentication keys. +.RT + +The goal has been to make the software as easy to use as possible for +ordinary users. The protocol has been designed to be as secure as +possible while making it possible to create implementations that +are easy to use and install. The sample implementation has a number +of convenient features that are not described in this document as they +are not relevant for the protocol. + + +.ti 0 +Overview of the Protocol + +The software consists of a server program running on a server machine, +and a client program running on a client machine (plus a few auxiliary +programs). The machines are connected by an insecure IP [RFC0791] +network (that can be monitored, tampered with, and spoofed by hostile +parties). + +A connection is always initiated by the client side. The server +listens on a specific port waiting for connections. Many clients may +connect to the same server machine. + +The client and the server are connected via a TCP/IP [RFC0793] socket +that is used for bidirectional communication. Other types of +transport can be used but are currently not defined. + +When the client connects the server, the server accepts the connection +and responds by sending back its version identification string. The +client parses the server's identification, and sends its own +identification. The purpose of the identification strings is to +validate that the connection was to the correct port, declare the +protocol version number used, and to declare the software version used +on each side (for debugging purposes). The identification strings are +human-readable. If either side fails to understand or support the +other side's version, it closes the connection. + +After the protocol identification phase, both sides switch to a packet +based binary protocol. The server starts by sending its host key +(every host has an RSA key used to authenticate the host), server key +(an RSA key regenerated every hour), and other information to the +client. The client then generates a 256 bit session key, encrypts it +using both RSA keys (see below for details), and sends the encrypted +session key and selected cipher type to the server. Both sides then +turn on encryption using the selected algorithm and key. The server +sends an encrypted confirmation message to the client. + +The client then authenticates itself using any of a number of +authentication methods. The currently supported authentication +methods are .rhosts or /etc/hosts.equiv authentication (disabled by +default), the same with RSA-based host authentication, RSA +authentication, and password authentication. + +After successful authentication, the client makes a number of requests +to prepare for the session. Typical requests include allocating a +pseudo tty, starting X11 [X11] or TCP/IP port forwarding, starting +authentication agent forwarding, and executing the shell or a command. + +When a shell or command is executed, the connection enters interactive +session mode. In this mode, data is passed in both directions, +new forwarded connections may be opened, etc. The interactive session +normally terminates when the server sends the exit status of the +program to the client. + + +The protocol makes several reservations for future extensibility. +First of all, the initial protocol identification messages include the +protocol version number. Second, the first packet by both sides +includes a protocol flags field, which can be used to agree on +extensions in a compatible manner. Third, the authentication and +session preparation phases work so that the client sends requests to +the server, and the server responds with success or failure. If the +client sends a request that the server does not support, the server +simply returns failure for it. This permits compatible addition of +new authentication methods and preparation operations. The +interactive session phase, on the other hand, works asynchronously and +does not permit the use of any extensions (because there is no easy +and reliable way to signal rejection to the other side and problems +would be hard to debug). Any compatible extensions to this phase must +be agreed upon during any of the earlier phases. + +.ti 0 +The Binary Packet Protocol + +After the protocol identification strings, both sides only send +specially formatted packets. The packet layout is as follows: +.IP o +Packet length: 32 bit unsigned integer, coded as four 8-bit bytes, msb +first. Gives the length of the packet, not including the length field +and padding. The maximum length of a packet (not including the length +field and padding) is 262144 bytes. +.IP o +Padding: 1-8 bytes of random data (or zeroes if not encrypting). The +amount of padding is (8 - (length % 8)) bytes (where % stands for the +modulo operator). The rationale for always having some random padding +at the beginning of each packet is to make known plaintext attacks +more difficult. +.IP o +Packet type: 8-bit unsigned byte. The value 255 is reserved for +future extension. +.IP o +Data: binary data bytes, depending on the packet type. The number of +data bytes is the "length" field minus 5. +.IP o +Check bytes: 32-bit crc, four 8-bit bytes, msb first. The crc is the +Cyclic Redundancy Check, with the polynomial 0xedb88320, of the +Padding, Packet type, and Data fields. The crc is computed before +any encryption. +.RT + +The packet, except for the length field, may be encrypted using any of +a number of algorithms. The length of the encrypted part (Padding + +Type + Data + Check) is always a multiple of 8 bytes. Typically the +cipher is used in a chained mode, with all packets chained together as +if it was a single data stream (the length field is never included in +the encryption process). Details of encryption are described below. + +When the session starts, encryption is turned off. Encryption is +enabled after the client has sent the session key. The encryption +algorithm to use is selected by the client. + + +.ti 0 +Packet Compression + +If compression is supported (it is an optional feature, see +SSH_CMSG_REQUEST_COMPRESSION below), the packet type and data fields +of the packet are compressed using the gzip deflate algorithm [GZIP]. +If compression is in effect, the packet length field indicates the +length of the compressed data, plus 4 for the crc. The amount of +padding is computed from the compressed data, so that the amount of +data to be encrypted becomes a multiple of 8 bytes. + +When compressing, the packets (type + data portions) in each direction +are compressed as if they formed a continuous data stream, with only the +current compression block flushed between packets. This corresponds +to the GNU ZLIB library Z_PARTIAL_FLUSH option. The compression +dictionary is not flushed between packets. The two directions are +compressed independently of each other. + + +.ti 0 +Packet Encryption + +The protocol supports several encryption methods. During session +initialization, the server sends a bitmask of all encryption methods +that it supports, and the client selects one of these methods. The +client also generates a 256-bit random session key (32 8-bit bytes) and +sends it to the server. + +The encryption methods supported by the current implementation, and +their codes are: +.TS +center; +l r l. +SSH_CIPHER_NONE 0 No encryption +SSH_CIPHER_IDEA 1 IDEA in CFB mode +SSH_CIPHER_DES 2 DES in CBC mode +SSH_CIPHER_3DES 3 Triple-DES in CBC mode +SSH_CIPHER_TSS 4 An experimental stream cipher +SSH_CIPHER_RC4 5 RC4 +.TE + +All implementations are required to support SSH_CIPHER_DES and +SSH_CIPHER_3DES. Supporting SSH_CIPHER_IDEA, SSH_CIPHER_RC4, and +SSH_CIPHER_NONE is recommended. Support for SSH_CIPHER_TSS is +optional (and it is not described in this document). Other ciphers +may be added at a later time; support for them is optional. + +For encryption, the encrypted portion of the packet is considered a +linear byte stream. The length of the stream is always a multiple of +8. The encrypted portions of consecutive packets (in the same +direction) are encrypted as if they were a continuous buffer (that is, +any initialization vectors are passed from the previous packet to the +next packet). Data in each direction is encrypted independently. +.IP SSH_CIPHER_DES +The key is taken from the first 8 bytes of the session key. The least +significant bit of each byte is ignored. This results in 56 bits of +key data. DES [DES] is used in CBC mode. The iv (initialization vector) is +initialized to all zeroes. +.IP SSH_CIPHER_3DES +The variant of triple-DES used here works as follows: there are three +independent DES-CBC ciphers, with independent initialization vectors. +The data (the whole encrypted data stream) is first encrypted with the +first cipher, then decrypted with the second cipher, and finally +encrypted with the third cipher. All these operations are performed +in CBC mode. + +The key for the first cipher is taken from the first 8 bytes of the +session key; the key for the next cipher from the next 8 bytes, and +the key for the third cipher from the following 8 bytes. All three +initialization vectors are initialized to zero. + +(Note: the variant of 3DES used here differs from some other +descriptions.) +.IP SSH_CIPHER_IDEA +The key is taken from the first 16 bytes of the session key. IDEA +[IDEA] is used in CFB mode. The initialization vector is initialized +to all zeroes. +.IP SSH_CIPHER_TSS +All 32 bytes of the session key are used as the key. + +There is no reference available for the TSS algorithm; it is currently +only documented in the sample implementation source code. The +security of this cipher is unknown (but it is quite fast). The cipher +is basically a stream cipher that uses MD5 as a random number +generator and takes feedback from the data. +.IP SSH_CIPHER_RC4 +The first 16 bytes of the session key are used as the key for the +server to client direction. The remaining 16 bytes are used as the +key for the client to server direction. This gives independent +128-bit keys for each direction. + +This algorithm is the alleged RC4 cipher posted to the Usenet in 1995. +It is widely believed to be equivalent with the original RSADSI RC4 +cipher. This is a very fast algorithm. +.RT + + +.ti 0 +Data Type Encodings + +The Data field of each packet contains data encoded as described in +this section. There may be several data items; each item is coded as +described here, and their representations are concatenated together +(without any alignment or padding). + +Each data type is stored as follows: +.IP "8-bit byte" +The byte is stored directly as a single byte. +.IP "32-bit unsigned integer" +Stored in 4 bytes, msb first. +.IP "Arbitrary length binary string" +First 4 bytes are the length of the string, msb first (not including +the length itself). The following "length" bytes are the string +value. There are no terminating null characters. +.IP "Multiple-precision integer" +First 2 bytes are the number of bits in the integer, msb first (for +example, the value 0x00012345 would have 17 bits). The value zero has +zero bits. It is permissible that the number of bits be larger than the +real number of bits. + +The number of bits is followed by (bits + 7) / 8 bytes of binary data, +msb first, giving the value of the integer. +.RT + + +.ti 0 +TCP/IP Port Number and Other Options + +The server listens for connections on TCP/IP port 22. + +The client may connect the server from any port. However, if the +client wishes to use any form of .rhosts or /etc/hosts.equiv +authentication, it must connect from a privileged port (less than +1024). + +For the IP Type of Service field [RFC0791], it is recommended that +interactive sessions (those having a user terminal or forwarding X11 +connections) use the IPTOS_LOWDELAY, and non-interactive connections +use IPTOS_THROUGHPUT. + +It is recommended that keepalives are used, because otherwise programs +on the server may never notice if the other end of the connection is +rebooted. + + +.ti 0 +Protocol Version Identification + +After the socket is opened, the server sends an identification string, +which is of the form +"SSH-.-\\n", where + and are integers and specify the +protocol version number (not software distribution version). + is server side software version string (max 40 characters); +it is not interpreted by the remote side but may be useful for +debugging. + +The client parses the server's string, and sends a corresponding +string with its own information in response. If the server has lower +version number, and the client contains special code to emulate it, +the client responds with the lower number; otherwise it responds with +its own number. The server then compares the version number the +client sent with its own, and determines whether they can work +together. The server either disconnects, or sends the first packet +using the binary packet protocol and both sides start working +according to the lower of the protocol versions. + +By convention, changes which keep the protocol compatible with +previous versions keep the same major protocol version; changes that +are not compatible increment the major version (which will hopefully +never happen). The version described in this document is 1.3. + +The client will + +.ti 0 +Key Exchange and Server Host Authentication + +The first message sent by the server using the packet protocol is +SSH_SMSG_PUBLIC_KEY. It declares the server's host key, server public +key, supported ciphers, supported authentication methods, and flags +for protocol extensions. It also contains a 64-bit random number +(cookie) that must be returned in the client's reply (to make IP +spoofing more difficult). No encryption is used for this message. + +Both sides compute a session id as follows. The modulus of the server +key is interpreted as a byte string (without explicit length field, +with minimum length able to hold the whole value), most significant +byte first. This string is concatenated with the server host key +interpreted the same way. Additionally, the cookie is concatenated +with this. Both sides compute MD5 of the resulting string. The +resulting 16 bytes (128 bits) are stored by both parties and are +called the session id. + +The client responds with a SSH_CMSG_SESSION_KEY message, which +contains the selected cipher type, a copy of the 64-bit cookie sent by +the server, client's protocol flags, and a session key encrypted +with both the server's host key and server key. No encryption is used +for this message. + +The session key is 32 8-bit bytes (a total of 256 random bits +generated by the client). The client first xors the 16 bytes of the +session id with the first 16 bytes of the session key. The resulting +string is then encrypted using the smaller key (one with smaller +modulus), and the result is then encrypted using the other key. The +number of bits in the public modulus of the two keys must differ by at +least 128 bits. + +At each encryption step, a multiple-precision integer is constructed +from the data to be encrypted as follows (the integer is here +interpreted as a sequence of bytes, msb first; the number of bytes is +the number of bytes needed to represent the modulus). + +The most significant byte (which is only partial as the value must be +less than the public modulus, which is never a power of two) is zero. + +The next byte contains the value 2 (which stands for public-key +encrypted data in the PKCS standard [PKCS#1]). Then, there are +non-zero random bytes to fill any unused space, a zero byte, and the +data to be encrypted in the least significant bytes, the last byte of +the data in the least significant byte. + +This algorithm is used twice. First, it is used to encrypt the 32 +random bytes generated by the client to be used as the session key +(xored by the session id). This value is converted to an integer as +described above, and encrypted with RSA using the key with the smaller +modulus. The resulting integer is converted to a byte stream, msb +first. This byte stream is padded and encrypted identically using the +key with the larger modulus. + +After the client has sent the session key, it starts to use the +selected algorithm and key for decrypting any received packets, and +for encrypting any sent packets. Separate ciphers are used for +different directions (that is, both directions have separate +initialization vectors or other state for the ciphers). + +When the server has received the session key message, and has turned +on encryption, it sends a SSH_SMSG_SUCCESS message to the client. + +The recommended size of the host key is 1024 bits, and 768 bits for +the server key. The minimum size is 512 bits for the smaller key. + + +.ti 0 +Declaring the User Name + +The client then sends a SSH_CMSG_USER message to the server. This +message specifies the user name to log in as. + +The server validates that such a user exists, checks whether +authentication is needed, and responds with either SSH_SMSG_SUCCESS or +SSH_SMSG_FAILURE. SSH_SMSG_SUCCESS indicates that no authentication +is needed for this user (no password), and authentication phase has +now been completed. SSH_SMSG_FAILURE indicates that authentication is +needed (or the user does not exist). + +If the user does not exist, it is recommended that this returns +failure, but the server keeps reading messages from the client, and +responds to any messages (except SSH_MSG_DISCONNECT, SSH_MSG_IGNORE, +and SSH_MSG_DEBUG) with SSH_SMSG_FAILURE. This way the client cannot +be certain whether the user exists. + + +.ti 0 +Authentication Phase + +Provided the server didn't immediately accept the login, an +authentication exchange begins. The client sends messages to the +server requesting different types of authentication in arbitrary order as +many times as desired (however, the server may close the connection +after a timeout). The server always responds with SSH_SMSG_SUCCESS if +it has accepted the authentication, and with SSH_SMSG_FAILURE if it has +denied authentication with the requested method or it does not +recognize the message. Some authentication methods cause an exchange +of further messages before the final result is sent. The +authentication phase ends when the server responds with success. + +The recommended value for the authentication timeout (timeout before +disconnecting if no successful authentication has been made) is 5 +minutes. + +The following authentication methods are currently supported: +.TS +center; +l r l. +SSH_AUTH_RHOSTS 1 .rhosts or /etc/hosts.equiv +SSH_AUTH_RSA 2 pure RSA authentication +SSH_AUTH_PASSWORD 3 password authentication +SSH_AUTH_RHOSTS_RSA 4 .rhosts with RSA host authentication +.TE +.IP SSH_AUTH_RHOSTS + +This is the authentication method used by rlogin and rsh [RFC1282]. + +The client sends SSH_CMSG_AUTH_RHOSTS with the client-side user name +as an argument. + +The server checks whether to permit authentication. On UNIX systems, +this is usually done by checking /etc/hosts.equiv, and .rhosts in the +user's home directory. The connection must come from a privileged +port. + +It is recommended that the server checks that there are no IP options +(such as source routing) specified for the socket before accepting +this type of authentication. The client host name should be +reverse-mapped and then forward mapped to ensure that it has the +proper IP-address. + +This authentication method trusts the remote host (root on the remote +host can pretend to be any other user on that host), the name +services, and partially the network: anyone who can see packets coming +out from the server machine can do IP-spoofing and pretend to be any +machine; however, the protocol prevents blind IP-spoofing (which used +to be possible with rlogin). + +Many sites probably want to disable this authentication method because +of the fundamental insecurity of conventional .rhosts or +/etc/hosts.equiv authentication when faced with spoofing. It is +recommended that this method not be supported by the server by +default. +.IP SSH_AUTH_RHOSTS_RSA + +In addition to conventional .rhosts and hosts.equiv authentication, +this method additionally requires that the client host be +authenticated using RSA. + +The client sends SSH_CMSG_AUTH_RHOSTS_RSA specifying the client-side +user name, and the public host key of the client host. + +The server first checks if normal .rhosts or /etc/hosts.equiv +authentication would be accepted, and if not, responds with +SSH_SMSG_FAILURE. Otherwise, it checks whether it knows the host key +for the client machine (using the same name for the host that was used +for checking the .rhosts and /etc/hosts.equiv files). If it does not +know the RSA key for the client, access is denied and SSH_SMSG_FAILURE +is sent. + +If the server knows the host key of the client machine, it verifies +that the given host key matches that known for the client. If not, +access is denied and SSH_SMSG_FAILURE is sent. + +The server then sends a SSH_SMSG_AUTH_RSA_CHALLENGE message containing +an encrypted challenge for the client. The challenge is 32 8-bit +random bytes (256 bits). When encrypted, the highest (partial) byte +is left as zero, the next byte contains the value 2, the following are +non-zero random bytes, followed by a zero byte, and the challenge put +in the remaining bytes. This is then encrypted using RSA with the +client host's public key. (The padding and encryption algorithm is +the same as that used for the session key.) + +The client decrypts the challenge using its private host key, +concatenates this with the session id, and computes an MD5 checksum +of the resulting 48 bytes. The MD5 output is returned as 16 bytes in +a SSH_CMSG_AUTH_RSA_RESPONSE message. (MD5 is used to deter chosen +plaintext attacks against RSA; the session id binds it to a specific +session). + +The server verifies that the MD5 of the decrypted challenge returned by +the client matches that of the original value, and sends SSH_SMSG_SUCCESS if +so. Otherwise it sends SSH_SMSG_FAILURE and refuses the +authentication attempt. + +This authentication method trusts the client side machine in that root +on that machine can pretend to be any user on that machine. +Additionally, it trusts the client host key. The name and/or IP +address of the client host is only used to select the public host key. +The same host name is used when scanning .rhosts or /etc/hosts.equiv +and when selecting the host key. It would in principle be possible to +eliminate the host name entirely and substitute it directly by the +host key. IP and/or DNS [RFC1034] spoofing can only be used +to pretend to be a host for which the attacker has the private host +key. +.IP SSH_AUTH_RSA + +The idea behind RSA authentication is that the server recognizes the +public key offered by the client, generates a random challenge, and +encrypts the challenge with the public key. The client must then +prove that it has the corresponding private key by decrypting the +challenge. + +The client sends SSH_CMSG_AUTH_RSA with public key modulus (n) as an +argument. + +The server may respond immediately with SSH_SMSG_FAILURE if it does +not permit authentication with this key. Otherwise it generates a +challenge, encrypts it using the user's public key (stored on the +server and identified using the modulus), and sends +SSH_SMSG_AUTH_RSA_CHALLENGE with the challenge (mp-int) as an +argument. + +The challenge is 32 8-bit random bytes (256 bits). When encrypted, +the highest (partial) byte is left as zero, the next byte contains the +value 2, the following are non-zero random bytes, followed by a zero +byte, and the challenge put in the remaining bytes. This is then +encrypted with the public key. (The padding and encryption algorithm +is the same as that used for the session key.) + +The client decrypts the challenge using its private key, concatenates +it with the session id, and computes an MD5 checksum of the resulting +48 bytes. The MD5 output is returned as 16 bytes in a +SSH_CMSG_AUTH_RSA_RESPONSE message. (Note that the MD5 is necessary +to avoid chosen plaintext attacks against RSA; the session id binds it +to a specific session.) + +The server verifies that the MD5 of the decrypted challenge returned +by the client matches that of the original value, and sends +SSH_SMSG_SUCCESS if so. Otherwise it sends SSH_SMSG_FAILURE and +refuses the authentication attempt. + +This authentication method does not trust the remote host, the +network, name services, or anything else. Authentication is based +solely on the possession of the private identification keys. Anyone +in possession of the private keys can log in, but nobody else. + +The server may have additional requirements for a successful +authentiation. For example, to limit damage due to a compromised RSA +key, a server might restrict access to a limited set of hosts. +.IP SSH_AUTH_PASSWORD + +The client sends a SSH_CMSG_AUTH_PASSWORD message with the plain text +password. (Note that even though the password is plain text inside +the message, it is normally encrypted by the packet mechanism.) + +The server verifies the password, and sends SSH_SMSG_SUCCESS if +authentication was accepted and SSH_SMSG_FAILURE otherwise. + +Note that the password is read from the user by the client; the user +never interacts with a login program. + +This authentication method does not trust the remote host, the +network, name services or anything else. Authentication is based +solely on the possession of the password. Anyone in possession of the +password can log in, but nobody else. +.RT + +.ti 0 +Preparatory Operations + +After successful authentication, the server waits for a request from +the client, processes the request, and responds with SSH_SMSG_SUCCESS +whenever a request has been successfully processed. If it receives a +message that it does not recognize or it fails to honor a request, it +returns SSH_SMSG_FAILURE. It is expected that new message types might +be added to this phase in future. + +The following messages are currently defined for this phase. +.IP SSH_CMSG_REQUEST_COMPRESSION +Requests that compression be enabled for this session. A +gzip-compatible compression level (1-9) is passed as an argument. +.IP SSH_CMSG_REQUEST_PTY +Requests that a pseudo terminal device be allocated for this session. +The user terminal type and terminal modes are supplied as arguments. +.IP SSH_CMSG_X11_REQUEST_FORWARDING +Requests forwarding of X11 connections from the remote machine to the +local machine over the secure channel. Causes an internet-domain +socket to be allocated and the DISPLAY variable to be set on the server. +X11 authentication data is automatically passed to the server, and the +client may implement spoofing of authentication data for added +security. The authentication data is passed as arguments. +.IP SSH_CMSG_PORT_FORWARD_REQUEST +Requests forwarding of a TCP/IP port on the server host over the +secure channel. What happens is that whenever a connection is made to +the port on the server, a connection will be made from the client end +to the specified host/port. Any user can forward unprivileged ports; +only the root can forward privileged ports (as determined by +authentication done earlier). +.IP SSH_CMSG_AGENT_REQUEST_FORWARDING +Requests forwarding of the connection to the authentication agent. +.IP SSH_CMSG_EXEC_SHELL +Starts a shell (command interpreter) for the user, and moves into +interactive session mode. +.IP SSH_CMSG_EXEC_CMD +Executes the given command (actually " -c " or +equivalent) for the user, and moves into interactive session mode. +.RT + + +.ti 0 +Interactive Session and Exchange of Data + +During the interactive session, any data written by the shell or +command running on the server machine is forwarded to stdin or +stderr on the client machine, and any input available from stdin on +the client machine is forwarded to the program on the server machine. + +All exchange is asynchronous; either side can send at any time, and +there are no acknowledgements (TCP/IP already provides reliable +transport, and the packet protocol protects against tampering or IP +spoofing). + +When the client receives EOF from its standard input, it will send +SSH_CMSG_EOF; however, this in no way terminates the exchange. The +exchange terminates and interactive mode is left when the server sends +SSH_SMSG_EXITSTATUS to indicate that the client program has +terminated. Alternatively, either side may disconnect at any time by +sending SSH_MSG_DISCONNECT or closing the connection. + +The server may send any of the following messages: +.IP SSH_SMSG_STDOUT_DATA +Data written to stdout by the program running on the server. The data +is passed as a string argument. The client writes this data to +stdout. +.IP SSH_SMSG_STDERR_DATA +Data written to stderr by the program running on the server. The data +is passed as a string argument. The client writes this data to +stderr. (Note that if the program is running on a tty, it is not +possible to separate stdout and stderr data, and all data will be sent +as stdout data.) +.IP SSH_SMSG_EXITSTATUS +Indicates that the shell or command has exited. Exit status is passed +as an integer argument. This message causes termination of the +interactive session. +.IP SSH_SMSG_AGENT_OPEN +Indicates that someone on the server side is requesting a connection +to the authentication agent. The server-side channel number is passed +as an argument. The client must respond with either +SSH_CHANNEL_OPEN_CONFIRMATION or SSH_CHANNEL_OPEN_FAILURE. +.IP SSH_SMSG_X11_OPEN +Indicates that a connection has been made to the X11 socket on the +server side and should be forwarded to the real X server. An integer +argument indicates the channel number allocated for this connection on +the server side. The client should send back either +SSH_MSG_CHANNEL_OPEN_CONFIRMATION or SSH_MSG_CHANNEL_OPEN_FAILURE with +the same server side channel number. +.IP SSH_MSG_PORT_OPEN +Indicates that a connection has been made to a port on the server side +for which forwarding has been requested. Arguments are server side +channel number, host name to connect to, and port to connect to. The +client should send back either +SSH_MSG_CHANNEL_OPEN_CONFIRMATION or SSH_MSG_CHANNEL_OPEN_FAILURE with +the same server side channel number. +.IP SSH_MSG_CHANNEL_OPEN_CONFIRMATION +This is sent by the server to indicate that it has opened a connection +as requested in a previous message. The first argument indicates the +client side channel number, and the second argument is the channel number +that the server has allocated for this connection. +.IP SSH_MSG_CHANNEL_OPEN_FAILURE +This is sent by the server to indicate that it failed to open a +connection as requested in a previous message. The client-side +channel number is passed as an argument. The client will close the +descriptor associated with the channel and free the channel. +.IP SSH_MSG_CHANNEL_DATA +This packet contains data for a channel from the server. The first +argument is the client-side channel number, and the second argument (a +string) is the data. +.IP SSH_MSG_CHANNEL_CLOSE +This is sent by the server to indicate that whoever was in the other +end of the channel has closed it. The argument is the client side channel +number. The client will let all buffered data in the channel to +drain, and when ready, will close the socket, free the channel, and +send the server a SSH_MSG_CHANNEL_CLOSE_CONFIRMATION message for the +channel. +.IP SSH_MSG_CHANNEL_CLOSE_CONFIRMATION +This is send by the server to indicate that a channel previously +closed by the client has now been closed on the server side as well. +The argument indicates the client channel number. The client frees +the channel. +.RT + +The client may send any of the following messages: +.IP SSH_CMSG_STDIN_DATA +This is data to be sent as input to the program running on the server. +The data is passed as a string. +.IP SSH_CMSG_EOF +Indicates that the client has encountered EOF while reading standard +input. The server will allow any buffered input data to drain, and +will then close the input to the program. +.IP SSH_CMSG_WINDOW_SIZE +Indicates that window size on the client has been changed. The server +updates the window size of the tty and causes SIGWINCH to be sent to +the program. The new window size is passed as four integer arguments: +row, col, xpixel, ypixel. +.IP SSH_MSG_PORT_OPEN +Indicates that a connection has been made to a port on the client side +for which forwarding has been requested. Arguments are client side +channel number, host name to connect to, and port to connect to. The +server should send back either SSH_MSG_CHANNEL_OPEN_CONFIRMATION or +SSH_MSG_CHANNEL_OPEN_FAILURE with the same client side channel number. +.IP SSH_MSG_CHANNEL_OPEN_CONFIRMATION +This is sent by the client to indicate that it has opened a connection +as requested in a previous message. The first argument indicates the +server side channel number, and the second argument is the channel +number that the client has allocated for this connection. +.IP SSH_MSG_CHANNEL_OPEN_FAILURE +This is sent by the client to indicate that it failed to open a +connection as requested in a previous message. The server side +channel number is passed as an argument. The server will close the +descriptor associated with the channel and free the channel. +.IP SSH_MSG_CHANNEL_DATA +This packet contains data for a channel from the client. The first +argument is the server side channel number, and the second argument (a +string) is the data. +.IP SSH_MSG_CHANNEL_CLOSE +This is sent by the client to indicate that whoever was in the other +end of the channel has closed it. The argument is the server channel +number. The server will allow buffered data to drain, and when ready, +will close the socket, free the channel, and send the client a +SSH_MSG_CHANNEL_CLOSE_CONFIRMATION message for the channel. +.IP SSH_MSG_CHANNEL_CLOSE_CONFIRMATION +This is send by the client to indicate that a channel previously +closed by the server has now been closed on the client side as well. +The argument indicates the server channel number. The server frees +the channel. +.RT + +Any unsupported messages during interactive mode cause the connection +to be terminated with SSH_MSG_DISCONNECT and an error message. +Compatible protocol upgrades should agree about any extensions during +the preparation phase or earlier. + + +.ti 0 +Termination of the Connection + +Normal termination of the connection is always initiated by the server +by sending SSH_SMSG_EXITSTATUS after the program has exited. The +client responds to this message by sending SSH_CMSG_EXIT_CONFIRMATION +and closes the socket; the server then closes the socket. There are +two purposes for the confirmation: some systems may lose previously +sent data when the socket is closed, and closing the client side first +causes any TCP/IP TIME_WAIT [RFC0793] waits to occur on the client side, not +consuming server resources. + +If the program terminates due to a signal, the server will send +SSH_MSG_DISCONNECT with an appropriate message. If the connection is +closed, all file descriptors to the program will be closed and the +server will exit. If the program runs on a tty, the kernel sends it +the SIGHUP signal when the pty master side is closed. + +.ti 0 +Protocol Flags + +Both the server and the client pass 32 bits of protocol flags to the +other side. The flags are intended for compatible protocol extension; +the server first announces which added capabilities it supports, and +the client then sends the capabilities that it supports. + +The following flags are currently defined (the values are bit masks): +.IP "1 SSH_PROTOFLAG_SCREEN_NUMBER" +This flag can only be sent by the client. It indicates that the X11 +forwarding requests it sends will include the screen number. +.IP "2 SSH_PROTOFLAG_HOST_IN_FWD_OPEN" +If both sides specify this flag, SSH_SMSG_X11_OPEN and +SSH_MSG_PORT_OPEN messages will contain an additional field containing +a description of the host at the other end of the connection. +.RT + +.ti 0 +Detailed Description of Packet Types and Formats + +The supported packet types and the corresponding message numbers are +given in the following table. Messages with _MSG_ in their name may +be sent by either side. Messages with _CMSG_ are only sent by the +client, and messages with _SMSG_ only by the server. + +A packet may contain additional data after the arguments specified +below. Any such data should be ignored by the receiver. However, it +is recommended that no such data be stored without good reason. (This +helps build compatible extensions.) +.IP "0 SSH_MSG_NONE" +This code is reserved. This message type is never sent. +.IP "1 SSH_MSG_DISCONNECT" +.TS +; +l l. +string Cause of disconnection +.TE +This message may be sent by either party at any time. It causes the +immediate disconnection of the connection. The message is intended to +be displayed to a human, and describes the reason for disconnection. +.IP "2 SSH_SMSG_PUBLIC_KEY" +.TS +; +l l. +8 bytes anti_spoofing_cookie +32-bit int server_key_bits +mp-int server_key_public_exponent +mp-int server_key_public_modulus +32-bit int host_key_bits +mp-int host_key_public_exponent +mp-int host_key_public_modulus +32-bit int protocol_flags +32-bit int supported_ciphers_mask +32-bit int supported_authentications_mask +.TE +Sent as the first message by the server. This message gives the +server's host key, server key, protocol flags (intended for compatible +protocol extension), supported_ciphers_mask (which is the +bitwise or of (1 << cipher_number), where << is the left shift +operator, for all supported ciphers), and +supported_authentications_mask (which is the bitwise or of (1 << +authentication_type) for all supported authentication types). The +anti_spoofing_cookie is 64 random bytes, and must be sent back +verbatim by the client in its reply. It is used to make IP-spoofing +more difficult (encryption and host keys are the real defense against +spoofing). +.IP "3 SSH_CMSG_SESSION_KEY" +.TS +; +l l. +1 byte cipher_type (must be one of the supported values) +8 bytes anti_spoofing_cookie (must match data sent by the server) +mp-int double-encrypted session key +32-bit int protocol_flags +.TE +Sent by the client as the first message in the session. Selects the +cipher to use, and sends the encrypted session key to the server. The +anti_spoofing_cookie must be the same bytes that were sent by the +server. Protocol_flags is intended for negotiating compatible +protocol extensions. +.IP "4 SSH_CMSG_USER" +.TS +; +l l. +string user login name on server +.TE +Sent by the client to begin authentication. Specifies the user name +on the server to log in as. The server responds with SSH_SMSG_SUCCESS +if no authentication is needed for this user, or SSH_SMSG_FAILURE if +authentication is needed (or the user does not exist). [Note to the +implementator: the user name is of arbitrary size. The implementation +must be careful not to overflow internal buffers.] +.IP "5 SSH_CMSG_AUTH_RHOSTS" +.TS +; +l l. +string client-side user name +.TE +Requests authentication using /etc/hosts.equiv and .rhosts (or +equivalent mechanisms). This authentication method is normally +disabled in the server because it is not secure (but this is the +method used by rsh and rlogin). The server responds with +SSH_SMSG_SUCCESS if authentication was successful, and +SSH_SMSG_FAILURE if access was not granted. The server should check +that the client side port number is less than 1024 (a privileged +port), and immediately reject authentication if it is not. Supporting +this authentication method is optional. This method should normally +not be enabled in the server because it is not safe. (However, not +enabling this only helps if rlogind and rshd are disabled.) +.IP "6 SSH_CMSG_AUTH_RSA" +.TS +; +l l. +mp-int identity_public_modulus +.TE +Requests authentication using pure RSA authentication. The server +checks if the given key is permitted to log in, and if so, responds +with SSH_SMSG_AUTH_RSA_CHALLENGE. Otherwise, it responds with +SSH_SMSG_FAILURE. The client often tries several different keys in +sequence until one supported by the server is found. Authentication +is accepted if the client gives the correct response to the challenge. +The server is free to add other criteria for authentication, such as a +requirement that the connection must come from a certain host. Such +additions are not visible at the protocol level. Supporting this +authentication method is optional but recommended. +.IP "7 SSH_SMSG_AUTH_RSA_CHALLENGE" +.TS +; +l l. +mp-int encrypted challenge +.TE +Presents an RSA authentication challenge to the client. The challenge +is a 256-bit random value encrypted as described elsewhere in this +document. The client must decrypt the challenge using the RSA private +key, compute MD5 of the challenge plus session id, and send back the +resulting 16 bytes using SSH_CMSG_AUTH_RSA_RESPONSE. +.IP "8 SSH_CMSG_AUTH_RSA_RESPONSE" +.TS +; +l l. +16 bytes MD5 of decrypted challenge +.TE +This message is sent by the client in response to an RSA challenge. +The MD5 checksum is returned instead of the decrypted challenge to +deter known-plaintext attacks against the RSA key. The server +responds to this message with either SSH_SMSG_SUCCESS or +SSH_SMSG_FAILURE. +.IP "9 SSH_CMSG_AUTH_PASSWORD" +.TS +; +l l. +string plain text password +.TE +Requests password authentication using the given password. Note that +even though the password is plain text inside the packet, the whole +packet is normally encrypted by the packet layer. It would not be +possible for the client to perform password encryption/hashing, +because it cannot know which kind of encryption/hashing, if any, the +server uses. The server responds to this message with +SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE. +.IP "10 SSH_CMSG_REQUEST_PTY" +.TS +; +l l. +string TERM environment variable value (e.g. vt100) +32-bit int terminal height, rows (e.g., 24) +32-bit int terminal width, columns (e.g., 80) +32-bit int terminal width, pixels (0 if no graphics) (e.g., 480) +32-bit int terminal height, pixels (0 if no graphics) (e.g., 640) +n bytes tty modes encoded in binary +.TE +Requests a pseudo-terminal to be allocated for this command. This +message can be used regardless of whether the session will later +execute the shell or a command. If a pty has been requested with this +message, the shell or command will run on a pty. Otherwise it will +communicate with the server using pipes, sockets or some other similar +mechanism. + +The terminal type gives the type of the user's terminal. In the UNIX +environment it is passed to the shell or command in the TERM +environment variable. + +The width and height values give the initial size of the user's +terminal or window. All values can be zero if not supported by the +operating system. The server will pass these values to the kernel if +supported. + +Terminal modes are encoded into a byte stream in a portable format. +The exact format is described later in this document. + +The server responds to the request with either SSH_SMSG_SUCCESS or +SSH_SMSG_FAILURE. If the server does not have the concept of pseudo +terminals, it should return success if it is possible to execute a +shell or a command so that it looks to the client as if it was running +on a pseudo terminal. +.IP "11 SSH_CMSG_WINDOW_SIZE" +.TS +; +l l. +32-bit int terminal height, rows +32-bit int terminal width, columns +32-bit int terminal width, pixels +32-bit int terminal height, pixels +.TE +This message can only be sent by the client during the interactive +session. This indicates that the size of the user's window has +changed, and provides the new size. The server will update the +kernel's notion of the window size, and a SIGWINCH signal or +equivalent will be sent to the shell or command (if supported by the +operating system). +.IP "12 SSH_CMSG_EXEC_SHELL" + +(no arguments) + +Starts a shell (command interpreter), and enters interactive session +mode. +.IP "13 SSH_CMSG_EXEC_CMD" +.TS +; +l l. +string command to execute +.TE +Starts executing the given command, and enters interactive session +mode. On UNIX, the command is run as " -c ", where + is the user's login shell. +.IP "14 SSH_SMSG_SUCCESS" + +(no arguments) + +This message is sent by the server in response to the session key, a +successful authentication request, and a successfully completed +preparatory operation. +.IP "15 SSH_SMSG_FAILURE" + +(no arguments) + +This message is sent by the server in response to a failed +authentication operation to indicate that the user has not yet been +successfully authenticated, and in response to a failed preparatory +operation. This is also sent in response to an authentication or +preparatory operation request that is not recognized or supported. +.IP "16 SSH_CMSG_STDIN_DATA" +.TS +; +l l. +string data +.TE +Delivers data from the client to be supplied as input to the shell or +program running on the server side. This message can only be used in +the interactive session mode. No acknowledgement is sent for this +message. +.IP "17 SSH_SMSG_STDOUT_DATA" +.TS +; +l l. +string data +.TE +Delivers data from the server that was read from the standard output of +the shell or program running on the server side. This message can +only be used in the interactive session mode. No acknowledgement is +sent for this message. +.IP "18 SSH_SMSG_STDERR_DATA" +.TS +; +l l. +string data +.TE +Delivers data from the server that was read from the standard error of +the shell or program running on the server side. This message can +only be used in the interactive session mode. No acknowledgement is +sent for this message. +.IP "19 SSH_CMSG_EOF" + +(no arguments) + +This message is sent by the client to indicate that EOF has been +reached on the input. Upon receiving this message, and after all +buffered input data has been sent to the shell or program, the server +will close the input file descriptor to the program. This message can +only be used in the interactive session mode. No acknowledgement is +sent for this message. +.IP "20 SSH_SMSG_EXITSTATUS" +.TS +; +l l. +32-bit int exit status of the command +.TE +Returns the exit status of the shell or program after it has exited. +The client should respond with SSH_CMSG_EXIT_CONFIRMATION when it has +received this message. This will be the last message sent by the +server. If the program being executed dies with a signal instead of +exiting normally, the server should terminate the session with +SSH_MSG_DISCONNECT (which can be used to pass a human-readable string +indicating that the program died due to a signal) instead of using +this message. +.IP "21 SSH_MSG_CHANNEL_OPEN_CONFIRMATION" +.TS +; +l l. +32-bit int remote_channel +32-bit int local_channel +.TE +This is sent in response to any channel open request if the channel +has been successfully opened. Remote_channel is the channel number +received in the initial open request; local_channel is the channel +number the side sending this message has allocated for the channel. +Data can be transmitted on the channel after this message. +.IP "22 SSH_MSG_CHANNEL_OPEN_FAILURE" +.TS +; +l l. +32-bit int remote_channel +.TE +This message indicates that an earlier channel open request by the +other side has failed or has been denied. Remote_channel is the +channel number given in the original request. +.IP "23 SSH_MSG_CHANNEL_DATA" +.TS +; +l l. +32-bit int remote_channel +string data +.TE +Data is transmitted in a channel in these messages. A channel is +bidirectional, and both sides can send these messages. There is no +acknowledgement for these messages. It is possible that either side +receives these messages after it has sent SSH_MSG_CHANNEL_CLOSE for +the channel. These messages cannot be received after the party has +sent or received SSH_MSG_CHANNEL_CLOSE_CONFIRMATION. +.IP "24 SSH_MSG_CHANNEL_CLOSE" +.TS +; +l l. +32-bit int remote_channel +.TE +When a channel is closed at one end of the connection, that side sends +this message. Upon receiving this message, the channel should be +closed. When this message is received, if the channel is already +closed (the receiving side has sent this message for the same channel +earlier), the channel is freed and no further action is taken; +otherwise the channel is freed and SSH_MSG_CHANNEL_CLOSE_CONFIRMATION +is sent in response. (It is possible that the channel is closed +simultaneously at both ends.) +.IP "25 SSH_MSG_CHANNEL_CLOSE_CONFIRMATION" +.TS +; +l l. +32-bit int remote_channel +.TE +This message is sent in response to SSH_MSG_CHANNEL_CLOSE unless the +channel was already closed. When this message is sent or received, +the channel is freed. +.IP "26 (OBSOLETED; was unix-domain X11 forwarding) +.IP "27 SSH_SMSG_X11_OPEN" +.TS +; +l l. +32-bit int local_channel +string originator_string (see below) +.TE +This message can be sent by the server during the interactive session +mode to indicate that a client has connected the fake X server. +Local_channel is the channel number that the server has allocated for +the connection. The client should try to open a connection to the +real X server, and respond with SSH_MSG_CHANNEL_OPEN_CONFIRMATION or +SSH_MSG_CHANNEL_OPEN_FAILURE. + +The field originator_string is present if both sides +specified SSH_PROTOFLAG_HOST_IN_FWD_OPEN in the protocol flags. It +contains a description of the host originating the connection. +.IP "28 SSH_CMSG_PORT_FORWARD_REQUEST" +.TS +; +l l. +32-bit int server_port +string host_to_connect +32-bit int port_to_connect +.TE +Sent by the client in the preparatory phase, this message requests +that server_port on the server machine be forwarded over the secure +channel to the client machine, and from there to the specified host +and port. The server should start listening on the port, and send +SSH_MSG_PORT_OPEN whenever a connection is made to it. Supporting +this message is optional, and the server is free to reject any forward +request. For example, it is highly recommended that unless the user +has been authenticated as root, forwarding any privileged port numbers +(below 1024) is denied. +.IP "29 SSH_MSG_PORT_OPEN" +.TS +; +l l. +32-bit int local_channel +string host_name +32-bit int port +string originator_string (see below) +.TE +Sent by either party in interactive session mode, this message +indicates that a connection has been opened to a forwarded TCP/IP +port. Local_channel is the channel number that the sending party has +allocated for the connection. Host_name is the host the connection +should be be forwarded to, and the port is the port on that host to +connect. The receiving party should open the connection, and respond +with SSH_MSG_CHANNEL_OPEN_CONFIRMATION or +SSH_MSG_CHANNEL_OPEN_FAILURE. It is recommended that the receiving +side check the host_name and port for validity to avoid compromising +local security by compromised remote side software. Particularly, it +is recommended that the client permit connections only to those ports +for which it has requested forwarding with SSH_CMSG_PORT_FORWARD_REQUEST. + +The field originator_string is present if both sides +specified SSH_PROTOFLAG_HOST_IN_FWD_OPEN in the protocol flags. It +contains a description of the host originating the connection. +.IP "30 SSH_CMSG_AGENT_REQUEST_FORWARDING" + +(no arguments) + +Requests that the connection to the authentication agent be forwarded +over the secure channel. The method used by clients to contact the +authentication agent within each machine is implementation and machine +dependent. If the server accepts this request, it should arrange that +any clients run from this session will actually contact the server +program when they try to contact the authentication agent. The server +should then send a SSH_SMSG_AGENT_OPEN to open a channel to the agent, +and the client should forward the connection to the real +authentication agent. Supporting this message is optional. +.IP "31 SSH_SMSG_AGENT_OPEN" +.TS +; +l l. +32-bit int local_channel +.TE +Sent by the server in interactive session mode, this message requests +opening a channel to the authentication agent. The client should open +a channel, and respond with either SSH_MSG_CHANNEL_OPEN_CONFIRMATION +or SSH_MSG_CHANNEL_OPEN_FAILURE. +.IP "32 SSH_MSG_IGNORE" +.TS +; +l l. +string data +.TE +Either party may send this message at any time. This message, and the +argument string, is silently ignored. This message might be used in +some implementations to make traffic analysis more difficult. This +message is not currently sent by the implementation, but all +implementations are required to recognize and ignore it. +.IP "33 SSH_CMSG_EXIT_CONFIRMATION" + +(no arguments) + +Sent by the client in response to SSH_SMSG_EXITSTATUS. This is the +last message sent by the client. +.IP "34 SSH_CMSG_X11_REQUEST_FORWARDING" +.TS +; +l l. +string x11_authentication_protocol +string x11_authentication_data +32-bit int screen number (if SSH_PROTOFLAG_SCREEN_NUMBER) +.TE +Sent by the client during the preparatory phase, this message requests +that the server create a fake X11 display and set the DISPLAY +environment variable accordingly. An internet-domain display is +preferable. The given authentication protocol and the associated data +should be recorded by the server so that it is used as authentication +on connections (e.g., in .Xauthority). The authentication protocol +must be one of the supported X11 authentication protocols, e.g., +"MIT-MAGIC-COOKIE-1". Authentication data must be a lowercase hex +string of even length. Its interpretation is protocol dependent. +The data is in a format that can be used with e.g. the xauth program. +Supporting this message is optional. + +The client is permitted (and recommended) to generate fake +authentication information and send fake information to the server. +This way, a corrupt server will not have access to the user's terminal +after the connection has terminated. The correct authorization codes +will also not be left hanging around in files on the server (many +users keep the same X session for months, thus protecting the +authorization data becomes important). + +X11 authentication spoofing works by initially sending fake (random) +authentication data to the server, and interpreting the first packet +sent by the X11 client after the connection has been opened. The +first packet contains the client's authentication. If the packet +contains the correct fake data, it is replaced by the client by the +correct authentication data, and then sent to the X server. +.IP "35 SSH_CMSG_AUTH_RHOSTS_RSA" +.TS +; +l l. +string clint-side user name +32-bit int client_host_key_bits +mp-int client_host_key_public_exponent +mp-int client_host_key_public_modulus +.TE +Requests authentication using /etc/hosts.equiv and .rhosts (or +equivalent) together with RSA host authentication. The server should +check that the client side port number is less than 1024 (a privileged +port), and immediately reject authentication if it is not. The server +responds with SSH_SMSG_FAILURE or SSH_SMSG_AUTH_RSA_CHALLENGE. The +client must respond to the challenge with the proper +SSH_CMSG_AUTH_RSA_RESPONSE. The server then responds with success if +access was granted, or failure if the client gave a wrong response. +Supporting this authentication method is optional but recommended in +most environments. +.IP "36 SSH_MSG_DEBUG" +.TS +; +l l. +string debugging message sent to the other side +.TE +This message may be sent by either party at any time. It is used to +send debugging messages that may be informative to the user in +solving various problems. For example, if authentication fails +because of some configuration error (e.g., incorrect permissions for +some file), it can be very helpful for the user to make the cause of +failure available. On the other hand, one should not make too much +information available for security reasons. It is recommended that +the client provides an option to display the debugging information +sent by the sender (the user probably does not want to see it by default). +The server can log debugging data sent by the client (if any). Either +party is free to ignore any received debugging data. Every +implementation must be able to receive this message, but no +implementation is required to send these. +.IP "37 SSH_CMSG_REQUEST_COMPRESSION" +.TS +; +l l. +32-bit int gzip compression level (1-9) +.TE +This message can be sent by the client in the preparatory operations +phase. The server responds with SSH_SMSG_FAILURE if it does not +support compression or does not want to compress; it responds with +SSH_SMSG_SUCCESS if it accepted the compression request. In the +latter case the response to this packet will still be uncompressed, +but all further packets in either direction will be compressed by gzip. +.RT + + +.ti 0 +Encoding of Terminal Modes + +Terminal modes (as passed in SSH_CMSG_REQUEST_PTY) are encoded into a +byte stream. It is intended that the coding be portable across +different environments. + +The tty mode description is a stream of bytes. The stream consists of +opcode-argument pairs. It is terminated by opcode TTY_OP_END (0). +Opcodes 1-127 have one-byte arguments. Opcodes 128-159 have 32-bit +integer arguments (stored msb first). Opcodes 160-255 are not yet +defined, and cause parsing to stop (they should only be used after any +other data). + +The client puts in the stream any modes it knows about, and the server +ignores any modes it does not know about. This allows some degree of +machine-independence, at least between systems that use a POSIX-like +[POSIX] tty interface. The protocol can support other systems as +well, but the client may need to fill reasonable values for a number +of parameters so the server pty gets set to a reasonable mode (the +server leaves all unspecified mode bits in their default values, and +only some combinations make sense). + +The following opcodes have been defined. The naming of opcodes mostly +follows the POSIX terminal mode flags. +.IP "0 TTY_OP_END" +Indicates end of options. +.IP "1 VINTR" +Interrupt character; 255 if none. Similarly for the other characters. +Not all of these characters are supported on all systems. +.IP "2 VQUIT" +The quit character (sends SIGQUIT signal on UNIX systems). +.IP "3 VERASE" +Erase the character to left of the cursor. +.IP "4 VKILL" +Kill the current input line. +.IP "5 VEOF " +End-of-file character (sends EOF from the terminal). +.IP "6 VEOL " +End-of-line character in addition to carriage return and/or linefeed. +.IP "7 VEOL2" +Additional end-of-line character. +.IP "8 VSTART" +Continues paused output (normally ^Q). +.IP "9 VSTOP" +Pauses output (^S). +.IP "10 VSUSP" +Suspends the current program. +.IP "11 VDSUSP" +Another suspend character. +.IP "12 VREPRINT" +Reprints the current input line. +.IP "13 VWERASE" +Erases a word left of cursor. +.IP "14 VLNEXT" +More special input characters; these are probably not supported on +most systems. +.IP "15 VFLUSH" +.IP "16 VSWTCH" +.IP "17 VSTATUS" +.IP "18 VDISCARD" + +.IP "30 IGNPAR" +The ignore parity flag. The next byte should be 0 if this flag is not +set, and 1 if it is set. +.IP "31 PARMRK" +More flags. The exact definitions can be found in the POSIX standard. +.IP "32 INPCK" +.IP "33 ISTRIP" +.IP "34 INLCR" +.IP "35 IGNCR" +.IP "36 ICRNL" +.IP "37 IUCLC" +.IP "38 IXON" +.IP "39 IXANY" +.IP "40 IXOFF" +.IP "41 IMAXBEL" + +.IP "50 ISIG" +.IP "51 ICANON" +.IP "52 XCASE" +.IP "53 ECHO" +.IP "54 ECHOE" +.IP "55 ECHOK" +.IP "56 ECHONL" +.IP "57 NOFLSH" +.IP "58 TOSTOP" +.IP "59 IEXTEN" +.IP "60 ECHOCTL" +.IP "61 ECHOKE" +.IP "62 PENDIN" + +.IP "70 OPOST" +.IP "71 OLCUC" +.IP "72 ONLCR" +.IP "73 OCRNL" +.IP "74 ONOCR" +.IP "75 ONLRET" + +.IP "90 CS7" +.IP "91 CS8" +.IP "92 PARENB" +.IP "93 PARODD" + +.IP "192 TTY_OP_ISPEED" +Specifies the input baud rate in bits per second. +.IP "193 TTY_OP_OSPEED" +Specifies the output baud rate in bits per second. +.RT + + +.ti 0 +The Authentication Agent Protocol + +The authentication agent is a program that can be used to hold RSA +authentication keys for the user (in future, it might hold data for +other authentication types as well). An authorized program can send +requests to the agent to generate a proper response to an RSA +challenge. How the connection is made to the agent (or its +representative) inside a host and how access control is done inside a +host is implementation-dependent; however, how it is forwarded and how +one interacts with it is specified in this protocol. The connection +to the agent is normally automatically forwarded over the secure +channel. + +A program that wishes to use the agent first opens a connection to its +local representative (typically, the agent itself or an SSH server). +It then writes a request to the connection, and waits for response. +It is recommended that at least five minutes of timeout are provided +waiting for the agent to respond to an authentication challenge (this +gives sufficient time for the user to cut-and-paste the challenge to a +separate machine, perform the computation there, and cut-and-paste the +result back if so desired). + +Messages sent to and by the agent are in the following format: +.TS +; +l l. +4 bytes Length, msb first. Does not include length itself. +1 byte Packet type. The value 255 is reserved for future extensions. +data Any data, depending on packet type. Encoding as in the ssh packet +protocol. +.TE + +The following message types are currently defined: +.IP "1 SSH_AGENTC_REQUEST_RSA_IDENTITIES" + +(no arguments) + +Requests the agent to send a list of all RSA keys for which it can +answer a challenge. +.IP "2 SSH_AGENT_RSA_IDENTITIES_ANSWER" +.TS +; +l l. +32-bit int howmany +howmany times: +32-bit int bits +mp-int public exponent +mp-int public modulus +string comment +.TE +The agent sends this message in response to the to +SSH_AGENTC_REQUEST_RSA_IDENTITIES. The answer lists all RSA keys for +which the agent can answer a challenge. The comment field is intended +to help identify each key; it may be printed by an application to +indicate which key is being used. If the agent is not holding any +keys, howmany will be zero. +.IP "3 SSH_AGENTC_RSA_CHALLENGE +.TS +; +l l. +32-bit int bits +mp-int public exponent +mp-int public modulus +mp-int challenge +16 bytes session_id +32-bit int response_type +.TE +Requests RSA decryption of random challenge to authenticate the other +side. The challenge will be decrypted with the RSA private key +corresponding to the given public key. + +The decrypted challenge must contain a zero in the highest (partial) +byte, 2 in the next byte, followed by non-zero random bytes, a zero +byte, and then the real challenge value in the lowermost bytes. The +real challenge must be 32 8-bit bytes (256 bits). + +Response_type indicates the format of the response to be returned. +Currently the only supported value is 1, which means to compute MD5 of +the real challenge plus session id, and return the resulting 16 bytes +in a SSH_AGENT_RSA_RESPONSE message. +.IP "4 SSH_AGENT_RSA_RESPONSE" +.TS +; +l l. +16 bytes MD5 of decrypted challenge +.TE +Answers an RSA authentication challenge. The response is 16 bytes: +the MD5 checksum of the 32-byte challenge. +.IP "5 SSH_AGENT_FAILURE" + +(no arguments) + +This message is sent whenever the agent fails to answer a request +properly. For example, if the agent cannot answer a challenge (e.g., +no longer has the proper key), it can respond with this. The agent +also responds with this message if it receives a message it does not +recognize. +.IP "6 SSH_AGENT_SUCCESS" + +(no arguments) + +This message is sent by the agent as a response to certain requests +that do not otherwise cause a message be sent. Currently, this is +only sent in response to SSH_AGENTC_ADD_RSA_IDENTITY and +SSH_AGENTC_REMOVE_RSA_IDENTITY. +.IP "7 SSH_AGENTC_ADD_RSA_IDENTITY" +.TS +; +l l. +32-bit int bits +mp-int public modulus +mp-int public exponent +mp-int private exponent +mp-int multiplicative inverse of p mod q +mp-int p +mp-int q +string comment +.TE +Registers an RSA key with the agent. After this request, the agent can +use this RSA key to answer requests. The agent responds with +SSH_AGENT_SUCCESS or SSH_AGENT_FAILURE. +.IP "8 SSH_AGENT_REMOVE_RSA_IDENTITY" +.TS +; +l l. +32-bit int bits +mp-int public exponent +mp-int public modulus +.TE +Removes an RSA key from the agent. The agent will no longer accept +challenges for this key and will not list it as a supported identity. +The agent responds with SSH_AGENT_SUCCESS or SSH_AGENT_FAILURE. +.RT + +If the agent receives a message that it does not understand, it +responds with SSH_AGENT_FAILURE. This permits compatible future +extensions. + +It is possible that several clients have a connection open to the +authentication agent simultaneously. Each client will use a separate +connection (thus, any SSH connection can have multiple agent +connections active simultaneously). + + +.ti 0 +References + +.IP "[DES] " +FIPS PUB 46-1: Data Encryption Standard. National Bureau of +Standards, January 1988. FIPS PUB 81: DES Modes of Operation. +National Bureau of Standards, December 1980. Bruce Schneier: Applied +Cryptography. John Wiley & Sons, 1994. J. Seberry and J. Pieprzyk: +Cryptography: An Introduction to Computer Security. Prentice-Hall, +1989. +.IP "[GZIP] " +The GNU GZIP program; available for anonymous ftp at prep.ai.mit.edu. +Please let me know if you know a paper describing the algorithm. +.IP "[IDEA] " +Xuejia Lai: On the Design and Security of Block Ciphers, ETH Series in +Information Processing, vol. 1, Hartung-Gorre Verlag, Konstanz, +Switzerland, 1992. Bruce Schneier: Applied Cryptography, John Wiley & +Sons, 1994. See also the following patents: PCT/CH91/00117, EP 0 482 +154 B1, US Pat. 5,214,703. +.IP [PKCS#1] +PKCS #1: RSA Encryption Standard. Version 1.5, RSA Laboratories, +November 1993. Available for anonymous ftp at ftp.rsa.com. +.IP [POSIX] +Portable Operating System Interface (POSIX) - Part 1: Application +Program Interface (API) [C language], ISO/IEC 9945-1, IEEE Std 1003.1, +1990. +.IP [RFC0791] +J. Postel: Internet Protocol, RFC 791, USC/ISI, September 1981. +.IP [RFC0793] +J. Postel: Transmission Control Protocol, RFC 793, USC/ISI, September +1981. +.IP [RFC1034] +P. Mockapetris: Domain Names - Concepts and Facilities, RFC 1034, +USC/ISI, November 1987. +.IP [RFC1282] +B. Kantor: BSD Rlogin, RFC 1258, UCSD, December 1991. +.IP "[RSA] " +Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1994. See +also R. Rivest, A. Shamir, and L. M. Adleman: Cryptographic +Communications System and Method. US Patent 4,405,829, 1983. +.IP "[X11] " +R. Scheifler: X Window System Protocol, X Consortium Standard, Version +11, Release 6. Massachusetts Institute of Technology, Laboratory of +Computer Science, 1994. +.RT + + +.ti 0 +Security Considerations + +This protocol deals with the very issue of user authentication and +security. + +First of all, as an implementation issue, the server program will have +to run as root (or equivalent) on the server machine. This is because +the server program will need be able to change to an arbitrary user +id. The server must also be able to create a privileged TCP/IP port. + +The client program will need to run as root if any variant of .rhosts +authentication is to be used. This is because the client program will +need to create a privileged port. The client host key is also usually +stored in a file which is readable by root only. The client needs the +host key in .rhosts authentication only. Root privileges can be +dropped as soon as the privileged port has been created and the host +key has been read. + +The SSH protocol offers major security advantages over existing telnet +and rlogin protocols. +.IP o +IP spoofing is restricted to closing a connection (by encryption, host +keys, and the special random cookie). If encryption is not used, IP +spoofing is possible for those who can hear packets going out from the +server. +.IP o +DNS spoofing is made ineffective (by host keys). +.IP o +Routing spoofing is made ineffective (by host keys). +.IP o +All data is encrypted with strong algorithms to make eavesdropping as +difficult as possible. This includes encrypting any authentication +information such as passwords. The information for decrypting session +keys is destroyed every hour. +.IP o +Strong authentication methods: .rhosts combined with RSA host +authentication, and pure RSA authentication. +.IP o +X11 connections and arbitrary TCP/IP ports can be forwarded securely. +.IP o +Man-in-the-middle attacks are deterred by using the server host key to +encrypt the session key. +.IP o +Trojan horses to catch a password by routing manipulation are deterred +by checking that the host key of the server machine matches that +stored on the client host. +.RT + +The security of SSH against man-in-the-middle attacks and the security +of the new form of .rhosts authentication, as well as server host +validation, depends on the integrity of the host key and the files +containing known host keys. + +The host key is normally stored in a root-readable file. If the host +key is compromised, it permits attackers to use IP, DNS and routing +spoofing as with current rlogin and rsh. It should never be any worse +than the current situation. + +The files containing known host keys are not sensitive. However, if an +attacker gets to modify the known host key files, it has the same +consequences as a compromised host key, because the attacker can then +change the recorded host key. + +The security improvements obtained by this protocol for X11 are of +particular significance. Previously, there has been no way to protect +data communicated between an X server and a client running on a remote +machine. By creating a fake display on the server, and forwarding all +X11 requests over the secure channel, SSH can be used to run any X11 +applications securely without any cooperation with the vendors of the +X server or the application. + +Finally, the security of this program relies on the strength of the +underlying cryptographic algorithms. The RSA algorithm is used for +authentication key exchange. It is widely believed to be secure. Of +the algorithms used to encrypt the session, DES has a rather small key +these days, probably permitting governments and organized criminals to +break it in very short time with specialized hardware. 3DES is +probably safe (but slower). IDEA is widely believed to be secure. +People have varying degrees of confidence in the other algorithms. +This program is not secure if used with no encryption at all. + + +.ti 0 +Additional Information + +Additional information (especially on the implementation and mailing +lists) is available via WWW at http://www.cs.hut.fi/ssh. + +Comments should be sent to Tatu Ylonen or the SSH +Mailing List . + +.ti 0 +Author's Address + +.TS +; +l. +Tatu Ylonen +Helsinki University of Technology +Otakaari 1 +FIN-02150 Espoo, Finland + +Phone: +358-0-451-3374 +Fax: +358-0-451-3293 +EMail: ylo@cs.hut.fi +.TE diff -ruN --exclude CVS ssh-openbsd-2003091600/rijndael.c openssh-3.7p1/rijndael.c --- ssh-openbsd-2003091600/rijndael.c 2003-03-26 16:04:05.000000000 +1100 +++ openssh-3.7p1/rijndael.c 2002-07-11 14:01:29.000000000 +1000 @@ -25,6 +25,8 @@ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "includes.h" + #include #include diff -ruN --exclude CVS ssh-openbsd-2003091600/scard/.cvsignore openssh-3.7p1/scard/.cvsignore --- ssh-openbsd-2003091600/scard/.cvsignore 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/scard/.cvsignore 2001-12-29 18:00:08.000000000 +1100 @@ -0,0 +1,2 @@ +Makefile +Ssh.bin diff -ruN --exclude CVS ssh-openbsd-2003091600/scard/Makefile openssh-3.7p1/scard/Makefile --- ssh-openbsd-2003091600/scard/Makefile 2001-06-29 17:02:09.000000000 +1000 +++ openssh-3.7p1/scard/Makefile 1970-01-01 10:00:00.000000000 +1000 @@ -1,20 +0,0 @@ -# $OpenBSD: Makefile,v 1.2 2001/06/29 07:02:09 markus Exp $ - -.PATH: ${.CURDIR}/.. - -CARDLET= Ssh.bin -DATADIR= /usr/libdata/ssh - -all: ${CARDLET} - -clean: - rm -f ${CARDLET} - -install: ${CARDLET} - install -c -m ${LIBMODE} -o ${LIBOWN} -g ${LIBGRP} \ - ${CARDLET} ${DESTDIR}${DATADIR} - -Ssh.bin: ${.CURDIR}/Ssh.bin.uu - uudecode ${.CURDIR}/$@.uu - -.include diff -ruN --exclude CVS ssh-openbsd-2003091600/scard/Makefile.in openssh-3.7p1/scard/Makefile.in --- ssh-openbsd-2003091600/scard/Makefile.in 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/scard/Makefile.in 2002-04-26 11:25:41.000000000 +1000 @@ -0,0 +1,28 @@ +# $Id: Makefile.in,v 1.4 2002/04/26 01:25:41 djm Exp $ + +prefix=@prefix@ +datadir=@datadir@ +srcdir=@srcdir@ +top_srcdir=@top_srcdir@ + +INSTALL=@INSTALL@ + +VPATH=@srcdir@ + +all: + +#Ssh.bin: Ssh.bin.uu +# uudecode Ssh.bin.uu + +clean: +# rm -rf Ssh.bin + +distprep: + uudecode Ssh.bin.uu + +distclean: clean + rm -f Makefile *~ + +install: $(srcdir)/Ssh.bin + $(top_srcdir)/mkinstalldirs $(DESTDIR)$(datadir) + $(INSTALL) -m 0644 $(srcdir)/Ssh.bin $(DESTDIR)$(datadir)/Ssh.bin diff -ruN --exclude CVS ssh-openbsd-2003091600/scard/Ssh.java openssh-3.7p1/scard/Ssh.java --- ssh-openbsd-2003091600/scard/Ssh.java 2002-03-22 09:44:05.000000000 +1100 +++ openssh-3.7p1/scard/Ssh.java 2002-05-22 14:24:02.000000000 +1000 @@ -1,4 +1,4 @@ -// $Id: Ssh.java,v 1.3 2002/03/21 22:44:05 rees Exp $ +// $Id: Ssh.java,v 1.3 2002/05/22 04:24:02 djm Exp $ // // Ssh.java // SSH / smartcard integration project, smartcard side diff -ruN --exclude CVS ssh-openbsd-2003091600/scard.c openssh-3.7p1/scard.c --- ssh-openbsd-2003091600/scard.c 2003-06-18 19:57:06.000000000 +1000 +++ openssh-3.7p1/scard.c 2003-06-18 20:28:40.000000000 +1000 @@ -22,8 +22,8 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifdef SMARTCARD #include "includes.h" +#if defined(SMARTCARD) && defined(USE_SECTOK) RCSID("$OpenBSD: scard.c,v 1.28 2003/06/12 19:12:02 markus Exp $"); #include @@ -561,4 +561,4 @@ return xstrdup("smartcard key"); } -#endif /* SMARTCARD */ +#endif /* SMARTCARD && USE_SECTOK */ diff -ruN --exclude CVS ssh-openbsd-2003091600/scard-opensc.c openssh-3.7p1/scard-opensc.c --- ssh-openbsd-2003091600/scard-opensc.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/scard-opensc.c 2003-08-25 10:58:26.000000000 +1000 @@ -0,0 +1,525 @@ +/* + * Copyright (c) 2002 Juha Yrjölä. All rights reserved. + * Copyright (c) 2001 Markus Friedl. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR 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(SMARTCARD) && defined(USE_OPENSC) + +#include +#include + +#include +#include + +#include "key.h" +#include "log.h" +#include "xmalloc.h" +#include "readpass.h" +#include "scard.h" + +#if OPENSSL_VERSION_NUMBER < 0x00907000L && defined(CRYPTO_LOCK_ENGINE) +#define USE_ENGINE +#define RSA_get_default_method RSA_get_default_openssl_method +#else +#endif + +#ifdef USE_ENGINE +#include +#define sc_get_rsa sc_get_engine +#else +#define sc_get_rsa sc_get_rsa_method +#endif + +static int sc_reader_id; +static sc_context_t *ctx = NULL; +static sc_card_t *card = NULL; +static sc_pkcs15_card_t *p15card = NULL; + +static char *sc_pin = NULL; + +struct sc_priv_data +{ + struct sc_pkcs15_id cert_id; + int ref_count; +}; + +void +sc_close(void) +{ + if (p15card) { + sc_pkcs15_unbind(p15card); + p15card = NULL; + } + if (card) { + sc_disconnect_card(card, 0); + card = NULL; + } + if (ctx) { + sc_release_context(ctx); + ctx = NULL; + } +} + +static int +sc_init(void) +{ + int r; + + r = sc_establish_context(&ctx, "openssh"); + if (r) + goto err; + if (sc_reader_id >= ctx->reader_count) { + r = SC_ERROR_NO_READERS_FOUND; + error("Illegal reader number %d (max %d)", sc_reader_id, + ctx->reader_count -1); + goto err; + } + r = sc_connect_card(ctx->reader[sc_reader_id], 0, &card); + if (r) + goto err; + r = sc_pkcs15_bind(card, &p15card); + if (r) + goto err; + return 0; +err: + sc_close(); + return r; +} + +/* private key operations */ + +static int +sc_prkey_op_init(RSA *rsa, struct sc_pkcs15_object **key_obj_out, + unsigned int usage) +{ + int r; + struct sc_priv_data *priv; + struct sc_pkcs15_object *key_obj; + struct sc_pkcs15_prkey_info *key; + struct sc_pkcs15_object *pin_obj; + struct sc_pkcs15_pin_info *pin; + + priv = (struct sc_priv_data *) RSA_get_app_data(rsa); + if (priv == NULL) + return -1; + if (p15card == NULL) { + sc_close(); + r = sc_init(); + if (r) { + error("SmartCard init failed: %s", sc_strerror(r)); + goto err; + } + } + r = sc_pkcs15_find_prkey_by_id_usage(p15card, &priv->cert_id, + usage, &key_obj); + if (r) { + error("Unable to find private key from SmartCard: %s", + sc_strerror(r)); + goto err; + } + key = key_obj->data; + r = sc_pkcs15_find_pin_by_auth_id(p15card, &key_obj->auth_id, + &pin_obj); + if (r == SC_ERROR_OBJECT_NOT_FOUND) { + /* no pin required */ + r = sc_lock(card); + if (r) { + error("Unable to lock smartcard: %s", sc_strerror(r)); + goto err; + } + *key_obj_out = key_obj; + return 0; + } else if (r) { + error("Unable to find PIN object from SmartCard: %s", + sc_strerror(r)); + goto err; + } + pin = pin_obj->data; + r = sc_lock(card); + if (r) { + error("Unable to lock smartcard: %s", sc_strerror(r)); + goto err; + } + if (sc_pin != NULL) { + r = sc_pkcs15_verify_pin(p15card, pin, sc_pin, + strlen(sc_pin)); + if (r) { + sc_unlock(card); + error("PIN code verification failed: %s", + sc_strerror(r)); + goto err; + } + } + *key_obj_out = key_obj; + return 0; +err: + sc_close(); + return -1; +} + +#define SC_USAGE_DECRYPT SC_PKCS15_PRKEY_USAGE_DECRYPT | \ + SC_PKCS15_PRKEY_USAGE_UNWRAP + +static int +sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa, + int padding) +{ + struct sc_pkcs15_object *key_obj; + int r; + + if (padding != RSA_PKCS1_PADDING) + return -1; + r = sc_prkey_op_init(rsa, &key_obj, SC_USAGE_DECRYPT); + if (r) + return -1; + r = sc_pkcs15_decipher(p15card, key_obj, SC_ALGORITHM_RSA_PAD_PKCS1, + from, flen, to, flen); + sc_unlock(card); + if (r < 0) { + error("sc_pkcs15_decipher() failed: %s", sc_strerror(r)); + goto err; + } + return r; +err: + sc_close(); + return -1; +} + +#define SC_USAGE_SIGN SC_PKCS15_PRKEY_USAGE_SIGN | \ + SC_PKCS15_PRKEY_USAGE_SIGNRECOVER + +static int +sc_sign(int type, u_char *m, unsigned int m_len, + unsigned char *sigret, unsigned int *siglen, RSA *rsa) +{ + struct sc_pkcs15_object *key_obj; + int r; + unsigned long flags = 0; + + /* XXX: sc_prkey_op_init will search for a pkcs15 private + * key object with the sign or signrecover usage flag set. + * If the signing key has only the non-repudiation flag set + * the key will be rejected as using a non-repudiation key + * for authentication is not recommended. Note: This does not + * prevent the use of a non-repudiation key for authentication + * if the sign or signrecover flag is set as well. + */ + r = sc_prkey_op_init(rsa, &key_obj, SC_USAGE_SIGN); + if (r) + return -1; + /* FIXME: length of sigret correct? */ + /* FIXME: check 'type' and modify flags accordingly */ + flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA1; + r = sc_pkcs15_compute_signature(p15card, key_obj, flags, + m, m_len, sigret, RSA_size(rsa)); + sc_unlock(card); + if (r < 0) { + error("sc_pkcs15_compute_signature() failed: %s", + sc_strerror(r)); + goto err; + } + *siglen = r; + return 1; +err: + sc_close(); + return 0; +} + +static int +sc_private_encrypt(int flen, u_char *from, u_char *to, RSA *rsa, + int padding) +{ + error("Private key encryption not supported"); + return -1; +} + +/* called on free */ + +static int (*orig_finish)(RSA *rsa) = NULL; + +static int +sc_finish(RSA *rsa) +{ + struct sc_priv_data *priv; + + priv = RSA_get_app_data(rsa); + priv->ref_count--; + if (priv->ref_count == 0) { + free(priv); + sc_close(); + } + if (orig_finish) + orig_finish(rsa); + return 1; +} + +/* engine for overloading private key operations */ + +static RSA_METHOD * +sc_get_rsa_method(void) +{ + static RSA_METHOD smart_rsa; + const RSA_METHOD *def = RSA_get_default_method(); + + /* use the OpenSSL version */ + memcpy(&smart_rsa, def, sizeof(smart_rsa)); + + smart_rsa.name = "opensc"; + + /* overload */ + smart_rsa.rsa_priv_enc = sc_private_encrypt; + smart_rsa.rsa_priv_dec = sc_private_decrypt; + smart_rsa.rsa_sign = sc_sign; + + /* save original */ + orig_finish = def->finish; + smart_rsa.finish = sc_finish; + + return &smart_rsa; +} + +#ifdef USE_ENGINE +static ENGINE * +sc_get_engine(void) +{ + static ENGINE *smart_engine = NULL; + + if ((smart_engine = ENGINE_new()) == NULL) + fatal("ENGINE_new failed"); + + ENGINE_set_id(smart_engine, "opensc"); + ENGINE_set_name(smart_engine, "OpenSC"); + + ENGINE_set_RSA(smart_engine, sc_get_rsa_method()); + ENGINE_set_DSA(smart_engine, DSA_get_default_openssl_method()); + ENGINE_set_DH(smart_engine, DH_get_default_openssl_method()); + ENGINE_set_RAND(smart_engine, RAND_SSLeay()); + ENGINE_set_BN_mod_exp(smart_engine, BN_mod_exp); + + return smart_engine; +} +#endif + +static void +convert_rsa_to_rsa1(Key * in, Key * out) +{ + struct sc_priv_data *priv; + + out->rsa->flags = in->rsa->flags; + out->flags = in->flags; + RSA_set_method(out->rsa, RSA_get_method(in->rsa)); + BN_copy(out->rsa->n, in->rsa->n); + BN_copy(out->rsa->e, in->rsa->e); + priv = RSA_get_app_data(in->rsa); + priv->ref_count++; + RSA_set_app_data(out->rsa, priv); + return; +} + +static int +sc_read_pubkey(Key * k, const struct sc_pkcs15_object *cert_obj) +{ + int r; + sc_pkcs15_cert_t *cert = NULL; + struct sc_priv_data *priv = NULL; + sc_pkcs15_cert_info_t *cinfo = cert_obj->data; + + X509 *x509 = NULL; + EVP_PKEY *pubkey = NULL; + u8 *p; + char *tmp; + + debug("sc_read_pubkey() with cert id %02X", cinfo->id.value[0]); + r = sc_pkcs15_read_certificate(p15card, cinfo, &cert); + if (r) { + logit("Certificate read failed: %s", sc_strerror(r)); + goto err; + } + x509 = X509_new(); + if (x509 == NULL) { + r = -1; + goto err; + } + p = cert->data; + if (!d2i_X509(&x509, &p, cert->data_len)) { + logit("Unable to parse X.509 certificate"); + r = -1; + goto err; + } + sc_pkcs15_free_certificate(cert); + cert = NULL; + pubkey = X509_get_pubkey(x509); + X509_free(x509); + x509 = NULL; + if (pubkey->type != EVP_PKEY_RSA) { + logit("Public key is of unknown type"); + r = -1; + goto err; + } + k->rsa = EVP_PKEY_get1_RSA(pubkey); + EVP_PKEY_free(pubkey); + + k->rsa->flags |= RSA_FLAG_SIGN_VER; + RSA_set_method(k->rsa, sc_get_rsa_method()); + priv = xmalloc(sizeof(struct sc_priv_data)); + priv->cert_id = cinfo->id; + priv->ref_count = 1; + RSA_set_app_data(k->rsa, priv); + + k->flags = KEY_FLAG_EXT; + tmp = key_fingerprint(k, SSH_FP_MD5, SSH_FP_HEX); + debug("fingerprint %d %s", key_size(k), tmp); + xfree(tmp); + + return 0; +err: + if (cert) + sc_pkcs15_free_certificate(cert); + if (pubkey) + EVP_PKEY_free(pubkey); + if (x509) + X509_free(x509); + return r; +} + +Key ** +sc_get_keys(const char *id, const char *pin) +{ + Key *k, **keys; + int i, r, real_count = 0, key_count; + sc_pkcs15_id_t cert_id; + sc_pkcs15_object_t *certs[32]; + char *buf = xstrdup(id), *p; + + debug("sc_get_keys called: id = %s", id); + + if (sc_pin != NULL) + xfree(sc_pin); + sc_pin = (pin == NULL) ? NULL : xstrdup(pin); + + cert_id.len = 0; + if ((p = strchr(buf, ':')) != NULL) { + *p = 0; + p++; + sc_pkcs15_hex_string_to_id(p, &cert_id); + } + r = sscanf(buf, "%d", &sc_reader_id); + xfree(buf); + if (r != 1) + goto err; + if (p15card == NULL) { + sc_close(); + r = sc_init(); + if (r) { + error("Smartcard init failed: %s", sc_strerror(r)); + goto err; + } + } + if (cert_id.len) { + r = sc_pkcs15_find_cert_by_id(p15card, &cert_id, &certs[0]); + if (r < 0) + goto err; + key_count = 1; + } else { + r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_CERT_X509, + certs, 32); + if (r == 0) { + logit("No certificates found on smartcard"); + r = -1; + goto err; + } else if (r < 0) { + error("Certificate enumeration failed: %s", + sc_strerror(r)); + goto err; + } + key_count = r; + } + keys = xmalloc(sizeof(Key *) * (key_count*2+1)); + for (i = 0; i < key_count; i++) { + sc_pkcs15_object_t *tmp_obj = NULL; + cert_id = ((sc_pkcs15_cert_info_t *)(certs[i]->data))->id; + if (sc_pkcs15_find_prkey_by_id(p15card, &cert_id, &tmp_obj)) + /* skip the public key (certificate) if no + * corresponding private key is present */ + continue; + k = key_new(KEY_RSA); + if (k == NULL) + break; + r = sc_read_pubkey(k, certs[i]); + if (r) { + error("sc_read_pubkey failed: %s", sc_strerror(r)); + key_free(k); + continue; + } + keys[real_count] = k; + real_count++; + k = key_new(KEY_RSA1); + if (k == NULL) + break; + convert_rsa_to_rsa1(keys[real_count-1], k); + keys[real_count] = k; + real_count++; + } + keys[real_count] = NULL; + + return keys; +err: + sc_close(); + return NULL; +} + +int +sc_put_key(Key *prv, const char *id) +{ + error("key uploading not yet supported"); + return -1; +} + +char * +sc_get_key_label(Key *key) +{ + int r; + const struct sc_priv_data *priv; + struct sc_pkcs15_object *key_obj; + + priv = (const struct sc_priv_data *) RSA_get_app_data(key->rsa); + if (priv == NULL || p15card == NULL) { + logit("SmartCard key not loaded"); + /* internal error => return default label */ + return xstrdup("smartcard key"); + } + r = sc_pkcs15_find_prkey_by_id(p15card, &priv->cert_id, &key_obj); + if (r) { + logit("Unable to find private key from SmartCard: %s", + sc_strerror(r)); + return xstrdup("smartcard key"); + } + if (key_obj == NULL || key_obj->label == NULL) + /* the optional PKCS#15 label does not exists + * => return the default label */ + return xstrdup("smartcard key"); + return xstrdup(key_obj->label); +} + +#endif /* SMARTCARD */ diff -ruN --exclude CVS ssh-openbsd-2003091600/scp/Makefile openssh-3.7p1/scp/Makefile --- ssh-openbsd-2003091600/scp/Makefile 2003-03-10 11:06:00.000000000 +1100 +++ openssh-3.7p1/scp/Makefile 1970-01-01 10:00:00.000000000 +1000 @@ -1,15 +0,0 @@ -# $OpenBSD: Makefile,v 1.16 2003/01/12 16:59:14 markus Exp $ - -.PATH: ${.CURDIR}/.. - -PROG= scp -BINOWN= root - -BINMODE?=555 - -BINDIR= /usr/bin -MAN= scp.1 - -SRCS= scp.c - -.include diff -ruN --exclude CVS ssh-openbsd-2003091600/scp.c openssh-3.7p1/scp.c --- ssh-openbsd-2003091600/scp.c 2003-07-30 14:56:28.000000000 +1000 +++ openssh-3.7p1/scp.c 2003-08-22 09:34:41.000000000 +1000 @@ -80,7 +80,11 @@ #include "misc.h" #include "progressmeter.h" -int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc); +#ifdef HAVE___PROGNAME +extern char *__progname; +#else +char *__progname; +#endif void bwlimit(int); @@ -88,7 +92,7 @@ arglist args; /* Bandwidth limit */ -off_t limit = 0; +off_t limitbw = 0; /* Name of current file being transferred. */ char *curfile; @@ -218,6 +222,8 @@ extern char *optarg; extern int optind; + __progname = ssh_get_progname(argv[0]); + args.list = NULL; addargs(&args, "ssh"); /* overwritten with ssh_program */ addargs(&args, "-x"); @@ -251,7 +257,7 @@ speed = strtod(optarg, &endp); if (speed <= 0 || *endp != '\0') usage(); - limit = speed * 1024; + limitbw = speed * 1024; break; case 'p': pflag = 1; @@ -281,6 +287,9 @@ case 't': /* "to" */ iamremote = 1; tflag = 1; +#ifdef HAVE_CYGWIN + setmode(0, O_BINARY); +#endif break; default: usage(); @@ -547,7 +556,7 @@ #define FILEMODEMASK (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO) snprintf(buf, sizeof buf, "C%04o %lld %s\n", (u_int) (stb.st_mode & FILEMODEMASK), - (long long)stb.st_size, last); + (int64_t)stb.st_size, last); if (verbose_mode) { fprintf(stderr, "Sending file modes: %s", buf); } @@ -578,7 +587,7 @@ haderr = result >= 0 ? EIO : errno; statbytes += result; } - if (limit) + if (limitbw) bwlimit(amt); } if (showprogress) @@ -670,7 +679,7 @@ return; lamt *= 8; - wait = (double)1000000L * lamt / limit; + wait = (double)1000000L * lamt / limitbw; bwstart.tv_sec = wait / 1000000L; bwstart.tv_usec = wait % 1000000L; @@ -897,7 +906,7 @@ statbytes += j; } while (amt > 0); - if (limit) + if (limitbw) bwlimit(4096); if (count == bp->cnt) { @@ -926,12 +935,20 @@ } if (pflag) { if (exists || omode != mode) +#ifdef HAVE_FCHMOD if (fchmod(ofd, omode)) +#else /* HAVE_FCHMOD */ + if (chmod(np, omode)) +#endif /* HAVE_FCHMOD */ run_err("%s: set mode: %s", np, strerror(errno)); } else { if (!exists && omode != mode) +#ifdef HAVE_FCHMOD if (fchmod(ofd, omode & ~mask)) +#else /* HAVE_FCHMOD */ + if (chmod(np, omode & ~mask)) +#endif /* HAVE_FCHMOD */ run_err("%s: set mode: %s", np, strerror(errno)); } @@ -1080,6 +1097,7 @@ allocbuf(BUF *bp, int fd, int blksize) { size_t size; +#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE struct stat stb; if (fstat(fd, &stb) < 0) { @@ -1089,6 +1107,9 @@ size = roundup(stb.st_blksize, blksize); if (size == 0) size = blksize; +#else /* HAVE_STRUCT_STAT_ST_BLKSIZE */ + size = blksize; +#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */ if (bp->cnt >= size) return (bp); if (bp->buf == NULL) diff -ruN --exclude CVS ssh-openbsd-2003091600/servconf.c openssh-3.7p1/servconf.c --- ssh-openbsd-2003091600/servconf.c 2003-09-03 12:07:14.000000000 +1000 +++ openssh-3.7p1/servconf.c 2003-09-02 22:58:22.000000000 +1000 @@ -38,6 +38,11 @@ initialize_server_options(ServerOptions *options) { memset(options, 0, sizeof(*options)); + + /* Portable-specific options */ + options->use_pam = -1; + + /* Standard Options */ options->num_ports = 0; options->ports_from_cmdline = 0; options->listen_addrs = NULL; @@ -103,6 +108,11 @@ void fill_default_server_options(ServerOptions *options) { + /* Portable-specific options */ + if (options->use_pam == -1) + options->use_pam = 1; + + /* Standard Options */ if (options->protocol == SSH_PROTO_UNKNOWN) options->protocol = SSH_PROTO_1|SSH_PROTO_2; if (options->num_host_key_files == 0) { @@ -218,11 +228,24 @@ /* Turn privilege separation on by default */ if (use_privsep == -1) use_privsep = 1; + +#ifndef HAVE_MMAP + if (use_privsep && options->compression == 1) { + error("This platform does not support both privilege " + "separation and compression"); + error("Compression disabled"); + options->compression = 0; + } +#endif + } /* Keyword tokens. */ typedef enum { sBadOption, /* == unknown option */ + /* Portable-specific options */ + sUsePAM, + /* Standard Options */ sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime, sPermitRootLogin, sLogFacility, sLogLevel, sRhostsRSAAuthentication, sRSAAuthentication, @@ -249,6 +272,14 @@ const char *name; ServerOpCodes opcode; } keywords[] = { + /* Portable-specific options */ +#ifdef USE_PAM + { "usepam", sUsePAM }, +#else + { "usepam", sUnsupported }, +#endif + { "pamauthenticationviakbdint", sDeprecated }, + /* Standard Options */ { "port", sPort }, { "hostkey", sHostKeyFile }, { "hostdsakey", sHostKeyFile }, /* alias */ @@ -401,6 +432,12 @@ charptr = NULL; opcode = parse_token(arg, filename, linenum); switch (opcode) { + /* Portable-specific options */ + case sUsePAM: + intptr = &options->use_pam; + goto parse_flag; + + /* Standard Options */ case sBadOption: return -1; case sPort: diff -ruN --exclude CVS ssh-openbsd-2003091600/servconf.h openssh-3.7p1/servconf.h --- ssh-openbsd-2003091600/servconf.h 2003-09-03 12:07:14.000000000 +1000 +++ openssh-3.7p1/servconf.h 2003-09-02 22:58:22.000000000 +1000 @@ -122,6 +122,7 @@ char *authorized_keys_file; /* File containing public keys */ char *authorized_keys_file2; + int use_pam; /* Enable auth via PAM */ } ServerOptions; void initialize_server_options(ServerOptions *); diff -ruN --exclude CVS ssh-openbsd-2003091600/serverloop.c openssh-3.7p1/serverloop.c --- ssh-openbsd-2003091600/serverloop.c 2003-06-28 11:22:37.000000000 +1000 +++ openssh-3.7p1/serverloop.c 2003-06-28 12:38:02.000000000 +1000 @@ -144,7 +144,9 @@ int save_errno = errno; debug("Received SIGCHLD."); child_terminated = 1; - signal(SIGCHLD, sigchld_handler); +#ifndef _UNICOS + mysignal(SIGCHLD, sigchld_handler); +#endif notify_parent(); errno = save_errno; } @@ -500,7 +502,7 @@ /* Initialize the SIGCHLD kludge. */ child_terminated = 0; - signal(SIGCHLD, sigchld_handler); + mysignal(SIGCHLD, sigchld_handler); /* Initialize our global variables. */ fdin = fdin_arg; @@ -672,7 +674,7 @@ channel_free_all(); /* We no longer want our SIGCHLD handler to be called. */ - signal(SIGCHLD, SIG_DFL); + mysignal(SIGCHLD, SIG_DFL); while ((wait_pid = waitpid(-1, &wait_status, 0)) < 0) if (errno != EINTR) @@ -744,7 +746,7 @@ debug("Entering interactive session for SSH2."); - signal(SIGCHLD, sigchld_handler); + mysignal(SIGCHLD, sigchld_handler); child_terminated = 0; connection_in = packet_get_connection_in(); connection_out = packet_get_connection_out(); @@ -982,8 +984,11 @@ /* check permissions */ if (!options.allow_tcp_forwarding || - no_port_forwarding_flag || - (listen_port < IPPORT_RESERVED && pw->pw_uid != 0)) { + no_port_forwarding_flag +#ifndef NO_IPPORT_RESERVED_CONCEPT + || (listen_port < IPPORT_RESERVED && pw->pw_uid != 0) +#endif + ) { success = 0; packet_send_debug("Server has disabled port forwarding."); } else { diff -ruN --exclude CVS ssh-openbsd-2003091600/session.c openssh-3.7p1/session.c --- ssh-openbsd-2003091600/session.c 2003-09-03 12:07:14.000000000 +1000 +++ openssh-3.7p1/session.c 2003-09-16 11:52:19.000000000 +1000 @@ -73,6 +73,9 @@ void do_exec_no_pty(Session *, const char *); void do_exec(Session *, const char *); void do_login(Session *, const char *); +#ifdef LOGIN_NEEDS_UTMPX +static void do_pre_login(Session *s); +#endif void do_child(Session *, const char *); void do_motd(void); int check_quietlogin(Session *, const char *); @@ -90,6 +93,7 @@ extern u_int utmp_len; extern int startup_pipe; extern void destroy_sensitive_data(void); +extern Buffer loginmsg; /* original command from peer. */ const char *original_command = NULL; @@ -203,6 +207,7 @@ close(startup_pipe); startup_pipe = -1; } + /* setup the channel layer */ if (!no_port_forwarding_flag && options.allow_tcp_forwarding) channel_permit_all_opens(); @@ -389,6 +394,15 @@ session_proctitle(s); +#if defined(USE_PAM) + if (options.use_pam) { + do_pam_setcred(1); + if (is_pam_password_change_required()) + packet_disconnect("Password change required but no " + "TTY available"); + } +#endif /* USE_PAM */ + /* Fork the child. */ if ((pid = fork()) == 0) { fatal_remove_all_cleanups(); @@ -440,10 +454,21 @@ perror("dup2 stderr"); #endif /* USE_PIPES */ +#ifdef _UNICOS + cray_init_job(s->pw); /* set up cray jid and tmpdir */ +#endif + /* Do processing for the child (exec command etc). */ do_child(s, command); /* NOTREACHED */ } +#ifdef _UNICOS + signal(WJSIGNAL, cray_job_termination_handler); +#endif /* _UNICOS */ +#ifdef HAVE_CYGWIN + if (is_winnt) + cygwin_set_impersonation_token(INVALID_HANDLE_VALUE); +#endif if (pid < 0) packet_disconnect("fork failed: %.100s", strerror(errno)); s->pid = pid; @@ -497,6 +522,13 @@ ptyfd = s->ptyfd; ttyfd = s->ttyfd; +#if defined(USE_PAM) + if (options.use_pam) { + do_pam_set_tty(s->tty); + do_pam_setcred(1); + } +#endif + /* Fork the child. */ if ((pid = fork()) == 0) { fatal_remove_all_cleanups(); @@ -521,13 +553,30 @@ close(ttyfd); /* record login, etc. similar to login(1) */ - if (!(options.use_login && command == NULL)) +#ifndef HAVE_OSF_SIA + if (!(options.use_login && command == NULL)) { +#ifdef _UNICOS + cray_init_job(s->pw); /* set up cray jid and tmpdir */ +#endif /* _UNICOS */ do_login(s, command); + } +# ifdef LOGIN_NEEDS_UTMPX + else + do_pre_login(s); +# endif +#endif /* Do common processing for the child, such as execing the command. */ do_child(s, command); /* NOTREACHED */ } +#ifdef _UNICOS + signal(WJSIGNAL, cray_job_termination_handler); +#endif /* _UNICOS */ +#ifdef HAVE_CYGWIN + if (is_winnt) + cygwin_set_impersonation_token(INVALID_HANDLE_VALUE); +#endif if (pid < 0) packet_disconnect("fork failed: %.100s", strerror(errno)); s->pid = pid; @@ -560,6 +609,34 @@ } } +#ifdef LOGIN_NEEDS_UTMPX +static void +do_pre_login(Session *s) +{ + socklen_t fromlen; + struct sockaddr_storage from; + pid_t pid = getpid(); + + /* + * Get IP address of client. If the connection is not a socket, let + * the address be 0.0.0.0. + */ + memset(&from, 0, sizeof(from)); + fromlen = sizeof(from); + if (packet_connection_is_on_socket()) { + if (getpeername(packet_get_connection_in(), + (struct sockaddr *) & from, &fromlen) < 0) { + debug("getpeername: %.100s", strerror(errno)); + fatal_cleanup(); + } + } + + record_utmp_only(pid, s->tty, s->pw->pw_name, + get_remote_name_or_ip(utmp_len, options.use_dns), + (struct sockaddr *)&from, fromlen); +} +#endif + /* * This is called to fork and execute a command. If another command is * to be forced, execute that instead. @@ -621,9 +698,34 @@ options.use_dns), (struct sockaddr *)&from, fromlen); +#ifdef USE_PAM + /* + * If password change is needed, do it now. + * This needs to occur before the ~/.hushlogin check. + */ + if (options.use_pam && is_pam_password_change_required()) { + print_pam_messages(); + do_pam_chauthtok(); + /* XXX - signal [net] parent to enable forwardings */ + } +#endif + if (check_quietlogin(s, command)) return; +#ifdef USE_PAM + if (options.use_pam && !is_pam_password_change_required()) + print_pam_messages(); +#endif /* USE_PAM */ + + /* display post-login message */ + if (buffer_len(&loginmsg) > 0) { + buffer_append(&loginmsg, "\0", 1); + printf("%s\n", (char *)buffer_ptr(&loginmsg)); + } + buffer_free(&loginmsg); + +#ifndef NO_SSH_LASTLOG if (options.print_lastlog && s->last_login_time != 0) { time_string = ctime(&s->last_login_time); if (strchr(time_string, '\n')) @@ -634,6 +736,7 @@ printf("Last login: %s from %s\r\n", time_string, s->hostname); } +#endif /* NO_SSH_LASTLOG */ do_motd(); } @@ -699,6 +802,16 @@ char **env; /* + * If we're passed an uninitialized list, allocate a single null + * entry before continuing. + */ + if (*envp == NULL && *envsizep == 0) { + *envp = xmalloc(sizeof(char *)); + *envp[0] = NULL; + *envsizep = 1; + } + + /* * Find the slot where the value should be stored. If the variable * already exists, we reuse the slot; otherwise we append a new slot * at the end of the array, expanding if necessary. @@ -774,12 +887,88 @@ fclose(f); } +#ifdef HAVE_ETC_DEFAULT_LOGIN +/* + * Return named variable from specified environment, or NULL if not present. + */ +static char * +child_get_env(char **env, const char *name) +{ + int i; + size_t len; + + len = strlen(name); + for (i=0; env[i] != NULL; i++) + if (strncmp(name, env[i], len) == 0 && env[i][len] == '=') + return(env[i] + len + 1); + return NULL; +} + +/* + * Read /etc/default/login. + * We pick up the PATH (or SUPATH for root) and UMASK. + */ +static void +read_etc_default_login(char ***env, u_int *envsize, uid_t uid) +{ + char **tmpenv = NULL, *var; + u_int i; + size_t tmpenvsize = 0; + mode_t mask; + + /* + * We don't want to copy the whole file to the child's environment, + * so we use a temporary environment and copy the variables we're + * interested in. + */ + read_environment_file(&tmpenv, &tmpenvsize, "/etc/default/login"); + + if (uid == 0) + var = child_get_env(tmpenv, "SUPATH"); + else + var = child_get_env(tmpenv, "PATH"); + if (var != NULL) + child_set_env(env, envsize, "PATH", var); + + if ((var = child_get_env(tmpenv, "UMASK")) != NULL) + if (sscanf(var, "%5lo", &mask) == 1) + umask(mask); + + for (i = 0; tmpenv[i] != NULL; i++) + xfree(tmpenv[i]); + xfree(tmpenv); +} +#endif /* HAVE_ETC_DEFAULT_LOGIN */ + +void copy_environment(char **source, char ***env, u_int *envsize) +{ + char *var_name, *var_val; + int i; + + if (source == NULL) + return; + + for(i = 0; source[i] != NULL; i++) { + var_name = xstrdup(source[i]); + if ((var_val = strstr(var_name, "=")) == NULL) { + xfree(var_name); + continue; + } + *var_val++ = '\0'; + + debug3("Copy environment: %s=%s", var_name, var_val); + child_set_env(env, envsize, var_name, var_val); + + xfree(var_name); + } +} + static char ** do_setup_env(Session *s, const char *shell) { char buf[256]; u_int i, envsize; - char **env, *laddr; + char **env, *laddr, *path = NULL; struct passwd *pw = s->pw; /* Initialize the environment. */ @@ -787,6 +976,14 @@ env = xmalloc(envsize * sizeof(char *)); env[0] = NULL; +#ifdef HAVE_CYGWIN + /* + * The Windows environment contains some setting which are + * important for a running system. They must not be dropped. + */ + copy_environment(environ, &env, &envsize); +#endif + #ifdef GSSAPI /* Allow any GSSAPI methods that we've used to alter * the childs environment as they see fit @@ -798,15 +995,34 @@ /* Set basic environment. */ child_set_env(&env, &envsize, "USER", pw->pw_name); child_set_env(&env, &envsize, "LOGNAME", pw->pw_name); +#ifdef _AIX + child_set_env(&env, &envsize, "LOGIN", pw->pw_name); +#endif child_set_env(&env, &envsize, "HOME", pw->pw_dir); #ifdef HAVE_LOGIN_CAP if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETPATH) < 0) child_set_env(&env, &envsize, "PATH", _PATH_STDPATH); else child_set_env(&env, &envsize, "PATH", getenv("PATH")); -#else - child_set_env(&env, &envsize, "PATH", _PATH_STDPATH); -#endif +#else /* HAVE_LOGIN_CAP */ +# ifndef HAVE_CYGWIN + /* + * There's no standard path on Windows. The path contains + * important components pointing to the system directories, + * needed for loading shared libraries. So the path better + * remains intact here. + */ +# ifdef HAVE_ETC_DEFAULT_LOGIN + read_etc_default_login(&env, &envsize, pw->pw_uid); + path = child_get_env(env, "PATH"); +# endif /* HAVE_ETC_DEFAULT_LOGIN */ + if (path == NULL || *path == '\0') { + child_set_env(&env, &envsize, "PATH", + s->pw->pw_uid == 0 ? + SUPERUSER_PATH : _PATH_STDPATH); + } +# endif /* HAVE_CYGWIN */ +#endif /* HAVE_LOGIN_CAP */ snprintf(buf, sizeof buf, "%.200s/%.50s", _PATH_MAILDIR, pw->pw_name); @@ -856,11 +1072,41 @@ if (original_command) child_set_env(&env, &envsize, "SSH_ORIGINAL_COMMAND", original_command); + +#ifdef _UNICOS + if (cray_tmpdir[0] != '\0') + child_set_env(&env, &envsize, "TMPDIR", cray_tmpdir); +#endif /* _UNICOS */ + +#ifdef _AIX + { + char *cp; + + if ((cp = getenv("AUTHSTATE")) != NULL) + child_set_env(&env, &envsize, "AUTHSTATE", cp); + if ((cp = getenv("KRB5CCNAME")) != NULL) + child_set_env(&env, &envsize, "KRB5CCNAME", cp); + read_environment_file(&env, &envsize, "/etc/environment"); + } +#endif #ifdef KRB5 if (s->authctxt->krb5_ticket_file) child_set_env(&env, &envsize, "KRB5CCNAME", s->authctxt->krb5_ticket_file); #endif +#ifdef USE_PAM + /* + * Pull in any environment variables that may have + * been set by PAM. + */ + if (options.use_pam) { + char **p = fetch_pam_environment(); + + copy_environment(p, &env, &envsize); + free_pam_environment(p); + } +#endif /* USE_PAM */ + if (auth_sock_name != NULL) child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME, auth_sock_name); @@ -868,7 +1114,7 @@ /* read $HOME/.ssh/environment. */ if (options.permit_user_env && !options.use_login) { snprintf(buf, sizeof buf, "%.200s/.ssh/environment", - pw->pw_dir); + strcmp(pw->pw_dir, "/") ? pw->pw_dir : ""); read_environment_file(&env, &envsize, buf); } if (debug_flag) { @@ -972,6 +1218,7 @@ while (fgets(buf, sizeof(buf), f)) fputs(buf, stderr); fclose(f); + fflush(NULL); exit(254); } } @@ -980,14 +1227,31 @@ void do_setusercontext(struct passwd *pw) { - if (getuid() == 0 || geteuid() == 0) { +#ifndef HAVE_CYGWIN + if (getuid() == 0 || geteuid() == 0) +#endif /* HAVE_CYGWIN */ + { + +#ifdef HAVE_SETPCRED + if (setpcred(pw->pw_name, (char **)NULL) == -1) + fatal("Failed to set process credentials"); +#endif /* HAVE_SETPCRED */ #ifdef HAVE_LOGIN_CAP +# ifdef __bsdi__ + setpgid(0, 0); +# endif if (setusercontext(lc, pw, pw->pw_uid, (LOGIN_SETALL & ~LOGIN_SETPATH)) < 0) { perror("unable to set user context"); exit(1); } #else +# if defined(HAVE_GETLUID) && defined(HAVE_SETLUID) + /* Sets login uid for accounting */ + if (getluid() == -1 && setluid(pw->pw_uid) == -1) + error("setluid: %s", strerror(errno)); +# endif /* defined(HAVE_GETLUID) && defined(HAVE_SETLUID) */ + if (setlogin(pw->pw_name) < 0) error("setlogin failed: %s", strerror(errno)); if (setgid(pw->pw_gid) < 0) { @@ -1000,11 +1264,31 @@ exit(1); } endgrent(); - +# ifdef USE_PAM + /* + * PAM credentials may take the form of supplementary groups. + * These will have been wiped by the above initgroups() call. + * Reestablish them here. + */ + if (options.use_pam) { + do_pam_session(); + do_pam_setcred(0); + } +# endif /* USE_PAM */ +# if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) + irix_setusercontext(pw); +# endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */ +# ifdef _AIX + aix_usrinfo(pw); +# endif /* _AIX */ /* Permanently switch to the desired uid. */ permanently_set_uid(pw); #endif } + +#ifdef HAVE_CYGWIN + if (is_winnt) +#endif if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid) fatal("Failed to set uids to %u.", (u_int) pw->pw_uid); } @@ -1014,8 +1298,15 @@ { /* Launch login(1). */ - execl("/usr/bin/login", "login", "-h", hostname, + execl(LOGIN_PROGRAM, "login", "-h", hostname, +#ifdef xxxLOGIN_NEEDS_TERM + (s->term ? s->term : "unknown"), +#endif /* LOGIN_NEEDS_TERM */ +#ifdef LOGIN_NO_ENDOPT + "-p", "-f", pw->pw_name, (char *)NULL); +#else "-p", "-f", "--", pw->pw_name, (char *)NULL); +#endif /* Login couldn't be executed, die. */ @@ -1045,13 +1336,23 @@ if (options.use_login && command != NULL) options.use_login = 0; +#ifdef _UNICOS + cray_setup(pw->pw_uid, pw->pw_name, command); +#endif /* _UNICOS */ + /* * Login(1) does this as well, and it needs uid 0 for the "-h" * switch, so we let login(1) to this for us. */ if (!options.use_login) { +#ifdef HAVE_OSF_SIA + session_setup_sia(pw, s->ttyfd == -1 ? NULL : s->tty); + if (!check_quietlogin(s, command)) + do_motd(); +#else /* HAVE_OSF_SIA */ do_nologin(pw); do_setusercontext(pw); +#endif /* HAVE_OSF_SIA */ } /* @@ -1559,7 +1860,7 @@ /* Record that the user has logged out. */ if (s->pid != 0) - record_logout(s->pid, s->tty); + record_logout(s->pid, s->tty, s->pw->pw_name); /* Release the pseudo-tty. */ if (getuid() == 0) @@ -1622,7 +1923,11 @@ } else if (WIFSIGNALED(status)) { channel_request_start(s->chanid, "exit-signal", 0); packet_put_cstring(sig2name(WTERMSIG(status))); +#ifdef WCOREDUMP packet_put_char(WCOREDUMP(status)); +#else /* WCOREDUMP */ + packet_put_char(0); +#endif /* WCOREDUMP */ packet_put_cstring(""); packet_put_cstring(""); packet_send(); @@ -1733,13 +2038,22 @@ { static char buf[1024]; int i; + char *cp; + buf[0] = '\0'; for (i = 0; i < MAX_SESSIONS; i++) { Session *s = &sessions[i]; if (s->used && s->ttyfd != -1) { + + if (strncmp(s->tty, "/dev/", 5) != 0) { + cp = strrchr(s->tty, '/'); + cp = (cp == NULL) ? s->tty : cp + 1; + } else + cp = s->tty + 5; + if (buf[0] != '\0') strlcat(buf, ",", sizeof buf); - strlcat(buf, strrchr(s->tty, '/') + 1, sizeof buf); + strlcat(buf, cp, sizeof buf); } } if (buf[0] == '\0') @@ -1808,8 +2122,23 @@ s->display = xstrdup(display); s->auth_display = xstrdup(auth_display); } else { +#ifdef IPADDR_IN_DISPLAY + struct hostent *he; + struct in_addr my_addr; + + he = gethostbyname(hostname); + if (he == NULL) { + error("Can't get IP address for X11 DISPLAY."); + packet_send_debug("Can't get IP address for X11 DISPLAY."); + return 0; + } + memcpy(&my_addr, he->h_addr_list[0], sizeof(struct in_addr)); + snprintf(display, sizeof display, "%.50s:%u.%u", inet_ntoa(my_addr), + s->display_number, s->screen); +#else snprintf(display, sizeof display, "%.400s:%u.%u", hostname, s->display_number, s->screen); +#endif s->display = xstrdup(display); s->auth_display = xstrdup(display); } diff -ruN --exclude CVS ssh-openbsd-2003091600/sftp/Makefile openssh-3.7p1/sftp/Makefile --- ssh-openbsd-2003091600/sftp/Makefile 2003-03-10 11:06:00.000000000 +1100 +++ openssh-3.7p1/sftp/Makefile 1970-01-01 10:00:00.000000000 +1000 @@ -1,19 +0,0 @@ -# $OpenBSD: Makefile,v 1.7 2003/01/12 16:59:14 markus Exp $ - -.PATH: ${.CURDIR}/.. - -PROG= sftp -BINOWN= root - -BINMODE?=555 - -BINDIR= /usr/bin -MAN= sftp.1 - -SRCS= sftp.c sftp-client.c sftp-int.c sftp-common.c sftp-glob.c - -.include - -LDADD+= -lcrypto -DPADD+= ${LIBCRYPTO} - diff -ruN --exclude CVS ssh-openbsd-2003091600/sftp.c openssh-3.7p1/sftp.c --- ssh-openbsd-2003091600/sftp.c 2003-07-30 14:56:28.000000000 +1000 +++ openssh-3.7p1/sftp.c 2003-08-22 09:34:41.000000000 +1000 @@ -37,6 +37,12 @@ #include "sftp-client.h" #include "sftp-int.h" +#ifdef HAVE___PROGNAME +extern char *__progname; +#else +char *__progname; +#endif + FILE* infile; size_t copy_buffer_len = 32768; size_t num_requests = 16; @@ -126,6 +132,7 @@ extern int optind; extern char *optarg; + __progname = ssh_get_progname(argv[0]); args.list = NULL; addargs(&args, "ssh"); /* overwritten with ssh_program */ addargs(&args, "-oForwardX11 no"); @@ -244,6 +251,11 @@ err = interactive_loop(in, out, file1, file2); +#if !defined(USE_PIPES) + shutdown(in, SHUT_RDWR); + shutdown(out, SHUT_RDWR); +#endif + close(in); close(out); if (infile != stdin) diff -ruN --exclude CVS ssh-openbsd-2003091600/sftp-client.c openssh-3.7p1/sftp-client.c --- ssh-openbsd-2003091600/sftp-client.c 2003-07-30 14:56:28.000000000 +1000 +++ openssh-3.7p1/sftp-client.c 2003-07-03 13:46:57.000000000 +1000 @@ -30,7 +30,7 @@ #include "includes.h" RCSID("$OpenBSD: sftp-client.c,v 1.44 2003/06/28 16:23:06 deraadt Exp $"); -#include +#include "openbsd-compat/sys-queue.h" #include "buffer.h" #include "bufaux.h" @@ -944,7 +944,11 @@ status = do_close(conn, handle, handle_len); /* Override umask and utimes if asked */ +#ifdef HAVE_FCHMOD if (pflag && fchmod(local_fd, mode) == -1) +#else + if (pflag && chmod(local_path, mode) == -1) +#endif /* HAVE_FCHMOD */ error("Couldn't set mode on \"%s\": %s", local_path, strerror(errno)); if (pflag && (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME)) { diff -ruN --exclude CVS ssh-openbsd-2003091600/sftp-glob.c openssh-3.7p1/sftp-glob.c --- ssh-openbsd-2003091600/sftp-glob.c 2003-03-26 16:04:06.000000000 +1100 +++ openssh-3.7p1/sftp-glob.c 2002-09-12 09:54:27.000000000 +1000 @@ -25,8 +25,6 @@ #include "includes.h" RCSID("$OpenBSD: sftp-glob.c,v 1.13 2002/09/11 22:41:50 djm Exp $"); -#include - #include "buffer.h" #include "bufaux.h" #include "xmalloc.h" @@ -66,16 +64,40 @@ static struct dirent * fudge_readdir(struct SFTP_OPENDIR *od) { - static struct dirent ret; - + /* Solaris needs sizeof(dirent) + path length (see below) */ + static char buf[sizeof(struct dirent) + MAXPATHLEN]; + struct dirent *ret = (struct dirent *)buf; +#ifdef __GNU_LIBRARY__ + static int inum = 1; +#endif /* __GNU_LIBRARY__ */ + if (od->dir[od->offset] == NULL) return(NULL); - memset(&ret, 0, sizeof(ret)); - strlcpy(ret.d_name, od->dir[od->offset++]->filename, - sizeof(ret.d_name)); + memset(buf, 0, sizeof(buf)); + + /* + * Solaris defines dirent->d_name as a one byte array and expects + * you to hack around it. + */ +#ifdef BROKEN_ONE_BYTE_DIRENT_D_NAME + strlcpy(ret->d_name, od->dir[od->offset++]->filename, MAXPATHLEN); +#else + strlcpy(ret->d_name, od->dir[od->offset++]->filename, + sizeof(ret->d_name)); +#endif +#ifdef __GNU_LIBRARY__ + /* + * Idiot glibc uses extensions to struct dirent for readdir with + * ALTDIRFUNCs. Not that this is documented anywhere but the + * source... Fake an inode number to appease it. + */ + ret->d_ino = inum++; + if (!inum) + inum = 1; +#endif /* __GNU_LIBRARY__ */ - return(&ret); + return(ret); } static void diff -ruN --exclude CVS ssh-openbsd-2003091600/sftp-int.c openssh-3.7p1/sftp-int.c --- ssh-openbsd-2003091600/sftp-int.c 2003-09-03 12:07:14.000000000 +1000 +++ openssh-3.7p1/sftp-int.c 2003-08-26 12:12:56.000000000 +1000 @@ -27,8 +27,6 @@ #include "includes.h" RCSID("$OpenBSD: sftp-int.c,v 1.62 2003/08/25 08:13:09 fgsch Exp $"); -#include - #include "buffer.h" #include "xmalloc.h" #include "log.h" @@ -1155,8 +1153,13 @@ xfree(dir); } +#if HAVE_SETVBUF setvbuf(stdout, NULL, _IOLBF, 0); setvbuf(infile, NULL, _IOLBF, 0); +#else + setlinebuf(stdout); + setlinebuf(infile); +#endif err = 0; for (;;) { diff -ruN --exclude CVS ssh-openbsd-2003091600/sftp-server/Makefile openssh-3.7p1/sftp-server/Makefile --- ssh-openbsd-2003091600/sftp-server/Makefile 2001-03-04 10:59:36.000000000 +1100 +++ openssh-3.7p1/sftp-server/Makefile 1970-01-01 10:00:00.000000000 +1000 @@ -1,18 +0,0 @@ -# $OpenBSD: Makefile,v 1.5 2001/03/03 23:59:36 markus Exp $ - -.PATH: ${.CURDIR}/.. - -PROG= sftp-server -BINOWN= root - -BINMODE?=555 - -BINDIR= /usr/libexec -MAN= sftp-server.8 - -SRCS= sftp-server.c sftp-common.c - -.include - -LDADD+= -lcrypto -DPADD+= ${LIBCRYPTO} diff -ruN --exclude CVS ssh-openbsd-2003091600/sftp-server.8 openssh-3.7p1/sftp-server.8 --- ssh-openbsd-2003091600/sftp-server.8 2003-06-10 20:43:59.000000000 +1000 +++ openssh-3.7p1/sftp-server.8 2003-06-11 22:04:39.000000000 +1000 @@ -55,9 +55,8 @@ .%D January 2001 .%O work in progress material .Re -.Sh HISTORY -.Nm -first appeared in -.Ox 2.8 . .Sh AUTHORS .An Markus Friedl Aq markus@openbsd.org +.Sh HISTORY +.Nm +first appeared in OpenBSD 2.8 . diff -ruN --exclude CVS ssh-openbsd-2003091600/sftp-server.c openssh-3.7p1/sftp-server.c --- ssh-openbsd-2003091600/sftp-server.c 2003-06-28 11:22:37.000000000 +1000 +++ openssh-3.7p1/sftp-server.c 2003-08-22 09:34:41.000000000 +1000 @@ -39,6 +39,12 @@ #define get_string(lenp) buffer_get_string(&iqueue, lenp); #define TRACE debug +#ifdef HAVE___PROGNAME +extern char *__progname; +#else +char *__progname; +#endif + /* input and output queue */ Buffer iqueue; Buffer oqueue; @@ -433,7 +439,7 @@ len = get_int(); TRACE("read id %u handle %d off %llu len %d", id, handle, - (unsigned long long)off, len); + (u_int64_t)off, len); if (len > sizeof buf) { len = sizeof buf; logit("read change len %d", len); @@ -474,7 +480,7 @@ data = get_string(&len); TRACE("write id %u handle %d off %llu len %d", id, handle, - (unsigned long long)off, len); + (u_int64_t)off, len); fd = handle_to_fd(handle); if (fd >= 0) { if (lseek(fd, off, SEEK_SET) < 0) { @@ -615,13 +621,15 @@ u_int32_t id; int handle, fd, ret; int status = SSH2_FX_OK; + char *name; id = get_int(); handle = get_handle(); a = get_attrib(); TRACE("fsetstat id %u handle %d", id, handle); fd = handle_to_fd(handle); - if (fd < 0) { + name = handle_to_name(handle); + if (fd < 0 || name == NULL) { status = SSH2_FX_FAILURE; } else { if (a->flags & SSH2_FILEXFER_ATTR_SIZE) { @@ -630,17 +638,29 @@ status = errno_to_portable(errno); } if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) { +#ifdef HAVE_FCHMOD ret = fchmod(fd, a->perm & 0777); +#else + ret = chmod(name, a->perm & 0777); +#endif if (ret == -1) status = errno_to_portable(errno); } if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) { +#ifdef HAVE_FUTIMES ret = futimes(fd, attrib_to_tv(a)); +#else + ret = utimes(name, attrib_to_tv(a)); +#endif if (ret == -1) status = errno_to_portable(errno); } if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) { +#ifdef HAVE_FCHOWN ret = fchown(fd, a->uid, a->gid); +#else + ret = chown(name, a->uid, a->gid); +#endif if (ret == -1) status = errno_to_portable(errno); } @@ -1010,6 +1030,7 @@ /* XXX should use getopt */ + __progname = ssh_get_progname(av[0]); handle_init(); #ifdef DEBUG_SFTP_SERVER @@ -1019,6 +1040,11 @@ in = dup(STDIN_FILENO); out = dup(STDOUT_FILENO); +#ifdef HAVE_CYGWIN + setmode(in, O_BINARY); + setmode(out, O_BINARY); +#endif + max = 0; if (in > max) max = in; diff -ruN --exclude CVS ssh-openbsd-2003091600/ssh/Makefile openssh-3.7p1/ssh/Makefile --- ssh-openbsd-2003091600/ssh/Makefile 2003-09-03 12:07:15.000000000 +1000 +++ openssh-3.7p1/ssh/Makefile 1970-01-01 10:00:00.000000000 +1000 @@ -1,32 +0,0 @@ -# $OpenBSD: Makefile,v 1.50 2003/08/28 07:49:13 markus Exp $ - -.PATH: ${.CURDIR}/.. - -PROG= ssh -BINOWN= root - -#BINMODE?=4555 - -BINDIR= /usr/bin -MAN= ssh.1 ssh_config.5 -LINKS= ${BINDIR}/ssh ${BINDIR}/slogin -MLINKS= ssh.1 slogin.1 - -SRCS= ssh.c readconf.c clientloop.c sshtty.c \ - sshconnect.c sshconnect1.c sshconnect2.c - -.include # for AFS - -.if (${KERBEROS5:L} == "yes") -CFLAGS+= -DKRB5 -I${DESTDIR}/usr/include/kerberosV -DGSSAPI -.endif # KERBEROS5 - -.include - -.if (${KERBEROS5:L} == "yes") -DPADD+= ${LIBGSSAPI} ${LIBKRB5} -LDADD+= -lgssapi -lkrb5 -.endif # KERBEROS5 - -DPADD+= ${LIBCRYPTO} ${LIBZ} ${LIBDES} -LDADD+= -lcrypto -lz -ldes diff -ruN --exclude CVS ssh-openbsd-2003091600/ssh-add/Makefile openssh-3.7p1/ssh-add/Makefile --- ssh-openbsd-2003091600/ssh-add/Makefile 2001-03-04 11:51:25.000000000 +1100 +++ openssh-3.7p1/ssh-add/Makefile 1970-01-01 10:00:00.000000000 +1000 @@ -1,18 +0,0 @@ -# $OpenBSD: Makefile,v 1.20 2001/03/04 00:51:25 markus Exp $ - -.PATH: ${.CURDIR}/.. - -PROG= ssh-add -BINOWN= root - -BINMODE?=555 - -BINDIR= /usr/bin -MAN= ssh-add.1 - -SRCS= ssh-add.c - -.include - -LDADD+= -lcrypto -DPADD+= ${LIBCRYPTO} diff -ruN --exclude CVS ssh-openbsd-2003091600/ssh-add.c openssh-3.7p1/ssh-add.c --- ssh-openbsd-2003091600/ssh-add.c 2003-06-18 19:57:07.000000000 +1000 +++ openssh-3.7p1/ssh-add.c 2003-08-22 09:34:41.000000000 +1000 @@ -50,6 +50,12 @@ #include "readpass.h" #include "misc.h" +#ifdef HAVE___PROGNAME +extern char *__progname; +#else +char *__progname; +#endif + /* argv0 */ extern char *__progname; @@ -313,6 +319,10 @@ char *sc_reader_id = NULL; int i, ch, deleting = 0, ret = 0; + __progname = ssh_get_progname(argv[0]); + init_rng(); + seed_rng(); + SSLeay_add_all_algorithms(); /* At first, get a connection to the authentication agent. */ diff -ruN --exclude CVS ssh-openbsd-2003091600/ssh-agent/Makefile openssh-3.7p1/ssh-agent/Makefile --- ssh-openbsd-2003091600/ssh-agent/Makefile 2002-09-12 08:55:46.000000000 +1000 +++ openssh-3.7p1/ssh-agent/Makefile 1970-01-01 10:00:00.000000000 +1000 @@ -1,19 +0,0 @@ -# $OpenBSD: Makefile,v 1.22 2002/08/12 10:46:35 markus Exp $ - -.PATH: ${.CURDIR}/.. - -PROG= ssh-agent -BINOWN= root -BINGRP= _sshagnt - -BINMODE?=2555 - -BINDIR= /usr/bin -MAN= ssh-agent.1 - -SRCS= ssh-agent.c - -.include - -LDADD+= -lcrypto -DPADD+= ${LIBCRYPTO} diff -ruN --exclude CVS ssh-openbsd-2003091600/ssh-agent.c openssh-3.7p1/ssh-agent.c --- ssh-openbsd-2003091600/ssh-agent.c 2003-06-18 19:57:07.000000000 +1000 +++ openssh-3.7p1/ssh-agent.c 2003-08-22 09:34:41.000000000 +1000 @@ -34,7 +34,7 @@ */ #include "includes.h" -#include +#include "openbsd-compat/sys-queue.h" RCSID("$OpenBSD: ssh-agent.c,v 1.111 2003/06/12 19:12:03 markus Exp $"); #include @@ -103,7 +103,11 @@ int locked = 0; char *lock_passwd = NULL; +#ifdef HAVE___PROGNAME extern char *__progname; +#else +char *__progname; +#endif /* Default lifetime (0 == forever) */ static int lifetime = 0; @@ -975,7 +979,7 @@ /* printf("Parent has died - Authentication agent exiting.\n"); */ cleanup_handler(sig); /* safe */ } - signal(SIGALRM, check_parent_exists); + mysignal(SIGALRM, check_parent_exists); alarm(10); errno = save_errno; } @@ -1003,7 +1007,12 @@ char *shell, *format, *pidstr, *agentsocket = NULL; fd_set *readsetp = NULL, *writesetp = NULL; struct sockaddr_un sunaddr; +#ifdef HAVE_SETRLIMIT struct rlimit rlim; +#endif +#ifdef HAVE_CYGWIN + int prev_mask; +#endif extern int optind; extern char *optarg; pid_t pid; @@ -1015,6 +1024,10 @@ SSLeay_add_all_algorithms(); + __progname = ssh_get_progname(av[0]); + init_rng(); + seed_rng(); + while ((ch = getopt(ac, av, "cdksa:t:")) != -1) { switch (ch) { case 'c': @@ -1111,10 +1124,19 @@ memset(&sunaddr, 0, sizeof(sunaddr)); sunaddr.sun_family = AF_UNIX; strlcpy(sunaddr.sun_path, socket_name, sizeof(sunaddr.sun_path)); +#ifdef HAVE_CYGWIN + prev_mask = umask(0177); +#endif if (bind(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0) { perror("bind"); +#ifdef HAVE_CYGWIN + umask(prev_mask); +#endif cleanup_exit(1); } +#ifdef HAVE_CYGWIN + umask(prev_mask); +#endif if (listen(sock, 128) < 0) { perror("listen"); cleanup_exit(1); @@ -1176,18 +1198,20 @@ close(fd); } +#ifdef HAVE_SETRLIMIT /* deny core dumps, since memory contains unencrypted private keys */ rlim.rlim_cur = rlim.rlim_max = 0; if (setrlimit(RLIMIT_CORE, &rlim) < 0) { error("setrlimit RLIMIT_CORE: %s", strerror(errno)); cleanup_exit(1); } +#endif skip: fatal_add_cleanup(cleanup_socket, NULL); new_socket(AUTH_SOCKET, sock); if (ac > 0) { - signal(SIGALRM, check_parent_exists); + mysignal(SIGALRM, check_parent_exists); alarm(10); } idtab_init(); diff -ruN --exclude CVS ssh-openbsd-2003091600/ssh.c openssh-3.7p1/ssh.c --- ssh-openbsd-2003091600/ssh.c 2003-09-03 12:07:14.000000000 +1000 +++ openssh-3.7p1/ssh.c 2003-09-02 22:58:22.000000000 +1000 @@ -73,7 +73,11 @@ #include "scard.h" #endif +#ifdef HAVE___PROGNAME extern char *__progname; +#else +char *__progname; +#endif /* Flag indicating whether debug mode is on. This can be set on the command line. */ int debug_flag = 0; @@ -207,13 +211,16 @@ extern int optind, optreset; extern char *optarg; + __progname = ssh_get_progname(av[0]); + init_rng(); + /* * Save the original real uid. It will be needed later (uid-swapping * may clobber the real uid). */ original_real_uid = getuid(); original_effective_uid = geteuid(); - + /* * Use uid-swapping to give up root privileges for the duration of * option processing. We will re-instantiate the rights when we are @@ -223,6 +230,7 @@ */ PRIV_END; +#ifdef HAVE_SETRLIMIT /* If we are installed setuid root be careful to not drop core. */ if (original_real_uid != original_effective_uid) { struct rlimit rlim; @@ -230,6 +238,7 @@ if (setrlimit(RLIMIT_CORE, &rlim) < 0) fatal("setrlimit failed: %.100s", strerror(errno)); } +#endif /* Get user data. */ pw = getpwuid(original_real_uid); if (!pw) { @@ -404,9 +413,9 @@ case 'L': case 'R': - if (sscanf(optarg, "%5[0-9]:%255[^:]:%5[0-9]", + if (sscanf(optarg, "%5[0123456789]:%255[^:]:%5[0123456789]", sfwd_port, buf, sfwd_host_port) != 3 && - sscanf(optarg, "%5[0-9]/%255[^/]/%5[0-9]", + sscanf(optarg, "%5[0123456789]/%255[^/]/%5[0123456789]", sfwd_port, buf, sfwd_host_port) != 3) { fprintf(stderr, "Bad forwarding specification '%s'\n", @@ -571,6 +580,8 @@ /* reinit */ log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, 1); + seed_rng(); + if (options.user == NULL) options.user = xstrdup(pw->pw_name); @@ -589,9 +600,13 @@ options.proxy_command = NULL; /* Open a connection to the remote host. */ - if (ssh_connect(host, &hostaddr, options.port, + if (ssh_connect(host, &hostaddr, options.port, options.address_family, options.connection_attempts, +#ifdef HAVE_CYGWIN + options.use_privileged_port, +#else original_effective_uid == 0 && options.use_privileged_port, +#endif options.proxy_command) != 0) exit(1); diff -ruN --exclude CVS ssh-openbsd-2003091600/sshconnect2.c openssh-3.7p1/sshconnect2.c --- ssh-openbsd-2003091600/sshconnect2.c 2003-09-03 12:07:15.000000000 +1000 +++ openssh-3.7p1/sshconnect2.c 2003-08-26 12:14:05.000000000 +1000 @@ -25,6 +25,8 @@ #include "includes.h" RCSID("$OpenBSD: sshconnect2.c,v 1.124 2003/08/25 10:33:33 djm Exp $"); +#include "openbsd-compat/sys-queue.h" + #include "ssh.h" #include "ssh2.h" #include "xmalloc.h" @@ -734,7 +736,7 @@ * parse PASSWD_CHANGEREQ, prompt user and send SSH2_MSG_USERAUTH_REQUEST */ void -input_userauth_passwd_changereq(int type, uint32_t seqnr, void *ctxt) +input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt) { Authctxt *authctxt = ctxt; char *info, *lang, *password = NULL, *retype = NULL; diff -ruN --exclude CVS ssh-openbsd-2003091600/sshconnect.c openssh-3.7p1/sshconnect.c --- ssh-openbsd-2003091600/sshconnect.c 2003-07-30 14:56:29.000000000 +1000 +++ openssh-3.7p1/sshconnect.c 2003-07-03 13:48:04.000000000 +1000 @@ -51,6 +51,10 @@ extern uid_t original_effective_uid; extern pid_t proxy_command_pid; +#ifndef INET6_ADDRSTRLEN /* for non IPv6 machines */ +#define INET6_ADDRSTRLEN 46 +#endif + static int show_other_keys(const char *, Key *); /* @@ -567,6 +571,7 @@ HostStatus host_status; HostStatus ip_status; int local = 0, host_ip_differ = 0; + int salen; char ntop[NI_MAXHOST]; char msg[1024]; int len, host_line, ip_line; @@ -585,13 +590,16 @@ case AF_INET: local = (ntohl(((struct sockaddr_in *)hostaddr)-> sin_addr.s_addr) >> 24) == IN_LOOPBACKNET; + salen = sizeof(struct sockaddr_in); break; case AF_INET6: local = IN6_IS_ADDR_LOOPBACK( &(((struct sockaddr_in6 *)hostaddr)->sin6_addr)); + salen = sizeof(struct sockaddr_in6); break; default: local = 0; + salen = sizeof(struct sockaddr_storage); break; } if (options.no_host_authentication_for_localhost == 1 && local && @@ -606,7 +614,7 @@ * using a proxy command */ if (options.proxy_command == NULL) { - if (getnameinfo(hostaddr, hostaddr->sa_len, ntop, sizeof(ntop), + if (getnameinfo(hostaddr, salen, ntop, sizeof(ntop), NULL, 0, NI_NUMERICHOST) != 0) fatal("check_host_key: getnameinfo failed"); ip = xstrdup(ntop); diff -ruN --exclude CVS ssh-openbsd-2003091600/sshd/Makefile openssh-3.7p1/sshd/Makefile --- ssh-openbsd-2003091600/sshd/Makefile 2003-09-03 12:07:15.000000000 +1000 +++ openssh-3.7p1/sshd/Makefile 1970-01-01 10:00:00.000000000 +1000 @@ -1,48 +0,0 @@ -# $OpenBSD: Makefile,v 1.61 2003/08/24 18:17:38 deraadt Exp $ - -.PATH: ${.CURDIR}/.. - -PROG= sshd -BINOWN= root -BINMODE=555 -BINDIR= /usr/sbin -MAN= sshd.8 sshd_config.5 -CFLAGS+=-DHAVE_LOGIN_CAP -DBSD_AUTH - -SRCS= sshd.c auth-rhosts.c auth-passwd.c auth-rsa.c auth-rh-rsa.c \ - sshpty.c sshlogin.c servconf.c serverloop.c uidswap.c \ - auth.c auth1.c auth2.c auth-options.c session.c \ - auth-chall.c auth2-chall.c groupaccess.c \ - auth-skey.c auth-bsdauth.c auth2-hostbased.c auth2-kbdint.c \ - auth2-none.c auth2-passwd.c auth2-pubkey.c \ - monitor_mm.c monitor.c monitor_wrap.c monitor_fdpass.c \ - kexdhs.c kexgexs.c - -.include # for KERBEROS and AFS - -.if (${KERBEROS5:L} == "yes") -CFLAGS+=-DKRB5 -I${DESTDIR}/usr/include/kerberosV -DGSSAPI -SRCS+= auth-krb5.c auth2-gss.c gss-serv.c gss-serv-krb5.c -.endif - -.include - -.if (${KERBEROS5:L} == "yes") -LDADD+= -lgssapi -lkrb5 -DPADD+= ${LIBGSSAPI} ${LIBKRB5} -.endif - -DPADD+= ${LIBCRYPTO} ${LIBUTIL} ${LIBZ} ${LIBDES} -LDADD+= -lcrypto -lutil -lz -ldes - -.if (${TCP_WRAPPERS:L} == "yes") -CFLAGS+= -DLIBWRAP -DPADD+= ${LIBWRAP} -LDADD+= -lwrap -.endif - -#.if (${SKEY:L} == "yes") -#CFLAGS+= -DSKEY -#DPADD+= ${SKEY} -#LDADD+= -lskey -#.endif diff -ruN --exclude CVS ssh-openbsd-2003091600/sshd.8 openssh-3.7p1/sshd.8 --- ssh-openbsd-2003091600/sshd.8 2003-09-03 12:07:15.000000000 +1000 +++ openssh-3.7p1/sshd.8 2003-08-25 11:51:19.000000000 +1000 @@ -114,6 +114,29 @@ authentication, RSA challenge-response authentication, or password based authentication. .Pp +Regardless of the authentication type, the account is checked to +ensure that it is accessible. An account is not accessible if it is +locked, listed in +.Cm DenyUsers +or its group is listed in +.Cm DenyGroups +\&. The definition of a locked account is system dependant. Some platforms +have their own account database (eg AIX) and some modify the passwd field ( +.Ql \&*LK\&* +on Solaris, +.Ql \&* +on HP-UX, containing +.Ql Nologin +on Tru64 and a leading +.Ql \&!! +on Linux). If there is a requirement to disable password authentication +for the account while allowing still public-key, then the passwd field +should be set to something other than these values (eg +.Ql NP +or +.Ql \&*NP\&* +). +.Pp Rhosts authentication is normally disabled because it is fundamentally insecure, but can be enabled in the server configuration file if desired. diff -ruN --exclude CVS ssh-openbsd-2003091600/sshd.c openssh-3.7p1/sshd.c --- ssh-openbsd-2003091600/sshd.c 2003-09-03 12:07:15.000000000 +1000 +++ openssh-3.7p1/sshd.c 2003-09-02 22:51:17.000000000 +1000 @@ -48,6 +48,10 @@ #include #include #include +#ifdef HAVE_SECUREWARE +#include +#include +#endif #include "ssh.h" #include "ssh1.h" @@ -92,7 +96,11 @@ #define O_NOCTTY 0 #endif +#ifdef HAVE___PROGNAME extern char *__progname; +#else +char *__progname; +#endif /* Server configuration options. */ ServerOptions options; @@ -128,6 +136,7 @@ /* Saved arguments to main(). */ char **saved_argv; +int saved_argc; /* * The sockets that the server is listening; this is used in the SIGHUP @@ -192,6 +201,9 @@ int use_privsep; struct monitor *pmonitor; +/* message to be displayed after login */ +Buffer loginmsg; + /* Prototypes for various functions defined later in this file. */ void destroy_sensitive_data(void); void demote_sensitive_data(void); @@ -616,7 +628,11 @@ /* XXX - Remote port forwarding */ x_authctxt = authctxt; +#ifdef DISABLE_FD_PASSING + if (1) { +#else if (authctxt->pw->pw_uid == 0 || options.use_login) { +#endif /* File descriptor passing is broken or root login */ monitor_apply_keystate(pmonitor); use_privsep = 0; @@ -800,8 +816,24 @@ Key *key; int ret, key_used = 0; - /* Save argv. */ - saved_argv = av; +#ifdef HAVE_SECUREWARE + (void)set_auth_parameters(ac, av); +#endif + __progname = ssh_get_progname(av[0]); + init_rng(); + + /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ + saved_argc = ac; + saved_argv = xmalloc(sizeof(*saved_argv) * (ac + 1)); + for (i = 0; i < ac; i++) + saved_argv[i] = xstrdup(av[i]); + saved_argv[i] = NULL; + +#ifndef HAVE_SETPROCTITLE + /* Prepare for later setproctitle emulation */ + compat_init_setproctitle(ac, av); + av = saved_argv; +#endif /* Initialize configuration options to their default values. */ initialize_server_options(&options); @@ -909,6 +941,15 @@ SYSLOG_FACILITY_AUTH : options.log_facility, log_stderr || !inetd_flag); +#ifdef _UNICOS + /* Cray can define user privs drop all prives now! + * Not needed on PRIV_SU systems! + */ + drop_cray_privs(); +#endif + + seed_rng(); + /* Read server configuration options from the configuration file. */ read_server_config(&options, config_file_name); @@ -1004,7 +1045,14 @@ (S_ISDIR(st.st_mode) == 0)) fatal("Missing privilege separation directory: %s", _PATH_PRIVSEP_CHROOT_DIR); + +#ifdef HAVE_CYGWIN + if (check_ntsec(_PATH_PRIVSEP_CHROOT_DIR) && + (st.st_uid != getuid () || + (st.st_mode & (S_IWGRP|S_IWOTH)) != 0)) +#else if (st.st_uid != 0 || (st.st_mode & (S_IWGRP|S_IWOTH)) != 0) +#endif fatal("%s must be owned by root and not group or " "world-writable.", _PATH_PRIVSEP_CHROOT_DIR); } @@ -1013,6 +1061,16 @@ if (test_flag) exit(0); + /* + * Clear out any supplemental groups we may have inherited. This + * prevents inadvertent creation of files with bad modes (in the + * portable version at least, it's certainly possible for PAM + * to create a file, and we can't control the code in every + * module which might be used). + */ + if (setgroups(0, NULL) < 0) + debug("setgroups() failed: %.200s", strerror(errno)); + /* Initialize the log (it is reinitialized below in case we forked). */ if (debug_flag && !inetd_flag) log_stderr = 1; @@ -1106,8 +1164,9 @@ /* Bind the socket to the desired port. */ if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) < 0) { - error("Bind to port %s on %s failed: %.200s.", - strport, ntop, strerror(errno)); + if (!ai->ai_next) + error("Bind to port %s on %s failed: %.200s.", + strport, ntop, strerror(errno)); close(listen_sock); continue; } @@ -1149,7 +1208,7 @@ * fail if there already is a daemon, and this will * overwrite any old pid in the file. */ - f = fopen(options.pid_file, "w"); + f = fopen(options.pid_file, "wb"); if (f == NULL) { error("Couldn't create pid file \"%s\": %s", options.pid_file, strerror(errno)); @@ -1332,8 +1391,15 @@ * setlogin() affects the entire process group. We don't * want the child to be able to affect the parent. */ +#if !defined(SSHD_ACQUIRES_CTTY) + /* + * If setsid is called, on some platforms sshd will later acquire a + * controlling terminal which will result in "could not set + * controlling tty" errors. + */ if (!debug_flag && !inetd_flag && setsid() < 0) error("setsid: %.100s", strerror(errno)); +#endif /* * Disable the key regeneration alarm. We will not regenerate the @@ -1346,6 +1412,7 @@ signal(SIGTERM, SIG_DFL); signal(SIGQUIT, SIG_DFL); signal(SIGCHLD, SIG_DFL); + signal(SIGINT, SIG_DFL); /* Set keepalives if requested. */ if (options.keepalives && @@ -1398,6 +1465,9 @@ packet_set_nonblocking(); + /* prepare buffers to collect authentication messages */ + buffer_init(&loginmsg); + if (use_privsep) if ((authctxt = privsep_preauth()) != NULL) goto authenticated; @@ -1437,6 +1507,12 @@ /* The connection has been terminated. */ verbose("Closing connection to %.100s", remote_ip); + +#ifdef USE_PAM + if (options.use_pam) + finish_pam(); +#endif /* USE_PAM */ + packet_close(); if (use_privsep) diff -ruN --exclude CVS ssh-openbsd-2003091600/.#sshd.c.1.268 openssh-3.7p1/.#sshd.c.1.268 --- ssh-openbsd-2003091600/.#sshd.c.1.268 2003-06-28 11:22:07.000000000 +1000 +++ openssh-3.7p1/.#sshd.c.1.268 1970-01-01 10:00:00.000000000 +1000 @@ -1,1774 +0,0 @@ -/* - * Author: Tatu Ylonen - * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland - * All rights reserved - * This program is the ssh daemon. It listens for connections from clients, - * and performs authentication, executes use commands or shell, and forwards - * information to/from the application to the user client over an encrypted - * connection. This can also handle forwarding of X11, TCP/IP, and - * authentication agent connections. - * - * As far as I am concerned, the code I have written for this software - * can be used freely for any purpose. Any derived versions of this - * software must be clearly marked as such, and if the derived work is - * incompatible with the protocol description in the RFC file, it must be - * called by a name other than "ssh" or "Secure Shell". - * - * SSH2 implementation: - * Privilege Separation: - * - * Copyright (c) 2000, 2001, 2002 Markus Friedl. All rights reserved. - * Copyright (c) 2002 Niels Provos. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "includes.h" -RCSID("$OpenBSD: sshd.c,v 1.268 2003/06/04 10:23:48 djm Exp $"); - -#include -#include -#include -#include - -#include "ssh.h" -#include "ssh1.h" -#include "ssh2.h" -#include "xmalloc.h" -#include "rsa.h" -#include "sshpty.h" -#include "packet.h" -#include "mpaux.h" -#include "log.h" -#include "servconf.h" -#include "uidswap.h" -#include "compat.h" -#include "buffer.h" -#include "cipher.h" -#include "kex.h" -#include "key.h" -#include "dh.h" -#include "myproposal.h" -#include "authfile.h" -#include "pathnames.h" -#include "atomicio.h" -#include "canohost.h" -#include "auth.h" -#include "misc.h" -#include "dispatch.h" -#include "channels.h" -#include "session.h" -#include "monitor_mm.h" -#include "monitor.h" -#include "monitor_wrap.h" -#include "monitor_fdpass.h" - -#ifdef LIBWRAP -#include -#include -int allow_severity = LOG_INFO; -int deny_severity = LOG_WARNING; -#endif /* LIBWRAP */ - -#ifndef O_NOCTTY -#define O_NOCTTY 0 -#endif - -extern char *__progname; - -/* Server configuration options. */ -ServerOptions options; - -/* Name of the server configuration file. */ -char *config_file_name = _PATH_SERVER_CONFIG_FILE; - -/* - * Flag indicating whether IPv4 or IPv6. This can be set on the command line. - * Default value is AF_UNSPEC means both IPv4 and IPv6. - */ -int IPv4or6 = AF_UNSPEC; - -/* - * Debug mode flag. This can be set on the command line. If debug - * mode is enabled, extra debugging output will be sent to the system - * log, the daemon will not go to background, and will exit after processing - * the first connection. - */ -int debug_flag = 0; - -/* Flag indicating that the daemon should only test the configuration and keys. */ -int test_flag = 0; - -/* Flag indicating that the daemon is being started from inetd. */ -int inetd_flag = 0; - -/* Flag indicating that sshd should not detach and become a daemon. */ -int no_daemon_flag = 0; - -/* debug goes to stderr unless inetd_flag is set */ -int log_stderr = 0; - -/* Saved arguments to main(). */ -char **saved_argv; - -/* - * The sockets that the server is listening; this is used in the SIGHUP - * signal handler. - */ -#define MAX_LISTEN_SOCKS 16 -int listen_socks[MAX_LISTEN_SOCKS]; -int num_listen_socks = 0; - -/* - * the client's version string, passed by sshd2 in compat mode. if != NULL, - * sshd will skip the version-number exchange - */ -char *client_version_string = NULL; -char *server_version_string = NULL; - -/* for rekeying XXX fixme */ -Kex *xxx_kex; - -/* - * Any really sensitive data in the application is contained in this - * structure. The idea is that this structure could be locked into memory so - * that the pages do not get written into swap. However, there are some - * problems. The private key contains BIGNUMs, and we do not (in principle) - * have access to the internals of them, and locking just the structure is - * not very useful. Currently, memory locking is not implemented. - */ -struct { - Key *server_key; /* ephemeral server key */ - Key *ssh1_host_key; /* ssh1 host key */ - Key **host_keys; /* all private host keys */ - int have_ssh1_key; - int have_ssh2_key; - u_char ssh1_cookie[SSH_SESSION_KEY_LENGTH]; -} sensitive_data; - -/* - * Flag indicating whether the RSA server key needs to be regenerated. - * Is set in the SIGALRM handler and cleared when the key is regenerated. - */ -static volatile sig_atomic_t key_do_regen = 0; - -/* This is set to true when a signal is received. */ -static volatile sig_atomic_t received_sighup = 0; -static volatile sig_atomic_t received_sigterm = 0; - -/* session identifier, used by RSA-auth */ -u_char session_id[16]; - -/* same for ssh2 */ -u_char *session_id2 = NULL; -int session_id2_len = 0; - -/* record remote hostname or ip */ -u_int utmp_len = MAXHOSTNAMELEN; - -/* options.max_startup sized array of fd ints */ -int *startup_pipes = NULL; -int startup_pipe; /* in child */ - -/* variables used for privilege separation */ -int use_privsep; -struct monitor *pmonitor; - -/* Prototypes for various functions defined later in this file. */ -void destroy_sensitive_data(void); -void demote_sensitive_data(void); - -static void do_ssh1_kex(void); -static void do_ssh2_kex(void); - -/* - * Close all listening sockets - */ -static void -close_listen_socks(void) -{ - int i; - - for (i = 0; i < num_listen_socks; i++) - close(listen_socks[i]); - num_listen_socks = -1; -} - -static void -close_startup_pipes(void) -{ - int i; - - if (startup_pipes) - for (i = 0; i < options.max_startups; i++) - if (startup_pipes[i] != -1) - close(startup_pipes[i]); -} - -/* - * Signal handler for SIGHUP. Sshd execs itself when it receives SIGHUP; - * the effect is to reread the configuration file (and to regenerate - * the server key). - */ -static void -sighup_handler(int sig) -{ - int save_errno = errno; - - received_sighup = 1; - signal(SIGHUP, sighup_handler); - errno = save_errno; -} - -/* - * Called from the main program after receiving SIGHUP. - * Restarts the server. - */ -static void -sighup_restart(void) -{ - logit("Received SIGHUP; restarting."); - close_listen_socks(); - close_startup_pipes(); - execv(saved_argv[0], saved_argv); - logit("RESTART FAILED: av[0]='%.100s', error: %.100s.", saved_argv[0], - strerror(errno)); - exit(1); -} - -/* - * Generic signal handler for terminating signals in the master daemon. - */ -static void -sigterm_handler(int sig) -{ - received_sigterm = sig; -} - -/* - * SIGCHLD handler. This is called whenever a child dies. This will then - * reap any zombies left by exited children. - */ -static void -main_sigchld_handler(int sig) -{ - int save_errno = errno; - pid_t pid; - int status; - - while ((pid = waitpid(-1, &status, WNOHANG)) > 0 || - (pid < 0 && errno == EINTR)) - ; - - signal(SIGCHLD, main_sigchld_handler); - errno = save_errno; -} - -/* - * Signal handler for the alarm after the login grace period has expired. - */ -static void -grace_alarm_handler(int sig) -{ - /* XXX no idea how fix this signal handler */ - - /* Log error and exit. */ - fatal("Timeout before authentication for %s", get_remote_ipaddr()); -} - -/* - * Signal handler for the key regeneration alarm. Note that this - * alarm only occurs in the daemon waiting for connections, and it does not - * do anything with the private key or random state before forking. - * Thus there should be no concurrency control/asynchronous execution - * problems. - */ -static void -generate_ephemeral_server_key(void) -{ - u_int32_t rnd = 0; - int i; - - verbose("Generating %s%d bit RSA key.", - sensitive_data.server_key ? "new " : "", options.server_key_bits); - if (sensitive_data.server_key != NULL) - key_free(sensitive_data.server_key); - sensitive_data.server_key = key_generate(KEY_RSA1, - options.server_key_bits); - verbose("RSA key generation complete."); - - for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) { - if (i % 4 == 0) - rnd = arc4random(); - sensitive_data.ssh1_cookie[i] = rnd & 0xff; - rnd >>= 8; - } - arc4random_stir(); -} - -static void -key_regeneration_alarm(int sig) -{ - int save_errno = errno; - - signal(SIGALRM, SIG_DFL); - errno = save_errno; - key_do_regen = 1; -} - -static void -sshd_exchange_identification(int sock_in, int sock_out) -{ - int i, mismatch; - int remote_major, remote_minor; - int major, minor; - char *s; - char buf[256]; /* Must not be larger than remote_version. */ - char remote_version[256]; /* Must be at least as big as buf. */ - - if ((options.protocol & SSH_PROTO_1) && - (options.protocol & SSH_PROTO_2)) { - major = PROTOCOL_MAJOR_1; - minor = 99; - } else if (options.protocol & SSH_PROTO_2) { - major = PROTOCOL_MAJOR_2; - minor = PROTOCOL_MINOR_2; - } else { - major = PROTOCOL_MAJOR_1; - minor = PROTOCOL_MINOR_1; - } - snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", major, minor, SSH_VERSION); - server_version_string = xstrdup(buf); - - if (client_version_string == NULL) { - /* Send our protocol version identification. */ - if (atomicio(write, sock_out, server_version_string, - strlen(server_version_string)) - != strlen(server_version_string)) { - logit("Could not write ident string to %s", get_remote_ipaddr()); - fatal_cleanup(); - } - - /* Read other sides version identification. */ - memset(buf, 0, sizeof(buf)); - for (i = 0; i < sizeof(buf) - 1; i++) { - if (atomicio(read, sock_in, &buf[i], 1) != 1) { - logit("Did not receive identification string from %s", - get_remote_ipaddr()); - fatal_cleanup(); - } - if (buf[i] == '\r') { - buf[i] = 0; - /* Kludge for F-Secure Macintosh < 1.0.2 */ - if (i == 12 && - strncmp(buf, "SSH-1.5-W1.0", 12) == 0) - break; - continue; - } - if (buf[i] == '\n') { - buf[i] = 0; - break; - } - } - buf[sizeof(buf) - 1] = 0; - client_version_string = xstrdup(buf); - } - - /* - * Check that the versions match. In future this might accept - * several versions and set appropriate flags to handle them. - */ - if (sscanf(client_version_string, "SSH-%d.%d-%[^\n]\n", - &remote_major, &remote_minor, remote_version) != 3) { - s = "Protocol mismatch.\n"; - (void) atomicio(write, sock_out, s, strlen(s)); - close(sock_in); - close(sock_out); - logit("Bad protocol version identification '%.100s' from %s", - client_version_string, get_remote_ipaddr()); - fatal_cleanup(); - } - debug("Client protocol version %d.%d; client software version %.100s", - remote_major, remote_minor, remote_version); - - compat_datafellows(remote_version); - - if (datafellows & SSH_BUG_PROBE) { - logit("probed from %s with %s. Don't panic.", - get_remote_ipaddr(), client_version_string); - fatal_cleanup(); - } - - if (datafellows & SSH_BUG_SCANNER) { - logit("scanned from %s with %s. Don't panic.", - get_remote_ipaddr(), client_version_string); - fatal_cleanup(); - } - - mismatch = 0; - switch (remote_major) { - case 1: - if (remote_minor == 99) { - if (options.protocol & SSH_PROTO_2) - enable_compat20(); - else - mismatch = 1; - break; - } - if (!(options.protocol & SSH_PROTO_1)) { - mismatch = 1; - break; - } - if (remote_minor < 3) { - packet_disconnect("Your ssh version is too old and " - "is no longer supported. Please install a newer version."); - } else if (remote_minor == 3) { - /* note that this disables agent-forwarding */ - enable_compat13(); - } - break; - case 2: - if (options.protocol & SSH_PROTO_2) { - enable_compat20(); - break; - } - /* FALLTHROUGH */ - default: - mismatch = 1; - break; - } - chop(server_version_string); - debug("Local version string %.200s", server_version_string); - - if (mismatch) { - s = "Protocol major versions differ.\n"; - (void) atomicio(write, sock_out, s, strlen(s)); - close(sock_in); - close(sock_out); - logit("Protocol major versions differ for %s: %.200s vs. %.200s", - get_remote_ipaddr(), - server_version_string, client_version_string); - fatal_cleanup(); - } -} - -/* Destroy the host and server keys. They will no longer be needed. */ -void -destroy_sensitive_data(void) -{ - int i; - - if (sensitive_data.server_key) { - key_free(sensitive_data.server_key); - sensitive_data.server_key = NULL; - } - for (i = 0; i < options.num_host_key_files; i++) { - if (sensitive_data.host_keys[i]) { - key_free(sensitive_data.host_keys[i]); - sensitive_data.host_keys[i] = NULL; - } - } - sensitive_data.ssh1_host_key = NULL; - memset(sensitive_data.ssh1_cookie, 0, SSH_SESSION_KEY_LENGTH); -} - -/* Demote private to public keys for network child */ -void -demote_sensitive_data(void) -{ - Key *tmp; - int i; - - if (sensitive_data.server_key) { - tmp = key_demote(sensitive_data.server_key); - key_free(sensitive_data.server_key); - sensitive_data.server_key = tmp; - } - - for (i = 0; i < options.num_host_key_files; i++) { - if (sensitive_data.host_keys[i]) { - tmp = key_demote(sensitive_data.host_keys[i]); - key_free(sensitive_data.host_keys[i]); - sensitive_data.host_keys[i] = tmp; - if (tmp->type == KEY_RSA1) - sensitive_data.ssh1_host_key = tmp; - } - } - - /* We do not clear ssh1_host key and cookie. XXX - Okay Niels? */ -} - -static void -privsep_preauth_child(void) -{ - u_int32_t rnd[256]; - gid_t gidset[1]; - struct passwd *pw; - int i; - - /* Enable challenge-response authentication for privilege separation */ - privsep_challenge_enable(); - - for (i = 0; i < 256; i++) - rnd[i] = arc4random(); - RAND_seed(rnd, sizeof(rnd)); - - /* Demote the private keys to public keys. */ - demote_sensitive_data(); - - if ((pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) - fatal("Privilege separation user %s does not exist", - SSH_PRIVSEP_USER); - memset(pw->pw_passwd, 0, strlen(pw->pw_passwd)); - endpwent(); - - /* Change our root directory */ - if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1) - fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR, - strerror(errno)); - if (chdir("/") == -1) - fatal("chdir(\"/\"): %s", strerror(errno)); - - /* Drop our privileges */ - debug3("privsep user:group %u:%u", (u_int)pw->pw_uid, - (u_int)pw->pw_gid); -#if 0 - /* XXX not ready, to heavy after chroot */ - do_setusercontext(pw); -#else - gidset[0] = pw->pw_gid; - if (setgroups(1, gidset) < 0) - fatal("setgroups: %.100s", strerror(errno)); - permanently_set_uid(pw); -#endif -} - -static Authctxt * -privsep_preauth(void) -{ - Authctxt *authctxt = NULL; - int status; - pid_t pid; - - /* Set up unprivileged child process to deal with network data */ - pmonitor = monitor_init(); - /* Store a pointer to the kex for later rekeying */ - pmonitor->m_pkex = &xxx_kex; - - pid = fork(); - if (pid == -1) { - fatal("fork of unprivileged child failed"); - } else if (pid != 0) { - fatal_remove_cleanup((void (*) (void *)) packet_close, NULL); - - debug2("Network child is on pid %ld", (long)pid); - - close(pmonitor->m_recvfd); - authctxt = monitor_child_preauth(pmonitor); - close(pmonitor->m_sendfd); - - /* Sync memory */ - monitor_sync(pmonitor); - - /* Wait for the child's exit status */ - while (waitpid(pid, &status, 0) < 0) - if (errno != EINTR) - break; - - /* Reinstall, since the child has finished */ - fatal_add_cleanup((void (*) (void *)) packet_close, NULL); - - return (authctxt); - } else { - /* child */ - - close(pmonitor->m_sendfd); - - /* Demote the child */ - if (getuid() == 0 || geteuid() == 0) - privsep_preauth_child(); - setproctitle("%s", "[net]"); - } - return (NULL); -} - -static void -privsep_postauth(Authctxt *authctxt) -{ - extern Authctxt *x_authctxt; - - /* XXX - Remote port forwarding */ - x_authctxt = authctxt; - - if (authctxt->pw->pw_uid == 0 || options.use_login) { - /* File descriptor passing is broken or root login */ - monitor_apply_keystate(pmonitor); - use_privsep = 0; - return; - } - - /* Authentication complete */ - alarm(0); - if (startup_pipe != -1) { - close(startup_pipe); - startup_pipe = -1; - } - - /* New socket pair */ - monitor_reinit(pmonitor); - - pmonitor->m_pid = fork(); - if (pmonitor->m_pid == -1) - fatal("fork of unprivileged child failed"); - else if (pmonitor->m_pid != 0) { - fatal_remove_cleanup((void (*) (void *)) packet_close, NULL); - - debug2("User child is on pid %ld", (long)pmonitor->m_pid); - close(pmonitor->m_recvfd); - monitor_child_postauth(pmonitor); - - /* NEVERREACHED */ - exit(0); - } - - close(pmonitor->m_sendfd); - - /* Demote the private keys to public keys. */ - demote_sensitive_data(); - - /* Drop privileges */ - do_setusercontext(authctxt->pw); - - /* It is safe now to apply the key state */ - monitor_apply_keystate(pmonitor); -} - -static char * -list_hostkey_types(void) -{ - Buffer b; - char *p; - int i; - - buffer_init(&b); - for (i = 0; i < options.num_host_key_files; i++) { - Key *key = sensitive_data.host_keys[i]; - if (key == NULL) - continue; - switch (key->type) { - case KEY_RSA: - case KEY_DSA: - if (buffer_len(&b) > 0) - buffer_append(&b, ",", 1); - p = key_ssh_name(key); - buffer_append(&b, p, strlen(p)); - break; - } - } - buffer_append(&b, "\0", 1); - p = xstrdup(buffer_ptr(&b)); - buffer_free(&b); - debug("list_hostkey_types: %s", p); - return p; -} - -Key * -get_hostkey_by_type(int type) -{ - int i; - - for (i = 0; i < options.num_host_key_files; i++) { - Key *key = sensitive_data.host_keys[i]; - if (key != NULL && key->type == type) - return key; - } - return NULL; -} - -Key * -get_hostkey_by_index(int ind) -{ - if (ind < 0 || ind >= options.num_host_key_files) - return (NULL); - return (sensitive_data.host_keys[ind]); -} - -int -get_hostkey_index(Key *key) -{ - int i; - - for (i = 0; i < options.num_host_key_files; i++) { - if (key == sensitive_data.host_keys[i]) - return (i); - } - return (-1); -} - -/* - * returns 1 if connection should be dropped, 0 otherwise. - * dropping starts at connection #max_startups_begin with a probability - * of (max_startups_rate/100). the probability increases linearly until - * all connections are dropped for startups > max_startups - */ -static int -drop_connection(int startups) -{ - double p, r; - - if (startups < options.max_startups_begin) - return 0; - if (startups >= options.max_startups) - return 1; - if (options.max_startups_rate == 100) - return 1; - - p = 100 - options.max_startups_rate; - p *= startups - options.max_startups_begin; - p /= (double) (options.max_startups - options.max_startups_begin); - p += options.max_startups_rate; - p /= 100.0; - r = arc4random() / (double) UINT_MAX; - - debug("drop_connection: p %g, r %g", p, r); - return (r < p) ? 1 : 0; -} - -static void -usage(void) -{ - fprintf(stderr, "sshd version %s\n", SSH_VERSION); - fprintf(stderr, "Usage: %s [options]\n", __progname); - fprintf(stderr, "Options:\n"); - fprintf(stderr, " -f file Configuration file (default %s)\n", _PATH_SERVER_CONFIG_FILE); - fprintf(stderr, " -d Debugging mode (multiple -d means more debugging)\n"); - fprintf(stderr, " -i Started from inetd\n"); - fprintf(stderr, " -D Do not fork into daemon mode\n"); - fprintf(stderr, " -t Only test configuration file and keys\n"); - fprintf(stderr, " -q Quiet (no logging)\n"); - fprintf(stderr, " -p port Listen on the specified port (default: 22)\n"); - fprintf(stderr, " -k seconds Regenerate server key every this many seconds (default: 3600)\n"); - fprintf(stderr, " -g seconds Grace period for authentication (default: 600)\n"); - fprintf(stderr, " -b bits Size of server RSA key (default: 768 bits)\n"); - fprintf(stderr, " -h file File from which to read host key (default: %s)\n", - _PATH_HOST_KEY_FILE); - fprintf(stderr, " -u len Maximum hostname length for utmp recording\n"); - fprintf(stderr, " -4 Use IPv4 only\n"); - fprintf(stderr, " -6 Use IPv6 only\n"); - fprintf(stderr, " -o option Process the option as if it was read from a configuration file.\n"); - exit(1); -} - -/* - * Main program for the daemon. - */ -int -main(int ac, char **av) -{ - extern char *optarg; - extern int optind; - int opt, sock_in = 0, sock_out = 0, newsock, j, i, fdsetsz, on = 1; - pid_t pid; - socklen_t fromlen; - fd_set *fdset; - struct sockaddr_storage from; - const char *remote_ip; - int remote_port; - FILE *f; - struct addrinfo *ai; - char ntop[NI_MAXHOST], strport[NI_MAXSERV]; - int listen_sock, maxfd; - int startup_p[2]; - int startups = 0; - Authctxt *authctxt; - Key *key; - int ret, key_used = 0; - - /* Save argv. */ - saved_argv = av; - - /* Initialize configuration options to their default values. */ - initialize_server_options(&options); - - /* Parse command-line arguments. */ - while ((opt = getopt(ac, av, "f:p:b:k:h:g:V:u:o:dDeiqtQ46")) != -1) { - switch (opt) { - case '4': - IPv4or6 = AF_INET; - break; - case '6': - IPv4or6 = AF_INET6; - break; - case 'f': - config_file_name = optarg; - break; - case 'd': - if (0 == debug_flag) { - debug_flag = 1; - options.log_level = SYSLOG_LEVEL_DEBUG1; - } else if (options.log_level < SYSLOG_LEVEL_DEBUG3) { - options.log_level++; - } else { - fprintf(stderr, "Too high debugging level.\n"); - exit(1); - } - break; - case 'D': - no_daemon_flag = 1; - break; - case 'e': - log_stderr = 1; - break; - case 'i': - inetd_flag = 1; - break; - case 'Q': - /* ignored */ - break; - case 'q': - options.log_level = SYSLOG_LEVEL_QUIET; - break; - case 'b': - options.server_key_bits = atoi(optarg); - break; - case 'p': - options.ports_from_cmdline = 1; - if (options.num_ports >= MAX_PORTS) { - fprintf(stderr, "too many ports.\n"); - exit(1); - } - options.ports[options.num_ports++] = a2port(optarg); - if (options.ports[options.num_ports-1] == 0) { - fprintf(stderr, "Bad port number.\n"); - exit(1); - } - break; - case 'g': - if ((options.login_grace_time = convtime(optarg)) == -1) { - fprintf(stderr, "Invalid login grace time.\n"); - exit(1); - } - break; - case 'k': - if ((options.key_regeneration_time = convtime(optarg)) == -1) { - fprintf(stderr, "Invalid key regeneration interval.\n"); - exit(1); - } - break; - case 'h': - if (options.num_host_key_files >= MAX_HOSTKEYS) { - fprintf(stderr, "too many host keys.\n"); - exit(1); - } - options.host_key_files[options.num_host_key_files++] = optarg; - break; - case 'V': - client_version_string = optarg; - /* only makes sense with inetd_flag, i.e. no listen() */ - inetd_flag = 1; - break; - case 't': - test_flag = 1; - break; - case 'u': - utmp_len = atoi(optarg); - if (utmp_len > MAXHOSTNAMELEN) { - fprintf(stderr, "Invalid utmp length.\n"); - exit(1); - } - break; - case 'o': - if (process_server_config_line(&options, optarg, - "command-line", 0) != 0) - exit(1); - break; - case '?': - default: - usage(); - break; - } - } - SSLeay_add_all_algorithms(); - channel_set_af(IPv4or6); - - /* - * Force logging to stderr until we have loaded the private host - * key (unless started from inetd) - */ - log_init(__progname, - options.log_level == SYSLOG_LEVEL_NOT_SET ? - SYSLOG_LEVEL_INFO : options.log_level, - options.log_facility == SYSLOG_FACILITY_NOT_SET ? - SYSLOG_FACILITY_AUTH : options.log_facility, - log_stderr || !inetd_flag); - - /* Read server configuration options from the configuration file. */ - read_server_config(&options, config_file_name); - - /* Fill in default values for those options not explicitly set. */ - fill_default_server_options(&options); - - /* Check that there are no remaining arguments. */ - if (optind < ac) { - fprintf(stderr, "Extra argument %s.\n", av[optind]); - exit(1); - } - - debug("sshd version %.100s", SSH_VERSION); - - /* load private host keys */ - sensitive_data.host_keys = xmalloc(options.num_host_key_files * - sizeof(Key *)); - for (i = 0; i < options.num_host_key_files; i++) - sensitive_data.host_keys[i] = NULL; - sensitive_data.server_key = NULL; - sensitive_data.ssh1_host_key = NULL; - sensitive_data.have_ssh1_key = 0; - sensitive_data.have_ssh2_key = 0; - - for (i = 0; i < options.num_host_key_files; i++) { - key = key_load_private(options.host_key_files[i], "", NULL); - sensitive_data.host_keys[i] = key; - if (key == NULL) { - error("Could not load host key: %s", - options.host_key_files[i]); - sensitive_data.host_keys[i] = NULL; - continue; - } - switch (key->type) { - case KEY_RSA1: - sensitive_data.ssh1_host_key = key; - sensitive_data.have_ssh1_key = 1; - break; - case KEY_RSA: - case KEY_DSA: - sensitive_data.have_ssh2_key = 1; - break; - } - debug("private host key: #%d type %d %s", i, key->type, - key_type(key)); - } - if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) { - logit("Disabling protocol version 1. Could not load host key"); - options.protocol &= ~SSH_PROTO_1; - } - if ((options.protocol & SSH_PROTO_2) && !sensitive_data.have_ssh2_key) { - logit("Disabling protocol version 2. Could not load host key"); - options.protocol &= ~SSH_PROTO_2; - } - if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) { - logit("sshd: no hostkeys available -- exiting."); - exit(1); - } - - /* Check certain values for sanity. */ - if (options.protocol & SSH_PROTO_1) { - if (options.server_key_bits < 512 || - options.server_key_bits > 32768) { - fprintf(stderr, "Bad server key size.\n"); - exit(1); - } - /* - * Check that server and host key lengths differ sufficiently. This - * is necessary to make double encryption work with rsaref. Oh, I - * hate software patents. I dont know if this can go? Niels - */ - if (options.server_key_bits > - BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) - - SSH_KEY_BITS_RESERVED && options.server_key_bits < - BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + - SSH_KEY_BITS_RESERVED) { - options.server_key_bits = - BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + - SSH_KEY_BITS_RESERVED; - debug("Forcing server key to %d bits to make it differ from host key.", - options.server_key_bits); - } - } - - if (use_privsep) { - struct passwd *pw; - struct stat st; - - if ((pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) - fatal("Privilege separation user %s does not exist", - SSH_PRIVSEP_USER); - if ((stat(_PATH_PRIVSEP_CHROOT_DIR, &st) == -1) || - (S_ISDIR(st.st_mode) == 0)) - fatal("Missing privilege separation directory: %s", - _PATH_PRIVSEP_CHROOT_DIR); - if (st.st_uid != 0 || (st.st_mode & (S_IWGRP|S_IWOTH)) != 0) - fatal("%s must be owned by root and not group or " - "world-writable.", _PATH_PRIVSEP_CHROOT_DIR); - } - - /* Configuration looks good, so exit if in test mode. */ - if (test_flag) - exit(0); - - /* Initialize the log (it is reinitialized below in case we forked). */ - if (debug_flag && !inetd_flag) - log_stderr = 1; - log_init(__progname, options.log_level, options.log_facility, log_stderr); - - /* - * If not in debugging mode, and not started from inetd, disconnect - * from the controlling terminal, and fork. The original process - * exits. - */ - if (!(debug_flag || inetd_flag || no_daemon_flag)) { -#ifdef TIOCNOTTY - int fd; -#endif /* TIOCNOTTY */ - if (daemon(0, 0) < 0) - fatal("daemon() failed: %.200s", strerror(errno)); - - /* Disconnect from the controlling tty. */ -#ifdef TIOCNOTTY - fd = open(_PATH_TTY, O_RDWR | O_NOCTTY); - if (fd >= 0) { - (void) ioctl(fd, TIOCNOTTY, NULL); - close(fd); - } -#endif /* TIOCNOTTY */ - } - /* Reinitialize the log (because of the fork above). */ - log_init(__progname, options.log_level, options.log_facility, log_stderr); - - /* Initialize the random number generator. */ - arc4random_stir(); - - /* Chdir to the root directory so that the current disk can be - unmounted if desired. */ - chdir("/"); - - /* ignore SIGPIPE */ - signal(SIGPIPE, SIG_IGN); - - /* Start listening for a socket, unless started from inetd. */ - if (inetd_flag) { - int s1; - s1 = dup(0); /* Make sure descriptors 0, 1, and 2 are in use. */ - dup(s1); - sock_in = dup(0); - sock_out = dup(1); - startup_pipe = -1; - /* - * We intentionally do not close the descriptors 0, 1, and 2 - * as our code for setting the descriptors won\'t work if - * ttyfd happens to be one of those. - */ - debug("inetd sockets after dupping: %d, %d", sock_in, sock_out); - if (options.protocol & SSH_PROTO_1) - generate_ephemeral_server_key(); - } else { - for (ai = options.listen_addrs; ai; ai = ai->ai_next) { - if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) - continue; - if (num_listen_socks >= MAX_LISTEN_SOCKS) - fatal("Too many listen sockets. " - "Enlarge MAX_LISTEN_SOCKS"); - if (getnameinfo(ai->ai_addr, ai->ai_addrlen, - ntop, sizeof(ntop), strport, sizeof(strport), - NI_NUMERICHOST|NI_NUMERICSERV) != 0) { - error("getnameinfo failed"); - continue; - } - /* Create socket for listening. */ - listen_sock = socket(ai->ai_family, ai->ai_socktype, - ai->ai_protocol); - if (listen_sock < 0) { - /* kernel may not support ipv6 */ - verbose("socket: %.100s", strerror(errno)); - continue; - } - if (fcntl(listen_sock, F_SETFL, O_NONBLOCK) < 0) { - error("listen_sock O_NONBLOCK: %s", strerror(errno)); - close(listen_sock); - continue; - } - /* - * Set socket options. - * Allow local port reuse in TIME_WAIT. - */ - if (setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, - &on, sizeof(on)) == -1) - error("setsockopt SO_REUSEADDR: %s", strerror(errno)); - - debug("Bind to port %s on %s.", strport, ntop); - - /* Bind the socket to the desired port. */ - if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) < 0) { - error("Bind to port %s on %s failed: %.200s.", - strport, ntop, strerror(errno)); - close(listen_sock); - continue; - } - listen_socks[num_listen_socks] = listen_sock; - num_listen_socks++; - - /* Start listening on the port. */ - logit("Server listening on %s port %s.", ntop, strport); - if (listen(listen_sock, 5) < 0) - fatal("listen: %.100s", strerror(errno)); - - } - freeaddrinfo(options.listen_addrs); - - if (!num_listen_socks) - fatal("Cannot bind any address."); - - if (options.protocol & SSH_PROTO_1) - generate_ephemeral_server_key(); - - /* - * Arrange to restart on SIGHUP. The handler needs - * listen_sock. - */ - signal(SIGHUP, sighup_handler); - - signal(SIGTERM, sigterm_handler); - signal(SIGQUIT, sigterm_handler); - - /* Arrange SIGCHLD to be caught. */ - signal(SIGCHLD, main_sigchld_handler); - - /* Write out the pid file after the sigterm handler is setup */ - if (!debug_flag) { - /* - * Record our pid in /var/run/sshd.pid to make it - * easier to kill the correct sshd. We don't want to - * do this before the bind above because the bind will - * fail if there already is a daemon, and this will - * overwrite any old pid in the file. - */ - f = fopen(options.pid_file, "w"); - if (f == NULL) { - error("Couldn't create pid file \"%s\": %s", - options.pid_file, strerror(errno)); - } else { - fprintf(f, "%ld\n", (long) getpid()); - fclose(f); - } - } - - /* setup fd set for listen */ - fdset = NULL; - maxfd = 0; - for (i = 0; i < num_listen_socks; i++) - if (listen_socks[i] > maxfd) - maxfd = listen_socks[i]; - /* pipes connected to unauthenticated childs */ - startup_pipes = xmalloc(options.max_startups * sizeof(int)); - for (i = 0; i < options.max_startups; i++) - startup_pipes[i] = -1; - - /* - * Stay listening for connections until the system crashes or - * the daemon is killed with a signal. - */ - for (;;) { - if (received_sighup) - sighup_restart(); - if (fdset != NULL) - xfree(fdset); - fdsetsz = howmany(maxfd+1, NFDBITS) * sizeof(fd_mask); - fdset = (fd_set *)xmalloc(fdsetsz); - memset(fdset, 0, fdsetsz); - - for (i = 0; i < num_listen_socks; i++) - FD_SET(listen_socks[i], fdset); - for (i = 0; i < options.max_startups; i++) - if (startup_pipes[i] != -1) - FD_SET(startup_pipes[i], fdset); - - /* Wait in select until there is a connection. */ - ret = select(maxfd+1, fdset, NULL, NULL, NULL); - if (ret < 0 && errno != EINTR) - error("select: %.100s", strerror(errno)); - if (received_sigterm) { - logit("Received signal %d; terminating.", - (int) received_sigterm); - close_listen_socks(); - unlink(options.pid_file); - exit(255); - } - if (key_used && key_do_regen) { - generate_ephemeral_server_key(); - key_used = 0; - key_do_regen = 0; - } - if (ret < 0) - continue; - - for (i = 0; i < options.max_startups; i++) - if (startup_pipes[i] != -1 && - FD_ISSET(startup_pipes[i], fdset)) { - /* - * the read end of the pipe is ready - * if the child has closed the pipe - * after successful authentication - * or if the child has died - */ - close(startup_pipes[i]); - startup_pipes[i] = -1; - startups--; - } - for (i = 0; i < num_listen_socks; i++) { - if (!FD_ISSET(listen_socks[i], fdset)) - continue; - fromlen = sizeof(from); - newsock = accept(listen_socks[i], (struct sockaddr *)&from, - &fromlen); - if (newsock < 0) { - if (errno != EINTR && errno != EWOULDBLOCK) - error("accept: %.100s", strerror(errno)); - continue; - } - if (fcntl(newsock, F_SETFL, 0) < 0) { - error("newsock del O_NONBLOCK: %s", strerror(errno)); - close(newsock); - continue; - } - if (drop_connection(startups) == 1) { - debug("drop connection #%d", startups); - close(newsock); - continue; - } - if (pipe(startup_p) == -1) { - close(newsock); - continue; - } - - for (j = 0; j < options.max_startups; j++) - if (startup_pipes[j] == -1) { - startup_pipes[j] = startup_p[0]; - if (maxfd < startup_p[0]) - maxfd = startup_p[0]; - startups++; - break; - } - - /* - * Got connection. Fork a child to handle it, unless - * we are in debugging mode. - */ - if (debug_flag) { - /* - * In debugging mode. Close the listening - * socket, and start processing the - * connection without forking. - */ - debug("Server will not fork when running in debugging mode."); - close_listen_socks(); - sock_in = newsock; - sock_out = newsock; - startup_pipe = -1; - pid = getpid(); - break; - } else { - /* - * Normal production daemon. Fork, and have - * the child process the connection. The - * parent continues listening. - */ - if ((pid = fork()) == 0) { - /* - * Child. Close the listening and max_startup - * sockets. Start using the accepted socket. - * Reinitialize logging (since our pid has - * changed). We break out of the loop to handle - * the connection. - */ - startup_pipe = startup_p[1]; - close_startup_pipes(); - close_listen_socks(); - sock_in = newsock; - sock_out = newsock; - log_init(__progname, options.log_level, options.log_facility, log_stderr); - break; - } - } - - /* Parent. Stay in the loop. */ - if (pid < 0) - error("fork: %.100s", strerror(errno)); - else - debug("Forked child %ld.", (long)pid); - - close(startup_p[1]); - - /* Mark that the key has been used (it was "given" to the child). */ - if ((options.protocol & SSH_PROTO_1) && - key_used == 0) { - /* Schedule server key regeneration alarm. */ - signal(SIGALRM, key_regeneration_alarm); - alarm(options.key_regeneration_time); - key_used = 1; - } - - arc4random_stir(); - - /* Close the new socket (the child is now taking care of it). */ - close(newsock); - } - /* child process check (or debug mode) */ - if (num_listen_socks < 0) - break; - } - } - - /* This is the child processing a new connection. */ - - /* - * Create a new session and process group since the 4.4BSD - * setlogin() affects the entire process group. We don't - * want the child to be able to affect the parent. - */ - if (!debug_flag && !inetd_flag && setsid() < 0) - error("setsid: %.100s", strerror(errno)); - - /* - * Disable the key regeneration alarm. We will not regenerate the - * key since we are no longer in a position to give it to anyone. We - * will not restart on SIGHUP since it no longer makes sense. - */ - alarm(0); - signal(SIGALRM, SIG_DFL); - signal(SIGHUP, SIG_DFL); - signal(SIGTERM, SIG_DFL); - signal(SIGQUIT, SIG_DFL); - signal(SIGCHLD, SIG_DFL); - - /* Set keepalives if requested. */ - if (options.keepalives && - setsockopt(sock_in, SOL_SOCKET, SO_KEEPALIVE, &on, - sizeof(on)) < 0) - error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); - - /* - * Register our connection. This turns encryption off because we do - * not have a key. - */ - packet_set_connection(sock_in, sock_out); - - remote_port = get_remote_port(); - remote_ip = get_remote_ipaddr(); - -#ifdef LIBWRAP - /* Check whether logins are denied from this host. */ - { - struct request_info req; - - request_init(&req, RQ_DAEMON, __progname, RQ_FILE, sock_in, 0); - fromhost(&req); - - if (!hosts_access(&req)) { - debug("Connection refused by tcp wrapper"); - refuse(&req); - /* NOTREACHED */ - fatal("libwrap refuse returns"); - } - } -#endif /* LIBWRAP */ - - /* Log the connection. */ - verbose("Connection from %.500s port %d", remote_ip, remote_port); - - /* - * We don\'t want to listen forever unless the other side - * successfully authenticates itself. So we set up an alarm which is - * cleared after successful authentication. A limit of zero - * indicates no limit. Note that we don\'t set the alarm in debugging - * mode; it is just annoying to have the server exit just when you - * are about to discover the bug. - */ - signal(SIGALRM, grace_alarm_handler); - if (!debug_flag) - alarm(options.login_grace_time); - - sshd_exchange_identification(sock_in, sock_out); - /* - * Check that the connection comes from a privileged port. - * Rhosts-Authentication only makes sense from privileged - * programs. Of course, if the intruder has root access on his local - * machine, he can connect from any port. So do not use these - * authentication methods from machines that you do not trust. - */ - if (options.rhosts_authentication && - (remote_port >= IPPORT_RESERVED || - remote_port < IPPORT_RESERVED / 2)) { - debug("Rhosts Authentication disabled, " - "originating port %d not trusted.", remote_port); - options.rhosts_authentication = 0; - } -#if defined(KRB4) && !defined(KRB5) - if (!packet_connection_is_ipv4() && - options.kerberos_authentication) { - debug("Kerberos Authentication disabled, only available for IPv4."); - options.kerberos_authentication = 0; - } -#endif /* KRB4 && !KRB5 */ -#ifdef AFS - /* If machine has AFS, set process authentication group. */ - if (k_hasafs()) { - k_setpag(); - k_unlog(); - } -#endif /* AFS */ - - packet_set_nonblocking(); - - if (use_privsep) - if ((authctxt = privsep_preauth()) != NULL) - goto authenticated; - - /* perform the key exchange */ - /* authenticate user and start session */ - if (compat20) { - do_ssh2_kex(); - authctxt = do_authentication2(); - } else { - do_ssh1_kex(); - authctxt = do_authentication(); - } - /* - * If we use privilege separation, the unprivileged child transfers - * the current keystate and exits - */ - if (use_privsep) { - mm_send_keystate(pmonitor); - exit(0); - } - - authenticated: - /* - * In privilege separation, we fork another child and prepare - * file descriptor passing. - */ - if (use_privsep) { - privsep_postauth(authctxt); - /* the monitor process [priv] will not return */ - if (!compat20) - destroy_sensitive_data(); - } - - /* Perform session preparation. */ - do_authenticated(authctxt); - - /* The connection has been terminated. */ - verbose("Closing connection to %.100s", remote_ip); - packet_close(); - - if (use_privsep) - mm_terminate(); - - exit(0); -} - -/* - * Decrypt session_key_int using our private server key and private host key - * (key with larger modulus first). - */ -int -ssh1_session_key(BIGNUM *session_key_int) -{ - int rsafail = 0; - - if (BN_cmp(sensitive_data.server_key->rsa->n, sensitive_data.ssh1_host_key->rsa->n) > 0) { - /* Server key has bigger modulus. */ - if (BN_num_bits(sensitive_data.server_key->rsa->n) < - BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + SSH_KEY_BITS_RESERVED) { - fatal("do_connection: %s: server_key %d < host_key %d + SSH_KEY_BITS_RESERVED %d", - get_remote_ipaddr(), - BN_num_bits(sensitive_data.server_key->rsa->n), - BN_num_bits(sensitive_data.ssh1_host_key->rsa->n), - SSH_KEY_BITS_RESERVED); - } - if (rsa_private_decrypt(session_key_int, session_key_int, - sensitive_data.server_key->rsa) <= 0) - rsafail++; - if (rsa_private_decrypt(session_key_int, session_key_int, - sensitive_data.ssh1_host_key->rsa) <= 0) - rsafail++; - } else { - /* Host key has bigger modulus (or they are equal). */ - if (BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) < - BN_num_bits(sensitive_data.server_key->rsa->n) + SSH_KEY_BITS_RESERVED) { - fatal("do_connection: %s: host_key %d < server_key %d + SSH_KEY_BITS_RESERVED %d", - get_remote_ipaddr(), - BN_num_bits(sensitive_data.ssh1_host_key->rsa->n), - BN_num_bits(sensitive_data.server_key->rsa->n), - SSH_KEY_BITS_RESERVED); - } - if (rsa_private_decrypt(session_key_int, session_key_int, - sensitive_data.ssh1_host_key->rsa) < 0) - rsafail++; - if (rsa_private_decrypt(session_key_int, session_key_int, - sensitive_data.server_key->rsa) < 0) - rsafail++; - } - return (rsafail); -} -/* - * SSH1 key exchange - */ -static void -do_ssh1_kex(void) -{ - int i, len; - int rsafail = 0; - BIGNUM *session_key_int; - u_char session_key[SSH_SESSION_KEY_LENGTH]; - u_char cookie[8]; - u_int cipher_type, auth_mask, protocol_flags; - u_int32_t rnd = 0; - - /* - * Generate check bytes that the client must send back in the user - * packet in order for it to be accepted; this is used to defy ip - * spoofing attacks. Note that this only works against somebody - * doing IP spoofing from a remote machine; any machine on the local - * network can still see outgoing packets and catch the random - * cookie. This only affects rhosts authentication, and this is one - * of the reasons why it is inherently insecure. - */ - for (i = 0; i < 8; i++) { - if (i % 4 == 0) - rnd = arc4random(); - cookie[i] = rnd & 0xff; - rnd >>= 8; - } - - /* - * Send our public key. We include in the packet 64 bits of random - * data that must be matched in the reply in order to prevent IP - * spoofing. - */ - packet_start(SSH_SMSG_PUBLIC_KEY); - for (i = 0; i < 8; i++) - packet_put_char(cookie[i]); - - /* Store our public server RSA key. */ - packet_put_int(BN_num_bits(sensitive_data.server_key->rsa->n)); - packet_put_bignum(sensitive_data.server_key->rsa->e); - packet_put_bignum(sensitive_data.server_key->rsa->n); - - /* Store our public host RSA key. */ - packet_put_int(BN_num_bits(sensitive_data.ssh1_host_key->rsa->n)); - packet_put_bignum(sensitive_data.ssh1_host_key->rsa->e); - packet_put_bignum(sensitive_data.ssh1_host_key->rsa->n); - - /* Put protocol flags. */ - packet_put_int(SSH_PROTOFLAG_HOST_IN_FWD_OPEN); - - /* Declare which ciphers we support. */ - packet_put_int(cipher_mask_ssh1(0)); - - /* Declare supported authentication types. */ - auth_mask = 0; - if (options.rhosts_authentication) - auth_mask |= 1 << SSH_AUTH_RHOSTS; - if (options.rhosts_rsa_authentication) - auth_mask |= 1 << SSH_AUTH_RHOSTS_RSA; - if (options.rsa_authentication) - auth_mask |= 1 << SSH_AUTH_RSA; -#if defined(KRB4) || defined(KRB5) - if (options.kerberos_authentication) - auth_mask |= 1 << SSH_AUTH_KERBEROS; -#endif -#if defined(AFS) || defined(KRB5) - if (options.kerberos_tgt_passing) - auth_mask |= 1 << SSH_PASS_KERBEROS_TGT; -#endif -#ifdef AFS - if (options.afs_token_passing) - auth_mask |= 1 << SSH_PASS_AFS_TOKEN; -#endif - if (options.challenge_response_authentication == 1) - auth_mask |= 1 << SSH_AUTH_TIS; - if (options.password_authentication) - auth_mask |= 1 << SSH_AUTH_PASSWORD; - packet_put_int(auth_mask); - - /* Send the packet and wait for it to be sent. */ - packet_send(); - packet_write_wait(); - - debug("Sent %d bit server key and %d bit host key.", - BN_num_bits(sensitive_data.server_key->rsa->n), - BN_num_bits(sensitive_data.ssh1_host_key->rsa->n)); - - /* Read clients reply (cipher type and session key). */ - packet_read_expect(SSH_CMSG_SESSION_KEY); - - /* Get cipher type and check whether we accept this. */ - cipher_type = packet_get_char(); - - if (!(cipher_mask_ssh1(0) & (1 << cipher_type))) - packet_disconnect("Warning: client selects unsupported cipher."); - - /* Get check bytes from the packet. These must match those we - sent earlier with the public key packet. */ - for (i = 0; i < 8; i++) - if (cookie[i] != packet_get_char()) - packet_disconnect("IP Spoofing check bytes do not match."); - - debug("Encryption type: %.200s", cipher_name(cipher_type)); - - /* Get the encrypted integer. */ - if ((session_key_int = BN_new()) == NULL) - fatal("do_ssh1_kex: BN_new failed"); - packet_get_bignum(session_key_int); - - protocol_flags = packet_get_int(); - packet_set_protocol_flags(protocol_flags); - packet_check_eom(); - - /* Decrypt session_key_int using host/server keys */ - rsafail = PRIVSEP(ssh1_session_key(session_key_int)); - - /* - * Extract session key from the decrypted integer. The key is in the - * least significant 256 bits of the integer; the first byte of the - * key is in the highest bits. - */ - if (!rsafail) { - BN_mask_bits(session_key_int, sizeof(session_key) * 8); - len = BN_num_bytes(session_key_int); - if (len < 0 || len > sizeof(session_key)) { - error("do_connection: bad session key len from %s: " - "session_key_int %d > sizeof(session_key) %lu", - get_remote_ipaddr(), len, (u_long)sizeof(session_key)); - rsafail++; - } else { - memset(session_key, 0, sizeof(session_key)); - BN_bn2bin(session_key_int, - session_key + sizeof(session_key) - len); - - compute_session_id(session_id, cookie, - sensitive_data.ssh1_host_key->rsa->n, - sensitive_data.server_key->rsa->n); - /* - * Xor the first 16 bytes of the session key with the - * session id. - */ - for (i = 0; i < 16; i++) - session_key[i] ^= session_id[i]; - } - } - if (rsafail) { - int bytes = BN_num_bytes(session_key_int); - u_char *buf = xmalloc(bytes); - MD5_CTX md; - - logit("do_connection: generating a fake encryption key"); - BN_bn2bin(session_key_int, buf); - MD5_Init(&md); - MD5_Update(&md, buf, bytes); - MD5_Update(&md, sensitive_data.ssh1_cookie, SSH_SESSION_KEY_LENGTH); - MD5_Final(session_key, &md); - MD5_Init(&md); - MD5_Update(&md, session_key, 16); - MD5_Update(&md, buf, bytes); - MD5_Update(&md, sensitive_data.ssh1_cookie, SSH_SESSION_KEY_LENGTH); - MD5_Final(session_key + 16, &md); - memset(buf, 0, bytes); - xfree(buf); - for (i = 0; i < 16; i++) - session_id[i] = session_key[i] ^ session_key[i + 16]; - } - /* Destroy the private and public keys. No longer. */ - destroy_sensitive_data(); - - if (use_privsep) - mm_ssh1_session_id(session_id); - - /* Destroy the decrypted integer. It is no longer needed. */ - BN_clear_free(session_key_int); - - /* Set the session key. From this on all communications will be encrypted. */ - packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, cipher_type); - - /* Destroy our copy of the session key. It is no longer needed. */ - memset(session_key, 0, sizeof(session_key)); - - debug("Received session key; encryption turned on."); - - /* Send an acknowledgment packet. Note that this packet is sent encrypted. */ - packet_start(SSH_SMSG_SUCCESS); - packet_send(); - packet_write_wait(); -} - -/* - * SSH2 key exchange: diffie-hellman-group1-sha1 - */ -static void -do_ssh2_kex(void) -{ - Kex *kex; - - if (options.ciphers != NULL) { - myproposal[PROPOSAL_ENC_ALGS_CTOS] = - myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; - } - myproposal[PROPOSAL_ENC_ALGS_CTOS] = - compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]); - myproposal[PROPOSAL_ENC_ALGS_STOC] = - compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_STOC]); - - if (options.macs != NULL) { - myproposal[PROPOSAL_MAC_ALGS_CTOS] = - myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; - } - if (!options.compression) { - myproposal[PROPOSAL_COMP_ALGS_CTOS] = - myproposal[PROPOSAL_COMP_ALGS_STOC] = "none"; - } - myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types(); - - /* start key exchange */ - kex = kex_setup(myproposal); - kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; - kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; - kex->server = 1; - kex->client_version_string=client_version_string; - kex->server_version_string=server_version_string; - kex->load_host_key=&get_hostkey_by_type; - kex->host_key_index=&get_hostkey_index; - - xxx_kex = kex; - - dispatch_run(DISPATCH_BLOCK, &kex->done, kex); - - session_id2 = kex->session_id; - session_id2_len = kex->session_id_len; - -#ifdef DEBUG_KEXDH - /* send 1st encrypted/maced/compressed message */ - packet_start(SSH2_MSG_IGNORE); - packet_put_cstring("markus"); - packet_send(); - packet_write_wait(); -#endif - debug("KEX done"); -} diff -ruN --exclude CVS ssh-openbsd-2003091600/.#sshd.c.1.269 openssh-3.7p1/.#sshd.c.1.269 --- ssh-openbsd-2003091600/.#sshd.c.1.269 2003-06-28 11:22:38.000000000 +1000 +++ openssh-3.7p1/.#sshd.c.1.269 1970-01-01 10:00:00.000000000 +1000 @@ -1,1774 +0,0 @@ -/* - * Author: Tatu Ylonen - * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland - * All rights reserved - * This program is the ssh daemon. It listens for connections from clients, - * and performs authentication, executes use commands or shell, and forwards - * information to/from the application to the user client over an encrypted - * connection. This can also handle forwarding of X11, TCP/IP, and - * authentication agent connections. - * - * As far as I am concerned, the code I have written for this software - * can be used freely for any purpose. Any derived versions of this - * software must be clearly marked as such, and if the derived work is - * incompatible with the protocol description in the RFC file, it must be - * called by a name other than "ssh" or "Secure Shell". - * - * SSH2 implementation: - * Privilege Separation: - * - * Copyright (c) 2000, 2001, 2002 Markus Friedl. All rights reserved. - * Copyright (c) 2002 Niels Provos. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "includes.h" -RCSID("$OpenBSD: sshd.c,v 1.269 2003/06/24 08:23:46 markus Exp $"); - -#include -#include -#include -#include - -#include "ssh.h" -#include "ssh1.h" -#include "ssh2.h" -#include "xmalloc.h" -#include "rsa.h" -#include "sshpty.h" -#include "packet.h" -#include "mpaux.h" -#include "log.h" -#include "servconf.h" -#include "uidswap.h" -#include "compat.h" -#include "buffer.h" -#include "cipher.h" -#include "kex.h" -#include "key.h" -#include "dh.h" -#include "myproposal.h" -#include "authfile.h" -#include "pathnames.h" -#include "atomicio.h" -#include "canohost.h" -#include "auth.h" -#include "misc.h" -#include "dispatch.h" -#include "channels.h" -#include "session.h" -#include "monitor_mm.h" -#include "monitor.h" -#include "monitor_wrap.h" -#include "monitor_fdpass.h" - -#ifdef LIBWRAP -#include -#include -int allow_severity = LOG_INFO; -int deny_severity = LOG_WARNING; -#endif /* LIBWRAP */ - -#ifndef O_NOCTTY -#define O_NOCTTY 0 -#endif - -extern char *__progname; - -/* Server configuration options. */ -ServerOptions options; - -/* Name of the server configuration file. */ -char *config_file_name = _PATH_SERVER_CONFIG_FILE; - -/* - * Flag indicating whether IPv4 or IPv6. This can be set on the command line. - * Default value is AF_UNSPEC means both IPv4 and IPv6. - */ -int IPv4or6 = AF_UNSPEC; - -/* - * Debug mode flag. This can be set on the command line. If debug - * mode is enabled, extra debugging output will be sent to the system - * log, the daemon will not go to background, and will exit after processing - * the first connection. - */ -int debug_flag = 0; - -/* Flag indicating that the daemon should only test the configuration and keys. */ -int test_flag = 0; - -/* Flag indicating that the daemon is being started from inetd. */ -int inetd_flag = 0; - -/* Flag indicating that sshd should not detach and become a daemon. */ -int no_daemon_flag = 0; - -/* debug goes to stderr unless inetd_flag is set */ -int log_stderr = 0; - -/* Saved arguments to main(). */ -char **saved_argv; - -/* - * The sockets that the server is listening; this is used in the SIGHUP - * signal handler. - */ -#define MAX_LISTEN_SOCKS 16 -int listen_socks[MAX_LISTEN_SOCKS]; -int num_listen_socks = 0; - -/* - * the client's version string, passed by sshd2 in compat mode. if != NULL, - * sshd will skip the version-number exchange - */ -char *client_version_string = NULL; -char *server_version_string = NULL; - -/* for rekeying XXX fixme */ -Kex *xxx_kex; - -/* - * Any really sensitive data in the application is contained in this - * structure. The idea is that this structure could be locked into memory so - * that the pages do not get written into swap. However, there are some - * problems. The private key contains BIGNUMs, and we do not (in principle) - * have access to the internals of them, and locking just the structure is - * not very useful. Currently, memory locking is not implemented. - */ -struct { - Key *server_key; /* ephemeral server key */ - Key *ssh1_host_key; /* ssh1 host key */ - Key **host_keys; /* all private host keys */ - int have_ssh1_key; - int have_ssh2_key; - u_char ssh1_cookie[SSH_SESSION_KEY_LENGTH]; -} sensitive_data; - -/* - * Flag indicating whether the RSA server key needs to be regenerated. - * Is set in the SIGALRM handler and cleared when the key is regenerated. - */ -static volatile sig_atomic_t key_do_regen = 0; - -/* This is set to true when a signal is received. */ -static volatile sig_atomic_t received_sighup = 0; -static volatile sig_atomic_t received_sigterm = 0; - -/* session identifier, used by RSA-auth */ -u_char session_id[16]; - -/* same for ssh2 */ -u_char *session_id2 = NULL; -u_int session_id2_len = 0; - -/* record remote hostname or ip */ -u_int utmp_len = MAXHOSTNAMELEN; - -/* options.max_startup sized array of fd ints */ -int *startup_pipes = NULL; -int startup_pipe; /* in child */ - -/* variables used for privilege separation */ -int use_privsep; -struct monitor *pmonitor; - -/* Prototypes for various functions defined later in this file. */ -void destroy_sensitive_data(void); -void demote_sensitive_data(void); - -static void do_ssh1_kex(void); -static void do_ssh2_kex(void); - -/* - * Close all listening sockets - */ -static void -close_listen_socks(void) -{ - int i; - - for (i = 0; i < num_listen_socks; i++) - close(listen_socks[i]); - num_listen_socks = -1; -} - -static void -close_startup_pipes(void) -{ - int i; - - if (startup_pipes) - for (i = 0; i < options.max_startups; i++) - if (startup_pipes[i] != -1) - close(startup_pipes[i]); -} - -/* - * Signal handler for SIGHUP. Sshd execs itself when it receives SIGHUP; - * the effect is to reread the configuration file (and to regenerate - * the server key). - */ -static void -sighup_handler(int sig) -{ - int save_errno = errno; - - received_sighup = 1; - signal(SIGHUP, sighup_handler); - errno = save_errno; -} - -/* - * Called from the main program after receiving SIGHUP. - * Restarts the server. - */ -static void -sighup_restart(void) -{ - logit("Received SIGHUP; restarting."); - close_listen_socks(); - close_startup_pipes(); - execv(saved_argv[0], saved_argv); - logit("RESTART FAILED: av[0]='%.100s', error: %.100s.", saved_argv[0], - strerror(errno)); - exit(1); -} - -/* - * Generic signal handler for terminating signals in the master daemon. - */ -static void -sigterm_handler(int sig) -{ - received_sigterm = sig; -} - -/* - * SIGCHLD handler. This is called whenever a child dies. This will then - * reap any zombies left by exited children. - */ -static void -main_sigchld_handler(int sig) -{ - int save_errno = errno; - pid_t pid; - int status; - - while ((pid = waitpid(-1, &status, WNOHANG)) > 0 || - (pid < 0 && errno == EINTR)) - ; - - signal(SIGCHLD, main_sigchld_handler); - errno = save_errno; -} - -/* - * Signal handler for the alarm after the login grace period has expired. - */ -static void -grace_alarm_handler(int sig) -{ - /* XXX no idea how fix this signal handler */ - - /* Log error and exit. */ - fatal("Timeout before authentication for %s", get_remote_ipaddr()); -} - -/* - * Signal handler for the key regeneration alarm. Note that this - * alarm only occurs in the daemon waiting for connections, and it does not - * do anything with the private key or random state before forking. - * Thus there should be no concurrency control/asynchronous execution - * problems. - */ -static void -generate_ephemeral_server_key(void) -{ - u_int32_t rnd = 0; - int i; - - verbose("Generating %s%d bit RSA key.", - sensitive_data.server_key ? "new " : "", options.server_key_bits); - if (sensitive_data.server_key != NULL) - key_free(sensitive_data.server_key); - sensitive_data.server_key = key_generate(KEY_RSA1, - options.server_key_bits); - verbose("RSA key generation complete."); - - for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) { - if (i % 4 == 0) - rnd = arc4random(); - sensitive_data.ssh1_cookie[i] = rnd & 0xff; - rnd >>= 8; - } - arc4random_stir(); -} - -static void -key_regeneration_alarm(int sig) -{ - int save_errno = errno; - - signal(SIGALRM, SIG_DFL); - errno = save_errno; - key_do_regen = 1; -} - -static void -sshd_exchange_identification(int sock_in, int sock_out) -{ - int i, mismatch; - int remote_major, remote_minor; - int major, minor; - char *s; - char buf[256]; /* Must not be larger than remote_version. */ - char remote_version[256]; /* Must be at least as big as buf. */ - - if ((options.protocol & SSH_PROTO_1) && - (options.protocol & SSH_PROTO_2)) { - major = PROTOCOL_MAJOR_1; - minor = 99; - } else if (options.protocol & SSH_PROTO_2) { - major = PROTOCOL_MAJOR_2; - minor = PROTOCOL_MINOR_2; - } else { - major = PROTOCOL_MAJOR_1; - minor = PROTOCOL_MINOR_1; - } - snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", major, minor, SSH_VERSION); - server_version_string = xstrdup(buf); - - if (client_version_string == NULL) { - /* Send our protocol version identification. */ - if (atomicio(write, sock_out, server_version_string, - strlen(server_version_string)) - != strlen(server_version_string)) { - logit("Could not write ident string to %s", get_remote_ipaddr()); - fatal_cleanup(); - } - - /* Read other sides version identification. */ - memset(buf, 0, sizeof(buf)); - for (i = 0; i < sizeof(buf) - 1; i++) { - if (atomicio(read, sock_in, &buf[i], 1) != 1) { - logit("Did not receive identification string from %s", - get_remote_ipaddr()); - fatal_cleanup(); - } - if (buf[i] == '\r') { - buf[i] = 0; - /* Kludge for F-Secure Macintosh < 1.0.2 */ - if (i == 12 && - strncmp(buf, "SSH-1.5-W1.0", 12) == 0) - break; - continue; - } - if (buf[i] == '\n') { - buf[i] = 0; - break; - } - } - buf[sizeof(buf) - 1] = 0; - client_version_string = xstrdup(buf); - } - - /* - * Check that the versions match. In future this might accept - * several versions and set appropriate flags to handle them. - */ - if (sscanf(client_version_string, "SSH-%d.%d-%[^\n]\n", - &remote_major, &remote_minor, remote_version) != 3) { - s = "Protocol mismatch.\n"; - (void) atomicio(write, sock_out, s, strlen(s)); - close(sock_in); - close(sock_out); - logit("Bad protocol version identification '%.100s' from %s", - client_version_string, get_remote_ipaddr()); - fatal_cleanup(); - } - debug("Client protocol version %d.%d; client software version %.100s", - remote_major, remote_minor, remote_version); - - compat_datafellows(remote_version); - - if (datafellows & SSH_BUG_PROBE) { - logit("probed from %s with %s. Don't panic.", - get_remote_ipaddr(), client_version_string); - fatal_cleanup(); - } - - if (datafellows & SSH_BUG_SCANNER) { - logit("scanned from %s with %s. Don't panic.", - get_remote_ipaddr(), client_version_string); - fatal_cleanup(); - } - - mismatch = 0; - switch (remote_major) { - case 1: - if (remote_minor == 99) { - if (options.protocol & SSH_PROTO_2) - enable_compat20(); - else - mismatch = 1; - break; - } - if (!(options.protocol & SSH_PROTO_1)) { - mismatch = 1; - break; - } - if (remote_minor < 3) { - packet_disconnect("Your ssh version is too old and " - "is no longer supported. Please install a newer version."); - } else if (remote_minor == 3) { - /* note that this disables agent-forwarding */ - enable_compat13(); - } - break; - case 2: - if (options.protocol & SSH_PROTO_2) { - enable_compat20(); - break; - } - /* FALLTHROUGH */ - default: - mismatch = 1; - break; - } - chop(server_version_string); - debug("Local version string %.200s", server_version_string); - - if (mismatch) { - s = "Protocol major versions differ.\n"; - (void) atomicio(write, sock_out, s, strlen(s)); - close(sock_in); - close(sock_out); - logit("Protocol major versions differ for %s: %.200s vs. %.200s", - get_remote_ipaddr(), - server_version_string, client_version_string); - fatal_cleanup(); - } -} - -/* Destroy the host and server keys. They will no longer be needed. */ -void -destroy_sensitive_data(void) -{ - int i; - - if (sensitive_data.server_key) { - key_free(sensitive_data.server_key); - sensitive_data.server_key = NULL; - } - for (i = 0; i < options.num_host_key_files; i++) { - if (sensitive_data.host_keys[i]) { - key_free(sensitive_data.host_keys[i]); - sensitive_data.host_keys[i] = NULL; - } - } - sensitive_data.ssh1_host_key = NULL; - memset(sensitive_data.ssh1_cookie, 0, SSH_SESSION_KEY_LENGTH); -} - -/* Demote private to public keys for network child */ -void -demote_sensitive_data(void) -{ - Key *tmp; - int i; - - if (sensitive_data.server_key) { - tmp = key_demote(sensitive_data.server_key); - key_free(sensitive_data.server_key); - sensitive_data.server_key = tmp; - } - - for (i = 0; i < options.num_host_key_files; i++) { - if (sensitive_data.host_keys[i]) { - tmp = key_demote(sensitive_data.host_keys[i]); - key_free(sensitive_data.host_keys[i]); - sensitive_data.host_keys[i] = tmp; - if (tmp->type == KEY_RSA1) - sensitive_data.ssh1_host_key = tmp; - } - } - - /* We do not clear ssh1_host key and cookie. XXX - Okay Niels? */ -} - -static void -privsep_preauth_child(void) -{ - u_int32_t rnd[256]; - gid_t gidset[1]; - struct passwd *pw; - int i; - - /* Enable challenge-response authentication for privilege separation */ - privsep_challenge_enable(); - - for (i = 0; i < 256; i++) - rnd[i] = arc4random(); - RAND_seed(rnd, sizeof(rnd)); - - /* Demote the private keys to public keys. */ - demote_sensitive_data(); - - if ((pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) - fatal("Privilege separation user %s does not exist", - SSH_PRIVSEP_USER); - memset(pw->pw_passwd, 0, strlen(pw->pw_passwd)); - endpwent(); - - /* Change our root directory */ - if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1) - fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR, - strerror(errno)); - if (chdir("/") == -1) - fatal("chdir(\"/\"): %s", strerror(errno)); - - /* Drop our privileges */ - debug3("privsep user:group %u:%u", (u_int)pw->pw_uid, - (u_int)pw->pw_gid); -#if 0 - /* XXX not ready, to heavy after chroot */ - do_setusercontext(pw); -#else - gidset[0] = pw->pw_gid; - if (setgroups(1, gidset) < 0) - fatal("setgroups: %.100s", strerror(errno)); - permanently_set_uid(pw); -#endif -} - -static Authctxt * -privsep_preauth(void) -{ - Authctxt *authctxt = NULL; - int status; - pid_t pid; - - /* Set up unprivileged child process to deal with network data */ - pmonitor = monitor_init(); - /* Store a pointer to the kex for later rekeying */ - pmonitor->m_pkex = &xxx_kex; - - pid = fork(); - if (pid == -1) { - fatal("fork of unprivileged child failed"); - } else if (pid != 0) { - fatal_remove_cleanup((void (*) (void *)) packet_close, NULL); - - debug2("Network child is on pid %ld", (long)pid); - - close(pmonitor->m_recvfd); - authctxt = monitor_child_preauth(pmonitor); - close(pmonitor->m_sendfd); - - /* Sync memory */ - monitor_sync(pmonitor); - - /* Wait for the child's exit status */ - while (waitpid(pid, &status, 0) < 0) - if (errno != EINTR) - break; - - /* Reinstall, since the child has finished */ - fatal_add_cleanup((void (*) (void *)) packet_close, NULL); - - return (authctxt); - } else { - /* child */ - - close(pmonitor->m_sendfd); - - /* Demote the child */ - if (getuid() == 0 || geteuid() == 0) - privsep_preauth_child(); - setproctitle("%s", "[net]"); - } - return (NULL); -} - -static void -privsep_postauth(Authctxt *authctxt) -{ - extern Authctxt *x_authctxt; - - /* XXX - Remote port forwarding */ - x_authctxt = authctxt; - - if (authctxt->pw->pw_uid == 0 || options.use_login) { - /* File descriptor passing is broken or root login */ - monitor_apply_keystate(pmonitor); - use_privsep = 0; - return; - } - - /* Authentication complete */ - alarm(0); - if (startup_pipe != -1) { - close(startup_pipe); - startup_pipe = -1; - } - - /* New socket pair */ - monitor_reinit(pmonitor); - - pmonitor->m_pid = fork(); - if (pmonitor->m_pid == -1) - fatal("fork of unprivileged child failed"); - else if (pmonitor->m_pid != 0) { - fatal_remove_cleanup((void (*) (void *)) packet_close, NULL); - - debug2("User child is on pid %ld", (long)pmonitor->m_pid); - close(pmonitor->m_recvfd); - monitor_child_postauth(pmonitor); - - /* NEVERREACHED */ - exit(0); - } - - close(pmonitor->m_sendfd); - - /* Demote the private keys to public keys. */ - demote_sensitive_data(); - - /* Drop privileges */ - do_setusercontext(authctxt->pw); - - /* It is safe now to apply the key state */ - monitor_apply_keystate(pmonitor); -} - -static char * -list_hostkey_types(void) -{ - Buffer b; - char *p; - int i; - - buffer_init(&b); - for (i = 0; i < options.num_host_key_files; i++) { - Key *key = sensitive_data.host_keys[i]; - if (key == NULL) - continue; - switch (key->type) { - case KEY_RSA: - case KEY_DSA: - if (buffer_len(&b) > 0) - buffer_append(&b, ",", 1); - p = key_ssh_name(key); - buffer_append(&b, p, strlen(p)); - break; - } - } - buffer_append(&b, "\0", 1); - p = xstrdup(buffer_ptr(&b)); - buffer_free(&b); - debug("list_hostkey_types: %s", p); - return p; -} - -Key * -get_hostkey_by_type(int type) -{ - int i; - - for (i = 0; i < options.num_host_key_files; i++) { - Key *key = sensitive_data.host_keys[i]; - if (key != NULL && key->type == type) - return key; - } - return NULL; -} - -Key * -get_hostkey_by_index(int ind) -{ - if (ind < 0 || ind >= options.num_host_key_files) - return (NULL); - return (sensitive_data.host_keys[ind]); -} - -int -get_hostkey_index(Key *key) -{ - int i; - - for (i = 0; i < options.num_host_key_files; i++) { - if (key == sensitive_data.host_keys[i]) - return (i); - } - return (-1); -} - -/* - * returns 1 if connection should be dropped, 0 otherwise. - * dropping starts at connection #max_startups_begin with a probability - * of (max_startups_rate/100). the probability increases linearly until - * all connections are dropped for startups > max_startups - */ -static int -drop_connection(int startups) -{ - double p, r; - - if (startups < options.max_startups_begin) - return 0; - if (startups >= options.max_startups) - return 1; - if (options.max_startups_rate == 100) - return 1; - - p = 100 - options.max_startups_rate; - p *= startups - options.max_startups_begin; - p /= (double) (options.max_startups - options.max_startups_begin); - p += options.max_startups_rate; - p /= 100.0; - r = arc4random() / (double) UINT_MAX; - - debug("drop_connection: p %g, r %g", p, r); - return (r < p) ? 1 : 0; -} - -static void -usage(void) -{ - fprintf(stderr, "sshd version %s\n", SSH_VERSION); - fprintf(stderr, "Usage: %s [options]\n", __progname); - fprintf(stderr, "Options:\n"); - fprintf(stderr, " -f file Configuration file (default %s)\n", _PATH_SERVER_CONFIG_FILE); - fprintf(stderr, " -d Debugging mode (multiple -d means more debugging)\n"); - fprintf(stderr, " -i Started from inetd\n"); - fprintf(stderr, " -D Do not fork into daemon mode\n"); - fprintf(stderr, " -t Only test configuration file and keys\n"); - fprintf(stderr, " -q Quiet (no logging)\n"); - fprintf(stderr, " -p port Listen on the specified port (default: 22)\n"); - fprintf(stderr, " -k seconds Regenerate server key every this many seconds (default: 3600)\n"); - fprintf(stderr, " -g seconds Grace period for authentication (default: 600)\n"); - fprintf(stderr, " -b bits Size of server RSA key (default: 768 bits)\n"); - fprintf(stderr, " -h file File from which to read host key (default: %s)\n", - _PATH_HOST_KEY_FILE); - fprintf(stderr, " -u len Maximum hostname length for utmp recording\n"); - fprintf(stderr, " -4 Use IPv4 only\n"); - fprintf(stderr, " -6 Use IPv6 only\n"); - fprintf(stderr, " -o option Process the option as if it was read from a configuration file.\n"); - exit(1); -} - -/* - * Main program for the daemon. - */ -int -main(int ac, char **av) -{ - extern char *optarg; - extern int optind; - int opt, sock_in = 0, sock_out = 0, newsock, j, i, fdsetsz, on = 1; - pid_t pid; - socklen_t fromlen; - fd_set *fdset; - struct sockaddr_storage from; - const char *remote_ip; - int remote_port; - FILE *f; - struct addrinfo *ai; - char ntop[NI_MAXHOST], strport[NI_MAXSERV]; - int listen_sock, maxfd; - int startup_p[2]; - int startups = 0; - Authctxt *authctxt; - Key *key; - int ret, key_used = 0; - - /* Save argv. */ - saved_argv = av; - - /* Initialize configuration options to their default values. */ - initialize_server_options(&options); - - /* Parse command-line arguments. */ - while ((opt = getopt(ac, av, "f:p:b:k:h:g:V:u:o:dDeiqtQ46")) != -1) { - switch (opt) { - case '4': - IPv4or6 = AF_INET; - break; - case '6': - IPv4or6 = AF_INET6; - break; - case 'f': - config_file_name = optarg; - break; - case 'd': - if (0 == debug_flag) { - debug_flag = 1; - options.log_level = SYSLOG_LEVEL_DEBUG1; - } else if (options.log_level < SYSLOG_LEVEL_DEBUG3) { - options.log_level++; - } else { - fprintf(stderr, "Too high debugging level.\n"); - exit(1); - } - break; - case 'D': - no_daemon_flag = 1; - break; - case 'e': - log_stderr = 1; - break; - case 'i': - inetd_flag = 1; - break; - case 'Q': - /* ignored */ - break; - case 'q': - options.log_level = SYSLOG_LEVEL_QUIET; - break; - case 'b': - options.server_key_bits = atoi(optarg); - break; - case 'p': - options.ports_from_cmdline = 1; - if (options.num_ports >= MAX_PORTS) { - fprintf(stderr, "too many ports.\n"); - exit(1); - } - options.ports[options.num_ports++] = a2port(optarg); - if (options.ports[options.num_ports-1] == 0) { - fprintf(stderr, "Bad port number.\n"); - exit(1); - } - break; - case 'g': - if ((options.login_grace_time = convtime(optarg)) == -1) { - fprintf(stderr, "Invalid login grace time.\n"); - exit(1); - } - break; - case 'k': - if ((options.key_regeneration_time = convtime(optarg)) == -1) { - fprintf(stderr, "Invalid key regeneration interval.\n"); - exit(1); - } - break; - case 'h': - if (options.num_host_key_files >= MAX_HOSTKEYS) { - fprintf(stderr, "too many host keys.\n"); - exit(1); - } - options.host_key_files[options.num_host_key_files++] = optarg; - break; - case 'V': - client_version_string = optarg; - /* only makes sense with inetd_flag, i.e. no listen() */ - inetd_flag = 1; - break; - case 't': - test_flag = 1; - break; - case 'u': - utmp_len = atoi(optarg); - if (utmp_len > MAXHOSTNAMELEN) { - fprintf(stderr, "Invalid utmp length.\n"); - exit(1); - } - break; - case 'o': - if (process_server_config_line(&options, optarg, - "command-line", 0) != 0) - exit(1); - break; - case '?': - default: - usage(); - break; - } - } - SSLeay_add_all_algorithms(); - channel_set_af(IPv4or6); - - /* - * Force logging to stderr until we have loaded the private host - * key (unless started from inetd) - */ - log_init(__progname, - options.log_level == SYSLOG_LEVEL_NOT_SET ? - SYSLOG_LEVEL_INFO : options.log_level, - options.log_facility == SYSLOG_FACILITY_NOT_SET ? - SYSLOG_FACILITY_AUTH : options.log_facility, - log_stderr || !inetd_flag); - - /* Read server configuration options from the configuration file. */ - read_server_config(&options, config_file_name); - - /* Fill in default values for those options not explicitly set. */ - fill_default_server_options(&options); - - /* Check that there are no remaining arguments. */ - if (optind < ac) { - fprintf(stderr, "Extra argument %s.\n", av[optind]); - exit(1); - } - - debug("sshd version %.100s", SSH_VERSION); - - /* load private host keys */ - sensitive_data.host_keys = xmalloc(options.num_host_key_files * - sizeof(Key *)); - for (i = 0; i < options.num_host_key_files; i++) - sensitive_data.host_keys[i] = NULL; - sensitive_data.server_key = NULL; - sensitive_data.ssh1_host_key = NULL; - sensitive_data.have_ssh1_key = 0; - sensitive_data.have_ssh2_key = 0; - - for (i = 0; i < options.num_host_key_files; i++) { - key = key_load_private(options.host_key_files[i], "", NULL); - sensitive_data.host_keys[i] = key; - if (key == NULL) { - error("Could not load host key: %s", - options.host_key_files[i]); - sensitive_data.host_keys[i] = NULL; - continue; - } - switch (key->type) { - case KEY_RSA1: - sensitive_data.ssh1_host_key = key; - sensitive_data.have_ssh1_key = 1; - break; - case KEY_RSA: - case KEY_DSA: - sensitive_data.have_ssh2_key = 1; - break; - } - debug("private host key: #%d type %d %s", i, key->type, - key_type(key)); - } - if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) { - logit("Disabling protocol version 1. Could not load host key"); - options.protocol &= ~SSH_PROTO_1; - } - if ((options.protocol & SSH_PROTO_2) && !sensitive_data.have_ssh2_key) { - logit("Disabling protocol version 2. Could not load host key"); - options.protocol &= ~SSH_PROTO_2; - } - if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) { - logit("sshd: no hostkeys available -- exiting."); - exit(1); - } - - /* Check certain values for sanity. */ - if (options.protocol & SSH_PROTO_1) { - if (options.server_key_bits < 512 || - options.server_key_bits > 32768) { - fprintf(stderr, "Bad server key size.\n"); - exit(1); - } - /* - * Check that server and host key lengths differ sufficiently. This - * is necessary to make double encryption work with rsaref. Oh, I - * hate software patents. I dont know if this can go? Niels - */ - if (options.server_key_bits > - BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) - - SSH_KEY_BITS_RESERVED && options.server_key_bits < - BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + - SSH_KEY_BITS_RESERVED) { - options.server_key_bits = - BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + - SSH_KEY_BITS_RESERVED; - debug("Forcing server key to %d bits to make it differ from host key.", - options.server_key_bits); - } - } - - if (use_privsep) { - struct passwd *pw; - struct stat st; - - if ((pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) - fatal("Privilege separation user %s does not exist", - SSH_PRIVSEP_USER); - if ((stat(_PATH_PRIVSEP_CHROOT_DIR, &st) == -1) || - (S_ISDIR(st.st_mode) == 0)) - fatal("Missing privilege separation directory: %s", - _PATH_PRIVSEP_CHROOT_DIR); - if (st.st_uid != 0 || (st.st_mode & (S_IWGRP|S_IWOTH)) != 0) - fatal("%s must be owned by root and not group or " - "world-writable.", _PATH_PRIVSEP_CHROOT_DIR); - } - - /* Configuration looks good, so exit if in test mode. */ - if (test_flag) - exit(0); - - /* Initialize the log (it is reinitialized below in case we forked). */ - if (debug_flag && !inetd_flag) - log_stderr = 1; - log_init(__progname, options.log_level, options.log_facility, log_stderr); - - /* - * If not in debugging mode, and not started from inetd, disconnect - * from the controlling terminal, and fork. The original process - * exits. - */ - if (!(debug_flag || inetd_flag || no_daemon_flag)) { -#ifdef TIOCNOTTY - int fd; -#endif /* TIOCNOTTY */ - if (daemon(0, 0) < 0) - fatal("daemon() failed: %.200s", strerror(errno)); - - /* Disconnect from the controlling tty. */ -#ifdef TIOCNOTTY - fd = open(_PATH_TTY, O_RDWR | O_NOCTTY); - if (fd >= 0) { - (void) ioctl(fd, TIOCNOTTY, NULL); - close(fd); - } -#endif /* TIOCNOTTY */ - } - /* Reinitialize the log (because of the fork above). */ - log_init(__progname, options.log_level, options.log_facility, log_stderr); - - /* Initialize the random number generator. */ - arc4random_stir(); - - /* Chdir to the root directory so that the current disk can be - unmounted if desired. */ - chdir("/"); - - /* ignore SIGPIPE */ - signal(SIGPIPE, SIG_IGN); - - /* Start listening for a socket, unless started from inetd. */ - if (inetd_flag) { - int s1; - s1 = dup(0); /* Make sure descriptors 0, 1, and 2 are in use. */ - dup(s1); - sock_in = dup(0); - sock_out = dup(1); - startup_pipe = -1; - /* - * We intentionally do not close the descriptors 0, 1, and 2 - * as our code for setting the descriptors won\'t work if - * ttyfd happens to be one of those. - */ - debug("inetd sockets after dupping: %d, %d", sock_in, sock_out); - if (options.protocol & SSH_PROTO_1) - generate_ephemeral_server_key(); - } else { - for (ai = options.listen_addrs; ai; ai = ai->ai_next) { - if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) - continue; - if (num_listen_socks >= MAX_LISTEN_SOCKS) - fatal("Too many listen sockets. " - "Enlarge MAX_LISTEN_SOCKS"); - if (getnameinfo(ai->ai_addr, ai->ai_addrlen, - ntop, sizeof(ntop), strport, sizeof(strport), - NI_NUMERICHOST|NI_NUMERICSERV) != 0) { - error("getnameinfo failed"); - continue; - } - /* Create socket for listening. */ - listen_sock = socket(ai->ai_family, ai->ai_socktype, - ai->ai_protocol); - if (listen_sock < 0) { - /* kernel may not support ipv6 */ - verbose("socket: %.100s", strerror(errno)); - continue; - } - if (fcntl(listen_sock, F_SETFL, O_NONBLOCK) < 0) { - error("listen_sock O_NONBLOCK: %s", strerror(errno)); - close(listen_sock); - continue; - } - /* - * Set socket options. - * Allow local port reuse in TIME_WAIT. - */ - if (setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, - &on, sizeof(on)) == -1) - error("setsockopt SO_REUSEADDR: %s", strerror(errno)); - - debug("Bind to port %s on %s.", strport, ntop); - - /* Bind the socket to the desired port. */ - if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) < 0) { - error("Bind to port %s on %s failed: %.200s.", - strport, ntop, strerror(errno)); - close(listen_sock); - continue; - } - listen_socks[num_listen_socks] = listen_sock; - num_listen_socks++; - - /* Start listening on the port. */ - logit("Server listening on %s port %s.", ntop, strport); - if (listen(listen_sock, 5) < 0) - fatal("listen: %.100s", strerror(errno)); - - } - freeaddrinfo(options.listen_addrs); - - if (!num_listen_socks) - fatal("Cannot bind any address."); - - if (options.protocol & SSH_PROTO_1) - generate_ephemeral_server_key(); - - /* - * Arrange to restart on SIGHUP. The handler needs - * listen_sock. - */ - signal(SIGHUP, sighup_handler); - - signal(SIGTERM, sigterm_handler); - signal(SIGQUIT, sigterm_handler); - - /* Arrange SIGCHLD to be caught. */ - signal(SIGCHLD, main_sigchld_handler); - - /* Write out the pid file after the sigterm handler is setup */ - if (!debug_flag) { - /* - * Record our pid in /var/run/sshd.pid to make it - * easier to kill the correct sshd. We don't want to - * do this before the bind above because the bind will - * fail if there already is a daemon, and this will - * overwrite any old pid in the file. - */ - f = fopen(options.pid_file, "w"); - if (f == NULL) { - error("Couldn't create pid file \"%s\": %s", - options.pid_file, strerror(errno)); - } else { - fprintf(f, "%ld\n", (long) getpid()); - fclose(f); - } - } - - /* setup fd set for listen */ - fdset = NULL; - maxfd = 0; - for (i = 0; i < num_listen_socks; i++) - if (listen_socks[i] > maxfd) - maxfd = listen_socks[i]; - /* pipes connected to unauthenticated childs */ - startup_pipes = xmalloc(options.max_startups * sizeof(int)); - for (i = 0; i < options.max_startups; i++) - startup_pipes[i] = -1; - - /* - * Stay listening for connections until the system crashes or - * the daemon is killed with a signal. - */ - for (;;) { - if (received_sighup) - sighup_restart(); - if (fdset != NULL) - xfree(fdset); - fdsetsz = howmany(maxfd+1, NFDBITS) * sizeof(fd_mask); - fdset = (fd_set *)xmalloc(fdsetsz); - memset(fdset, 0, fdsetsz); - - for (i = 0; i < num_listen_socks; i++) - FD_SET(listen_socks[i], fdset); - for (i = 0; i < options.max_startups; i++) - if (startup_pipes[i] != -1) - FD_SET(startup_pipes[i], fdset); - - /* Wait in select until there is a connection. */ - ret = select(maxfd+1, fdset, NULL, NULL, NULL); - if (ret < 0 && errno != EINTR) - error("select: %.100s", strerror(errno)); - if (received_sigterm) { - logit("Received signal %d; terminating.", - (int) received_sigterm); - close_listen_socks(); - unlink(options.pid_file); - exit(255); - } - if (key_used && key_do_regen) { - generate_ephemeral_server_key(); - key_used = 0; - key_do_regen = 0; - } - if (ret < 0) - continue; - - for (i = 0; i < options.max_startups; i++) - if (startup_pipes[i] != -1 && - FD_ISSET(startup_pipes[i], fdset)) { - /* - * the read end of the pipe is ready - * if the child has closed the pipe - * after successful authentication - * or if the child has died - */ - close(startup_pipes[i]); - startup_pipes[i] = -1; - startups--; - } - for (i = 0; i < num_listen_socks; i++) { - if (!FD_ISSET(listen_socks[i], fdset)) - continue; - fromlen = sizeof(from); - newsock = accept(listen_socks[i], (struct sockaddr *)&from, - &fromlen); - if (newsock < 0) { - if (errno != EINTR && errno != EWOULDBLOCK) - error("accept: %.100s", strerror(errno)); - continue; - } - if (fcntl(newsock, F_SETFL, 0) < 0) { - error("newsock del O_NONBLOCK: %s", strerror(errno)); - close(newsock); - continue; - } - if (drop_connection(startups) == 1) { - debug("drop connection #%d", startups); - close(newsock); - continue; - } - if (pipe(startup_p) == -1) { - close(newsock); - continue; - } - - for (j = 0; j < options.max_startups; j++) - if (startup_pipes[j] == -1) { - startup_pipes[j] = startup_p[0]; - if (maxfd < startup_p[0]) - maxfd = startup_p[0]; - startups++; - break; - } - - /* - * Got connection. Fork a child to handle it, unless - * we are in debugging mode. - */ - if (debug_flag) { - /* - * In debugging mode. Close the listening - * socket, and start processing the - * connection without forking. - */ - debug("Server will not fork when running in debugging mode."); - close_listen_socks(); - sock_in = newsock; - sock_out = newsock; - startup_pipe = -1; - pid = getpid(); - break; - } else { - /* - * Normal production daemon. Fork, and have - * the child process the connection. The - * parent continues listening. - */ - if ((pid = fork()) == 0) { - /* - * Child. Close the listening and max_startup - * sockets. Start using the accepted socket. - * Reinitialize logging (since our pid has - * changed). We break out of the loop to handle - * the connection. - */ - startup_pipe = startup_p[1]; - close_startup_pipes(); - close_listen_socks(); - sock_in = newsock; - sock_out = newsock; - log_init(__progname, options.log_level, options.log_facility, log_stderr); - break; - } - } - - /* Parent. Stay in the loop. */ - if (pid < 0) - error("fork: %.100s", strerror(errno)); - else - debug("Forked child %ld.", (long)pid); - - close(startup_p[1]); - - /* Mark that the key has been used (it was "given" to the child). */ - if ((options.protocol & SSH_PROTO_1) && - key_used == 0) { - /* Schedule server key regeneration alarm. */ - signal(SIGALRM, key_regeneration_alarm); - alarm(options.key_regeneration_time); - key_used = 1; - } - - arc4random_stir(); - - /* Close the new socket (the child is now taking care of it). */ - close(newsock); - } - /* child process check (or debug mode) */ - if (num_listen_socks < 0) - break; - } - } - - /* This is the child processing a new connection. */ - - /* - * Create a new session and process group since the 4.4BSD - * setlogin() affects the entire process group. We don't - * want the child to be able to affect the parent. - */ - if (!debug_flag && !inetd_flag && setsid() < 0) - error("setsid: %.100s", strerror(errno)); - - /* - * Disable the key regeneration alarm. We will not regenerate the - * key since we are no longer in a position to give it to anyone. We - * will not restart on SIGHUP since it no longer makes sense. - */ - alarm(0); - signal(SIGALRM, SIG_DFL); - signal(SIGHUP, SIG_DFL); - signal(SIGTERM, SIG_DFL); - signal(SIGQUIT, SIG_DFL); - signal(SIGCHLD, SIG_DFL); - - /* Set keepalives if requested. */ - if (options.keepalives && - setsockopt(sock_in, SOL_SOCKET, SO_KEEPALIVE, &on, - sizeof(on)) < 0) - error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); - - /* - * Register our connection. This turns encryption off because we do - * not have a key. - */ - packet_set_connection(sock_in, sock_out); - - remote_port = get_remote_port(); - remote_ip = get_remote_ipaddr(); - -#ifdef LIBWRAP - /* Check whether logins are denied from this host. */ - { - struct request_info req; - - request_init(&req, RQ_DAEMON, __progname, RQ_FILE, sock_in, 0); - fromhost(&req); - - if (!hosts_access(&req)) { - debug("Connection refused by tcp wrapper"); - refuse(&req); - /* NOTREACHED */ - fatal("libwrap refuse returns"); - } - } -#endif /* LIBWRAP */ - - /* Log the connection. */ - verbose("Connection from %.500s port %d", remote_ip, remote_port); - - /* - * We don\'t want to listen forever unless the other side - * successfully authenticates itself. So we set up an alarm which is - * cleared after successful authentication. A limit of zero - * indicates no limit. Note that we don\'t set the alarm in debugging - * mode; it is just annoying to have the server exit just when you - * are about to discover the bug. - */ - signal(SIGALRM, grace_alarm_handler); - if (!debug_flag) - alarm(options.login_grace_time); - - sshd_exchange_identification(sock_in, sock_out); - /* - * Check that the connection comes from a privileged port. - * Rhosts-Authentication only makes sense from privileged - * programs. Of course, if the intruder has root access on his local - * machine, he can connect from any port. So do not use these - * authentication methods from machines that you do not trust. - */ - if (options.rhosts_authentication && - (remote_port >= IPPORT_RESERVED || - remote_port < IPPORT_RESERVED / 2)) { - debug("Rhosts Authentication disabled, " - "originating port %d not trusted.", remote_port); - options.rhosts_authentication = 0; - } -#if defined(KRB4) && !defined(KRB5) - if (!packet_connection_is_ipv4() && - options.kerberos_authentication) { - debug("Kerberos Authentication disabled, only available for IPv4."); - options.kerberos_authentication = 0; - } -#endif /* KRB4 && !KRB5 */ -#ifdef AFS - /* If machine has AFS, set process authentication group. */ - if (k_hasafs()) { - k_setpag(); - k_unlog(); - } -#endif /* AFS */ - - packet_set_nonblocking(); - - if (use_privsep) - if ((authctxt = privsep_preauth()) != NULL) - goto authenticated; - - /* perform the key exchange */ - /* authenticate user and start session */ - if (compat20) { - do_ssh2_kex(); - authctxt = do_authentication2(); - } else { - do_ssh1_kex(); - authctxt = do_authentication(); - } - /* - * If we use privilege separation, the unprivileged child transfers - * the current keystate and exits - */ - if (use_privsep) { - mm_send_keystate(pmonitor); - exit(0); - } - - authenticated: - /* - * In privilege separation, we fork another child and prepare - * file descriptor passing. - */ - if (use_privsep) { - privsep_postauth(authctxt); - /* the monitor process [priv] will not return */ - if (!compat20) - destroy_sensitive_data(); - } - - /* Perform session preparation. */ - do_authenticated(authctxt); - - /* The connection has been terminated. */ - verbose("Closing connection to %.100s", remote_ip); - packet_close(); - - if (use_privsep) - mm_terminate(); - - exit(0); -} - -/* - * Decrypt session_key_int using our private server key and private host key - * (key with larger modulus first). - */ -int -ssh1_session_key(BIGNUM *session_key_int) -{ - int rsafail = 0; - - if (BN_cmp(sensitive_data.server_key->rsa->n, sensitive_data.ssh1_host_key->rsa->n) > 0) { - /* Server key has bigger modulus. */ - if (BN_num_bits(sensitive_data.server_key->rsa->n) < - BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + SSH_KEY_BITS_RESERVED) { - fatal("do_connection: %s: server_key %d < host_key %d + SSH_KEY_BITS_RESERVED %d", - get_remote_ipaddr(), - BN_num_bits(sensitive_data.server_key->rsa->n), - BN_num_bits(sensitive_data.ssh1_host_key->rsa->n), - SSH_KEY_BITS_RESERVED); - } - if (rsa_private_decrypt(session_key_int, session_key_int, - sensitive_data.server_key->rsa) <= 0) - rsafail++; - if (rsa_private_decrypt(session_key_int, session_key_int, - sensitive_data.ssh1_host_key->rsa) <= 0) - rsafail++; - } else { - /* Host key has bigger modulus (or they are equal). */ - if (BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) < - BN_num_bits(sensitive_data.server_key->rsa->n) + SSH_KEY_BITS_RESERVED) { - fatal("do_connection: %s: host_key %d < server_key %d + SSH_KEY_BITS_RESERVED %d", - get_remote_ipaddr(), - BN_num_bits(sensitive_data.ssh1_host_key->rsa->n), - BN_num_bits(sensitive_data.server_key->rsa->n), - SSH_KEY_BITS_RESERVED); - } - if (rsa_private_decrypt(session_key_int, session_key_int, - sensitive_data.ssh1_host_key->rsa) < 0) - rsafail++; - if (rsa_private_decrypt(session_key_int, session_key_int, - sensitive_data.server_key->rsa) < 0) - rsafail++; - } - return (rsafail); -} -/* - * SSH1 key exchange - */ -static void -do_ssh1_kex(void) -{ - int i, len; - int rsafail = 0; - BIGNUM *session_key_int; - u_char session_key[SSH_SESSION_KEY_LENGTH]; - u_char cookie[8]; - u_int cipher_type, auth_mask, protocol_flags; - u_int32_t rnd = 0; - - /* - * Generate check bytes that the client must send back in the user - * packet in order for it to be accepted; this is used to defy ip - * spoofing attacks. Note that this only works against somebody - * doing IP spoofing from a remote machine; any machine on the local - * network can still see outgoing packets and catch the random - * cookie. This only affects rhosts authentication, and this is one - * of the reasons why it is inherently insecure. - */ - for (i = 0; i < 8; i++) { - if (i % 4 == 0) - rnd = arc4random(); - cookie[i] = rnd & 0xff; - rnd >>= 8; - } - - /* - * Send our public key. We include in the packet 64 bits of random - * data that must be matched in the reply in order to prevent IP - * spoofing. - */ - packet_start(SSH_SMSG_PUBLIC_KEY); - for (i = 0; i < 8; i++) - packet_put_char(cookie[i]); - - /* Store our public server RSA key. */ - packet_put_int(BN_num_bits(sensitive_data.server_key->rsa->n)); - packet_put_bignum(sensitive_data.server_key->rsa->e); - packet_put_bignum(sensitive_data.server_key->rsa->n); - - /* Store our public host RSA key. */ - packet_put_int(BN_num_bits(sensitive_data.ssh1_host_key->rsa->n)); - packet_put_bignum(sensitive_data.ssh1_host_key->rsa->e); - packet_put_bignum(sensitive_data.ssh1_host_key->rsa->n); - - /* Put protocol flags. */ - packet_put_int(SSH_PROTOFLAG_HOST_IN_FWD_OPEN); - - /* Declare which ciphers we support. */ - packet_put_int(cipher_mask_ssh1(0)); - - /* Declare supported authentication types. */ - auth_mask = 0; - if (options.rhosts_authentication) - auth_mask |= 1 << SSH_AUTH_RHOSTS; - if (options.rhosts_rsa_authentication) - auth_mask |= 1 << SSH_AUTH_RHOSTS_RSA; - if (options.rsa_authentication) - auth_mask |= 1 << SSH_AUTH_RSA; -#if defined(KRB4) || defined(KRB5) - if (options.kerberos_authentication) - auth_mask |= 1 << SSH_AUTH_KERBEROS; -#endif -#if defined(AFS) || defined(KRB5) - if (options.kerberos_tgt_passing) - auth_mask |= 1 << SSH_PASS_KERBEROS_TGT; -#endif -#ifdef AFS - if (options.afs_token_passing) - auth_mask |= 1 << SSH_PASS_AFS_TOKEN; -#endif - if (options.challenge_response_authentication == 1) - auth_mask |= 1 << SSH_AUTH_TIS; - if (options.password_authentication) - auth_mask |= 1 << SSH_AUTH_PASSWORD; - packet_put_int(auth_mask); - - /* Send the packet and wait for it to be sent. */ - packet_send(); - packet_write_wait(); - - debug("Sent %d bit server key and %d bit host key.", - BN_num_bits(sensitive_data.server_key->rsa->n), - BN_num_bits(sensitive_data.ssh1_host_key->rsa->n)); - - /* Read clients reply (cipher type and session key). */ - packet_read_expect(SSH_CMSG_SESSION_KEY); - - /* Get cipher type and check whether we accept this. */ - cipher_type = packet_get_char(); - - if (!(cipher_mask_ssh1(0) & (1 << cipher_type))) - packet_disconnect("Warning: client selects unsupported cipher."); - - /* Get check bytes from the packet. These must match those we - sent earlier with the public key packet. */ - for (i = 0; i < 8; i++) - if (cookie[i] != packet_get_char()) - packet_disconnect("IP Spoofing check bytes do not match."); - - debug("Encryption type: %.200s", cipher_name(cipher_type)); - - /* Get the encrypted integer. */ - if ((session_key_int = BN_new()) == NULL) - fatal("do_ssh1_kex: BN_new failed"); - packet_get_bignum(session_key_int); - - protocol_flags = packet_get_int(); - packet_set_protocol_flags(protocol_flags); - packet_check_eom(); - - /* Decrypt session_key_int using host/server keys */ - rsafail = PRIVSEP(ssh1_session_key(session_key_int)); - - /* - * Extract session key from the decrypted integer. The key is in the - * least significant 256 bits of the integer; the first byte of the - * key is in the highest bits. - */ - if (!rsafail) { - BN_mask_bits(session_key_int, sizeof(session_key) * 8); - len = BN_num_bytes(session_key_int); - if (len < 0 || len > sizeof(session_key)) { - error("do_connection: bad session key len from %s: " - "session_key_int %d > sizeof(session_key) %lu", - get_remote_ipaddr(), len, (u_long)sizeof(session_key)); - rsafail++; - } else { - memset(session_key, 0, sizeof(session_key)); - BN_bn2bin(session_key_int, - session_key + sizeof(session_key) - len); - - compute_session_id(session_id, cookie, - sensitive_data.ssh1_host_key->rsa->n, - sensitive_data.server_key->rsa->n); - /* - * Xor the first 16 bytes of the session key with the - * session id. - */ - for (i = 0; i < 16; i++) - session_key[i] ^= session_id[i]; - } - } - if (rsafail) { - int bytes = BN_num_bytes(session_key_int); - u_char *buf = xmalloc(bytes); - MD5_CTX md; - - logit("do_connection: generating a fake encryption key"); - BN_bn2bin(session_key_int, buf); - MD5_Init(&md); - MD5_Update(&md, buf, bytes); - MD5_Update(&md, sensitive_data.ssh1_cookie, SSH_SESSION_KEY_LENGTH); - MD5_Final(session_key, &md); - MD5_Init(&md); - MD5_Update(&md, session_key, 16); - MD5_Update(&md, buf, bytes); - MD5_Update(&md, sensitive_data.ssh1_cookie, SSH_SESSION_KEY_LENGTH); - MD5_Final(session_key + 16, &md); - memset(buf, 0, bytes); - xfree(buf); - for (i = 0; i < 16; i++) - session_id[i] = session_key[i] ^ session_key[i + 16]; - } - /* Destroy the private and public keys. No longer. */ - destroy_sensitive_data(); - - if (use_privsep) - mm_ssh1_session_id(session_id); - - /* Destroy the decrypted integer. It is no longer needed. */ - BN_clear_free(session_key_int); - - /* Set the session key. From this on all communications will be encrypted. */ - packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, cipher_type); - - /* Destroy our copy of the session key. It is no longer needed. */ - memset(session_key, 0, sizeof(session_key)); - - debug("Received session key; encryption turned on."); - - /* Send an acknowledgment packet. Note that this packet is sent encrypted. */ - packet_start(SSH_SMSG_SUCCESS); - packet_send(); - packet_write_wait(); -} - -/* - * SSH2 key exchange: diffie-hellman-group1-sha1 - */ -static void -do_ssh2_kex(void) -{ - Kex *kex; - - if (options.ciphers != NULL) { - myproposal[PROPOSAL_ENC_ALGS_CTOS] = - myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; - } - myproposal[PROPOSAL_ENC_ALGS_CTOS] = - compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]); - myproposal[PROPOSAL_ENC_ALGS_STOC] = - compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_STOC]); - - if (options.macs != NULL) { - myproposal[PROPOSAL_MAC_ALGS_CTOS] = - myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs; - } - if (!options.compression) { - myproposal[PROPOSAL_COMP_ALGS_CTOS] = - myproposal[PROPOSAL_COMP_ALGS_STOC] = "none"; - } - myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types(); - - /* start key exchange */ - kex = kex_setup(myproposal); - kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; - kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; - kex->server = 1; - kex->client_version_string=client_version_string; - kex->server_version_string=server_version_string; - kex->load_host_key=&get_hostkey_by_type; - kex->host_key_index=&get_hostkey_index; - - xxx_kex = kex; - - dispatch_run(DISPATCH_BLOCK, &kex->done, kex); - - session_id2 = kex->session_id; - session_id2_len = kex->session_id_len; - -#ifdef DEBUG_KEXDH - /* send 1st encrypted/maced/compressed message */ - packet_start(SSH2_MSG_IGNORE); - packet_put_cstring("markus"); - packet_send(); - packet_write_wait(); -#endif - debug("KEX done"); -} diff -ruN --exclude CVS ssh-openbsd-2003091600/sshd_config openssh-3.7p1/sshd_config --- ssh-openbsd-2003091600/sshd_config 2003-09-03 12:07:15.000000000 +1000 +++ openssh-3.7p1/sshd_config 2003-09-02 22:51:18.000000000 +1000 @@ -3,6 +3,8 @@ # This is the sshd server system-wide configuration file. See # sshd_config(5) for more information. +# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin + # The strategy used for options in the default sshd_config shipped with # OpenSSH is to specify options with their default value where # possible, but leave them commented. Uncommented options change a @@ -64,6 +66,11 @@ #GSSAPIAuthentication no #GSSAPICleanupCreds yes +# Set this to 'yes' to enable PAM authentication (via challenge-response) +# and session processing. Depending on your PAM configuration, this may +# bypass the setting of 'PasswordAuthentication' +#UsePAM yes + #AllowTcpForwarding yes #GatewayPorts no #X11Forwarding no diff -ruN --exclude CVS ssh-openbsd-2003091600/sshd_config.5 openssh-3.7p1/sshd_config.5 --- ssh-openbsd-2003091600/sshd_config.5 2003-09-03 12:07:15.000000000 +1000 +++ openssh-3.7p1/sshd_config.5 2003-09-02 22:57:05.000000000 +1000 @@ -607,6 +607,13 @@ If .Cm UsePrivilegeSeparation is specified, it will be disabled after authentication. +.It Cm UsePAM +Enables PAM authentication (via challenge-response) and session set up. +If you enable this, you should probably disable +.Cm PasswordAuthentication . +If you enable +.CM UsePAM +then you will not be able to run sshd as a non-root user. .It Cm UsePrivilegeSeparation Specifies whether .Nm sshd diff -ruN --exclude CVS ssh-openbsd-2003091600/ssh-gss.h openssh-3.7p1/ssh-gss.h --- ssh-openbsd-2003091600/ssh-gss.h 2003-08-22 20:56:09.000000000 +1000 +++ openssh-3.7p1/ssh-gss.h 2003-08-26 11:58:16.000000000 +1000 @@ -31,6 +31,18 @@ #include +#ifdef KRB5 +#ifndef HEIMDAL +#include + +/* MIT Kerberos doesn't seem to define GSS_NT_HOSTBASED_SERVICE */ + +#ifndef GSS_C_NT_HOSTBASED_SERVICE +#define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name +#endif /* GSS_C_NT_... */ +#endif /* !HEIMDAL */ +#endif /* KRB5 */ + /* draft-ietf-secsh-gsskeyex-06 */ #define SSH2_MSG_USERAUTH_GSSAPI_RESPONSE 60 #define SSH2_MSG_USERAUTH_GSSAPI_TOKEN 61 diff -ruN --exclude CVS ssh-openbsd-2003091600/ssh.h openssh-3.7p1/ssh.h --- ssh-openbsd-2003091600/ssh.h 2003-09-03 12:07:14.000000000 +1000 +++ openssh-3.7p1/ssh.h 2003-09-02 22:57:54.000000000 +1000 @@ -15,6 +15,15 @@ #ifndef SSH_H #define SSH_H +#include /* For struct sockaddr_in */ +#include /* For struct pw */ +#include /* For va_list */ +#include /* For LOG_AUTH and friends */ +#include /* For struct sockaddr_storage */ +#ifdef HAVE_SYS_SELECT_H +# include +#endif + /* Cipher used for encrypting authentication files. */ #define SSH_AUTHFILE_CIPHER SSH_CIPHER_3DES @@ -87,7 +96,9 @@ * sshd will change its privileges to this user and its * primary group. */ +#ifndef SSH_PRIVSEP_USER #define SSH_PRIVSEP_USER "sshd" +#endif /* Minimum modulus size (n) for RSA keys. */ #define SSH_RSA_MINIMUM_MODULUS_SIZE 768 diff -ruN --exclude CVS ssh-openbsd-2003091600/ssh-keygen/Makefile openssh-3.7p1/ssh-keygen/Makefile --- ssh-openbsd-2003091600/ssh-keygen/Makefile 2003-07-30 14:56:29.000000000 +1000 +++ openssh-3.7p1/ssh-keygen/Makefile 1970-01-01 10:00:00.000000000 +1000 @@ -1,18 +0,0 @@ -# $OpenBSD: Makefile,v 1.22 2003/07/28 09:49:56 djm Exp $ - -.PATH: ${.CURDIR}/.. - -PROG= ssh-keygen -BINOWN= root - -BINMODE?=555 - -BINDIR= /usr/bin -MAN= ssh-keygen.1 - -SRCS= ssh-keygen.c moduli.c - -.include - -LDADD+= -lcrypto -DPADD+= ${LIBCRYPTO} diff -ruN --exclude CVS ssh-openbsd-2003091600/ssh-keygen.c openssh-3.7p1/ssh-keygen.c --- ssh-openbsd-2003091600/ssh-keygen.c 2003-09-03 12:07:14.000000000 +1000 +++ openssh-3.7p1/ssh-keygen.c 2003-09-09 09:11:33.000000000 +1000 @@ -79,7 +79,11 @@ char *key_type_name = NULL; /* argv0 */ +#ifdef HAVE___PROGNAME extern char *__progname; +#else +char *__progname; +#endif char hostname[MAXHOSTNAMELEN]; @@ -791,7 +795,7 @@ main(int ac, char **av) { char dotsshdir[MAXPATHLEN], comment[1024], *passphrase1, *passphrase2; - char out_file[PATH_MAX], *reader_id = NULL; + char out_file[MAXPATHLEN], *reader_id = NULL; char *resource_record_hostname = NULL; Key *private, *public; struct passwd *pw; @@ -805,9 +809,14 @@ extern int optind; extern char *optarg; + __progname = ssh_get_progname(av[0]); + SSLeay_add_all_algorithms(); log_init(av[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1); + init_rng(); + seed_rng(); + /* we need this for the home * directory. */ pw = getpwuid(getuid()); if (!pw) { diff -ruN --exclude CVS ssh-openbsd-2003091600/ssh-keyscan/Makefile openssh-3.7p1/ssh-keyscan/Makefile --- ssh-openbsd-2003091600/ssh-keyscan/Makefile 2001-08-06 09:18:20.000000000 +1000 +++ openssh-3.7p1/ssh-keyscan/Makefile 1970-01-01 10:00:00.000000000 +1000 @@ -1,18 +0,0 @@ -# $OpenBSD: Makefile,v 1.4 2001/08/05 23:18:20 markus Exp $ - -.PATH: ${.CURDIR}/.. - -PROG= ssh-keyscan -BINOWN= root - -BINMODE?=555 - -BINDIR= /usr/bin -MAN= ssh-keyscan.1 - -SRCS= ssh-keyscan.c - -.include - -LDADD+= -lcrypto -lz -DPADD+= ${LIBCRYPTO} ${LIBZ} diff -ruN --exclude CVS ssh-openbsd-2003091600/ssh-keyscan.c openssh-3.7p1/ssh-keyscan.c --- ssh-openbsd-2003091600/ssh-keyscan.c 2003-07-30 14:56:28.000000000 +1000 +++ openssh-3.7p1/ssh-keyscan.c 2003-08-22 09:34:41.000000000 +1000 @@ -9,8 +9,7 @@ #include "includes.h" RCSID("$OpenBSD: ssh-keyscan.c,v 1.44 2003/06/28 16:23:06 deraadt Exp $"); -#include -#include +#include "openbsd-compat/sys-queue.h" #include @@ -50,7 +49,11 @@ int maxfd; #define MAXCON (maxfd - 10) +#ifdef HAVE___PROGNAME extern char *__progname; +#else +char *__progname; +#endif fd_set *read_wait; size_t read_wait_size; int ncon; @@ -205,6 +208,7 @@ static int fdlim_get(int hard) { +#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE) struct rlimit rlfd; if (getrlimit(RLIMIT_NOFILE, &rlfd) < 0) @@ -213,20 +217,31 @@ return 10000; else return hard ? rlfd.rlim_max : rlfd.rlim_cur; +#elif defined (HAVE_SYSCONF) + return sysconf (_SC_OPEN_MAX); +#else + return 10000; +#endif } static int fdlim_set(int lim) { +#if defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE) struct rlimit rlfd; +#endif if (lim <= 0) return (-1); +#if defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE) if (getrlimit(RLIMIT_NOFILE, &rlfd) < 0) return (-1); rlfd.rlim_cur = lim; if (setrlimit(RLIMIT_NOFILE, &rlfd) < 0) return (-1); +#elif defined (HAVE_SETDTABLESIZE) + setdtablesize(lim); +#endif return (0); } @@ -682,6 +697,9 @@ extern int optind; extern char *optarg; + __progname = ssh_get_progname(argv[0]); + init_rng(); + seed_rng(); TAILQ_INIT(&tq); if (argc <= 1) diff -ruN --exclude CVS ssh-openbsd-2003091600/ssh-keysign/Makefile openssh-3.7p1/ssh-keysign/Makefile --- ssh-openbsd-2003091600/ssh-keysign/Makefile 2002-09-12 08:55:46.000000000 +1000 +++ openssh-3.7p1/ssh-keysign/Makefile 1970-01-01 10:00:00.000000000 +1000 @@ -1,18 +0,0 @@ -# $OpenBSD: Makefile,v 1.5 2002/07/03 14:21:05 markus Exp $ - -.PATH: ${.CURDIR}/.. - -PROG= ssh-keysign -BINOWN= root - -BINMODE?=4555 - -BINDIR= /usr/libexec -MAN= ssh-keysign.8 - -SRCS= ssh-keysign.c readconf.c - -.include - -LDADD+= -lcrypto -lz -DPADD+= ${LIBCRYPTO} ${LIBZ} diff -ruN --exclude CVS ssh-openbsd-2003091600/ssh-keysign.c openssh-3.7p1/ssh-keysign.c --- ssh-openbsd-2003091600/ssh-keysign.c 2003-07-30 14:56:29.000000000 +1000 +++ openssh-3.7p1/ssh-keysign.c 2003-07-03 20:37:47.000000000 +1000 @@ -45,6 +45,12 @@ /* XXX readconf.c needs these */ uid_t original_real_uid; +#ifdef HAVE___PROGNAME +extern char *__progname; +#else +char *__progname; +#endif + static int valid_request(struct passwd *pw, char *host, Key **ret, u_char *data, u_int datalen) @@ -150,6 +156,10 @@ seteuid(getuid()); setuid(getuid()); + init_rng(); + seed_rng(); + arc4random_stir(); + #ifdef DEBUG_SSH_KEYSIGN log_init("ssh-keysign", SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_AUTH, 0); #endif diff -ruN --exclude CVS ssh-openbsd-2003091600/sshlogin.c openssh-3.7p1/sshlogin.c --- ssh-openbsd-2003091600/sshlogin.c 2003-06-18 19:57:07.000000000 +1000 +++ openssh-3.7p1/sshlogin.c 2003-06-18 20:25:33.000000000 +1000 @@ -41,10 +41,7 @@ #include "includes.h" RCSID("$OpenBSD: sshlogin.c,v 1.7 2003/06/12 07:57:38 markus Exp $"); -#include -#include -#include "sshlogin.h" -#include "log.h" +#include "loginrec.h" /* * Returns the time when the user last logged in. Returns 0 if the @@ -55,27 +52,11 @@ get_last_login_time(uid_t uid, const char *logname, char *buf, u_int bufsize) { - struct lastlog ll; - char *lastlog; - int fd; - - lastlog = _PATH_LASTLOG; - buf[0] = '\0'; - - fd = open(lastlog, O_RDONLY); - if (fd < 0) - return 0; - lseek(fd, (off_t) ((long) uid * sizeof(ll)), SEEK_SET); - if (read(fd, &ll, sizeof(ll)) != sizeof(ll)) { - close(fd); - return 0; - } - close(fd); - if (bufsize > sizeof(ll.ll_host) + 1) - bufsize = sizeof(ll.ll_host) + 1; - strncpy(buf, ll.ll_host, bufsize - 1); - buf[bufsize - 1] = 0; - return ll.ll_time; + struct logininfo li; + + login_get_lastlog(&li, uid); + strlcpy(buf, li.hostname, bufsize); + return li.tv_sec; } /* @@ -86,48 +67,35 @@ record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid, const char *host, struct sockaddr * addr, socklen_t addrlen) { - int fd; - struct lastlog ll; - char *lastlog; - struct utmp u; - - /* Construct an utmp/wtmp entry. */ - memset(&u, 0, sizeof(u)); - strncpy(u.ut_line, ttyname + 5, sizeof(u.ut_line)); - u.ut_time = time(NULL); - strncpy(u.ut_name, user, sizeof(u.ut_name)); - strncpy(u.ut_host, host, sizeof(u.ut_host)); - - login(&u); - lastlog = _PATH_LASTLOG; - - /* Update lastlog unless actually recording a logout. */ - if (strcmp(user, "") != 0) { - /* - * It is safer to bzero the lastlog structure first because - * some systems might have some extra fields in it (e.g. SGI) - */ - memset(&ll, 0, sizeof(ll)); - - /* Update lastlog. */ - ll.ll_time = time(NULL); - strncpy(ll.ll_line, ttyname + 5, sizeof(ll.ll_line)); - strncpy(ll.ll_host, host, sizeof(ll.ll_host)); - fd = open(lastlog, O_RDWR); - if (fd >= 0) { - lseek(fd, (off_t) ((long) uid * sizeof(ll)), SEEK_SET); - if (write(fd, &ll, sizeof(ll)) != sizeof(ll)) - logit("Could not write %.100s: %.100s", lastlog, strerror(errno)); - close(fd); - } - } + struct logininfo *li; + + li = login_alloc_entry(pid, user, host, ttyname); + login_set_addr(li, addr, addrlen); + login_login(li); + login_free_entry(li); +} + +#ifdef LOGIN_NEEDS_UTMPX +void +record_utmp_only(pid_t pid, const char *ttyname, const char *user, + const char *host, struct sockaddr * addr, socklen_t addrlen) +{ + struct logininfo *li; + + li = login_alloc_entry(pid, user, host, ttyname); + login_set_addr(li, addr, addrlen); + login_utmp_only(li); + login_free_entry(li); } +#endif /* Records that the user has logged out. */ void -record_logout(pid_t pid, const char *ttyname) +record_logout(pid_t pid, const char *ttyname, const char *user) { - const char *line = ttyname + 5; /* /dev/ttyq8 -> ttyq8 */ - if (logout(line)) - logwtmp(line, "", ""); + struct logininfo *li; + + li = login_alloc_entry(pid, user, NULL, ttyname); + login_logout(li); + login_free_entry(li); } diff -ruN --exclude CVS ssh-openbsd-2003091600/sshlogin.h openssh-3.7p1/sshlogin.h --- ssh-openbsd-2003091600/sshlogin.h 2003-03-26 16:04:08.000000000 +1100 +++ openssh-3.7p1/sshlogin.h 2003-01-02 10:43:56.000000000 +1100 @@ -17,7 +17,12 @@ void record_login(pid_t, const char *, const char *, uid_t, const char *, struct sockaddr *, socklen_t); -void record_logout(pid_t, const char *); -u_long get_last_login_time(uid_t, const char *, char *, u_int); +void record_logout(pid_t, const char *, const char *); +u_long get_last_login_time(uid_t, const char *, char *, u_int); + +#ifdef LOGIN_NEEDS_UTMPX +void record_utmp_only(pid_t, const char *, const char *, const char *, + struct sockaddr *, socklen_t); +#endif #endif diff -ruN --exclude CVS ssh-openbsd-2003091600/ssh_prng_cmds.in openssh-3.7p1/ssh_prng_cmds.in --- ssh-openbsd-2003091600/ssh_prng_cmds.in 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/ssh_prng_cmds.in 2002-07-15 07:43:58.000000000 +1000 @@ -0,0 +1,75 @@ +# entropy gathering commands + +# Format is: "program-name args" path rate + +# The "rate" represents the number of bits of usuable entropy per +# byte of command output. Be conservative. +# +# $Id: ssh_prng_cmds.in,v 1.8 2002/07/14 21:43:58 tim Exp $ + +"ls -alni /var/log" @PROG_LS@ 0.02 +"ls -alni /var/adm" @PROG_LS@ 0.02 +"ls -alni /usr/adm" @PROG_LS@ 0.02 +"ls -alni /var/mail" @PROG_LS@ 0.02 +"ls -alni /usr/mail" @PROG_LS@ 0.02 +"ls -alni /var/adm/syslog" @PROG_LS@ 0.02 +"ls -alni /usr/adm/syslog" @PROG_LS@ 0.02 +"ls -alni /var/spool/mail" @PROG_LS@ 0.02 +"ls -alni /proc" @PROG_LS@ 0.02 +"ls -alni /tmp" @PROG_LS@ 0.02 +"ls -alni /var/tmp" @PROG_LS@ 0.02 +"ls -alni /usr/tmp" @PROG_LS@ 0.02 +"ls -alTi /var/log" @PROG_LS@ 0.02 +"ls -alTi /var/adm" @PROG_LS@ 0.02 +"ls -alTi /var/mail" @PROG_LS@ 0.02 +"ls -alTi /var/adm/syslog" @PROG_LS@ 0.02 +"ls -alTi /var/spool/mail" @PROG_LS@ 0.02 +"ls -alTi /proc" @PROG_LS@ 0.02 +"ls -alTi /tmp" @PROG_LS@ 0.02 +"ls -alTi /var/tmp" @PROG_LS@ 0.02 +"ls -alTi /usr/tmp" @PROG_LS@ 0.02 + +"netstat -an" @PROG_NETSTAT@ 0.05 +"netstat -in" @PROG_NETSTAT@ 0.05 +"netstat -rn" @PROG_NETSTAT@ 0.02 +"netstat -pn" @PROG_NETSTAT@ 0.02 +"netstat -ia" @PROG_NETSTAT@ 0.05 +"netstat -s" @PROG_NETSTAT@ 0.02 +"netstat -is" @PROG_NETSTAT@ 0.07 + +"arp -n -a" @PROG_ARP@ 0.02 + +"ifconfig -a" @PROG_IFCONFIG@ 0.02 + +"ps laxww" @PROG_PS@ 0.03 +"ps -al" @PROG_PS@ 0.03 +"ps -efl" @PROG_PS@ 0.03 +"jstat" @PROG_JSTAT@ 0.07 + +"w" @PROG_W@ 0.05 + +"who -i" @PROG_WHO@ 0.01 + +"last" @PROG_LAST@ 0.01 + +"lastlog" @PROG_LASTLOG@ 0.01 + +"df" @PROG_DF@ 0.01 +"df -i" @PROG_DF@ 0.01 + +"sar -d" @PROG_SAR@ 0.04 + +"vmstat" @PROG_VMSTAT@ 0.01 +"uptime" @PROG_UPTIME@ 0.01 + +"ipcs -a" @PROG_IPCS@ 0.01 + +"tail -200 /var/log/messages" @PROG_TAIL@ 0.01 +"tail -200 /var/log/syslog" @PROG_TAIL@ 0.01 +"tail -200 /var/adm/messages" @PROG_TAIL@ 0.01 +"tail -200 /var/adm/syslog" @PROG_TAIL@ 0.01 +"tail -200 /var/adm/syslog/syslog.log" @PROG_TAIL@ 0.01 +"tail -200 /var/log/maillog" @PROG_TAIL@ 0.01 +"tail -200 /var/adm/maillog" @PROG_TAIL@ 0.01 +"tail -200 /var/adm/syslog/mail.log" @PROG_TAIL@ 0.01 + diff -ruN --exclude CVS ssh-openbsd-2003091600/sshpty.c openssh-3.7p1/sshpty.c --- ssh-openbsd-2003091600/sshpty.c 2003-06-18 19:57:07.000000000 +1000 +++ openssh-3.7p1/sshpty.c 2003-08-25 11:16:21.000000000 +1000 @@ -14,15 +14,26 @@ #include "includes.h" RCSID("$OpenBSD: sshpty.c,v 1.10 2003/06/12 07:57:38 markus Exp $"); -#include +#ifdef HAVE_UTIL_H +# include +#endif /* HAVE_UTIL_H */ + #include "sshpty.h" #include "log.h" +#include "misc.h" /* Pty allocated with _getpty gets broken if we do I_PUSH:es to it. */ #if defined(HAVE__GETPTY) || defined(HAVE_OPENPTY) #undef HAVE_DEV_PTMX #endif +#ifdef HAVE_PTY_H +# include +#endif +#if defined(HAVE_DEV_PTMX) && defined(HAVE_SYS_STROPTS_H) +# include +#endif + #ifndef O_NOCTTY #define O_NOCTTY 0 #endif @@ -39,15 +50,19 @@ { #if defined(HAVE_OPENPTY) || defined(BSD4_4) /* openpty(3) exists in OSF/1 and some other os'es */ - char buf[64]; + char *name; int i; - i = openpty(ptyfd, ttyfd, buf, NULL, NULL); + i = openpty(ptyfd, ttyfd, NULL, NULL, NULL); if (i < 0) { error("openpty: %.100s", strerror(errno)); return 0; } - strlcpy(namebuf, buf, namebuflen); /* possible truncation */ + name = ttyname(*ttyfd); + if (!name) + fatal("openpty returns device for which ttyname fails."); + + strlcpy(namebuf, name, namebuflen); /* possible truncation */ return 1; #else /* HAVE_OPENPTY */ #ifdef HAVE__GETPTY @@ -72,23 +87,26 @@ } return 1; #else /* HAVE__GETPTY */ -#ifdef HAVE_DEV_PTMX +#if defined(HAVE_DEV_PTMX) /* * This code is used e.g. on Solaris 2.x. (Note that Solaris 2.3 * also has bsd-style ptys, but they simply do not work.) */ int ptm; char *pts; + mysig_t old_signal; ptm = open("/dev/ptmx", O_RDWR | O_NOCTTY); if (ptm < 0) { error("/dev/ptmx: %.100s", strerror(errno)); return 0; } + old_signal = signal(SIGCHLD, SIG_DFL); if (grantpt(ptm) < 0) { error("grantpt: %.100s", strerror(errno)); return 0; } + signal(SIGCHLD, old_signal); if (unlockpt(ptm) < 0) { error("unlockpt: %.100s", strerror(errno)); return 0; @@ -106,13 +124,20 @@ close(*ptyfd); return 0; } - /* Push the appropriate streams modules, as described in Solaris pts(7). */ +#ifndef HAVE_CYGWIN + /* + * Push the appropriate streams modules, as described in Solaris pts(7). + * HP-UX pts(7) doesn't have ttcompat module. + */ if (ioctl(*ttyfd, I_PUSH, "ptem") < 0) error("ioctl I_PUSH ptem: %.100s", strerror(errno)); if (ioctl(*ttyfd, I_PUSH, "ldterm") < 0) error("ioctl I_PUSH ldterm: %.100s", strerror(errno)); +#ifndef __hpux if (ioctl(*ttyfd, I_PUSH, "ttcompat") < 0) error("ioctl I_PUSH ttcompat: %.100s", strerror(errno)); +#endif +#endif return 1; #else /* HAVE_DEV_PTMX */ #ifdef HAVE_DEV_PTS_AND_PTC @@ -137,6 +162,36 @@ } return 1; #else /* HAVE_DEV_PTS_AND_PTC */ +#ifdef _UNICOS + char buf[64]; + int i; + int highpty; + +#ifdef _SC_CRAY_NPTY + highpty = sysconf(_SC_CRAY_NPTY); + if (highpty == -1) + highpty = 128; +#else + highpty = 128; +#endif + + for (i = 0; i < highpty; i++) { + snprintf(buf, sizeof(buf), "/dev/pty/%03d", i); + *ptyfd = open(buf, O_RDWR|O_NOCTTY); + if (*ptyfd < 0) + continue; + snprintf(namebuf, namebuflen, "/dev/ttyp%03d", i); + /* Open the slave side. */ + *ttyfd = open(namebuf, O_RDWR|O_NOCTTY); + if (*ttyfd < 0) { + error("%.100s: %.100s", namebuf, strerror(errno)); + close(*ptyfd); + return 0; + } + return 1; + } + return 0; +#else /* BSD-style pty code. */ char buf[64]; int i; @@ -144,16 +199,24 @@ const char *ptyminors = "0123456789abcdef"; int num_minors = strlen(ptyminors); int num_ptys = strlen(ptymajors) * num_minors; + struct termios tio; for (i = 0; i < num_ptys; i++) { snprintf(buf, sizeof buf, "/dev/pty%c%c", ptymajors[i / num_minors], ptyminors[i % num_minors]); - *ptyfd = open(buf, O_RDWR | O_NOCTTY); - if (*ptyfd < 0) - continue; snprintf(namebuf, namebuflen, "/dev/tty%c%c", ptymajors[i / num_minors], ptyminors[i % num_minors]); + *ptyfd = open(buf, O_RDWR | O_NOCTTY); + if (*ptyfd < 0) { + /* Try SCO style naming */ + snprintf(buf, sizeof buf, "/dev/ptyp%d", i); + snprintf(namebuf, namebuflen, "/dev/ttyp%d", i); + *ptyfd = open(buf, O_RDWR | O_NOCTTY); + if (*ptyfd < 0) + continue; + } + /* Open the slave side. */ *ttyfd = open(namebuf, O_RDWR | O_NOCTTY); if (*ttyfd < 0) { @@ -161,9 +224,23 @@ close(*ptyfd); return 0; } + /* set tty modes to a sane state for broken clients */ + if (tcgetattr(*ptyfd, &tio) < 0) + logit("Getting tty modes for pty failed: %.100s", strerror(errno)); + else { + tio.c_lflag |= (ECHO | ISIG | ICANON); + tio.c_oflag |= (OPOST | ONLCR); + tio.c_iflag |= ICRNL; + + /* Set the new modes for the terminal. */ + if (tcsetattr(*ptyfd, TCSANOW, &tio) < 0) + logit("Setting tty modes for pty failed: %.100s", strerror(errno)); + } + return 1; } return 0; +#endif /* CRAY */ #endif /* HAVE_DEV_PTS_AND_PTC */ #endif /* HAVE_DEV_PTMX */ #endif /* HAVE__GETPTY */ @@ -187,6 +264,33 @@ pty_make_controlling_tty(int *ttyfd, const char *ttyname) { int fd; +#ifdef USE_VHANGUP + void *old; +#endif /* USE_VHANGUP */ + +#ifdef _UNICOS + if (setsid() < 0) + error("setsid: %.100s", strerror(errno)); + + fd = open(ttyname, O_RDWR|O_NOCTTY); + if (fd != -1) { + signal(SIGHUP, SIG_IGN); + ioctl(fd, TCVHUP, (char *)NULL); + signal(SIGHUP, SIG_DFL); + setpgid(0, 0); + close(fd); + } else { + error("Failed to disconnect from controlling tty."); + } + + debug("Setting controlling tty using TCSETCTTY."); + ioctl(*ttyfd, TCSETCTTY, NULL); + fd = open("/dev/tty", O_RDWR); + if (fd < 0) + error("%.100s: %.100s", ttyname, strerror(errno)); + close(*ttyfd); + *ttyfd = fd; +#else /* _UNICOS */ /* First disconnect from the old controlling tty. */ #ifdef TIOCNOTTY @@ -214,19 +318,34 @@ if (ioctl(*ttyfd, TIOCSCTTY, NULL) < 0) error("ioctl(TIOCSCTTY): %.100s", strerror(errno)); #endif /* TIOCSCTTY */ +#ifdef HAVE_NEWS4 + if (setpgrp(0,0) < 0) + error("SETPGRP %s",strerror(errno)); +#endif /* HAVE_NEWS4 */ +#ifdef USE_VHANGUP + old = signal(SIGHUP, SIG_IGN); + vhangup(); + signal(SIGHUP, old); +#endif /* USE_VHANGUP */ fd = open(ttyname, O_RDWR); - if (fd < 0) + if (fd < 0) { error("%.100s: %.100s", ttyname, strerror(errno)); - else + } else { +#ifdef USE_VHANGUP + close(*ttyfd); + *ttyfd = fd; +#else /* USE_VHANGUP */ close(fd); - +#endif /* USE_VHANGUP */ + } /* Verify that we now have a controlling tty. */ fd = open(_PATH_TTY, O_WRONLY); if (fd < 0) error("open /dev/tty failed - could not set controlling tty: %.100s", strerror(errno)); - else + else close(fd); +#endif /* _UNICOS */ } /* Changes the window size associated with the pty. */ diff -ruN --exclude CVS ssh-openbsd-2003091600/ssh-rand-helper.8 openssh-3.7p1/ssh-rand-helper.8 --- ssh-openbsd-2003091600/ssh-rand-helper.8 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/ssh-rand-helper.8 2002-04-14 19:27:13.000000000 +1000 @@ -0,0 +1,94 @@ +.\" $Id: ssh-rand-helper.8,v 1.1 2002/04/14 09:27:13 djm Exp $ +.\" +.\" Copyright (c) 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. +.\" +.Dd April 14, 2002 +.Dt SSH-RAND-HELPER 8 +.Os +.Sh NAME +.Nm ssh-rand-helper +.Nd Random number gatherer for OpenSSH +.Sh SYNOPSIS +.Nm ssh-rand-hlper +.Op Fl vxXh +.Op Fl b Ar bytes +.Sh DESCRIPTION +.Nm +is a small helper program used by +.Xr ssh 1 , +.Xr ssh-add 1 , +.Xr ssh-agent 1 , +.Xr ssh-keygen 1 , +.Xr ssh-keyscan 1 +and +.Xr sshd 8 +to gather random numbers of cryptographic quality if the +.Xr openssl 4 +library has not been configured to provide them itself. +.Pp +Normally +.Nm +will generate a strong random seed and provide it to the calling +program via standard output. If standard output is a tty, +.Nm +will instead print the seed in hexidecimal format unless told otherwise. +.Pp +.Nm +will by default gather random numbers from the system commands listed +in +.Pa /etc/ssh/ssh_prng_cmds . +The output of each of the commands listed will be hashed and used to +generate a random seed for the calling program. +.Nm +will also store seed files in +.Pa ~/.ssh/prng_seed +between executions. +.Pp +Alternately, +.Nm +may be configured at build time to collect random numbers from a +EGD/PRNGd server via a unix domain or localhost tcp socket. +.Pp +This program is not intended to be run by the end-user, so the few +commandline options are for debugging purposes only. +.Bl -tag -width Ds +.It Fl b Ar bytes +Specify the number of random bytes to include in the output. +.It Fl x +Output a hexidecimal instead of a binary seed. +.It Fl X +Force output of a binary seed, even if standard output is a tty +.It Fl v +Turn on debugging message. Multiple +.Fl v +options will increase the debugging level. +.Fl h +Display a summary of options. +.El +.Sh AUTHORS +Damien Miller +.Sh SEE ALSO +.Xr ssh 1 , +.Xr ssh-add 1 , +.Xr ssh-keygen 1 , +.Xr sshd 8 diff -ruN --exclude CVS ssh-openbsd-2003091600/ssh-rand-helper.c openssh-3.7p1/ssh-rand-helper.c --- ssh-openbsd-2003091600/ssh-rand-helper.c 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/ssh-rand-helper.c 2003-08-22 09:34:41.000000000 +1000 @@ -0,0 +1,867 @@ +/* + * Copyright (c) 2001-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. + */ + +#include "includes.h" + +#include +#include +#include + +/* SunOS 4.4.4 needs this */ +#ifdef HAVE_FLOATINGPOINT_H +# include +#endif /* HAVE_FLOATINGPOINT_H */ + +#include "misc.h" +#include "xmalloc.h" +#include "atomicio.h" +#include "pathnames.h" +#include "log.h" + +RCSID("$Id: ssh-rand-helper.c,v 1.13 2003/08/21 23:34:41 djm Exp $"); + +/* Number of bytes we write out */ +#define OUTPUT_SEED_SIZE 48 + +/* Length of on-disk seedfiles */ +#define SEED_FILE_SIZE 1024 + +/* Maximum number of command-line arguments to read from file */ +#define NUM_ARGS 10 + +/* Minimum number of usable commands to be considered sufficient */ +#define MIN_ENTROPY_SOURCES 16 + +/* Path to on-disk seed file (relative to user's home directory */ +#ifndef SSH_PRNG_SEED_FILE +# define SSH_PRNG_SEED_FILE _PATH_SSH_USER_DIR"/prng_seed" +#endif + +/* Path to PRNG commands list */ +#ifndef SSH_PRNG_COMMAND_FILE +# define SSH_PRNG_COMMAND_FILE SSHDIR "/ssh_prng_cmds" +#endif + +#ifdef HAVE___PROGNAME +extern char *__progname; +#else +char *__progname; +#endif + +#ifndef offsetof +# define offsetof(type, member) ((size_t) &((type *)0)->member) +#endif + +#define WHITESPACE " \t\n" + +#ifndef RUSAGE_SELF +# define RUSAGE_SELF 0 +#endif +#ifndef RUSAGE_CHILDREN +# define RUSAGE_CHILDREN 0 +#endif + +#if !defined(PRNGD_SOCKET) && !defined(PRNGD_PORT) +# define USE_SEED_FILES +#endif + +typedef struct { + /* Proportion of data that is entropy */ + double rate; + /* Counter goes positive if this command times out */ + unsigned int badness; + /* Increases by factor of two each timeout */ + unsigned int sticky_badness; + /* Path to executable */ + char *path; + /* argv to pass to executable */ + char *args[NUM_ARGS]; /* XXX: arbitrary limit */ + /* full command string (debug) */ + char *cmdstring; +} entropy_cmd_t; + +/* slow command timeouts (all in milliseconds) */ +/* static int entropy_timeout_default = ENTROPY_TIMEOUT_MSEC; */ +static int entropy_timeout_current = ENTROPY_TIMEOUT_MSEC; + +/* this is initialised from a file, by prng_read_commands() */ +static entropy_cmd_t *entropy_cmds = NULL; + +/* Prototypes */ +double stir_from_system(void); +double stir_from_programs(void); +double stir_gettimeofday(double entropy_estimate); +double stir_clock(double entropy_estimate); +double stir_rusage(int who, double entropy_estimate); +double hash_command_output(entropy_cmd_t *src, unsigned char *hash); +int get_random_bytes_prngd(unsigned char *buf, int len, + unsigned short tcp_port, char *socket_path); + +/* + * 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; + 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 > 255) + fatal("Too many bytes to read from PRNGD"); + + 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) != 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; +} + +double +stir_gettimeofday(double entropy_estimate) +{ + struct timeval tv; + + if (gettimeofday(&tv, NULL) == -1) + fatal("Couldn't gettimeofday: %s", strerror(errno)); + + RAND_add(&tv, sizeof(tv), entropy_estimate); + + return entropy_estimate; +} + +double +stir_clock(double entropy_estimate) +{ +#ifdef HAVE_CLOCK + clock_t c; + + c = clock(); + RAND_add(&c, sizeof(c), entropy_estimate); + + return entropy_estimate; +#else /* _HAVE_CLOCK */ + return 0; +#endif /* _HAVE_CLOCK */ +} + +double +stir_rusage(int who, double entropy_estimate) +{ +#ifdef HAVE_GETRUSAGE + struct rusage ru; + + if (getrusage(who, &ru) == -1) + return 0; + + RAND_add(&ru, sizeof(ru), entropy_estimate); + + return entropy_estimate; +#else /* _HAVE_GETRUSAGE */ + return 0; +#endif /* _HAVE_GETRUSAGE */ +} + +static int +timeval_diff(struct timeval *t1, struct timeval *t2) +{ + int secdiff, usecdiff; + + secdiff = t2->tv_sec - t1->tv_sec; + usecdiff = (secdiff*1000000) + (t2->tv_usec - t1->tv_usec); + return (int)(usecdiff / 1000); +} + +double +hash_command_output(entropy_cmd_t *src, unsigned char *hash) +{ + char buf[8192]; + fd_set rdset; + int bytes_read, cmd_eof, error_abort, msec_elapsed, p[2]; + int status, total_bytes_read; + static int devnull = -1; + pid_t pid; + SHA_CTX sha; + struct timeval tv_start, tv_current; + + debug3("Reading output from \'%s\'", src->cmdstring); + + if (devnull == -1) { + devnull = open("/dev/null", O_RDWR); + if (devnull == -1) + fatal("Couldn't open /dev/null: %s", + strerror(errno)); + } + + if (pipe(p) == -1) + fatal("Couldn't open pipe: %s", strerror(errno)); + + (void)gettimeofday(&tv_start, NULL); /* record start time */ + + switch (pid = fork()) { + case -1: /* Error */ + close(p[0]); + close(p[1]); + fatal("Couldn't fork: %s", strerror(errno)); + /* NOTREACHED */ + case 0: /* Child */ + dup2(devnull, STDIN_FILENO); + dup2(p[1], STDOUT_FILENO); + dup2(p[1], STDERR_FILENO); + close(p[0]); + close(p[1]); + close(devnull); + + execv(src->path, (char**)(src->args)); + + debug("(child) Couldn't exec '%s': %s", + src->cmdstring, strerror(errno)); + _exit(-1); + default: /* Parent */ + break; + } + + RAND_add(&pid, sizeof(&pid), 0.0); + + close(p[1]); + + /* Hash output from child */ + SHA1_Init(&sha); + + cmd_eof = error_abort = msec_elapsed = total_bytes_read = 0; + while (!error_abort && !cmd_eof) { + int ret; + struct timeval tv; + int msec_remaining; + + (void) gettimeofday(&tv_current, 0); + msec_elapsed = timeval_diff(&tv_start, &tv_current); + if (msec_elapsed >= entropy_timeout_current) { + error_abort=1; + continue; + } + msec_remaining = entropy_timeout_current - msec_elapsed; + + FD_ZERO(&rdset); + FD_SET(p[0], &rdset); + tv.tv_sec = msec_remaining / 1000; + tv.tv_usec = (msec_remaining % 1000) * 1000; + + ret = select(p[0] + 1, &rdset, NULL, NULL, &tv); + + RAND_add(&tv, sizeof(tv), 0.0); + + switch (ret) { + case 0: + /* timer expired */ + error_abort = 1; + kill(pid, SIGINT); + break; + case 1: + /* command input */ + do { + bytes_read = read(p[0], buf, sizeof(buf)); + } while (bytes_read == -1 && errno == EINTR); + RAND_add(&bytes_read, sizeof(&bytes_read), 0.0); + if (bytes_read == -1) { + error_abort = 1; + break; + } else if (bytes_read) { + SHA1_Update(&sha, buf, bytes_read); + total_bytes_read += bytes_read; + } else { + cmd_eof = 1; + } + break; + case -1: + default: + /* error */ + debug("Command '%s': select() failed: %s", + src->cmdstring, strerror(errno)); + error_abort = 1; + break; + } + } + + SHA1_Final(hash, &sha); + + close(p[0]); + + debug3("Time elapsed: %d msec", msec_elapsed); + + if (waitpid(pid, &status, 0) == -1) { + error("Couldn't wait for child '%s' completion: %s", + src->cmdstring, strerror(errno)); + return 0.0; + } + + RAND_add(&status, sizeof(&status), 0.0); + + if (error_abort) { + /* + * Closing p[0] on timeout causes the entropy command to + * SIGPIPE. Take whatever output we got, and mark this + * command as slow + */ + debug2("Command '%s' timed out", src->cmdstring); + src->sticky_badness *= 2; + src->badness = src->sticky_badness; + return total_bytes_read; + } + + if (WIFEXITED(status)) { + if (WEXITSTATUS(status) == 0) { + return total_bytes_read; + } else { + debug2("Command '%s' exit status was %d", + src->cmdstring, WEXITSTATUS(status)); + src->badness = src->sticky_badness = 128; + return 0.0; + } + } else if (WIFSIGNALED(status)) { + debug2("Command '%s' returned on uncaught signal %d !", + src->cmdstring, status); + src->badness = src->sticky_badness = 128; + return 0.0; + } else + return 0.0; +} + +double +stir_from_system(void) +{ + double total_entropy_estimate; + long int i; + + total_entropy_estimate = 0; + + i = getpid(); + RAND_add(&i, sizeof(i), 0.5); + total_entropy_estimate += 0.1; + + i = getppid(); + RAND_add(&i, sizeof(i), 0.5); + total_entropy_estimate += 0.1; + + i = getuid(); + RAND_add(&i, sizeof(i), 0.0); + i = getgid(); + RAND_add(&i, sizeof(i), 0.0); + + total_entropy_estimate += stir_gettimeofday(1.0); + total_entropy_estimate += stir_clock(0.5); + total_entropy_estimate += stir_rusage(RUSAGE_SELF, 2.0); + + return total_entropy_estimate; +} + +double +stir_from_programs(void) +{ + int c; + double entropy, total_entropy; + unsigned char hash[SHA_DIGEST_LENGTH]; + + total_entropy = 0; + for(c = 0; entropy_cmds[c].path != NULL; c++) { + if (!entropy_cmds[c].badness) { + /* Hash output from command */ + entropy = hash_command_output(&entropy_cmds[c], + hash); + + /* Scale back estimate by command's rate */ + entropy *= entropy_cmds[c].rate; + + /* Upper bound of entropy is SHA_DIGEST_LENGTH */ + if (entropy > SHA_DIGEST_LENGTH) + entropy = SHA_DIGEST_LENGTH; + + /* Stir it in */ + RAND_add(hash, sizeof(hash), entropy); + + debug3("Got %0.2f bytes of entropy from '%s'", + entropy, entropy_cmds[c].cmdstring); + + total_entropy += entropy; + + /* Execution time should be a bit unpredictable */ + total_entropy += stir_gettimeofday(0.05); + total_entropy += stir_clock(0.05); + total_entropy += stir_rusage(RUSAGE_SELF, 0.1); + total_entropy += stir_rusage(RUSAGE_CHILDREN, 0.1); + } else { + debug2("Command '%s' disabled (badness %d)", + entropy_cmds[c].cmdstring, + entropy_cmds[c].badness); + + if (entropy_cmds[c].badness > 0) + entropy_cmds[c].badness--; + } + } + + return total_entropy; +} + +/* + * prng seedfile functions + */ +int +prng_check_seedfile(char *filename) +{ + struct stat st; + + /* + * XXX raceable: eg replace seed between this stat and subsequent + * open. Not such a problem because we don't really trust the + * seed file anyway. + * XXX: use secure path checking as elsewhere in OpenSSH + */ + if (lstat(filename, &st) == -1) { + /* Give up on hard errors */ + if (errno != ENOENT) + debug("WARNING: Couldn't stat random seed file " + "\"%.100s\": %s", filename, strerror(errno)); + return 0; + } + + /* regular file? */ + if (!S_ISREG(st.st_mode)) + fatal("PRNG seedfile %.100s is not a regular file", + filename); + + /* mode 0600, owned by root or the current user? */ + if (((st.st_mode & 0177) != 0) || !(st.st_uid == getuid())) { + debug("WARNING: PRNG seedfile %.100s must be mode 0600, " + "owned by uid %li", filename, (long int)getuid()); + return 0; + } + + return 1; +} + +void +prng_write_seedfile(void) +{ + int fd; + unsigned char seed[SEED_FILE_SIZE]; + char filename[MAXPATHLEN]; + struct passwd *pw; + + pw = getpwuid(getuid()); + if (pw == NULL) + fatal("Couldn't get password entry for current user " + "(%li): %s", (long int)getuid(), strerror(errno)); + + /* Try to ensure that the parent directory is there */ + snprintf(filename, sizeof(filename), "%.512s/%s", pw->pw_dir, + _PATH_SSH_USER_DIR); + mkdir(filename, 0700); + + snprintf(filename, sizeof(filename), "%.512s/%s", pw->pw_dir, + SSH_PRNG_SEED_FILE); + + debug("writing PRNG seed to file %.100s", filename); + + if (RAND_bytes(seed, sizeof(seed)) <= 0) + fatal("PRNG seed extration failed"); + + /* Don't care if the seed doesn't exist */ + prng_check_seedfile(filename); + + if ((fd = open(filename, O_WRONLY|O_TRUNC|O_CREAT, 0600)) == -1) { + debug("WARNING: couldn't access PRNG seedfile %.100s " + "(%.100s)", filename, strerror(errno)); + } else { + if (atomicio(vwrite, fd, &seed, sizeof(seed)) < sizeof(seed)) + fatal("problem writing PRNG seedfile %.100s " + "(%.100s)", filename, strerror(errno)); + close(fd); + } +} + +void +prng_read_seedfile(void) +{ + int fd; + char seed[SEED_FILE_SIZE], filename[MAXPATHLEN]; + struct passwd *pw; + + pw = getpwuid(getuid()); + if (pw == NULL) + fatal("Couldn't get password entry for current user " + "(%li): %s", (long int)getuid(), strerror(errno)); + + snprintf(filename, sizeof(filename), "%.512s/%s", pw->pw_dir, + SSH_PRNG_SEED_FILE); + + debug("loading PRNG seed from file %.100s", filename); + + if (!prng_check_seedfile(filename)) { + verbose("Random seed file not found or invalid, ignoring."); + return; + } + + /* open the file and read in the seed */ + fd = open(filename, O_RDONLY); + if (fd == -1) + fatal("could not open PRNG seedfile %.100s (%.100s)", + filename, strerror(errno)); + + if (atomicio(read, fd, &seed, sizeof(seed)) < sizeof(seed)) { + verbose("invalid or short read from PRNG seedfile " + "%.100s - ignoring", filename); + memset(seed, '\0', sizeof(seed)); + } + close(fd); + + /* stir in the seed, with estimated entropy zero */ + RAND_add(&seed, sizeof(seed), 0.0); +} + + +/* + * entropy command initialisation functions + */ +int +prng_read_commands(char *cmdfilename) +{ + char cmd[SEED_FILE_SIZE], *cp, line[1024], path[SEED_FILE_SIZE]; + double est; + entropy_cmd_t *entcmd; + FILE *f; + int cur_cmd, linenum, num_cmds, arg; + + if ((f = fopen(cmdfilename, "r")) == NULL) { + fatal("couldn't read entropy commands file %.100s: %.100s", + cmdfilename, strerror(errno)); + } + + num_cmds = 64; + entcmd = xmalloc(num_cmds * sizeof(entropy_cmd_t)); + memset(entcmd, '\0', num_cmds * sizeof(entropy_cmd_t)); + + /* Read in file */ + cur_cmd = linenum = 0; + while (fgets(line, sizeof(line), f)) { + linenum++; + + /* Skip leading whitespace, blank lines and comments */ + cp = line + strspn(line, WHITESPACE); + if ((*cp == 0) || (*cp == '#')) + continue; /* done with this line */ + + /* + * The first non-whitespace char should be a double quote + * delimiting the commandline + */ + if (*cp != '"') { + error("bad entropy command, %.100s line %d", + cmdfilename, linenum); + continue; + } + + /* + * First token, command args (incl. argv[0]) in double + * quotes + */ + cp = strtok(cp, "\""); + if (cp == NULL) { + error("missing or bad command string, %.100s " + "line %d -- ignored", cmdfilename, linenum); + continue; + } + strlcpy(cmd, cp, sizeof(cmd)); + + /* Second token, full command path */ + if ((cp = strtok(NULL, WHITESPACE)) == NULL) { + error("missing command path, %.100s " + "line %d -- ignored", cmdfilename, linenum); + continue; + } + + /* Did configure mark this as dead? */ + if (strncmp("undef", cp, 5) == 0) + continue; + + strlcpy(path, cp, sizeof(path)); + + /* Third token, entropy rate estimate for this command */ + if ((cp = strtok(NULL, WHITESPACE)) == NULL) { + error("missing entropy estimate, %.100s " + "line %d -- ignored", cmdfilename, linenum); + continue; + } + est = strtod(cp, NULL); + + /* end of line */ + if ((cp = strtok(NULL, WHITESPACE)) != NULL) { + error("garbage at end of line %d in %.100s " + "-- ignored", linenum, cmdfilename); + continue; + } + + /* save the command for debug messages */ + entcmd[cur_cmd].cmdstring = xstrdup(cmd); + + /* split the command args */ + cp = strtok(cmd, WHITESPACE); + arg = 0; + do { + entcmd[cur_cmd].args[arg] = xstrdup(cp); + arg++; + } while(arg < NUM_ARGS && (cp = strtok(NULL, WHITESPACE))); + + if (strtok(NULL, WHITESPACE)) + error("ignored extra commands (max %d), %.100s " + "line %d", NUM_ARGS, cmdfilename, linenum); + + /* Copy the command path and rate estimate */ + entcmd[cur_cmd].path = xstrdup(path); + entcmd[cur_cmd].rate = est; + + /* Initialise other values */ + entcmd[cur_cmd].sticky_badness = 1; + + cur_cmd++; + + /* + * If we've filled the array, reallocate it twice the size + * Do this now because even if this we're on the last + * command we need another slot to mark the last entry + */ + if (cur_cmd == num_cmds) { + num_cmds *= 2; + entcmd = xrealloc(entcmd, num_cmds * + sizeof(entropy_cmd_t)); + } + } + + /* zero the last entry */ + memset(&entcmd[cur_cmd], '\0', sizeof(entropy_cmd_t)); + + /* trim to size */ + entropy_cmds = xrealloc(entcmd, (cur_cmd + 1) * + sizeof(entropy_cmd_t)); + + debug("Loaded %d entropy commands from %.100s", cur_cmd, + cmdfilename); + + return cur_cmd < MIN_ENTROPY_SOURCES ? -1 : 0; +} + +void +usage(void) +{ + fprintf(stderr, "Usage: %s [options]\n", __progname); + fprintf(stderr, " -v Verbose; display verbose debugging messages.\n"); + fprintf(stderr, " Multiple -v increases verbosity.\n"); + fprintf(stderr, " -x Force output in hexidecimal (for debugging)\n"); + fprintf(stderr, " -X Force output in binary\n"); + fprintf(stderr, " -b bytes Number of bytes to output (default %d)\n", + OUTPUT_SEED_SIZE); +} + +int +main(int argc, char **argv) +{ + unsigned char *buf; + int ret, ch, debug_level, output_hex, bytes; + extern char *optarg; + LogLevel ll; + + __progname = ssh_get_progname(argv[0]); + log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1); + + ll = SYSLOG_LEVEL_INFO; + debug_level = output_hex = 0; + bytes = OUTPUT_SEED_SIZE; + + /* Don't write binary data to a tty, unless we are forced to */ + if (isatty(STDOUT_FILENO)) + output_hex = 1; + + while ((ch = getopt(argc, argv, "vxXhb:")) != -1) { + switch (ch) { + case 'v': + if (debug_level < 3) + ll = SYSLOG_LEVEL_DEBUG1 + debug_level++; + break; + case 'x': + output_hex = 1; + break; + case 'X': + output_hex = 0; + break; + case 'b': + if ((bytes = atoi(optarg)) <= 0) + fatal("Invalid number of output bytes"); + break; + case 'h': + usage(); + exit(0); + default: + error("Invalid commandline option"); + usage(); + } + } + + log_init(argv[0], ll, SYSLOG_FACILITY_USER, 1); + +#ifdef USE_SEED_FILES + prng_read_seedfile(); +#endif + + buf = xmalloc(bytes); + + /* + * Seed the RNG from wherever we can + */ + + /* Take whatever is on the stack, but don't credit it */ + RAND_add(buf, bytes, 0); + + debug("Seeded RNG with %i bytes from system calls", + (int)stir_from_system()); + +#ifdef PRNGD_PORT + if (get_random_bytes_prngd(buf, bytes, PRNGD_PORT, NULL) == -1) + fatal("Entropy collection failed"); + RAND_add(buf, bytes, bytes); +#elif defined(PRNGD_SOCKET) + if (get_random_bytes_prngd(buf, bytes, 0, PRNGD_SOCKET) == -1) + fatal("Entropy collection failed"); + RAND_add(buf, bytes, bytes); +#else + /* Read in collection commands */ + if (prng_read_commands(SSH_PRNG_COMMAND_FILE) == -1) + fatal("PRNG initialisation failed -- exiting."); + debug("Seeded RNG with %i bytes from programs", + (int)stir_from_programs()); +#endif + +#ifdef USE_SEED_FILES + prng_write_seedfile(); +#endif + + /* + * Write the seed to stdout + */ + + if (!RAND_status()) + fatal("Not enough entropy in RNG"); + + if (RAND_bytes(buf, bytes) <= 0) + fatal("Couldn't extract entropy from PRNG"); + + if (output_hex) { + for(ret = 0; ret < bytes; ret++) + printf("%02x", (unsigned char)(buf[ret])); + printf("\n"); + } else + ret = atomicio(vwrite, STDOUT_FILENO, buf, bytes); + + memset(buf, '\0', bytes); + xfree(buf); + + return ret == bytes ? 0 : 1; +} diff -ruN --exclude CVS ssh-openbsd-2003091600/TODO openssh-3.7p1/TODO --- ssh-openbsd-2003091600/TODO 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/TODO 2003-06-11 23:56:41.000000000 +1000 @@ -0,0 +1,99 @@ +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 + 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) + +- Handle changing passwords for the non-PAM expired password case + +- Improve PAM support (a pam_lastlog module will cause sshd to exit) + and maybe support alternate forms of authentications like OPIE via + pam? + +- Improve PAM ChallengeResponseAuthentication + - Informational messages + - chauthtok + - 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 + +- Fails to compile when cross compile. (vinschen@redhat.com) + +- 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: +- Solaris: Update packaging scripts and build new sysv startup scripts + Ideally the package metadata should be generated by autoconf. + (gilbert.r.loomis@saic.com) + +- 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.55 2003/06/11 13:56:41 dtucker Exp $ diff -ruN --exclude CVS ssh-openbsd-2003091600/ttymodes.h openssh-3.7p1/ttymodes.h --- ssh-openbsd-2003091600/ttymodes.h 2003-03-26 16:04:08.000000000 +1100 +++ openssh-3.7p1/ttymodes.h 2002-06-13 03:32:31.000000000 +1000 @@ -156,7 +156,9 @@ #if defined(OLCUC) TTYMODE(OLCUC, c_oflag, 71) #endif +#ifdef ONLCR TTYMODE(ONLCR, c_oflag, 72) +#endif #ifdef OCRNL TTYMODE(OCRNL, c_oflag, 73) #endif diff -ruN --exclude CVS ssh-openbsd-2003091600/uidswap.c openssh-3.7p1/uidswap.c --- ssh-openbsd-2003091600/uidswap.c 2003-06-02 18:50:54.000000000 +1000 +++ openssh-3.7p1/uidswap.c 2003-09-06 16:44:39.000000000 +1000 @@ -26,14 +26,18 @@ * POSIX saved uids or not. */ +#if defined(_POSIX_SAVED_IDS) && !defined(BROKEN_SAVED_UIDS) /* Lets assume that posix saved ids also work with seteuid, even though that is not part of the posix specification. */ +#define SAVED_IDS_WORK_WITH_SETEUID +/* Saved effective uid. */ +static uid_t saved_euid = 0; +static gid_t saved_egid = 0; +#endif /* Saved effective uid. */ static int privileged = 0; static int temporarily_use_uid_effective = 0; -static uid_t saved_euid = 0; -static gid_t saved_egid; static gid_t saved_egroups[NGROUPS_MAX], user_groups[NGROUPS_MAX]; static int saved_egroupslen = -1, user_groupslen = -1; @@ -45,6 +49,7 @@ temporarily_use_uid(struct passwd *pw) { /* Save the current euid, and egroups. */ +#ifdef SAVED_IDS_WORK_WITH_SETEUID saved_euid = geteuid(); saved_egid = getegid(); debug("temporarily_use_uid: %u/%u (e=%u/%u)", @@ -54,6 +59,13 @@ privileged = 0; return; } +#else + if (geteuid() != 0) { + privileged = 0; + return; + } +#endif /* SAVED_IDS_WORK_WITH_SETEUID */ + privileged = 1; temporarily_use_uid_effective = 1; saved_egroupslen = getgroups(NGROUPS_MAX, saved_egroups); @@ -72,6 +84,14 @@ /* Set the effective uid to the given (unprivileged) uid. */ if (setgroups(user_groupslen, user_groups) < 0) fatal("setgroups: %.100s", strerror(errno)); +#ifndef SAVED_IDS_WORK_WITH_SETEUID + /* Propagate the privileged gid to all of our gids. */ + if (setgid(getegid()) < 0) + debug("setgid %u: %.100s", (u_int) getegid(), strerror(errno)); + /* Propagate the privileged uid to all of our uids. */ + if (setuid(geteuid()) < 0) + debug("setuid %u: %.100s", (u_int) geteuid(), strerror(errno)); +#endif /* SAVED_IDS_WORK_WITH_SETEUID */ if (setegid(pw->pw_gid) < 0) fatal("setegid %u: %.100s", (u_int)pw->pw_gid, strerror(errno)); @@ -93,14 +113,26 @@ } if (!temporarily_use_uid_effective) fatal("restore_uid: temporarily_use_uid not effective"); + +#ifdef SAVED_IDS_WORK_WITH_SETEUID debug("restore_uid: %u/%u", (u_int)saved_euid, (u_int)saved_egid); /* Set the effective uid back to the saved privileged uid. */ if (seteuid(saved_euid) < 0) fatal("seteuid %u: %.100s", (u_int)saved_euid, strerror(errno)); - if (setgroups(saved_egroupslen, saved_egroups) < 0) - fatal("setgroups: %.100s", strerror(errno)); if (setegid(saved_egid) < 0) fatal("setegid %u: %.100s", (u_int)saved_egid, strerror(errno)); +#else /* SAVED_IDS_WORK_WITH_SETEUID */ + /* + * We are unable to restore the real uid to its unprivileged value. + * Propagate the real uid (usually more privileged) to effective uid + * as well. + */ + setuid(getuid()); + setgid(getgid()); +#endif /* SAVED_IDS_WORK_WITH_SETEUID */ + + if (setgroups(saved_egroupslen, saved_egroups) < 0) + fatal("setgroups: %.100s", strerror(errno)); temporarily_use_uid_effective = 0; } @@ -111,16 +143,63 @@ void permanently_set_uid(struct passwd *pw) { + uid_t old_uid = getuid(); + gid_t old_gid = getgid(); + if (temporarily_use_uid_effective) fatal("permanently_set_uid: temporarily_use_uid effective"); debug("permanently_set_uid: %u/%u", (u_int)pw->pw_uid, (u_int)pw->pw_gid); + +#if defined(HAVE_SETRESGID) + if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) < 0) + fatal("setresgid %u: %.100s", (u_int)pw->pw_gid, strerror(errno)); +#elif defined(HAVE_SETREGID) && !defined(BROKEN_SETREGID) + if (setregid(pw->pw_gid, pw->pw_gid) < 0) + fatal("setregid %u: %.100s", (u_int)pw->pw_gid, strerror(errno)); +#else if (setegid(pw->pw_gid) < 0) fatal("setegid %u: %.100s", (u_int)pw->pw_gid, strerror(errno)); if (setgid(pw->pw_gid) < 0) fatal("setgid %u: %.100s", (u_int)pw->pw_gid, strerror(errno)); +#endif + +#if defined(HAVE_SETRESUID) + if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) < 0) + fatal("setresuid %u: %.100s", (u_int)pw->pw_uid, strerror(errno)); +#elif defined(HAVE_SETREUID) && !defined(BROKEN_SETREUID) + if (setreuid(pw->pw_uid, pw->pw_uid) < 0) + fatal("setreuid %u: %.100s", (u_int)pw->pw_uid, strerror(errno)); +#else +# ifndef SETEUID_BREAKS_SETUID if (seteuid(pw->pw_uid) < 0) fatal("seteuid %u: %.100s", (u_int)pw->pw_uid, strerror(errno)); +# endif if (setuid(pw->pw_uid) < 0) fatal("setuid %u: %.100s", (u_int)pw->pw_uid, strerror(errno)); +#endif + + /* Try restoration of GID if changed (test clearing of saved gid) */ + if (old_gid != pw->pw_gid && + (setgid(old_gid) != -1 || setegid(old_gid) != -1)) + fatal("%s: was able to restore old [e]gid", __func__); + + /* Verify GID drop was successful */ + if (getgid() != pw->pw_gid || getegid() != pw->pw_gid) { + fatal("%s: egid incorrect gid:%u egid:%u (should be %u)", + __func__, (u_int)getgid(), (u_int)getegid(), + (u_int)pw->pw_gid); + } + + /* Try restoration of UID if changed (test clearing of saved uid) */ + if (old_uid != pw->pw_uid && + (setuid(old_uid) != -1 || seteuid(old_uid) != -1)) + fatal("%s: was able to restore old [e]uid", __func__); + + /* Verify UID drop was successful */ + if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid) { + fatal("%s: euid incorrect uid:%u euid:%u (should be %u)", + __func__, (u_int)getuid(), (u_int)geteuid(), + (u_int)pw->pw_uid); + } } diff -ruN --exclude CVS ssh-openbsd-2003091600/uuencode.c openssh-3.7p1/uuencode.c --- ssh-openbsd-2003091600/uuencode.c 2003-03-26 16:04:09.000000000 +1100 +++ openssh-3.7p1/uuencode.c 2002-09-12 09:49:18.000000000 +1000 @@ -28,8 +28,6 @@ #include "xmalloc.h" #include "uuencode.h" -#include - int uuencode(u_char *src, u_int srclength, char *target, size_t targsize) diff -ruN --exclude CVS ssh-openbsd-2003091600/version.h openssh-3.7p1/version.h --- ssh-openbsd-2003091600/version.h 2003-09-03 12:07:15.000000000 +1000 +++ openssh-3.7p1/version.h 2003-09-03 12:12:54.000000000 +1000 @@ -1,3 +1,3 @@ -/* $OpenBSD: version.h,v 1.38 2003/09/02 16:40:29 markus Exp $ */ +/* $OpenBSD: version.h,v 1.37 2003/04/01 10:56:46 markus Exp $ */ -#define SSH_VERSION "OpenSSH_3.7" +#define SSH_VERSION "OpenSSH_3.7p1" diff -ruN --exclude CVS ssh-openbsd-2003091600/WARNING.RNG openssh-3.7p1/WARNING.RNG --- ssh-openbsd-2003091600/WARNING.RNG 1970-01-01 10:00:00.000000000 +1000 +++ openssh-3.7p1/WARNING.RNG 2002-04-14 23:16:05.000000000 +1000 @@ -0,0 +1,96 @@ +This document contains a description of portable OpenSSH's random +number collection code. An alternate reading of this text could +well be titled "Why I should pressure my system vendor to supply +/dev/random in their OS". + +Why is this important? OpenSSH depends on good, unpredictable numbers +for generating keys, performing digital signatures and forming +cryptographic challenges. If the random numbers that it uses are +predictable, then the strength of the whole system is compromised. + +A particularly pernicious problem arises with DSA keys (used by the +ssh2 protocol). Performing a DSA signature (which is required for +authentication), entails the use of a 160 bit random number. If an +attacker can predict this number, then they can deduce your *private* +key and impersonate you or your hosts. + +If you are using the builtin random number support (configure will +tell you if this is the case), then read this document in its entirety. +Alternately, you can use Lutz Jaenicke's PRNGd - a small daemon which +collects random numbers and makes them available by a socket. + +Please also request that your OS vendor provides a kernel-based random +number collector (/dev/random) in future versions of your operating +systems by default. + +On to the description... + +The portable OpenSSH contains random number collection support for +systems which lack a kernel entropy pool (/dev/random). + +This collector (as of 3.1 and beyond) comes as an external application +that allows the local admin to decide on how to implement entropy +collection. + +The default entropy collector operates by executing the programs listed +in ($etcdir)/ssh_prng_cmds, reading their output and adding it to the +PRNG supplied by OpenSSL (which is hash-based). It also stirs in the +output of several system calls and timings from the execution of the +programs that it runs. + +The ssh_prng_cmds file also specifies a 'rate' for each program. This +represents the number of bits of randomness per byte of output from +the specified program. + +The random number code will also read and save a seed file to +~/.ssh/prng_seed. This contents of this file are added to the random +number generator at startup. The goal here is to maintain as much +randomness between sessions as possible. + +The default entropy collection code has two main problems: + +1. It is slow. + +Executing each program in the list can take a large amount of time, +especially on slower machines. Additionally some program can take a +disproportionate time to execute. + +Tuning the default entropy collection code is difficult at this point. +It requires doing 'times ./ssh-rand-helper' and modifying the +($etcdir)/ssh_prng_cmds until you have found the issue. In the next +release we will be looking at support '-v' for verbose output to allow +easier debugging. + +The default entropy collector will timeout programs which take too long +to execute, the actual timeout used can be adjusted with the +--with-entropy-timeout configure option. OpenSSH will not try to +re-execute programs which have not been found, have had a non-zero +exit status or have timed out more than a couple of times. + +2. Estimating the real 'rate' of program outputs is non-trivial + +The shear volume of the task is problematic: there are currently +around 50 commands in the ssh_prng_cmds list, portable OpenSSH +supports at least 12 different OSs. That is already 600 sets of data +to be analysed, without taking into account the numerous differences +between versions of each OS. + +On top of this, the different commands can produce varying amounts of +usable data depending on how busy the machine is, how long it has been +up and various other factors. + +To make matters even more complex, some of the commands are reporting +largely the same data as other commands (eg. the various "ps" calls). + + +How to avoid the default entropy code? + +The best way is to read the OpenSSL documentation and recompile OpenSSL +to use prngd or egd. Some platforms (like earily solaris) have 3rd +party /dev/random devices that can be also used for this task. + +If you are forced to use ssh-rand-helper consider still downloading +prngd/egd and configure OpenSSH using --with-prngd-port=xx or +--with-prngd-socket=xx (refer to INSTALL for more information). + +$Id: WARNING.RNG,v 1.5 2002/04/14 13:16:05 djm Exp $