From 08822d99de1b1080f8c730bbebc192b5b45bf89b Mon Sep 17 00:00:00 2001 From: jbasney Date: Thu, 2 Feb 2006 19:29:51 +0000 Subject: [PATCH] merged OpenSSH 4.3p1 to trunk --- openssh/Makefile.in | 2 +- openssh/README.platform | 10 + openssh/acconfig.h | 477 --------- openssh/auth-krb5.c | 7 +- openssh/auth-pam.c | 14 +- openssh/auth2-gss.c | 7 +- openssh/auth2.c | 12 +- openssh/canohost.c | 41 +- openssh/channels.c | 168 +++- openssh/channels.h | 20 +- openssh/cipher-aes.c | 12 +- openssh/cipher-ctr.c | 7 +- openssh/cipher.c | 4 +- openssh/configure.ac | 854 +++++++++++----- openssh/defines.h | 14 +- openssh/dns.c | 35 +- openssh/dns.h | 4 +- openssh/envpass.sh | 44 - openssh/gss-genr.c | 5 +- openssh/gss-serv-krb5.c | 2 +- openssh/gss-serv.c | 21 +- openssh/includes.h | 5 +- openssh/kex.c | 38 +- openssh/kex.h | 22 +- openssh/kexdhc.c | 15 +- openssh/kexdhs.c | 17 +- openssh/kexgexc.c | 17 +- openssh/kexgexs.c | 20 +- openssh/kexgssc.c | 15 +- openssh/kexgsss.c | 15 +- openssh/misc.c | 173 +++- openssh/monitor.c | 14 +- openssh/monitor_wrap.c | 1 - openssh/openbsd-compat/basename.c | 39 +- openssh/openbsd-compat/getopt.c | 4 +- openssh/openbsd-compat/getrrsetbyname.c | 114 ++- openssh/openbsd-compat/strtoul.c | 22 +- openssh/openbsd-compat/sys-queue.h | 4 +- openssh/openbsd-compat/sys-tree.h | 4 +- openssh/openbsd-compat/vis.c | 62 +- openssh/openbsd-compat/vis.h | 15 +- openssh/packet.c | 4 +- openssh/progressmeter.c | 6 +- openssh/readconf.c | 74 +- openssh/readconf.h | 10 +- openssh/scp.c | 152 ++- openssh/servconf.c | 31 +- openssh/servconf.h | 5 +- openssh/serverloop.c | 88 +- openssh/session.c | 58 +- openssh/ssh-agent.c | 7 +- openssh/ssh-keyscan.c | 23 +- openssh/ssh-keysign.c | 9 +- openssh/ssh.1 | 1185 +++++++++++++---------- openssh/ssh.c | 92 +- openssh/ssh_config.5 | 153 ++- openssh/sshconnect.c | 43 +- openssh/sshconnect1.c | 8 +- openssh/sshconnect2.c | 4 +- openssh/sshd.8 | 255 ++--- openssh/sshd.c | 52 +- openssh/sshd_config | 3 +- openssh/sshd_config.5 | 20 +- openssh/version.h | 6 +- 64 files changed, 2688 insertions(+), 1976 deletions(-) delete mode 100644 openssh/acconfig.h delete mode 100644 openssh/envpass.sh diff --git a/openssh/Makefile.in b/openssh/Makefile.in index 84e2c77..4a6c1e5 100644 --- a/openssh/Makefile.in +++ b/openssh/Makefile.in @@ -140,7 +140,7 @@ 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) + $(LD) -o $@ scp.o progressmeter.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-add.o $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) diff --git a/openssh/README.platform b/openssh/README.platform index 47e4b94..7356c10 100644 --- a/openssh/README.platform +++ b/openssh/README.platform @@ -45,4 +45,14 @@ number is already in use on your system, you may change it at build time by configure'ing --with-cflags=-DAUE_openssh=32801 then rebuilding. +Platforms using PAM +------------------- +As of OpenSSH 4.3p1, sshd will no longer check /etc/nologin itself when +PAM is enabled. To maintain existing behaviour, pam_nologin should be +added to sshd's session stack which will prevent users from starting shell +sessions. Alternatively, pam_nologin can be added to either the auth or +account stacks which will prevent authentication entirely, but will still +return the output from pam_nologin to the client. + + $Id$ diff --git a/openssh/acconfig.h b/openssh/acconfig.h deleted file mode 100644 index 9adbe8b..0000000 --- a/openssh/acconfig.h +++ /dev/null @@ -1,477 +0,0 @@ -/* $Id$ */ - -/* - * 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 if your setresuid() is broken */ -#undef BROKEN_SETRESUID - -/* Define if your setresgid() is broken */ -#undef BROKEN_SETRESGID - -/* Define to a Set Process Title type if your system is */ -/* supported by bsd-setproctitle.c */ -#undef SPT_TYPE -#undef SPT_PADCHAR - -/* 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 - -/* Full path of your "passwd" program */ -#undef _PATH_PASSWD_PROG - -/* 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 - -/* Define if you have the basename function. */ -#undef HAVE_BASENAME - -/* Work around problematic Linux PAM modules handling of PAM_TTY */ -#undef PAM_TTY_KLUDGE - -/* Define if pam_chauthtok wants real uid set to the unpriv'ed user */ -#undef SSHPAM_CHAUTHTOK_NEEDS_RUID - -/* 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 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 your skeychallenge() function takes 4 arguments (eg NetBSD) */ -#undef SKEYCHALLENGE_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 if you're building with GSSAPI MechGlue */ -#undef MECHGLUE - -/* 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 this if you want to use AFS/Kerberos 5 option, which runs aklog. */ -#undef AFS_KRB5 -#undef AKLOG_PATH - -/* Define if you want GSI/Globus authentication support */ -#undef GSI - -/* Define this if you want support for startup/shutdown hooks */ -#undef SESSION_HOOKS - -/* Define this if you want to use libkafs' AFS support */ -#undef USE_AFS - -/* 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 - -/* platform uses an in-memory credentials cache */ -#undef USE_CCAPI - -/* platform has a Security Authorization Session API */ -#undef USE_SECURITY_SESSION_API - -/* updwtmpx is broken (if present) */ -#undef BROKEN_UPDWTMPX - -/* 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 - -/* - * Define to whatever link() returns for "not supported" if it doesn't - * return EOPNOTSUPP. - */ -#undef LINK_OPNOTSUPP_ERRNO - -/* Strings used in /etc/passwd to denote locked account */ -#undef LOCKED_PASSWD_STRING -#undef LOCKED_PASSWD_PREFIX -#undef LOCKED_PASSWD_SUBSTR - -/* Define if getrrsetbyname() exists */ -#undef HAVE_GETRRSETBYNAME - -/* Define if HEADER.ad exists in arpa/nameser.h */ -#undef HAVE_HEADER_AD - -/* Define if your resolver libs need this for getrrsetbyname */ -#undef BIND_8_COMPAT - -/* Define if you have /proc/$pid/fd */ -#undef HAVE_PROC_PID - -@BOTTOM@ - -/* ******************* Shouldn't need to edit below this line ************** */ - -#endif /* _CONFIG_H */ diff --git a/openssh/auth-krb5.c b/openssh/auth-krb5.c index 5f554a6..fc85b88 100644 --- a/openssh/auth-krb5.c +++ b/openssh/auth-krb5.c @@ -28,7 +28,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth-krb5.c,v 1.15 2003/11/21 11:57:02 djm Exp $"); +RCSID("$OpenBSD: auth-krb5.c,v 1.16 2005/11/21 09:42:10 dtucker Exp $"); #include "ssh.h" #include "ssh1.h" @@ -69,9 +69,6 @@ auth_krb5_password(Authctxt *authctxt, const char *password) krb5_ccache ccache = NULL; int len; - if (!authctxt->valid) - return (0); - temporarily_use_uid(authctxt->pw); problem = krb5_init(authctxt); @@ -193,7 +190,7 @@ auth_krb5_password(Authctxt *authctxt, const char *password) else return (0); } - return (1); + return (authctxt->valid ? 1 : 0); } void diff --git a/openssh/auth-pam.c b/openssh/auth-pam.c index 4cbde4e..8ff3320 100644 --- a/openssh/auth-pam.c +++ b/openssh/auth-pam.c @@ -716,8 +716,18 @@ sshpam_query(void *ctx, char **name, char **info, plen++; xfree(msg); break; - case PAM_SUCCESS: case PAM_AUTH_ERR: + debug3("PAM: PAM_AUTH_ERR"); + if (**prompts != NULL && strlen(**prompts) != 0) { + *info = **prompts; + **prompts = NULL; + *num = 0; + **echo_on = 0; + ctxt->pam_done = -1; + return 0; + } + /* FALLTHROUGH */ + case PAM_SUCCESS: if (**prompts != NULL) { /* drain any accumulated messages */ debug("PAM: %s", **prompts); @@ -763,7 +773,7 @@ sshpam_respond(void *ctx, u_int num, char **resp) Buffer buffer; struct pam_ctxt *ctxt = ctx; - debug2("PAM: %s entering, %d responses", __func__, num); + debug2("PAM: %s entering, %u responses", __func__, num); switch (ctxt->pam_done) { case 1: sshpam_authenticated = 1; diff --git a/openssh/auth2-gss.c b/openssh/auth2-gss.c index 8622002..edf07b7 100644 --- a/openssh/auth2-gss.c +++ b/openssh/auth2-gss.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-gss.c,v 1.10 2005/07/17 07:17:54 djm Exp $ */ +/* $OpenBSD: auth2-gss.c,v 1.12 2005/10/13 22:24:31 stevesk Exp $ */ /* * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -34,7 +34,6 @@ #include "log.h" #include "dispatch.h" #include "servconf.h" -#include "compat.h" #include "packet.h" #include "monitor_wrap.h" @@ -110,7 +109,7 @@ userauth_gsskeyex(Authctxt *authctxt) /* * We only support those mechanisms that we know about (ie ones that we know - * how to check local user kuserok and the like + * how to check local user kuserok and the like) */ static int userauth_gssapi(Authctxt *authctxt) @@ -171,7 +170,7 @@ userauth_gssapi(Authctxt *authctxt) return (0); } - authctxt->methoddata=(void *)ctxt; + authctxt->methoddata = (void *)ctxt; packet_start(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE); diff --git a/openssh/auth2.c b/openssh/auth2.c index 319303c..1a5c91c 100644 --- a/openssh/auth2.c +++ b/openssh/auth2.c @@ -201,23 +201,19 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) 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)); -#endif } else { logit("input_userauth_request: invalid user %s", user); authctxt->pw = fakepw(); -#ifdef USE_PAM - if (options.use_pam) - PRIVSEP(start_pam(authctxt)); -#endif #ifdef SSH_AUDIT_EVENTS PRIVSEP(audit_event(SSH_INVALID_USER)); #endif } #ifdef GSSAPI } /* endif for setting username based on GSSAPI context */ +#endif +#ifdef USE_PAM + if (options.use_pam) + PRIVSEP(start_pam(authctxt)); #endif setproctitle("%s%s", authctxt->valid ? user : "unknown", use_privsep ? " [net]" : ""); diff --git a/openssh/canohost.c b/openssh/canohost.c index 626f1a8..3e6f482 100644 --- a/openssh/canohost.c +++ b/openssh/canohost.c @@ -12,7 +12,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: canohost.c,v 1.44 2005/06/17 02:44:32 djm Exp $"); +RCSID("$OpenBSD: canohost.c,v 1.48 2005/12/28 22:46:06 stevesk Exp $"); #include "packet.h" #include "xmalloc.h" @@ -43,9 +43,6 @@ get_remote_hostname(int sock, int use_dns) cleanup_exit(255); } - if (from.ss_family == AF_INET) - check_ip_options(sock, ntop); - ipv64_normalise_mapped(&from, &fromlen); if (from.ss_family == AF_INET6) @@ -55,6 +52,9 @@ get_remote_hostname(int sock, int use_dns) NULL, 0, NI_NUMERICHOST) != 0) fatal("get_remote_hostname: getnameinfo NI_NUMERICHOST failed"); + if (from.ss_family == AF_INET) + check_ip_options(sock, ntop); + if (!use_dns) return xstrdup(ntop); @@ -102,7 +102,7 @@ get_remote_hostname(int sock, int use_dns) hints.ai_socktype = SOCK_STREAM; if (getaddrinfo(name, NULL, &hints, &aitop) != 0) { logit("reverse mapping checking getaddrinfo for %.700s " - "failed - POSSIBLE BREAKIN ATTEMPT!", name); + "failed - POSSIBLE BREAK-IN ATTEMPT!", name); return xstrdup(ntop); } /* Look for the address from the list of addresses. */ @@ -117,7 +117,7 @@ get_remote_hostname(int sock, int use_dns) if (!ai) { /* Address not found for the host name. */ logit("Address %.100s maps to %.600s, but this does not " - "map back to the address - POSSIBLE BREAKIN ATTEMPT!", + "map back to the address - POSSIBLE BREAK-IN ATTEMPT!", ntop, name); return xstrdup(ntop); } @@ -158,9 +158,7 @@ check_ip_options(int sock, char *ipaddr) for (i = 0; i < option_size; i++) snprintf(text + i*3, sizeof(text) - i*3, " %2.2x", options[i]); - logit("Connection from %.100s with IP options:%.800s", - ipaddr, text); - packet_disconnect("Connection from %.100s with IP options:%.800s", + fatal("Connection from %.100s with IP options:%.800s", ipaddr, text); } #endif /* IP_OPTIONS */ @@ -200,26 +198,27 @@ ipv64_normalise_mapped(struct sockaddr_storage *addr, socklen_t *len) const char * get_canonical_hostname(int use_dns) { + char *host; static char *canonical_host_name = NULL; - static int use_dns_done = 0; + static char *remote_ip = NULL; /* Check if we have previously retrieved name with same option. */ - if (canonical_host_name != NULL) { - if (use_dns_done != use_dns) - xfree(canonical_host_name); - else - return canonical_host_name; - } + if (use_dns && canonical_host_name != NULL) + return canonical_host_name; + if (!use_dns && remote_ip != NULL) + return remote_ip; /* Get the real hostname if socket; otherwise return UNKNOWN. */ if (packet_connection_is_on_socket()) - canonical_host_name = get_remote_hostname( - packet_get_connection_in(), use_dns); + host = get_remote_hostname(packet_get_connection_in(), use_dns); else - canonical_host_name = xstrdup("UNKNOWN"); + host = "UNKNOWN"; - use_dns_done = use_dns; - return canonical_host_name; + if (use_dns) + canonical_host_name = host; + else + remote_ip = host; + return host; } /* diff --git a/openssh/channels.c b/openssh/channels.c index d22b88a..eead4bd 100644 --- a/openssh/channels.c +++ b/openssh/channels.c @@ -39,7 +39,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: channels.c,v 1.223 2005/07/17 07:17:54 djm Exp $"); +RCSID("$OpenBSD: channels.c,v 1.232 2006/01/30 12:22:22 reyk Exp $"); #include "ssh.h" #include "ssh1.h" @@ -58,8 +58,6 @@ RCSID("$OpenBSD: channels.c,v 1.223 2005/07/17 07:17:54 djm Exp $"); /* -- channel core */ -#define CHAN_RBUF 16*1024 - /* * Pointer to an array containing all allocated channels. The array is * dynamically extended as needed. @@ -142,22 +140,50 @@ static void port_open_helper(Channel *c, char *rtype); /* -- channel core */ Channel * -channel_lookup(int id) +channel_by_id(int id) { Channel *c; if (id < 0 || (u_int)id >= channels_alloc) { - logit("channel_lookup: %d: bad id", id); + logit("channel_by_id: %d: bad id", id); return NULL; } c = channels[id]; if (c == NULL) { - logit("channel_lookup: %d: bad id: channel free", id); + logit("channel_by_id: %d: bad id: channel free", id); return NULL; } return c; } +/* + * Returns the channel if it is allowed to receive protocol messages. + * Private channels, like listening sockets, may not receive messages. + */ +Channel * +channel_lookup(int id) +{ + Channel *c; + + if ((c = channel_by_id(id)) == NULL) + return (NULL); + + switch(c->type) { + case SSH_CHANNEL_X11_OPEN: + case SSH_CHANNEL_LARVAL: + case SSH_CHANNEL_CONNECTING: + case SSH_CHANNEL_DYNAMIC: + case SSH_CHANNEL_OPENING: + case SSH_CHANNEL_OPEN: + case SSH_CHANNEL_INPUT_DRAINING: + case SSH_CHANNEL_OUTPUT_DRAINING: + return (c); + break; + } + logit("Non-public channel %d, type %d.", id, c->type); + return (NULL); +} + /* * Register filedescriptors for a channel, used when allocating a channel or * when the channel consumer/producer is ready, e.g. shell exec'd @@ -270,9 +296,11 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd, c->force_drain = 0; c->single_connection = 0; c->detach_user = NULL; + c->detach_close = 0; c->confirm = NULL; c->confirm_ctx = NULL; c->input_filter = NULL; + c->output_filter = NULL; debug("channel %d: new [%s]", found, remote_name); return c; } @@ -629,29 +657,32 @@ channel_register_confirm(int id, channel_callback_fn *fn, void *ctx) c->confirm_ctx = ctx; } void -channel_register_cleanup(int id, channel_callback_fn *fn) +channel_register_cleanup(int id, channel_callback_fn *fn, int do_close) { - Channel *c = channel_lookup(id); + Channel *c = channel_by_id(id); if (c == NULL) { logit("channel_register_cleanup: %d: bad id", id); return; } c->detach_user = fn; + c->detach_close = do_close; } void channel_cancel_cleanup(int id) { - Channel *c = channel_lookup(id); + Channel *c = channel_by_id(id); if (c == NULL) { logit("channel_cancel_cleanup: %d: bad id", id); return; } c->detach_user = NULL; + c->detach_close = 0; } void -channel_register_filter(int id, channel_filter_fn *fn) +channel_register_filter(int id, channel_infilter_fn *ifn, + channel_outfilter_fn *ofn) { Channel *c = channel_lookup(id); @@ -659,7 +690,8 @@ channel_register_filter(int id, channel_filter_fn *fn) logit("channel_register_filter: %d: bad id", id); return; } - c->input_filter = fn; + c->input_filter = ifn; + c->output_filter = ofn; } void @@ -1228,6 +1260,19 @@ port_open_helper(Channel *c, char *rtype) xfree(remote_ipaddr); } +static void +channel_set_reuseaddr(int fd) +{ + int on = 1; + + /* + * Set socket options. + * Allow local port reuse in TIME_WAIT. + */ + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) + error("setsockopt SO_REUSEADDR fd %d: %s", fd, strerror(errno)); +} + /* * This socket is listening for connections to a forwarded TCP/IP port. */ @@ -1399,6 +1444,8 @@ channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset) debug2("channel %d: filter stops", c->self); chan_read_failed(c); } + } else if (c->datagram) { + buffer_put_string(&c->input, buf, len); } else { buffer_append(&c->input, buf, len); } @@ -1409,7 +1456,7 @@ static int channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset) { struct termios tio; - u_char *data; + u_char *data = NULL, *buf; u_int dlen; int len; @@ -1417,14 +1464,45 @@ channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset) if (c->wfd != -1 && FD_ISSET(c->wfd, writeset) && buffer_len(&c->output) > 0) { - data = buffer_ptr(&c->output); - dlen = buffer_len(&c->output); + if (c->output_filter != NULL) { + if ((buf = c->output_filter(c, &data, &dlen)) == NULL) { + debug2("channel %d: filter stops", c->self); + if (c->type != SSH_CHANNEL_OPEN) + chan_mark_dead(c); + else + chan_write_failed(c); + return -1; + } + } else if (c->datagram) { + buf = data = buffer_get_string(&c->output, &dlen); + } else { + buf = data = buffer_ptr(&c->output); + dlen = buffer_len(&c->output); + } + + if (c->datagram) { + /* ignore truncated writes, datagrams might get lost */ + c->local_consumed += dlen + 4; + len = write(c->wfd, buf, dlen); + xfree(data); + if (len < 0 && (errno == EINTR || errno == EAGAIN)) + return 1; + if (len <= 0) { + if (c->type != SSH_CHANNEL_OPEN) + chan_mark_dead(c); + else + chan_write_failed(c); + return -1; + } + return 1; + } #ifdef _AIX /* XXX: Later AIX versions can't push as much data to tty */ if (compat20 && c->wfd_isatty) dlen = MIN(dlen, 8*1024); #endif - len = write(c->wfd, data, dlen); + + len = write(c->wfd, buf, dlen); if (len < 0 && (errno == EINTR || errno == EAGAIN)) return 1; if (len <= 0) { @@ -1441,14 +1519,14 @@ channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset) } return -1; } - if (compat20 && c->isatty && dlen >= 1 && data[0] != '\r') { + if (compat20 && c->isatty && dlen >= 1 && buf[0] != '\r') { if (tcgetattr(c->wfd, &tio) == 0 && !(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) { /* * Simulate echo to reduce the impact of * traffic analysis. We need to match the * size of a SSH2_MSG_CHANNEL_DATA message - * (4 byte channel id + data) + * (4 byte channel id + buf) */ packet_send_ignore(4 + len); packet_send(); @@ -1682,7 +1760,7 @@ channel_garbage_collect(Channel *c) if (c == NULL) return; if (c->detach_user != NULL) { - if (!chan_is_dead(c, 0)) + if (!chan_is_dead(c, c->detach_close)) return; debug2("channel %d: gc: notify user", c->self); c->detach_user(c->self, NULL); @@ -1792,6 +1870,22 @@ channel_output_poll(void) if ((c->istate == CHAN_INPUT_OPEN || c->istate == CHAN_INPUT_WAIT_DRAIN) && (len = buffer_len(&c->input)) > 0) { + if (c->datagram) { + if (len > 0) { + u_char *data; + u_int dlen; + + data = buffer_get_string(&c->input, + &dlen); + packet_start(SSH2_MSG_CHANNEL_DATA); + packet_put_int(c->remote_id); + packet_put_string(data, dlen); + packet_send(); + c->remote_window -= dlen + 4; + xfree(data); + } + continue; + } /* * Send some data for the other side over the secure * connection. @@ -1914,7 +2008,10 @@ channel_input_data(int type, u_int32_t seq, void *ctxt) c->local_window -= data_len; } packet_check_eom(); - buffer_append(&c->output, data, data_len); + if (c->datagram) + buffer_put_string(&c->output, data, data_len); + else + buffer_append(&c->output, data, data_len); xfree(data); } @@ -2145,9 +2242,8 @@ channel_input_window_adjust(int type, u_int32_t seq, void *ctxt) id = packet_get_int(); c = channel_lookup(id); - if (c == NULL || c->type != SSH_CHANNEL_OPEN) { - logit("Received window adjust for " - "non-open channel %d.", id); + if (c == NULL) { + logit("Received window adjust for non-open channel %d.", id); return; } adjust = packet_get_int(); @@ -2204,7 +2300,7 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por const char *host_to_connect, u_short port_to_connect, int gateway_ports) { Channel *c; - int sock, r, success = 0, on = 1, wildcard = 0, is_client; + int sock, r, success = 0, wildcard = 0, is_client; struct addrinfo hints, *ai, *aitop; const char *host, *addr; char ntop[NI_MAXHOST], strport[NI_MAXSERV]; @@ -2291,13 +2387,8 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por verbose("socket: %.100s", strerror(errno)); continue; } - /* - * Set socket options. - * Allow local port reuse in TIME_WAIT. - */ - if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, - sizeof(on)) == -1) - error("setsockopt SO_REUSEADDR: %s", strerror(errno)); + + channel_set_reuseaddr(sock); debug("Local forwarding listening on %s port %s.", ntop, strport); @@ -2469,7 +2560,7 @@ channel_request_rforward_cancel(const char *host, u_short port) permitted_opens[i].listen_port = 0; permitted_opens[i].port_to_connect = 0; - free(permitted_opens[i].host_to_connect); + xfree(permitted_opens[i].host_to_connect); permitted_opens[i].host_to_connect = NULL; } @@ -2684,6 +2775,9 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost, char strport[NI_MAXSERV]; int gaierr, n, num_socks = 0, socks[NUM_SOCKS]; + if (chanids == NULL) + return -1; + for (display_number = x11_display_offset; display_number < MAX_DISPLAYS; display_number++) { @@ -2720,6 +2814,7 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost, error("setsockopt IPV6_V6ONLY: %.100s", strerror(errno)); } #endif + channel_set_reuseaddr(sock); if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) { debug2("bind port %d: %.100s", port, strerror(errno)); close(sock); @@ -2765,8 +2860,7 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost, } /* Allocate a channel for each socket. */ - if (chanids != NULL) - *chanids = xmalloc(sizeof(**chanids) * (num_socks + 1)); + *chanids = xmalloc(sizeof(**chanids) * (num_socks + 1)); for (n = 0; n < num_socks; n++) { sock = socks[n]; nc = channel_new("x11 listener", @@ -2774,11 +2868,9 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost, CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, "X11 inet listener", 1); nc->single_connection = single_connection; - if (*chanids != NULL) - (*chanids)[n] = nc->self; + (*chanids)[n] = nc->self; } - if (*chanids != NULL) - (*chanids)[n] = -1; + (*chanids)[n] = -1; /* Return the display number for the DISPLAY environment variable. */ *display_numberp = display_number; @@ -2964,7 +3056,7 @@ deny_input_open(int type, u_int32_t seq, void *ctxt) error("deny_input_open: type %d", type); break; } - error("Warning: this is probably a break in attempt by a malicious server."); + error("Warning: this is probably a break-in attempt by a malicious server."); packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); packet_put_int(rchan); packet_send(); diff --git a/openssh/channels.h b/openssh/channels.h index b351daa..3f4b788 100644 --- a/openssh/channels.h +++ b/openssh/channels.h @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.h,v 1.79 2005/07/17 06:49:04 djm Exp $ */ +/* $OpenBSD: channels.h,v 1.83 2005/12/30 15:56:37 reyk Exp $ */ /* * Author: Tatu Ylonen @@ -63,7 +63,8 @@ struct Channel; typedef struct Channel Channel; typedef void channel_callback_fn(int, void *); -typedef int channel_filter_fn(struct Channel *, char *, int); +typedef int channel_infilter_fn(struct Channel *, char *, int); +typedef u_char *channel_outfilter_fn(struct Channel *, u_char **, u_int *); struct Channel { int type; /* channel type/state */ @@ -107,11 +108,15 @@ struct Channel { /* callback */ channel_callback_fn *confirm; - channel_callback_fn *detach_user; void *confirm_ctx; + channel_callback_fn *detach_user; + int detach_close; /* filter */ - channel_filter_fn *input_filter; + channel_infilter_fn *input_filter; + channel_outfilter_fn *output_filter; + + int datagram; /* keep boundaries */ }; #define CHAN_EXTENDED_IGNORE 0 @@ -143,6 +148,8 @@ struct Channel { #define CHAN_EOF_SENT 0x04 #define CHAN_EOF_RCVD 0x08 +#define CHAN_RBUF 16*1024 + /* check whether 'efd' is still in use */ #define CHANNEL_EFD_INPUT_ACTIVE(c) \ (compat20 && c->extended_usage == CHAN_EXTENDED_READ && \ @@ -155,6 +162,7 @@ struct Channel { /* channel management */ +Channel *channel_by_id(int); Channel *channel_lookup(int); Channel *channel_new(char *, int, int, int, int, u_int, u_int, int, char *, int); void channel_set_fds(int, int, int, int, int, int, u_int); @@ -164,9 +172,9 @@ void channel_stop_listening(void); void channel_send_open(int); void channel_request_start(int, char *, int); -void channel_register_cleanup(int, channel_callback_fn *); +void channel_register_cleanup(int, channel_callback_fn *, int); void channel_register_confirm(int, channel_callback_fn *, void *); -void channel_register_filter(int, channel_filter_fn *); +void channel_register_filter(int, channel_infilter_fn *, channel_outfilter_fn *); void channel_cancel_cleanup(int); int channel_close_fd(int *); void channel_send_window_changes(void); diff --git a/openssh/cipher-aes.c b/openssh/cipher-aes.c index 22d500d..228ddb1 100644 --- a/openssh/cipher-aes.c +++ b/openssh/cipher-aes.c @@ -23,7 +23,11 @@ */ #include "includes.h" -#if OPENSSL_VERSION_NUMBER < 0x00907000L + +/* compatibility with old or broken OpenSSL versions */ +#include "openbsd-compat/openssl-compat.h" + +#ifdef USE_BUILTIN_RIJNDAEL RCSID("$OpenBSD: cipher-aes.c,v 1.2 2003/11/26 21:44:29 djm Exp $"); #include @@ -31,10 +35,6 @@ RCSID("$OpenBSD: cipher-aes.c,v 1.2 2003/11/26 21:44:29 djm Exp $"); #include "xmalloc.h" #include "log.h" -#if OPENSSL_VERSION_NUMBER < 0x00906000L -#define SSH_OLD_EVP -#endif - #define RIJNDAEL_BLOCKSIZE 16 struct ssh_rijndael_ctx { @@ -157,4 +157,4 @@ evp_rijndael(void) #endif return (&rijndal_cbc); } -#endif /* OPENSSL_VERSION_NUMBER */ +#endif /* USE_BUILTIN_RIJNDAEL */ diff --git a/openssh/cipher-ctr.c b/openssh/cipher-ctr.c index 8561773..8a98f3c 100644 --- a/openssh/cipher-ctr.c +++ b/openssh/cipher-ctr.c @@ -21,11 +21,10 @@ RCSID("$OpenBSD: cipher-ctr.c,v 1.6 2005/07/17 07:17:55 djm Exp $"); #include "log.h" #include "xmalloc.h" -#if OPENSSL_VERSION_NUMBER < 0x00906000L -#define SSH_OLD_EVP -#endif +/* compatibility with old or broken OpenSSL versions */ +#include "openbsd-compat/openssl-compat.h" -#if OPENSSL_VERSION_NUMBER < 0x00907000L +#ifdef USE_BUILTIN_RIJNDAEL #include "rijndael.h" #define AES_KEY rijndael_ctx #define AES_BLOCK_SIZE 16 diff --git a/openssh/cipher.c b/openssh/cipher.c index 48e5706..570bfd2 100644 --- a/openssh/cipher.c +++ b/openssh/cipher.c @@ -336,7 +336,7 @@ cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len) if ((u_int)evplen != len) fatal("%s: wrong iv length %d != %d", __func__, evplen, len); -#if OPENSSL_VERSION_NUMBER < 0x00907000L +#ifdef USE_BUILTIN_RIJNDAEL if (c->evptype == evp_rijndael) ssh_rijndael_iv(&cc->evp, 0, iv, len); else @@ -368,7 +368,7 @@ cipher_set_keyiv(CipherContext *cc, u_char *iv) evplen = EVP_CIPHER_CTX_iv_length(&cc->evp); if (evplen == 0) return; -#if OPENSSL_VERSION_NUMBER < 0x00907000L +#ifdef USE_BUILTIN_RIJNDAEL if (c->evptype == evp_rijndael) ssh_rijndael_iv(&cc->evp, 1, iv, evplen); else diff --git a/openssh/configure.ac b/openssh/configure.ac index a7fc06e..876c8fb 100644 --- a/openssh/configure.ac +++ b/openssh/configure.ac @@ -47,6 +47,11 @@ AC_PATH_PROG(PATH_GROUPADD_PROG, groupadd, groupadd, AC_PATH_PROG(PATH_USERADD_PROG, useradd, useradd, [/usr/sbin${PATH_SEPARATOR}/etc]) AC_CHECK_PROG(MAKE_PACKAGE_SUPPORTED, pkgmk, yes, no) +if test -x /sbin/sh; then + AC_SUBST(STARTUP_SCRIPT_SHELL,/sbin/sh) +else + AC_SUBST(STARTUP_SCRIPT_SHELL,/bin/sh) +fi # System features AC_SYS_LARGEFILE @@ -57,7 +62,9 @@ fi # Use LOGIN_PROGRAM from environment if possible if test ! -z "$LOGIN_PROGRAM" ; then - AC_DEFINE_UNQUOTED(LOGIN_PROGRAM_FALLBACK, "$LOGIN_PROGRAM") + AC_DEFINE_UNQUOTED(LOGIN_PROGRAM_FALLBACK, "$LOGIN_PROGRAM", + [If your header files don't define LOGIN_PROGRAM, + then use this (detected) from environment and PATH]) else # Search for login AC_PATH_PROG(LOGIN_PROGRAM_FALLBACK, login) @@ -68,7 +75,8 @@ fi AC_PATH_PROG(PATH_PASSWD_PROG, passwd) if test ! -z "$PATH_PASSWD_PROG" ; then - AC_DEFINE_UNQUOTED(_PATH_PASSWD_PROG, "$PATH_PASSWD_PROG") + AC_DEFINE_UNQUOTED(_PATH_PASSWD_PROG, "$PATH_PASSWD_PROG", + [Full path of your "passwd" program]) fi if test -z "$LD" ; then @@ -82,12 +90,14 @@ AC_CHECK_DECL(LLONG_MAX, have_llong_max=1, , [#include ]) if test "$GCC" = "yes" || test "$GCC" = "egcs"; then CFLAGS="$CFLAGS -Wall -Wpointer-arith -Wuninitialized" - GCC_VER=`$CC --version` + GCC_VER=`$CC -v 2>&1 | $AWK '/gcc version /{print $3}'` case $GCC_VER in 1.*) ;; 2.8* | 2.9*) CFLAGS="$CFLAGS -Wsign-compare" ;; 2.*) ;; - *) CFLAGS="$CFLAGS -Wsign-compare" ;; + 3.*) CFLAGS="$CFLAGS -Wsign-compare" ;; + 4.*) CFLAGS="$CFLAGS -Wsign-compare -Wno-pointer-sign" ;; + *) ;; esac if test -z "$have_llong_max"; then @@ -103,70 +113,6 @@ if test "$GCC" = "yes" || test "$GCC" = "egcs"; then fi fi -if test -z "$have_llong_max"; then - AC_MSG_CHECKING([for max value of long long]) - AC_RUN_IFELSE( - [AC_LANG_SOURCE([[ -#include -/* Why is this so damn hard? */ -#ifdef __GNUC__ -# undef __GNUC__ -#endif -#define __USE_ISOC99 -#include -#define DATA "conftest.llminmax" -int main(void) { - FILE *f; - long long i, llmin, llmax = 0; - - if((f = fopen(DATA,"w")) == NULL) - exit(1); - -#if defined(LLONG_MIN) && defined(LLONG_MAX) - fprintf(stderr, "Using system header for LLONG_MIN and LLONG_MAX\n"); - llmin = LLONG_MIN; - llmax = LLONG_MAX; -#else - fprintf(stderr, "Calculating LLONG_MIN and LLONG_MAX\n"); - /* This will work on one's complement and two's complement */ - for (i = 1; i > llmax; i <<= 1, i++) - llmax = i; - llmin = llmax + 1LL; /* wrap */ -#endif - - /* Sanity check */ - if (llmin + 1 < llmin || llmin - 1 < llmin || llmax + 1 > llmax - || llmax - 1 > llmax) { - fprintf(f, "unknown unknown\n"); - exit(2); - } - - if (fprintf(f ,"%lld %lld", llmin, llmax) < 0) - exit(3); - - exit(0); -} - ]])], - [ - llong_min=`$AWK '{print $1}' conftest.llminmax` - llong_max=`$AWK '{print $2}' conftest.llminmax` - AC_MSG_RESULT($llong_max) - AC_DEFINE_UNQUOTED(LLONG_MAX, [${llong_max}LL], - [max value of long long calculated by configure]) - AC_MSG_CHECKING([for min value of long long]) - AC_MSG_RESULT($llong_min) - AC_DEFINE_UNQUOTED(LLONG_MIN, [${llong_min}LL], - [min value of long long calculated by configure]) - ], - [ - AC_MSG_RESULT(not found) - ], - [ - AC_MSG_WARN([cross compiling: not checking]) - ] - ) -fi - AC_ARG_WITH(rpath, [ --without-rpath Disable auto-added -R linker paths], [ @@ -201,7 +147,8 @@ case "$host" in 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_FUNC(authenticate, [AC_DEFINE(WITH_AIXAUTHENTICATE, 1, + [Define if you want to enable AIX4's authenticate function])], [AC_CHECK_LIB(s,authenticate, [ AC_DEFINE(WITH_AIXAUTHENTICATE) LIBS="$LIBS -ls" @@ -217,7 +164,9 @@ case "$host" in [#include ], [(void)loginfailed("user","host","tty",0);], [AC_MSG_RESULT(yes) - AC_DEFINE(AIX_LOGINFAILED_4ARG)], + AC_DEFINE(AIX_LOGINFAILED_4ARG, 1, + [Define if your AIX loginfailed() function + takes 4 arguments (AIX >= 5.2)])], [AC_MSG_RESULT(no)] )], [], @@ -225,25 +174,38 @@ case "$host" in ) AC_CHECK_FUNCS(setauthdb) check_for_aix_broken_getaddrinfo=1 - AC_DEFINE(BROKEN_REALPATH) - AC_DEFINE(SETEUID_BREAKS_SETUID) - AC_DEFINE(BROKEN_SETREUID) - AC_DEFINE(BROKEN_SETREGID) + AC_DEFINE(BROKEN_REALPATH, 1, [Define if you have a broken realpath.]) + AC_DEFINE(SETEUID_BREAKS_SETUID, 1, + [Define if your platform breaks doing a seteuid before a setuid]) + AC_DEFINE(BROKEN_SETREUID, 1, [Define if your setreuid() is broken]) + AC_DEFINE(BROKEN_SETREGID, 1, [Define if your setregid() is broken]) dnl AIX handles lastlog as part of its login message - AC_DEFINE(DISABLE_LASTLOG) - AC_DEFINE(LOGIN_NEEDS_UTMPX) - AC_DEFINE(SPT_TYPE,SPT_REUSEARGV) + AC_DEFINE(DISABLE_LASTLOG, 1, [Define if you don't want to use lastlog]) + AC_DEFINE(LOGIN_NEEDS_UTMPX, 1, + [Some systems need a utmpx entry for /bin/login to work]) + AC_DEFINE(SPT_TYPE,SPT_REUSEARGV, + [Define to a Set Process Title type if your system is + supported by bsd-setproctitle.c]) + AC_DEFINE(SSHPAM_CHAUTHTOK_NEEDS_RUID, 1, + [AIX 5.2 and 5.3 (and presumably newer) require this]) ;; *-*-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(HAVE_CYGWIN, 1, [Define if you are on Cygwin]) + AC_DEFINE(USE_PIPES, 1, [Use PIPES instead of a socketpair()]) + AC_DEFINE(DISABLE_SHADOW, 1, + [Define if you want to disable shadow passwords]) + AC_DEFINE(IP_TOS_IS_BROKEN, 1, + [Define if your system choked on IP TOS setting]) + AC_DEFINE(NO_X11_UNIX_SOCKETS, 1, + [Define if X11 doesn't support AF_UNIX sockets on that system]) + AC_DEFINE(NO_IPPORT_RESERVED_CONCEPT, 1, + [Define if the concept of ports only accessible to + superusers isn't known]) + AC_DEFINE(DISABLE_FD_PASSING, 1, + [Define if your platform needs to skip post auth + file descriptor passing]) ;; *-*-dgux*) AC_DEFINE(IP_TOS_IS_BROKEN) @@ -252,16 +214,18 @@ case "$host" in AC_DEFINE(BROKEN_SETREGID) ;; *-*-darwin*) - AC_DEFINE(BROKEN_GETADDRINFO) + AC_DEFINE(BROKEN_GETADDRINFO, 1, [getaddrinfo is broken (if present)])], AC_DEFINE(SETEUID_BREAKS_SETUID) AC_DEFINE(BROKEN_SETREUID) AC_DEFINE(BROKEN_SETREGID) - AC_DEFINE_UNQUOTED(BIND_8_COMPAT, 1) + AC_DEFINE_UNQUOTED(BIND_8_COMPAT, 1, + [Define if your resolver libs need this for getrrsetbyname]) AC_MSG_CHECKING(if we have the Security Authorization Session API) AC_TRY_COMPILE([#include ], [SessionCreate(0, 0);], [ac_cv_use_security_session_api="yes" - AC_DEFINE(USE_SECURITY_SESSION_API) + AC_DEFINE(USE_SECURITY_SESSION_API, 1, + [platform has a Security Authorization Session API]) LIBS="$LIBS -framework Security" AC_MSG_RESULT(yes)], [ac_cv_use_security_session_api="no" @@ -271,7 +235,8 @@ case "$host" in [#include ], [cc_context_t c; (void) cc_initialize (&c, 0, NULL, NULL);], - [AC_DEFINE(USE_CCAPI) + [AC_DEFINE(USE_CCAPI, 1, + [platform uses an in-memory credentials cache]) LIBS="$LIBS -framework Security" AC_MSG_RESULT(yes) if test "x$ac_cv_use_security_session_api" = "xno"; then @@ -285,10 +250,13 @@ case "$host" in 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_NO_ENDOPT, 1, + [Define if your login program cannot handle end of options ("--")]) AC_DEFINE(LOGIN_NEEDS_UTMPX) - AC_DEFINE(LOCKED_PASSWD_STRING, "*") + AC_DEFINE(LOCKED_PASSWD_STRING, "*", + [String used in /etc/passwd to denote locked account]) AC_DEFINE(SPT_TYPE,SPT_PSTAT) + MAIL="/var/mail/username" LIBS="$LIBS -lsec" AC_CHECK_LIB(xnet, t_error, , AC_MSG_ERROR([*** -lxnet needed on HP-UX - check config.log ***])) @@ -301,8 +269,12 @@ case "$host" in fi ;; *-*-hpux11*) - AC_DEFINE(PAM_SUN_CODEBASE) - AC_DEFINE(DISABLE_UTMP) + AC_DEFINE(PAM_SUN_CODEBASE, 1, + [Define if you are using Solaris-derived PAM which + passes pam_messages to the conversation function + with an extra level of indirection]) + AC_DEFINE(DISABLE_UTMP, 1, + [Define if you don't want to use utmp]) AC_DEFINE(USE_BTMP, 1, [Use btmp to log bad logins]) check_for_hpux_broken_getaddrinfo=1 check_for_conflicting_getspnam=1 @@ -312,7 +284,9 @@ case "$host" in # lastly, we define options specific to minor releases case "$host" in *-*-hpux10.26) - AC_DEFINE(HAVE_SECUREWARE) + AC_DEFINE(HAVE_SECUREWARE, 1, + [Define if you have SecureWare-based + protected password database]) disable_ptmx_check=yes LIBS="$LIBS -lsecpw" ;; @@ -320,24 +294,33 @@ case "$host" in ;; *-*-irix5*) PATH="$PATH:/usr/etc" - AC_DEFINE(BROKEN_INET_NTOA) + AC_DEFINE(BROKEN_INET_NTOA, 1, + [Define if you system's inet_ntoa is busted + (e.g. Irix gcc issue)]) AC_DEFINE(SETEUID_BREAKS_SETUID) AC_DEFINE(BROKEN_SETREUID) AC_DEFINE(BROKEN_SETREGID) - AC_DEFINE(WITH_ABBREV_NO_TTY) + AC_DEFINE(WITH_ABBREV_NO_TTY, 1, + [Define if you shouldn't strip 'tty' from your + ttyname in [uw]tmp]) AC_DEFINE(LOCKED_PASSWD_STRING, "*LK*") ;; *-*-irix6*) PATH="$PATH:/usr/etc" - AC_DEFINE(WITH_IRIX_ARRAY) - AC_DEFINE(WITH_IRIX_PROJECT) - AC_DEFINE(WITH_IRIX_AUDIT) - AC_CHECK_FUNC(jlimit_startjob, [AC_DEFINE(WITH_IRIX_JOBS)]) + AC_DEFINE(WITH_IRIX_ARRAY, 1, + [Define if you have/want arrays + (cluster-wide session managment, not C arrays)]) + AC_DEFINE(WITH_IRIX_PROJECT, 1, + [Define if you want IRIX project management]) + AC_DEFINE(WITH_IRIX_AUDIT, 1, + [Define if you want IRIX audit trails]) + AC_CHECK_FUNC(jlimit_startjob, [AC_DEFINE(WITH_IRIX_JOBS, 1, + [Define if you want IRIX kernel jobs])]) AC_DEFINE(BROKEN_INET_NTOA) AC_DEFINE(SETEUID_BREAKS_SETUID) AC_DEFINE(BROKEN_SETREUID) AC_DEFINE(BROKEN_SETREGID) - AC_DEFINE(BROKEN_UPDWTMPX) + AC_DEFINE(BROKEN_UPDWTMPX, 1, [updwtmpx is broken (if present)]) AC_DEFINE(WITH_ABBREV_NO_TTY) AC_DEFINE(LOCKED_PASSWD_STRING, "*LK*") ;; @@ -345,22 +328,37 @@ case "$host" in 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(DONT_TRY_OTHER_AF, 1, [Workaround more Linux IPv6 quirks]) + AC_DEFINE(PAM_TTY_KLUDGE, 1, + [Work around problematic Linux PAM modules handling of PAM_TTY]) + AC_DEFINE(LOCKED_PASSWD_PREFIX, "!", + [String used in /etc/passwd to denote locked account]) AC_DEFINE(SPT_TYPE,SPT_REUSEARGV) - AC_DEFINE(LINK_OPNOTSUPP_ERRNO, EPERM) + AC_DEFINE(LINK_OPNOTSUPP_ERRNO, EPERM, + [Define to whatever link() returns for "not supported" + if it doesn't return EOPNOTSUPP.]) AC_DEFINE(_PATH_BTMP, "/var/log/btmp", [log for bad login attempts]) - AC_DEFINE(USE_BTMP, 1, [Use btmp to log bad logins]) + AC_DEFINE(USE_BTMP) inet6_default_4in6=yes case `uname -r` in 1.*|2.0.*) - AC_DEFINE(BROKEN_CMSG_TYPE) + AC_DEFINE(BROKEN_CMSG_TYPE, 1, + [Define if cmsg_type is not passed correctly]) ;; esac + # tun(4) forwarding compat code + AC_CHECK_HEADERS(linux/if_tun.h) + if test "x$ac_cv_header_linux_if_tun_h" = "xyes" ; then + AC_DEFINE(SSH_TUN_LINUX, 1, + [Open tunnel devices the Linux tun/tap way]) + AC_DEFINE(SSH_TUN_COMPAT_AF, 1, + [Use tunnel device compatibility to OpenBSD]) + AC_DEFINE(SSH_TUN_PREPEND_AF, 1, + [Prepend the address family to IP tunnel traffic]) + fi ;; mips-sony-bsd|mips-sony-newsos4) - AC_DEFINE(NEED_SETPRGP, [], [Need setpgrp to acquire controlling tty]) + AC_DEFINE(NEED_SETPRGP, 1, [Need setpgrp to acquire controlling tty]) SONY=1 ;; *-*-netbsd*) @@ -368,9 +366,18 @@ mips-sony-bsd|mips-sony-newsos4) if test "x$withval" != "xno" ; then need_dash_r=1 fi + AC_DEFINE(SSH_TUN_FREEBSD, 1, [Open tunnel devices the FreeBSD way]) + AC_CHECK_HEADER([net/if_tap.h], , + AC_DEFINE(SSH_TUN_NO_L2, 1, [No layer 2 tunnel support])) + AC_DEFINE(SSH_TUN_PREPEND_AF, 1, + [Prepend the address family to IP tunnel traffic]) ;; *-*-freebsd*) check_for_libcrypt_later=1 + AC_DEFINE(LOCKED_PASSWD_PREFIX, "*LOCKED*", [Account locked with pw(1)]) + AC_DEFINE(SSH_TUN_FREEBSD, 1, [Open tunnel devices the FreeBSD way]) + AC_CHECK_HEADER([net/if_tap.h], , + AC_DEFINE(SSH_TUN_NO_L2, 1, [No layer 2 tunnel support])) ;; *-*-bsdi*) AC_DEFINE(SETEUID_BREAKS_SETUID) @@ -382,13 +389,15 @@ mips-sony-bsd|mips-sony-newsos4) conf_utmp_location=/etc/utmp conf_wtmp_location=/usr/adm/wtmp MAIL=/usr/spool/mail - AC_DEFINE(HAVE_NEXT) + AC_DEFINE(HAVE_NEXT, 1, [Define if you are on NeXT]) AC_DEFINE(BROKEN_REALPATH) AC_DEFINE(USE_PIPES) - AC_DEFINE(BROKEN_SAVED_UIDS) + AC_DEFINE(BROKEN_SAVED_UIDS, 1, [Needed for NeXT]) ;; *-*-openbsd*) AC_DEFINE(HAVE_ATTRIBUTE__SENTINEL__, 1, [OpenBSD's gcc has sentinel]) + AC_DEFINE(HAVE_ATTRIBUTE__BOUNDED__, 1, [OpenBSD's gcc has bounded]) + AC_DEFINE(SSH_TUN_OPENBSD, 1, [Open tunnel devices the OpenBSD way]) ;; *-*-solaris*) if test "x$withval" != "xno" ; then @@ -396,12 +405,18 @@ mips-sony-bsd|mips-sony-newsos4) fi AC_DEFINE(PAM_SUN_CODEBASE) AC_DEFINE(LOGIN_NEEDS_UTMPX) - AC_DEFINE(LOGIN_NEEDS_TERM) + AC_DEFINE(LOGIN_NEEDS_TERM, 1, + [Some versions of /bin/login need the TERM supplied + on the commandline]) AC_DEFINE(PAM_TTY_KLUDGE) - AC_DEFINE(SSHPAM_CHAUTHTOK_NEEDS_RUID) + AC_DEFINE(SSHPAM_CHAUTHTOK_NEEDS_RUID, 1, + [Define if pam_chauthtok wants real uid set + to the unpriv'ed user]) AC_DEFINE(LOCKED_PASSWD_STRING, "*LK*") # Pushing STREAMS modules will cause sshd to acquire a controlling tty. - AC_DEFINE(SSHD_ACQUIRES_CTTY) + AC_DEFINE(SSHD_ACQUIRES_CTTY, 1, + [Define if sshd somehow reacquires a controlling TTY + after setsid()]) external_path_file=/etc/default/login # hardwire lastlog location (can't detect it on some versions) conf_lastlog_location="/var/adm/lastlog" @@ -410,7 +425,8 @@ mips-sony-bsd|mips-sony-newsos4) if test "$sol2ver" -ge 8; then AC_MSG_RESULT(yes) AC_DEFINE(DISABLE_UTMP) - AC_DEFINE(DISABLE_WTMP) + AC_DEFINE(DISABLE_WTMP, 1, + [Define if you don't want to use wtmp]) else AC_MSG_RESULT(no) fi @@ -435,8 +451,8 @@ mips-sony-bsd|mips-sony-newsos4) *-sni-sysv*) # /usr/ucblib MUST NOT be searched on ReliantUNIX AC_CHECK_LIB(dl, dlsym, ,) - # -lresolv needs to be at then end of LIBS or DNS lookups break - AC_CHECK_LIB(res_query, resolv, [ LIBS="$LIBS -lresolv" ]) + # -lresolv needs to be at the end of LIBS or DNS lookups break + AC_CHECK_LIB(resolv, res_query, [ LIBS="$LIBS -lresolv" ]) IPADDR_IN_DISPLAY=yes AC_DEFINE(USE_PIPES) AC_DEFINE(IP_TOS_IS_BROKEN) @@ -451,11 +467,13 @@ mips-sony-bsd|mips-sony-newsos4) ;; # UnixWare 1.x, UnixWare 2.x, and others based on code from Univel. *-*-sysv4.2*) + CFLAGS="$CFLAGS -Dva_list=_VA_LIST" AC_DEFINE(USE_PIPES) AC_DEFINE(SETEUID_BREAKS_SETUID) AC_DEFINE(BROKEN_SETREUID) AC_DEFINE(BROKEN_SETREGID) AC_DEFINE(PASSWD_NEEDS_USERNAME, 1, [must supply username to passwd]) + AC_DEFINE(LOCKED_PASSWD_STRING, "*LK*") ;; # UnixWare 7.x, OpenUNIX 8 *-*-sysv5*) @@ -465,11 +483,14 @@ mips-sony-bsd|mips-sony-newsos4) AC_DEFINE(SETEUID_BREAKS_SETUID) AC_DEFINE(BROKEN_SETREUID) AC_DEFINE(BROKEN_SETREGID) - AC_DEFINE(PASSWD_NEEDS_USERNAME, 1, [must supply username to passwd]) + AC_DEFINE(PASSWD_NEEDS_USERNAME) case "$host" in *-*-sysv5SCO_SV*) # SCO OpenServer 6.x TEST_SHELL=/u95/bin/sh - AC_DEFINE(BROKEN_LIBIAF, 1, [ia_uinfo routines not supported by OS yet]) + AC_DEFINE(BROKEN_LIBIAF, 1, + [ia_uinfo routines not supported by OS yet]) + ;; + *) AC_DEFINE(LOCKED_PASSWD_STRING, "*LK*") ;; esac ;; @@ -495,13 +516,14 @@ mips-sony-bsd|mips-sony-newsos4) AC_DEFINE(BROKEN_SETREGID) AC_DEFINE(WITH_ABBREV_NO_TTY) AC_DEFINE(BROKEN_UPDWTMPX) - AC_DEFINE(PASSWD_NEEDS_USERNAME, 1, [must supply username to passwd]) + AC_DEFINE(PASSWD_NEEDS_USERNAME) AC_CHECK_FUNCS(getluid setluid) MANTYPE=man TEST_SHELL=ksh ;; *-*-unicosmk*) - AC_DEFINE(NO_SSH_LASTLOG) + AC_DEFINE(NO_SSH_LASTLOG, 1, + [Define if you don't want to use lastlog in session.c]) AC_DEFINE(SETEUID_BREAKS_SETUID) AC_DEFINE(BROKEN_SETREUID) AC_DEFINE(BROKEN_SETREGID) @@ -548,13 +570,18 @@ mips-sony-bsd|mips-sony-newsos4) 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(HAVE_OSF_SIA, 1, + [Define if you have Digital Unix Security + Integration Architecture]) + AC_DEFINE(DISABLE_LOGIN, 1, + [Define if you don't want to use your + system's login() call]) AC_DEFINE(DISABLE_FD_PASSING) LIBS="$LIBS -lsecurity -ldb -lm -laud" else AC_MSG_RESULT(no) - AC_DEFINE(LOCKED_PASSWD_SUBSTR, "Nologin") + AC_DEFINE(LOCKED_PASSWD_SUBSTR, "Nologin", + [String used in /etc/passwd to denote locked account]) fi fi AC_DEFINE(BROKEN_GETADDRINFO) @@ -566,21 +593,21 @@ mips-sony-bsd|mips-sony-newsos4) *-*-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) + AC_DEFINE(MISSING_NFDBITS, 1, [Define on *nto-qnx systems]) + AC_DEFINE(MISSING_HOWMANY, 1, [Define on *nto-qnx systems]) + AC_DEFINE(MISSING_FD_MASK, 1, [Define on *nto-qnx systems]) ;; *-*-ultrix*) - AC_DEFINE(BROKEN_GETGROUPS, [], [getgroups(0,NULL) will return -1]) - AC_DEFINE(BROKEN_MMAP, [], [Ultrix mmap can't map files]) - AC_DEFINE(NEED_SETPRGP, [], [Need setpgrp to acquire controlling tty]) + AC_DEFINE(BROKEN_GETGROUPS, 1, [getgroups(0,NULL) will return -1]) + AC_DEFINE(BROKEN_MMAP, 1, [Ultrix mmap can't map files]) + AC_DEFINE(NEED_SETPRGP) AC_DEFINE(HAVE_SYS_SYSLOG_H, 1, [Force use of sys/syslog.h on Ultrix]) ;; *-*-lynxos) CFLAGS="$CFLAGS -D__NO_INCLUDE_WARN__" - AC_DEFINE(MISSING_HOWMANY) + AC_DEFINE(MISSING_HOWMANY) AC_DEFINE(BROKEN_SETVBUF, 1, [LynxOS has broken setvbuf() implementation]) ;; esac @@ -627,7 +654,7 @@ AC_ARG_WITH(Werror, [ if test -n "$withval" && test "x$withval" != "xno"; then werror_flags="-Werror" - if "x${withval}" != "xyes"; then + if test "x${withval}" != "xyes"; then werror_flags="$withval" fi fi @@ -666,6 +693,7 @@ AC_CHECK_HEADERS( \ login_cap.h \ maillock.h \ ndir.h \ + net/if.h \ netdb.h \ netgroup.h \ netinet/in_systm.h \ @@ -728,8 +756,8 @@ AC_CHECK_FUNCS(dirname, [AC_CHECK_HEADERS(libgen.h)] ,[ ac_cv_have_broken_dirname, [ save_LIBS="$LIBS" LIBS="$LIBS -lgen" - AC_TRY_RUN( - [ + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ #include #include @@ -744,9 +772,10 @@ int main(int argc, char **argv) { exit(0); } } - ], + ]])], + [ ac_cv_have_broken_dirname="no" ], + [ ac_cv_have_broken_dirname="yes" ], [ ac_cv_have_broken_dirname="no" ], - [ ac_cv_have_broken_dirname="yes" ] ) LIBS="$save_LIBS" ]) @@ -760,7 +789,8 @@ int main(int argc, char **argv) { AC_CHECK_FUNC(getspnam, , AC_CHECK_LIB(gen, getspnam, LIBS="$LIBS -lgen")) -AC_SEARCH_LIBS(basename, gen, AC_DEFINE(HAVE_BASENAME)) +AC_SEARCH_LIBS(basename, gen, AC_DEFINE(HAVE_BASENAME, 1, + [Define if you have the basename function.])) dnl zlib is required AC_ARG_WITH(zlib, @@ -864,14 +894,15 @@ dnl UnixWare 2.x AC_CHECK_FUNC(strcasecmp, [], [ AC_CHECK_LIB(resolv, strcasecmp, LIBS="$LIBS -lresolv") ] ) -AC_CHECK_FUNC(utimes, +AC_CHECK_FUNCS(utimes, [], [ AC_CHECK_LIB(c89, utimes, [AC_DEFINE(HAVE_UTIMES) LIBS="$LIBS -lc89"]) ] ) dnl Checks for libutil functions AC_CHECK_HEADERS(libutil.h) -AC_SEARCH_LIBS(login, util bsd, [AC_DEFINE(HAVE_LOGIN)]) +AC_SEARCH_LIBS(login, util bsd, [AC_DEFINE(HAVE_LOGIN, 1, + [Define if your libraries define login()])]) AC_CHECK_FUNCS(logout updwtmp logwtmp) AC_FUNC_STRFTIME @@ -886,7 +917,9 @@ AC_EGREP_CPP(FOUNDIT, #endif ], [ - AC_DEFINE(GLOB_HAS_ALTDIRFUNC) + AC_DEFINE(GLOB_HAS_ALTDIRFUNC, 1, + [Define if your system glob() function has + the GLOB_ALTDIRFUNC extension]) AC_MSG_RESULT(yes) ], [ @@ -902,7 +935,9 @@ AC_EGREP_CPP(FOUNDIT, int main(void){glob_t g; g.gl_matchc = 1;} ], [ - AC_DEFINE(GLOB_HAS_GL_MATCHC) + AC_DEFINE(GLOB_HAS_GL_MATCHC, 1, + [Define if your system glob() function has + gl_matchc options in glob_t]) AC_MSG_RESULT(yes) ], [ @@ -920,7 +955,9 @@ 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) + AC_DEFINE(BROKEN_ONE_BYTE_DIRENT_D_NAME, 1, + [Define if your struct dirent expects you to + allocate extra space for d_name]) ], [ AC_MSG_WARN([cross compiling: assuming BROKEN_ONE_BYTE_DIRENT_D_NAME]) @@ -950,7 +987,7 @@ AC_ARG_WITH(mechglue, fi AC_DEFINE(GSSAPI) - AC_DEFINE(MECHGLUE) + AC_DEFINE(MECHGLUE, 1, [Define this if you're building with GSSAPI MechGlue.]) GSSAPI="mechglue" ] @@ -998,7 +1035,7 @@ AC_ARG_WITH(globus-flavor, if test "x$gsi_path" != "xno" ; then # Globus GSSAPI configuration AC_MSG_CHECKING(for Globus GSI) - AC_DEFINE(GSI) + AC_DEFINE(GSI, 1, [Define if you want GSI/Globus authentication support.]) if test "$GSSAPI" -a "$GSSAPI" != "mechglue"; then AC_MSG_ERROR([Previously configured GSSAPI library conflicts with Globus GSI.]) @@ -1076,7 +1113,7 @@ AC_SUBST(INSTALL_GSISSH) AC_MSG_CHECKING([for /proc/pid/fd directory]) if test -d "/proc/$$/fd" ; then - AC_DEFINE(HAVE_PROC_PID) + AC_DEFINE(HAVE_PROC_PID, 1, [Define if you have /proc/$pid/fd]) AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) @@ -1094,17 +1131,17 @@ AC_ARG_WITH(skey, LDFLAGS="$LDFLAGS -L${withval}/lib" fi - AC_DEFINE(SKEY) + AC_DEFINE(SKEY, 1, [Define if you want S/Key support]) LIBS="-lskey $LIBS" SKEY_MSG="yes" AC_MSG_CHECKING([for s/key support]) - AC_TRY_RUN( - [ + AC_LINK_IFELSE( + [AC_LANG_SOURCE([[ #include #include int main() { char *ff = skey_keyinfo(""); ff=""; exit(0); } - ], + ]])], [AC_MSG_RESULT(yes)], [ AC_MSG_RESULT(no) @@ -1116,7 +1153,9 @@ int main() { char *ff = skey_keyinfo(""); ff=""; exit(0); } #include ], [(void)skeychallenge(NULL,"name","",0);], [AC_MSG_RESULT(yes) - AC_DEFINE(SKEYCHALLENGE_4ARG)], + AC_DEFINE(SKEYCHALLENGE_4ARG, 1, + [Define if your skeychallenge() + function takes 4 arguments (NetBSD)])], [AC_MSG_RESULT(no)] ) fi @@ -1167,7 +1206,9 @@ AC_ARG_WITH(tcp-wrappers, [hosts_access(0);], [ AC_MSG_RESULT(yes) - AC_DEFINE(LIBWRAP) + AC_DEFINE(LIBWRAP, 1, + [Define if you want + TCP Wrappers support]) AC_SUBST(LIBWRAP) TCPW_MSG="yes" ], @@ -1186,11 +1227,15 @@ AC_ARG_WITH(libedit, [ --with-libedit[[=PATH]] Enable libedit support for sftp], [ if test "x$withval" != "xno" ; then if test "x$withval" != "xyes"; then - CPPFLAGS="$CPPFLAGS -I$withval/include" - LDFLAGS="$LDFLAGS -L$withval/lib" + CPPFLAGS="$CPPFLAGS -I${withval}/include" + if test -n "${need_dash_r}"; then + LDFLAGS="-L${withval}/lib -R${withval}/lib ${LDFLAGS}" + else + LDFLAGS="-L${withval}/lib ${LDFLAGS}" + fi fi AC_CHECK_LIB(edit, el_init, - [ AC_DEFINE(USE_LIBEDIT, [], [Use libedit for sftp]) + [ AC_DEFINE(USE_LIBEDIT, 1, [Use libedit for sftp]) LIBEDIT="-ledit -lcurses" LIBEDIT_MSG="yes" AC_SUBST(LIBEDIT) @@ -1234,12 +1279,12 @@ AC_ARG_WITH(audit, [AC_MSG_ERROR(BSM enabled and required function not found)]) # These are optional AC_CHECK_FUNCS(getaudit_addr) - AC_DEFINE(USE_BSM_AUDIT, [], [Use BSM audit module]) + AC_DEFINE(USE_BSM_AUDIT, 1, [Use BSM audit module]) ;; debug) AUDIT_MODULE=debug AC_MSG_RESULT(debug) - AC_DEFINE(SSH_AUDIT_EVENTS, [], Use audit debugging module) + AC_DEFINE(SSH_AUDIT_EVENTS, 1, Use audit debugging module) ;; no) AC_MSG_RESULT(no) @@ -1253,6 +1298,7 @@ AC_ARG_WITH(audit, dnl Checks for library functions. Please keep in alphabetical order AC_CHECK_FUNCS( \ arc4random \ + asprintf \ b64_ntop \ __b64_ntop \ b64_pton \ @@ -1328,7 +1374,7 @@ AC_CHECK_FUNCS( \ truncate \ unsetenv \ updwtmpx \ - utimes \ + vasprintf \ vhangup \ vsnprintf \ waitpid \ @@ -1349,7 +1395,8 @@ str = gai_strerror(0);],[ AC_DEFINE(HAVE_CONST_GAI_STRERROR_PROTO, 1, [Define if gai_strerror() returns const char *])])]) -AC_SEARCH_LIBS(nanosleep, rt posix4, AC_DEFINE(HAVE_NANOSLEEP)) +AC_SEARCH_LIBS(nanosleep, rt posix4, AC_DEFINE(HAVE_NANOSLEEP, 1, + [Some systems put nanosleep outside of libc])) dnl Make sure prototypes are defined for these before using them. AC_CHECK_DECL(getrusage, [AC_CHECK_FUNCS(getrusage)]) @@ -1381,7 +1428,8 @@ AC_CHECK_FUNCS(setresuid, [ int main(){errno=0; setresuid(0,0,0); if (errno==ENOSYS) exit(1); else exit(0);} ]])], [AC_MSG_RESULT(yes)], - [AC_DEFINE(BROKEN_SETRESUID) + [AC_DEFINE(BROKEN_SETRESUID, 1, + [Define if your setresuid() is broken]) AC_MSG_RESULT(not implemented)], [AC_MSG_WARN([cross compiling: not checking setresuid])] ) @@ -1397,7 +1445,8 @@ AC_CHECK_FUNCS(setresgid, [ int main(){errno=0; setresgid(0,0,0); if (errno==ENOSYS) exit(1); else exit(0);} ]])], [AC_MSG_RESULT(yes)], - [AC_DEFINE(BROKEN_SETRESGID) + [AC_DEFINE(BROKEN_SETRESGID, 1, + [Define if your setresgid() is broken]) AC_MSG_RESULT(not implemented)], [AC_MSG_WARN([cross compiling: not checking setresuid])] ) @@ -1413,13 +1462,16 @@ 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_DEFINE(HAVE_DAEMON, 1, [Define if your libraries define daemon()])], + [AC_CHECK_LIB(bsd, daemon, + [LIBS="$LIBS -lbsd"; AC_DEFINE(HAVE_DAEMON)])] ) AC_CHECK_FUNC(getpagesize, - [AC_DEFINE(HAVE_GETPAGESIZE)], - [AC_CHECK_LIB(ucb, getpagesize, [LIBS="$LIBS -lucb"; AC_DEFINE(HAVE_GETPAGESIZE)])] + [AC_DEFINE(HAVE_GETPAGESIZE, 1, + [Define if your libraries define getpagesize()])], + [AC_CHECK_LIB(ucb, getpagesize, + [LIBS="$LIBS -lucb"; AC_DEFINE(HAVE_GETPAGESIZE)])] ) # Check for broken snprintf @@ -1433,13 +1485,62 @@ 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_DEFINE(BROKEN_SNPRINTF, 1, + [Define if your snprintf is busted]) AC_MSG_WARN([****** Your snprintf() function is broken, complain to your vendor]) ], [ AC_MSG_WARN([cross compiling: Assuming working snprintf()]) ] ) fi +# If we don't have a working asprintf, then we strongly depend on vsnprintf +# returning the right thing on overflow: the number of characters it tried to +# create (as per SUSv3) +if test "x$ac_cv_func_asprintf" != "xyes" && \ + test "x$ac_cv_func_vsnprintf" = "xyes" ; then + AC_MSG_CHECKING([whether vsnprintf returns correct values on overflow]) + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +#include + +int x_snprintf(char *str,size_t count,const char *fmt,...) +{ + size_t ret; va_list ap; + va_start(ap, fmt); ret = vsnprintf(str, count, fmt, ap); va_end(ap); + return ret; +} +int main(void) +{ + char x[1]; + exit(x_snprintf(x, 1, "%s %d", "hello", 12345) == 11 ? 0 : 1); +} ]])], + [AC_MSG_RESULT(yes)], + [ + AC_MSG_RESULT(no) + AC_DEFINE(BROKEN_SNPRINTF, 1, + [Define if your snprintf is busted]) + AC_MSG_WARN([****** Your vsnprintf() function is broken, complain to your vendor]) + ], + [ AC_MSG_WARN([cross compiling: Assuming working vsnprintf()]) ] + ) +fi + +# On systems where [v]snprintf is broken, but is declared in stdio, +# check that the fmt argument is const char * or just char *. +# This is only useful for when BROKEN_SNPRINTF +AC_MSG_CHECKING([whether snprintf can declare const char *fmt]) +AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#include + int snprintf(char *a, size_t b, const char *c, ...) { return 0; } + int main(void) { snprintf(0, 0, 0); } + ]])], + [AC_MSG_RESULT(yes) + AC_DEFINE(SNPRINTF_CONST, [const], + [Define as const if snprintf() can declare const char *fmt])], + [AC_MSG_RESULT(no) + AC_DEFINE(SNPRINTF_CONST, [/* not const */])]) + # Check for missing getpeereid (or equiv) support NO_PEERCHECK="" if test "x$ac_cv_func_getpeereid" != "xyes" ; then @@ -1449,7 +1550,7 @@ if test "x$ac_cv_func_getpeereid" != "xyes" ; then #include ], [int i = SO_PEERCRED;], [ AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_SO_PEERCRED, [], [Have PEERCRED socket option]) + AC_DEFINE(HAVE_SO_PEERCRED, 1, [Have PEERCRED socket option]) ], [AC_MSG_RESULT(no) NO_PEERCHECK=1] @@ -1459,21 +1560,21 @@ 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( - [ +AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ #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_DEFINE(HAVE_STRICT_MKSTEMP, 1, [Silly mkstemp()]) ], [ AC_MSG_RESULT(yes) @@ -1485,8 +1586,8 @@ 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( - [ + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ #include #include #include @@ -1518,13 +1619,16 @@ main() exit(0); /* Did not acquire ctty: OK */ } } - ], + ]])], [ AC_MSG_RESULT(yes) ], [ AC_MSG_RESULT(no) AC_DEFINE(SSHD_ACQUIRES_CTTY) + ], + [ + AC_MSG_RESULT(cross-compiling, assuming yes) ] ) fi @@ -1532,8 +1636,8 @@ fi if test "x$ac_cv_func_getaddrinfo" = "xyes" && \ test "x$check_for_hpux_broken_getaddrinfo" = "x1"; then AC_MSG_CHECKING(if getaddrinfo seems to work) - AC_TRY_RUN( - [ + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ #include #include #include @@ -1587,13 +1691,16 @@ main(void) } exit(0); } - ], + ]])], [ AC_MSG_RESULT(yes) ], [ AC_MSG_RESULT(no) AC_DEFINE(BROKEN_GETADDRINFO) + ], + [ + AC_MSG_RESULT(cross-compiling, assuming yes) ] ) fi @@ -1601,8 +1708,8 @@ fi if test "x$ac_cv_func_getaddrinfo" = "xyes" && \ test "x$check_for_aix_broken_getaddrinfo" = "x1"; then AC_MSG_CHECKING(if getaddrinfo seems to work) - AC_TRY_RUN( - [ + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ #include #include #include @@ -1644,15 +1751,18 @@ main(void) } exit(0); } - ], + ]])], [ AC_MSG_RESULT(yes) - AC_DEFINE(AIX_GETNAMEINFO_HACK, [], -[Define if you have a getaddrinfo that fails for the all-zeros IPv6 address]) + AC_DEFINE(AIX_GETNAMEINFO_HACK, 1, + [Define if you have a getaddrinfo that fails + for the all-zeros IPv6 address]) ], [ AC_MSG_RESULT(no) AC_DEFINE(BROKEN_GETADDRINFO) + ], + AC_MSG_RESULT(cross-compiling, assuming no) ] ) fi @@ -1695,7 +1805,8 @@ AC_ARG_WITH(pam, PAM_MSG="yes" - AC_DEFINE(USE_PAM) + AC_DEFINE(USE_PAM, 1, + [Define if you want to enable PAM support]) if test $ac_cv_lib_dl_dlopen = yes; then LIBPAM="-lpam -ldl" else @@ -1722,7 +1833,9 @@ if test "x$PAM_MSG" = "xyes" ; then [(void)pam_strerror((pam_handle_t *)NULL, -1);], [AC_MSG_RESULT(no)], [ - AC_DEFINE(HAVE_OLD_PAM) + AC_DEFINE(HAVE_OLD_PAM, 1, + [Define if you have an old version of PAM + which takes only one argument to pam_strerror]) AC_MSG_RESULT(yes) PAM_MSG="yes (old library)" ] @@ -1764,7 +1877,9 @@ AC_ARG_WITH(ssl-dir, if test -z "$GSI_LIBS" ; then LIBS="-lcrypto $LIBS" fi -AC_TRY_LINK_FUNC(RAND_add, AC_DEFINE(HAVE_OPENSSL), +AC_TRY_LINK_FUNC(RAND_add, AC_DEFINE(HAVE_OPENSSL, 1, + [Define if your ssl headers are included + with #include ]), [ dnl Check default openssl install dir if test -n "${need_dash_r}"; then @@ -1874,6 +1989,24 @@ Also see contrib/findssl.sh for help identifying header/library mismatches.]) ] ) +# Check for OpenSSL without EVP_aes_{192,256}_cbc +AC_MSG_CHECKING([whether OpenSSL has crippled AES support]) +AC_COMPILE_IFELSE( + [AC_LANG_SOURCE([[ +#include +#include +int main(void) { exit(EVP_aes_192_cbc() == NULL || EVP_aes_256_cbc() == NULL)} + ]])], + [ + AC_MSG_RESULT(no) + ], + [ + AC_MSG_RESULT(yes) + AC_DEFINE(OPENSSL_LOBOTOMISED_AES, 1, + [libcrypto is missing AES 192 and 256 bit functions]) + ] +) + # 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 @@ -1938,7 +2071,8 @@ AC_ARG_WITH(rand-helper, # Which randomness source do we use? if test ! -z "$OPENSSL_SEEDS_ITSELF" && test -z "$USE_RAND_HELPER" ; then # OpenSSL only - AC_DEFINE(OPENSSL_PRNG_ONLY) + AC_DEFINE(OPENSSL_PRNG_ONLY, 1, + [Define if you want OpenSSL's internally seeded PRNG only]) RAND_MSG="OpenSSL internal ONLY" INSTALL_SSH_RAND_HELPER="" elif test ! -z "$USE_RAND_HELPER" ; then @@ -1966,7 +2100,8 @@ AC_ARG_WITH(prngd-port, esac if test ! -z "$withval" ; then PRNGD_PORT="$withval" - AC_DEFINE_UNQUOTED(PRNGD_PORT, $PRNGD_PORT) + AC_DEFINE_UNQUOTED(PRNGD_PORT, $PRNGD_PORT, + [Port number of PRNGD/EGD random number socket]) fi ] ) @@ -1997,7 +2132,8 @@ AC_ARG_WITH(prngd-socket, AC_MSG_WARN(Entropy socket is not readable) fi PRNGD_SOCKET="$withval" - AC_DEFINE_UNQUOTED(PRNGD_SOCKET, "$PRNGD_SOCKET") + AC_DEFINE_UNQUOTED(PRNGD_SOCKET, "$PRNGD_SOCKET", + [Location of PRNGD/EGD random number socket]) fi ], [ @@ -2032,7 +2168,8 @@ AC_ARG_WITH(entropy-timeout, fi ] ) -AC_DEFINE_UNQUOTED(ENTROPY_TIMEOUT_MSEC, $entropy_timeout) +AC_DEFINE_UNQUOTED(ENTROPY_TIMEOUT_MSEC, $entropy_timeout, + [Builtin PRNG command timeout]) SSH_PRIVSEP_USER=sshd AC_ARG_WITH(privsep-user, @@ -2044,7 +2181,8 @@ AC_ARG_WITH(privsep-user, fi ] ) -AC_DEFINE_UNQUOTED(SSH_PRIVSEP_USER, "$SSH_PRIVSEP_USER") +AC_DEFINE_UNQUOTED(SSH_PRIVSEP_USER, "$SSH_PRIVSEP_USER", + [non-privileged user for privilege separation]) AC_SUBST(SSH_PRIVSEP_USER) # We do this little dance with the search path to insure @@ -2102,7 +2240,10 @@ if test ! -z "$SONY" ; then LIBS="$LIBS -liberty"; fi -# Checks for data types +# Check for long long datatypes +AC_CHECK_TYPES([long long, unsigned long long, long double]) + +# Check datatype sizes AC_CHECK_SIZEOF(char, 1) AC_CHECK_SIZEOF(short int, 2) AC_CHECK_SIZEOF(int, 4) @@ -2114,6 +2255,84 @@ if test "x$ac_cv_sizeof_long_long_int" = "x4" ; then ac_cv_sizeof_long_long_int=0 fi +# compute LLONG_MIN and LLONG_MAX if we don't know them. +if test -z "$have_llong_max"; then + AC_MSG_CHECKING([for max value of long long]) + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ +#include +/* Why is this so damn hard? */ +#ifdef __GNUC__ +# undef __GNUC__ +#endif +#define __USE_ISOC99 +#include +#define DATA "conftest.llminmax" +int main(void) { + FILE *f; + long long i, llmin, llmax = 0; + + if((f = fopen(DATA,"w")) == NULL) + exit(1); + +#if defined(LLONG_MIN) && defined(LLONG_MAX) + fprintf(stderr, "Using system header for LLONG_MIN and LLONG_MAX\n"); + llmin = LLONG_MIN; + llmax = LLONG_MAX; +#else + fprintf(stderr, "Calculating LLONG_MIN and LLONG_MAX\n"); + /* This will work on one's complement and two's complement */ + for (i = 1; i > llmax; i <<= 1, i++) + llmax = i; + llmin = llmax + 1LL; /* wrap */ +#endif + + /* Sanity check */ + if (llmin + 1 < llmin || llmin - 1 < llmin || llmax + 1 > llmax + || llmax - 1 > llmax) { + fprintf(f, "unknown unknown\n"); + exit(2); + } + + if (fprintf(f ,"%lld %lld", llmin, llmax) < 0) + exit(3); + + exit(0); +} + ]])], + [ + llong_min=`$AWK '{print $1}' conftest.llminmax` + llong_max=`$AWK '{print $2}' conftest.llminmax` + + # snprintf on some Tru64s doesn't understand "%lld" + case "$host" in + alpha-dec-osf*) + if test "x$ac_cv_sizeof_long_long_int" = "x8" && + test "x$llong_max" = "xld"; then + llong_min="-9223372036854775808" + llong_max="9223372036854775807" + fi + ;; + esac + + AC_MSG_RESULT($llong_max) + AC_DEFINE_UNQUOTED(LLONG_MAX, [${llong_max}LL], + [max value of long long calculated by configure]) + AC_MSG_CHECKING([for min value of long long]) + AC_MSG_RESULT($llong_min) + AC_DEFINE_UNQUOTED(LLONG_MIN, [${llong_min}LL], + [min value of long long calculated by configure]) + ], + [ + AC_MSG_RESULT(not found) + ], + [ + AC_MSG_WARN([cross compiling: not checking]) + ] + ) +fi + + # More checks for data types AC_CACHE_CHECK([for u_int type], ac_cv_have_u_int, [ AC_TRY_COMPILE( @@ -2124,7 +2343,7 @@ AC_CACHE_CHECK([for u_int type], ac_cv_have_u_int, [ ) ]) if test "x$ac_cv_have_u_int" = "xyes" ; then - AC_DEFINE(HAVE_U_INT) + AC_DEFINE(HAVE_U_INT, 1, [define if you have u_int data type]) have_u_int=1 fi @@ -2137,7 +2356,7 @@ AC_CACHE_CHECK([for intXX_t types], ac_cv_have_intxx_t, [ ) ]) if test "x$ac_cv_have_intxx_t" = "xyes" ; then - AC_DEFINE(HAVE_INTXX_T) + AC_DEFINE(HAVE_INTXX_T, 1, [define if you have intxx_t data type]) have_intxx_t=1 fi @@ -2174,7 +2393,7 @@ AC_CACHE_CHECK([for int64_t type], ac_cv_have_int64_t, [ ) ]) if test "x$ac_cv_have_int64_t" = "xyes" ; then - AC_DEFINE(HAVE_INT64_T) + AC_DEFINE(HAVE_INT64_T, 1, [define if you have int64_t data type]) fi AC_CACHE_CHECK([for u_intXX_t types], ac_cv_have_u_intxx_t, [ @@ -2186,7 +2405,7 @@ AC_CACHE_CHECK([for u_intXX_t types], ac_cv_have_u_intxx_t, [ ) ]) if test "x$ac_cv_have_u_intxx_t" = "xyes" ; then - AC_DEFINE(HAVE_U_INTXX_T) + AC_DEFINE(HAVE_U_INTXX_T, 1, [define if you have u_intxx_t data type]) have_u_intxx_t=1 fi @@ -2212,7 +2431,7 @@ AC_CACHE_CHECK([for u_int64_t types], ac_cv_have_u_int64_t, [ ) ]) if test "x$ac_cv_have_u_int64_t" = "xyes" ; then - AC_DEFINE(HAVE_U_INT64_T) + AC_DEFINE(HAVE_U_INT64_T, 1, [define if you have u_int64_t data type]) have_u_int64_t=1 fi @@ -2241,7 +2460,8 @@ if test -z "$have_u_intxx_t" ; then ) ]) if test "x$ac_cv_have_uintxx_t" = "xyes" ; then - AC_DEFINE(HAVE_UINTXX_T) + AC_DEFINE(HAVE_UINTXX_T, 1, + [define if you have uintxx_t data type]) fi fi @@ -2292,7 +2512,7 @@ AC_CACHE_CHECK([for u_char], ac_cv_have_u_char, [ ) ]) if test "x$ac_cv_have_u_char" = "xyes" ; then - AC_DEFINE(HAVE_U_CHAR) + AC_DEFINE(HAVE_U_CHAR, 1, [define if you have u_char data type]) fi TYPE_SOCKLEN_T @@ -2314,7 +2534,7 @@ AC_CACHE_CHECK([for size_t], ac_cv_have_size_t, [ ) ]) if test "x$ac_cv_have_size_t" = "xyes" ; then - AC_DEFINE(HAVE_SIZE_T) + AC_DEFINE(HAVE_SIZE_T, 1, [define if you have size_t data type]) fi AC_CACHE_CHECK([for ssize_t], ac_cv_have_ssize_t, [ @@ -2328,7 +2548,7 @@ AC_CACHE_CHECK([for ssize_t], ac_cv_have_ssize_t, [ ) ]) if test "x$ac_cv_have_ssize_t" = "xyes" ; then - AC_DEFINE(HAVE_SSIZE_T) + AC_DEFINE(HAVE_SSIZE_T, 1, [define if you have ssize_t data type]) fi AC_CACHE_CHECK([for clock_t], ac_cv_have_clock_t, [ @@ -2342,7 +2562,7 @@ AC_CACHE_CHECK([for clock_t], ac_cv_have_clock_t, [ ) ]) if test "x$ac_cv_have_clock_t" = "xyes" ; then - AC_DEFINE(HAVE_CLOCK_T) + AC_DEFINE(HAVE_CLOCK_T, 1, [define if you have clock_t data type]) fi AC_CACHE_CHECK([for sa_family_t], ac_cv_have_sa_family_t, [ @@ -2367,7 +2587,8 @@ AC_CACHE_CHECK([for sa_family_t], ac_cv_have_sa_family_t, [ ) ]) if test "x$ac_cv_have_sa_family_t" = "xyes" ; then - AC_DEFINE(HAVE_SA_FAMILY_T) + AC_DEFINE(HAVE_SA_FAMILY_T, 1, + [define if you have sa_family_t data type]) fi AC_CACHE_CHECK([for pid_t], ac_cv_have_pid_t, [ @@ -2381,7 +2602,7 @@ AC_CACHE_CHECK([for pid_t], ac_cv_have_pid_t, [ ) ]) if test "x$ac_cv_have_pid_t" = "xyes" ; then - AC_DEFINE(HAVE_PID_T) + AC_DEFINE(HAVE_PID_T, 1, [define if you have pid_t data type]) fi AC_CACHE_CHECK([for mode_t], ac_cv_have_mode_t, [ @@ -2395,7 +2616,7 @@ AC_CACHE_CHECK([for mode_t], ac_cv_have_mode_t, [ ) ]) if test "x$ac_cv_have_mode_t" = "xyes" ; then - AC_DEFINE(HAVE_MODE_T) + AC_DEFINE(HAVE_MODE_T, 1, [define if you have mode_t data type]) fi @@ -2411,7 +2632,8 @@ AC_CACHE_CHECK([for struct sockaddr_storage], ac_cv_have_struct_sockaddr_storage ) ]) if test "x$ac_cv_have_struct_sockaddr_storage" = "xyes" ; then - AC_DEFINE(HAVE_STRUCT_SOCKADDR_STORAGE) + AC_DEFINE(HAVE_STRUCT_SOCKADDR_STORAGE, 1, + [define if you have struct sockaddr_storage data type]) fi AC_CACHE_CHECK([for struct sockaddr_in6], ac_cv_have_struct_sockaddr_in6, [ @@ -2426,7 +2648,8 @@ AC_CACHE_CHECK([for struct sockaddr_in6], ac_cv_have_struct_sockaddr_in6, [ ) ]) if test "x$ac_cv_have_struct_sockaddr_in6" = "xyes" ; then - AC_DEFINE(HAVE_STRUCT_SOCKADDR_IN6) + AC_DEFINE(HAVE_STRUCT_SOCKADDR_IN6, 1, + [define if you have struct sockaddr_in6 data type]) fi AC_CACHE_CHECK([for struct in6_addr], ac_cv_have_struct_in6_addr, [ @@ -2441,7 +2664,8 @@ AC_CACHE_CHECK([for struct in6_addr], ac_cv_have_struct_in6_addr, [ ) ]) if test "x$ac_cv_have_struct_in6_addr" = "xyes" ; then - AC_DEFINE(HAVE_STRUCT_IN6_ADDR) + AC_DEFINE(HAVE_STRUCT_IN6_ADDR, 1, + [define if you have struct in6_addr data type]) fi AC_CACHE_CHECK([for struct addrinfo], ac_cv_have_struct_addrinfo, [ @@ -2457,7 +2681,8 @@ AC_CACHE_CHECK([for struct addrinfo], ac_cv_have_struct_addrinfo, [ ) ]) if test "x$ac_cv_have_struct_addrinfo" = "xyes" ; then - AC_DEFINE(HAVE_STRUCT_ADDRINFO) + AC_DEFINE(HAVE_STRUCT_ADDRINFO, 1, + [define if you have struct addrinfo data type]) fi AC_CACHE_CHECK([for struct timeval], ac_cv_have_struct_timeval, [ @@ -2469,7 +2694,7 @@ AC_CACHE_CHECK([for struct timeval], ac_cv_have_struct_timeval, [ ) ]) if test "x$ac_cv_have_struct_timeval" = "xyes" ; then - AC_DEFINE(HAVE_STRUCT_TIMEVAL) + AC_DEFINE(HAVE_STRUCT_TIMEVAL, 1, [define if you have struct timeval]) have_struct_timeval=1 fi @@ -2534,6 +2759,17 @@ OSSH_CHECK_HEADER_FOR_FIELD(ut_time, utmpx.h, HAVE_TIME_IN_UTMPX) OSSH_CHECK_HEADER_FOR_FIELD(ut_tv, utmpx.h, HAVE_TV_IN_UTMPX) AC_CHECK_MEMBERS([struct stat.st_blksize]) +AC_CHECK_MEMBER([struct __res_state.retrans], [], [AC_DEFINE(__res_state, state, + [Define if we don't have struct __res_state in resolv.h])], +[ +#include +#if HAVE_SYS_TYPES_H +# include +#endif +#include +#include +#include +]) AC_CACHE_CHECK([for ss_family field in struct sockaddr_storage], ac_cv_have_ss_family_in_struct_ss, [ @@ -2548,7 +2784,7 @@ AC_CACHE_CHECK([for ss_family field in struct sockaddr_storage], ) ]) if test "x$ac_cv_have_ss_family_in_struct_ss" = "xyes" ; then - AC_DEFINE(HAVE_SS_FAMILY_IN_SS) + AC_DEFINE(HAVE_SS_FAMILY_IN_SS, 1, [Fields in struct sockaddr_storage]) fi AC_CACHE_CHECK([for __ss_family field in struct sockaddr_storage], @@ -2564,7 +2800,8 @@ AC_CACHE_CHECK([for __ss_family field in struct sockaddr_storage], ) ]) if test "x$ac_cv_have___ss_family_in_struct_ss" = "xyes" ; then - AC_DEFINE(HAVE___SS_FAMILY_IN_SS) + AC_DEFINE(HAVE___SS_FAMILY_IN_SS, 1, + [Fields in struct sockaddr_storage]) fi AC_CACHE_CHECK([for pw_class field in struct passwd], @@ -2579,7 +2816,8 @@ AC_CACHE_CHECK([for pw_class field in struct passwd], ) ]) if test "x$ac_cv_have_pw_class_in_struct_passwd" = "xyes" ; then - AC_DEFINE(HAVE_PW_CLASS_IN_PASSWD) + AC_DEFINE(HAVE_PW_CLASS_IN_PASSWD, 1, + [Define if your password has a pw_class field]) fi AC_CACHE_CHECK([for pw_expire field in struct passwd], @@ -2594,7 +2832,8 @@ AC_CACHE_CHECK([for pw_expire field in struct passwd], ) ]) if test "x$ac_cv_have_pw_expire_in_struct_passwd" = "xyes" ; then - AC_DEFINE(HAVE_PW_EXPIRE_IN_PASSWD) + AC_DEFINE(HAVE_PW_EXPIRE_IN_PASSWD, 1, + [Define if your password has a pw_expire field]) fi AC_CACHE_CHECK([for pw_change field in struct passwd], @@ -2609,7 +2848,8 @@ AC_CACHE_CHECK([for pw_change field in struct passwd], ) ]) if test "x$ac_cv_have_pw_change_in_struct_passwd" = "xyes" ; then - AC_DEFINE(HAVE_PW_CHANGE_IN_PASSWD) + AC_DEFINE(HAVE_PW_CHANGE_IN_PASSWD, 1, + [Define if your password has a pw_change field]) fi dnl make sure we're using the real structure members and not defines @@ -2635,7 +2875,9 @@ exit(0); ) ]) if test "x$ac_cv_have_accrights_in_msghdr" = "xyes" ; then - AC_DEFINE(HAVE_ACCRIGHTS_IN_MSGHDR) + AC_DEFINE(HAVE_ACCRIGHTS_IN_MSGHDR, 1, + [Define if your system uses access rights style + file descriptor passing]) fi AC_CACHE_CHECK([for msg_control field in struct msghdr], @@ -2660,7 +2902,9 @@ exit(0); ) ]) if test "x$ac_cv_have_control_in_msghdr" = "xyes" ; then - AC_DEFINE(HAVE_CONTROL_IN_MSGHDR) + AC_DEFINE(HAVE_CONTROL_IN_MSGHDR, 1, + [Define if your system uses ancillary data style + file descriptor passing]) fi AC_CACHE_CHECK([if libc defines __progname], ac_cv_libc_defines___progname, [ @@ -2671,7 +2915,7 @@ AC_CACHE_CHECK([if libc defines __progname], ac_cv_libc_defines___progname, [ ) ]) if test "x$ac_cv_libc_defines___progname" = "xyes" ; then - AC_DEFINE(HAVE___PROGNAME) + AC_DEFINE(HAVE___PROGNAME, 1, [Define if libc defines __progname]) fi AC_CACHE_CHECK([whether $CC implements __FUNCTION__], ac_cv_cc_implements___FUNCTION__, [ @@ -2684,7 +2928,8 @@ AC_CACHE_CHECK([whether $CC implements __FUNCTION__], ac_cv_cc_implements___FUNC ) ]) if test "x$ac_cv_cc_implements___FUNCTION__" = "xyes" ; then - AC_DEFINE(HAVE___FUNCTION__) + AC_DEFINE(HAVE___FUNCTION__, 1, + [Define if compiler implements __FUNCTION__]) fi AC_CACHE_CHECK([whether $CC implements __func__], ac_cv_cc_implements___func__, [ @@ -2697,7 +2942,33 @@ AC_CACHE_CHECK([whether $CC implements __func__], ac_cv_cc_implements___func__, ) ]) if test "x$ac_cv_cc_implements___func__" = "xyes" ; then - AC_DEFINE(HAVE___func__) + AC_DEFINE(HAVE___func__, 1, [Define if compiler implements __func__]) +fi + +AC_CACHE_CHECK([whether va_copy exists], ac_cv_have_va_copy, [ + AC_TRY_LINK( + [#include + va_list x,y;], + [va_copy(x,y);], + [ ac_cv_have_va_copy="yes" ], + [ ac_cv_have_va_copy="no" ] + ) +]) +if test "x$ac_cv_have_va_copy" = "xyes" ; then + AC_DEFINE(HAVE_VA_COPY, 1, [Define if va_copy exists]) +fi + +AC_CACHE_CHECK([whether __va_copy exists], ac_cv_have___va_copy, [ + AC_TRY_LINK( + [#include + va_list x,y;], + [__va_copy(x,y);], + [ ac_cv_have___va_copy="yes" ], + [ ac_cv_have___va_copy="no" ] + ) +]) +if test "x$ac_cv_have___va_copy" = "xyes" ; then + AC_DEFINE(HAVE___VA_COPY, 1, [Define if __va_copy exists]) fi AC_CACHE_CHECK([whether getopt has optreset support], @@ -2712,7 +2983,8 @@ AC_CACHE_CHECK([whether getopt has optreset support], ) ]) if test "x$ac_cv_have_getopt_optreset" = "xyes" ; then - AC_DEFINE(HAVE_GETOPT_OPTRESET) + AC_DEFINE(HAVE_GETOPT_OPTRESET, 1, + [Define if your getopt(3) defines and uses optreset]) fi AC_CACHE_CHECK([if libc defines sys_errlist], ac_cv_libc_defines_sys_errlist, [ @@ -2723,7 +2995,8 @@ AC_CACHE_CHECK([if libc defines sys_errlist], ac_cv_libc_defines_sys_errlist, [ ) ]) if test "x$ac_cv_libc_defines_sys_errlist" = "xyes" ; then - AC_DEFINE(HAVE_SYS_ERRLIST) + AC_DEFINE(HAVE_SYS_ERRLIST, 1, + [Define if your system defines sys_errlist[]]) fi @@ -2735,7 +3008,7 @@ AC_CACHE_CHECK([if libc defines sys_nerr], ac_cv_libc_defines_sys_nerr, [ ) ]) if test "x$ac_cv_libc_defines_sys_nerr" = "xyes" ; then - AC_DEFINE(HAVE_SYS_NERR) + AC_DEFINE(HAVE_SYS_NERR, 1, [Define if your system defines sys_nerr]) fi SCARD_MSG="no" @@ -2762,8 +3035,11 @@ AC_ARG_WITH(sectok, 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) + AC_DEFINE(SMARTCARD, 1, + [Define if you want smartcard support]) + AC_DEFINE(USE_SECTOK, 1, + [Define if you want smartcard support + using sectok]) SCARD_MSG="yes, using sectok" fi ] @@ -2772,7 +3048,7 @@ AC_ARG_WITH(sectok, # Check whether user wants OpenSC support OPENSC_CONFIG="no" AC_ARG_WITH(opensc, - [--with-opensc[[=PFX]] Enable smartcard support using OpenSC (optionally in PATH)], + [ --with-opensc[[=PFX]] Enable smartcard support using OpenSC (optionally in PATH)], [ if test "x$withval" != "xno" ; then if test "x$withval" != "xyes" ; then @@ -2786,7 +3062,9 @@ AC_ARG_WITH(opensc, CPPFLAGS="$CPPFLAGS $LIBOPENSC_CFLAGS" LDFLAGS="$LDFLAGS $LIBOPENSC_LIBS" AC_DEFINE(SMARTCARD) - AC_DEFINE(USE_OPENSC) + AC_DEFINE(USE_OPENSC, 1, + [Define if you want smartcard support + using OpenSC]) SCARD_MSG="yes, using OpenSC" fi fi @@ -2795,7 +3073,8 @@ AC_ARG_WITH(opensc, # Check libraries needed by DNS fingerprint support AC_SEARCH_LIBS(getrrsetbyname, resolv, - [AC_DEFINE(HAVE_GETRRSETBYNAME)], + [AC_DEFINE(HAVE_GETRRSETBYNAME, 1, + [Define if getrrsetbyname() exists])], [ # Needed by our getrrsetbyname() AC_SEARCH_LIBS(res_query, resolv) @@ -2824,7 +3103,8 @@ int main() [#include #include ]) AC_CHECK_MEMBER(HEADER.ad, - [AC_DEFINE(HAVE_HEADER_AD)],, + [AC_DEFINE(HAVE_HEADER_AD, 1, + [Define if HEADER.ad exists in arpa/nameser.h])],, [#include ]) ]) @@ -2839,7 +3119,7 @@ AC_ARG_WITH(kerberos5, KRB5ROOT=${withval} fi - AC_DEFINE(KRB5) + AC_DEFINE(KRB5, 1, [Define if you want Kerberos 5 support]) KRB5_MSG="yes" AC_MSG_CHECKING(for krb5-config) @@ -2850,7 +3130,9 @@ AC_ARG_WITH(kerberos5, AC_MSG_CHECKING(for gssapi support) if $KRB5CONF | grep gssapi >/dev/null ; then AC_MSG_RESULT(yes) - AC_DEFINE(GSSAPI) + AC_DEFINE(GSSAPI, 1, + [Define this if you want GSSAPI + support in the version 2 protocol]) k5confopts=gssapi else AC_MSG_RESULT(no) @@ -2863,7 +3145,9 @@ AC_ARG_WITH(kerberos5, AC_TRY_COMPILE([ #include ], [ char *tmp = heimdal_version; ], [ AC_MSG_RESULT(yes) - AC_DEFINE(HEIMDAL) ], + AC_DEFINE(HEIMDAL, 1, + [Define this if you are using the + Heimdal version of Kerberos V5]) ], AC_MSG_RESULT(no) ) else @@ -2932,14 +3216,15 @@ AC_ARG_WITH(kerberos5, if test ! -z "$blibpath" ; then blibpath="$blibpath:${KRB5ROOT}/lib" fi - fi - AC_CHECK_HEADERS(gssapi.h gssapi/gssapi.h) - AC_CHECK_HEADERS(gssapi_krb5.h gssapi/gssapi_krb5.h) - AC_CHECK_HEADERS(gssapi_generic.h gssapi/gssapi_generic.h) + AC_CHECK_HEADERS(gssapi.h gssapi/gssapi.h) + AC_CHECK_HEADERS(gssapi_krb5.h gssapi/gssapi_krb5.h) + AC_CHECK_HEADERS(gssapi_generic.h gssapi/gssapi_generic.h) - LIBS="$LIBS $K5LIBS" - AC_SEARCH_LIBS(k_hasafs, kafs, AC_DEFINE(USE_AFS)) + LIBS="$LIBS $K5LIBS" + AC_SEARCH_LIBS(k_hasafs, kafs, AC_DEFINE(USE_AFS, 1, + [Define this if you want to use libkafs' AFS support])) + fi ] ) @@ -2951,9 +3236,12 @@ AC_ARG_WITH(afs-krb5, if test "x$withval" != "xno" ; then if test "x$withval" != "xyes" ; then - AC_DEFINE_UNQUOTED(AKLOG_PATH, "$withval") + AC_DEFINE_UNQUOTED(AKLOG_PATH, "$withval", + [Define this if you want to use AFS/Kerberos 5 option, which runs aklog.]) else - AC_DEFINE_UNQUOTED(AKLOG_PATH, "/usr/bin/aklog") + AC_DEFINE_UNQUOTED(AKLOG_PATH, + "/usr/bin/aklog", + [Define this if you want to use AFS/Kerberos 5 option, which runs aklog.]) fi if test -z "$KRB5ROOT" ; then @@ -2964,7 +3252,8 @@ AC_ARG_WITH(afs-krb5, if test ! -z "$AFS_LIBS" ; then LIBS="$LIBS $AFS_LIBS" fi - AC_DEFINE(AFS_KRB5) + AC_DEFINE(AFS_KRB5, 1, + [Define this if you want to use AFS/Kerberos 5 option, which runs aklog.]) AFS_KRB5_MSG="yes" fi ] @@ -2972,7 +3261,7 @@ AC_ARG_WITH(afs-krb5, AC_ARG_WITH(session-hooks, [ --with-session-hooks Enable hooks for executing external commands before/after a session], - [ AC_DEFINE(SESSION_HOOKS) ] + [ AC_DEFINE(SESSION_HOOKS, 1, [Define this if you want support for startup/shutdown hooks]) ] ) # Looking for programs, paths and files @@ -3025,7 +3314,8 @@ if test -z "$xauth_path" ; then XAUTH_PATH="undefined" AC_SUBST(XAUTH_PATH) else - AC_DEFINE_UNQUOTED(XAUTH_PATH, "$xauth_path") + AC_DEFINE_UNQUOTED(XAUTH_PATH, "$xauth_path", + [Define if xauth is found in your path]) XAUTH_PATH=$xauth_path AC_SUBST(XAUTH_PATH) fi @@ -3033,7 +3323,8 @@ 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") + AC_DEFINE_UNQUOTED(MAIL_DIRECTORY, "$maildir", + [Set this to your mail directory if you don't have maillock.h]) fi if test ! -z "$cross_compiling" && test "x$cross_compiling" = "xyes"; then @@ -3044,7 +3335,8 @@ 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) + AC_DEFINE_UNQUOTED(HAVE_DEV_PTMX, 1, + [Define if you have /dev/ptmx]) have_dev_ptmx=1 ] ) @@ -3054,7 +3346,8 @@ fi if test ! -z "$cross_compiling" && test "x$cross_compiling" != "xyes"; then AC_CHECK_FILE("/dev/ptc", [ - AC_DEFINE_UNQUOTED(HAVE_DEV_PTS_AND_PTC) + AC_DEFINE_UNQUOTED(HAVE_DEV_PTS_AND_PTC, 1, + [Define if you have /dev/ptc]) have_dev_ptc=1 ] ) @@ -3101,7 +3394,8 @@ AC_ARG_WITH(md5-passwords, [ --with-md5-passwords Enable use of MD5 passwords], [ if test "x$withval" != "xno" ; then - AC_DEFINE(HAVE_MD5_PASSWORDS) + AC_DEFINE(HAVE_MD5_PASSWORDS, 1, + [Define if you want to allow MD5 passwords]) MD5_MSG="yes" fi ] @@ -3131,7 +3425,8 @@ if test -z "$disable_shadow" ; then if test "x$sp_expire_available" = "xyes" ; then AC_MSG_RESULT(yes) - AC_DEFINE(HAS_SHADOW_EXPIRE) + AC_DEFINE(HAS_SHADOW_EXPIRE, 1, + [Define if you want to use shadow password expire field]) else AC_MSG_RESULT(no) fi @@ -3140,7 +3435,9 @@ 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) + AC_DEFINE(IPADDR_IN_DISPLAY, 1, + [Define if you need to use IP address + instead of hostname in $DISPLAY]) else DISPLAY_HACK_MSG="no" AC_ARG_WITH(ipaddr-display, @@ -3163,17 +3460,21 @@ AC_ARG_ENABLE(etc-default-login, else etc_default_login=yes fi ], - [ etc_default_login=yes ] + [ if test ! -z "$cross_compiling" && test "x$cross_compiling" = "xyes"; + then + AC_MSG_WARN([cross compiling: not checking /etc/default/login]) + etc_default_login=no + else + etc_default_login=yes + fi ] ) if test "x$etc_default_login" != "xno"; then AC_CHECK_FILE("/etc/default/login", [ external_path_file=/etc/default/login ]) - if test ! -z "$cross_compiling" && test "x$cross_compiling" = "xyes"; - then - AC_MSG_WARN([cross compiling: Disabling /etc/default/login test]) - elif test "x$external_path_file" = "x/etc/default/login"; then - AC_DEFINE(HAVE_ETC_DEFAULT_LOGIN) + if test "x$external_path_file" = "x/etc/default/login"; then + AC_DEFINE(HAVE_ETC_DEFAULT_LOGIN, 1, + [Define if your system has /etc/default/login]) fi fi @@ -3210,8 +3511,8 @@ $external_path_file .]) If PATH is defined in $external_path_file, ensure the path to scp is included, otherwise scp will not work.]) fi - AC_TRY_RUN( - [ + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ /* find out what STDPATH is */ #include #ifdef HAVE_PATHS_H @@ -3243,7 +3544,8 @@ main() exit(0); } - ], [ user_path=`cat conftest.stdpath` ], + ]])], + [ user_path=`cat conftest.stdpath` ], [ user_path="/usr/bin:/bin:/usr/sbin:/sbin" ], [ user_path="/usr/bin:/bin:/usr/sbin:/sbin" ] ) @@ -3266,7 +3568,7 @@ main() fi ] ) if test "x$external_path_file" != "x/etc/login.conf" ; then - AC_DEFINE_UNQUOTED(USER_PATH, "$user_path") + AC_DEFINE_UNQUOTED(USER_PATH, "$user_path", [Specify default $PATH]) AC_SUBST(user_path) fi @@ -3276,7 +3578,9 @@ AC_ARG_WITH(superuser-path, [ if test -n "$withval" && test "x$withval" != "xno" && \ test "x${withval}" != "xyes"; then - AC_DEFINE_UNQUOTED(SUPERUSER_PATH, "$withval") + AC_DEFINE_UNQUOTED(SUPERUSER_PATH, "$withval", + [Define if you want a different $PATH + for the superuser]) superuser_path=$withval fi ] @@ -3290,7 +3594,9 @@ AC_ARG_WITH(4in6, [ if test "x$withval" != "xno" ; then AC_MSG_RESULT(yes) - AC_DEFINE(IPV4_IN_IPV6) + AC_DEFINE(IPV4_IN_IPV6, 1, + [Detect IPv4 in IPv6 mapped addresses + and treat as IPv4]) IPV4_IN6_HACK_MSG="yes" else AC_MSG_RESULT(no) @@ -3312,7 +3618,8 @@ AC_ARG_WITH(bsd-auth, [ --with-bsd-auth Enable BSD auth support], [ if test "x$withval" != "xno" ; then - AC_DEFINE(BSD_AUTH) + AC_DEFINE(BSD_AUTH, 1, + [Define if you have BSD auth support]) BSD_AUTH_MSG=yes fi ] @@ -3341,7 +3648,7 @@ AC_ARG_WITH(pid-dir, ] ) -AC_DEFINE_UNQUOTED(_PATH_SSH_PIDDIR, "$piddir") +AC_DEFINE_UNQUOTED(_PATH_SSH_PIDDIR, "$piddir", [Specify location of ssh.pid]) AC_SUBST(piddir) dnl allow user to disable some login recording features @@ -3365,7 +3672,8 @@ AC_ARG_ENABLE(utmpx, [ --disable-utmpx disable use of utmpx even if detected [no]], [ if test "x$enableval" = "xno" ; then - AC_DEFINE(DISABLE_UTMPX) + AC_DEFINE(DISABLE_UTMPX, 1, + [Define if you don't want to use utmpx]) fi ] ) @@ -3381,7 +3689,8 @@ AC_ARG_ENABLE(wtmpx, [ --disable-wtmpx disable use of wtmpx even if detected [no]], [ if test "x$enableval" = "xno" ; then - AC_DEFINE(DISABLE_WTMPX) + AC_DEFINE(DISABLE_WTMPX, 1, + [Define if you don't want to use wtmpx]) fi ] ) @@ -3397,7 +3706,9 @@ AC_ARG_ENABLE(pututline, [ --disable-pututline disable use of pututline() etc. ([uw]tmp) [no]], [ if test "x$enableval" = "xno" ; then - AC_DEFINE(DISABLE_PUTUTLINE) + AC_DEFINE(DISABLE_PUTUTLINE, 1, + [Define if you don't want to use pututline() + etc. to write [uw]tmp]) fi ] ) @@ -3405,7 +3716,9 @@ AC_ARG_ENABLE(pututxline, [ --disable-pututxline disable use of pututxline() etc. ([uw]tmpx) [no]], [ if test "x$enableval" = "xno" ; then - AC_DEFINE(DISABLE_PUTUTXLINE) + AC_DEFINE(DISABLE_PUTUTXLINE, 1, + [Define if you don't want to use pututxline() + etc. to write [uw]tmpx]) fi ] ) @@ -3480,7 +3793,8 @@ if test -z "$conf_lastlog_location"; then fi if test -n "$conf_lastlog_location"; then - AC_DEFINE_UNQUOTED(CONF_LASTLOG_FILE, "$conf_lastlog_location") + AC_DEFINE_UNQUOTED(CONF_LASTLOG_FILE, "$conf_lastlog_location", + [Define if you want to specify the path to your lastlog file]) fi dnl utmp detection @@ -3510,7 +3824,8 @@ if test -z "$conf_utmp_location"; then fi fi if test -n "$conf_utmp_location"; then - AC_DEFINE_UNQUOTED(CONF_UTMP_FILE, "$conf_utmp_location") + AC_DEFINE_UNQUOTED(CONF_UTMP_FILE, "$conf_utmp_location", + [Define if you want to specify the path to your utmp file]) fi dnl wtmp detection @@ -3540,7 +3855,8 @@ if test -z "$conf_wtmp_location"; then fi fi if test -n "$conf_wtmp_location"; then - AC_DEFINE_UNQUOTED(CONF_WTMP_FILE, "$conf_wtmp_location") + AC_DEFINE_UNQUOTED(CONF_WTMP_FILE, "$conf_wtmp_location", + [Define if you want to specify the path to your wtmp file]) fi @@ -3568,7 +3884,8 @@ if test -z "$conf_utmpx_location"; then AC_DEFINE(DISABLE_UTMPX) fi else - AC_DEFINE_UNQUOTED(CONF_UTMPX_FILE, "$conf_utmpx_location") + AC_DEFINE_UNQUOTED(CONF_UTMPX_FILE, "$conf_utmpx_location", + [Define if you want to specify the path to your utmpx file]) fi dnl wtmpx detection @@ -3593,7 +3910,8 @@ if test -z "$conf_wtmpx_location"; then AC_DEFINE(DISABLE_WTMPX) fi else - AC_DEFINE_UNQUOTED(CONF_WTMPX_FILE, "$conf_wtmpx_location") + AC_DEFINE_UNQUOTED(CONF_WTMPX_FILE, "$conf_wtmpx_location", + [Define if you want to specify the path to your wtmpx file]) fi diff --git a/openssh/defines.h b/openssh/defines.h index fe8f814..3a24eaa 100644 --- a/openssh/defines.h +++ b/openssh/defines.h @@ -450,6 +450,10 @@ struct winsize { # define __sentinel__ #endif +#if !defined(HAVE_ATTRIBUTE__BOUNDED__) && !defined(__bounded__) +# define __bounded__(x, y, z) +#endif + /* *-*-nto-qnx doesn't define this macro in the system headers */ #ifdef MISSING_HOWMANY # define howmany(x,y) (((x)+((y)-1))/(y)) @@ -688,7 +692,7 @@ struct winsize { # define CUSTOM_SYS_AUTH_PASSWD 1 #endif -#if defined(HAVE_LIBIAF) && !defined(BROKEN_LIBIAF) +#ifdef HAVE_LIBIAF # define CUSTOM_SYS_AUTH_PASSWD 1 #endif @@ -711,4 +715,12 @@ struct winsize { # undef HAVE_MMAP #endif +/* some system headers on HP-UX define YES/NO */ +#ifdef YES +# undef YES +#endif +#ifdef NO +# undef NO +#endif + #endif /* _DEFINES_H */ diff --git a/openssh/dns.c b/openssh/dns.c index 4487c1a..a71dd9b 100644 --- a/openssh/dns.c +++ b/openssh/dns.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dns.c,v 1.12 2005/06/17 02:44:32 djm Exp $ */ +/* $OpenBSD: dns.c,v 1.16 2005/10/17 14:13:35 stevesk Exp $ */ /* * Copyright (c) 2003 Wesley Griffin. All rights reserved. @@ -25,27 +25,16 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - #include "includes.h" +RCSID("$OpenBSD: dns.c,v 1.16 2005/10/17 14:13:35 stevesk Exp $"); -#include -#ifdef LWRES -#include -#include -#else /* LWRES */ #include -#endif /* LWRES */ #include "xmalloc.h" #include "key.h" #include "dns.h" #include "log.h" -#include "uuencode.h" - -extern char *__progname; -RCSID("$OpenBSD: dns.c,v 1.12 2005/06/17 02:44:32 djm Exp $"); -#ifndef LWRES static const char *errset_text[] = { "success", /* 0 ERRSET_SUCCESS */ "out of memory", /* 1 ERRSET_NOMEMORY */ @@ -75,8 +64,6 @@ dns_result_totext(unsigned int res) return "unknown error"; } } -#endif /* LWRES */ - /* * Read SSHFP parameters from key buffer. @@ -95,12 +82,14 @@ dns_read_key(u_int8_t *algorithm, u_int8_t *digest_type, *algorithm = SSHFP_KEY_DSA; break; default: - *algorithm = SSHFP_KEY_RESERVED; + *algorithm = SSHFP_KEY_RESERVED; /* 0 */ } if (*algorithm) { *digest_type = SSHFP_HASH_SHA1; *digest = key_fingerprint_raw(key, SSH_FP_SHA1, digest_len); + if (*digest == NULL) + fatal("dns_read_key: null from key_fingerprint_raw()"); success = 1; } else { *digest_type = SSHFP_HASH_RESERVED; @@ -133,7 +122,7 @@ dns_read_rdata(u_int8_t *algorithm, u_int8_t *digest_type, *digest = (u_char *) xmalloc(*digest_len); memcpy(*digest, rdata + 2, *digest_len); } else { - *digest = NULL; + *digest = xstrdup(""); } success = 1; @@ -187,7 +176,7 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address, *flags = 0; - debug3("verify_hostkey_dns"); + debug3("verify_host_key_dns"); if (hostkey == NULL) fatal("No key to look up!"); @@ -223,7 +212,7 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address, if (fingerprints->rri_nrdatas) *flags |= DNS_VERIFY_FOUND; - for (counter = 0 ; counter < fingerprints->rri_nrdatas ; counter++) { + for (counter = 0; counter < fingerprints->rri_nrdatas; counter++) { /* * Extract the key from the answer. Ignore any badly * formatted fingerprints. @@ -247,8 +236,10 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address, *flags |= DNS_VERIFY_MATCH; } } + xfree(dnskey_digest); } + xfree(hostkey_digest); /* from key_fingerprint_raw() */ freerrset(fingerprints); if (*flags & DNS_VERIFY_FOUND) @@ -262,7 +253,6 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address, return 0; } - /* * Export the fingerprint of a key as a DNS resource record */ @@ -278,7 +268,7 @@ export_dns_rr(const char *hostname, const Key *key, FILE *f, int generic) int success = 0; if (dns_read_key(&rdata_pubkey_algorithm, &rdata_digest_type, - &rdata_digest, &rdata_digest_len, key)) { + &rdata_digest, &rdata_digest_len, key)) { if (generic) fprintf(f, "%s IN TYPE%d \\# %d %02x %02x ", hostname, @@ -291,9 +281,10 @@ export_dns_rr(const char *hostname, const Key *key, FILE *f, int generic) for (i = 0; i < rdata_digest_len; i++) fprintf(f, "%02x", rdata_digest[i]); fprintf(f, "\n"); + xfree(rdata_digest); /* from key_fingerprint_raw() */ success = 1; } else { - error("dns_export_rr: unsupported algorithm"); + error("export_dns_rr: unsupported algorithm"); } return success; diff --git a/openssh/dns.h b/openssh/dns.h index c5da22e..0aa1c28 100644 --- a/openssh/dns.h +++ b/openssh/dns.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dns.h,v 1.5 2003/11/12 16:39:58 jakob Exp $ */ +/* $OpenBSD: dns.h,v 1.6 2005/10/17 14:13:35 stevesk Exp $ */ /* * Copyright (c) 2003 Wesley Griffin. All rights reserved. @@ -25,7 +25,6 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - #include "includes.h" #ifndef DNS_H @@ -49,7 +48,6 @@ enum sshfp_hashes { #define DNS_VERIFY_MATCH 0x00000002 #define DNS_VERIFY_SECURE 0x00000004 - int verify_host_key_dns(const char *, struct sockaddr *, const Key *, int *); int export_dns_rr(const char *, const Key *, FILE *, int); diff --git a/openssh/envpass.sh b/openssh/envpass.sh deleted file mode 100644 index 67044d4..0000000 --- a/openssh/envpass.sh +++ /dev/null @@ -1,44 +0,0 @@ -# $OpenBSD: envpass.sh,v 1.1 2004/04/27 09:47:30 djm Exp $ -# Placed in the Public Domain. - -tid="environment passing" - -# NB accepted env vars are in test-exec.sh (_XXX_TEST_* and _XXX_TEST) - -trace "pass env, don't accept" -verbose "test $tid: pass env, don't accept" -_TEST_ENV=blah ${SSH} -oSendEnv="*" -F $OBJ/ssh_proxy otherhost \ - '[ -z "$_TEST_ENV" ]' -r=$? -if [ $r -ne 0 ]; then - fail "environment found" -fi - -trace "don't pass env, accept" -verbose "test $tid: don't pass env, accept" -${SSH} -F $OBJ/ssh_proxy otherhost \ - '[ -z "$_XXX_TEST_A" -a -z "$_XXX_TEST_B" ]' -r=$? -if [ $r -ne 0 ]; then - fail "environment found" -fi - -trace "pass single env, accept single env" -verbose "test $tid: pass single env, accept single env" -_XXX_TEST=blah ${SSH} -oSendEnv="_XXX_TEST" -F $OBJ/ssh_proxy otherhost \ - '[ "x$_XXX_TEST" = "xblah" ]' -r=$? -if [ $r -ne 0 ]; then - fail "environment not found" -fi - -trace "pass multiple env, accept multiple env" -verbose "test $tid: pass multiple env, accept multiple env" -_XXX_TEST_A=1 _XXX_TEST_B=2 ${SSH} -oSendEnv="_XXX_TEST_*" \ - -F $OBJ/ssh_proxy otherhost \ - '[ "x$_XXX_TEST_A" = "x1" -a "x$_XXX_TEST_B" = "x2" ]' -r=$? -if [ $r -ne 0 ]; then - fail "environment not found" -fi - diff --git a/openssh/gss-genr.c b/openssh/gss-genr.c index 26e20b9..12ceb04 100644 --- a/openssh/gss-genr.c +++ b/openssh/gss-genr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gss-genr.c,v 1.4 2005/07/17 07:17:55 djm Exp $ */ +/* $OpenBSD: gss-genr.c,v 1.6 2005/10/13 22:24:31 stevesk Exp $ */ /* * Copyright (c) 2001-2005 Simon Wilkinson. All rights reserved. @@ -445,7 +445,8 @@ ssh_gssapi_buildmic(Buffer *b, const char *user, const char *service, } OM_uint32 -ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) { +ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) +{ if (*ctx) ssh_gssapi_delete_ctx(ctx); ssh_gssapi_build_ctx(ctx); diff --git a/openssh/gss-serv-krb5.c b/openssh/gss-serv-krb5.c index a1e87ac..92c91b8 100644 --- a/openssh/gss-serv-krb5.c +++ b/openssh/gss-serv-krb5.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gss-serv-krb5.c,v 1.3 2004/07/21 10:36:23 djm Exp $ */ +/* $OpenBSD: gss-serv-krb5.c,v 1.4 2005/10/13 19:08:08 stevesk Exp $ */ /* * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. diff --git a/openssh/gss-serv.c b/openssh/gss-serv.c index 0c73250..79f8970 100644 --- a/openssh/gss-serv.c +++ b/openssh/gss-serv.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gss-serv.c,v 1.8 2005/08/30 22:08:05 djm Exp $ */ +/* $OpenBSD: gss-serv.c,v 1.13 2005/10/13 22:24:31 stevesk Exp $ */ /* * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -44,8 +44,6 @@ #include "ssh-gss.h" -extern ServerOptions options; - static ssh_gssapi_client gssapi_client = { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER, GSS_C_NO_CREDENTIAL, NULL, {NULL, NULL, NULL}}; @@ -126,7 +124,7 @@ ssh_gssapi_supported_oids(gss_OID_set *oidset) * oid * credentials (from ssh_gssapi_acquire_cred) */ -/* Priviledged */ +/* Privileged */ OM_uint32 ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *recv_tok, gss_buffer_desc *send_tok, OM_uint32 *flags) @@ -178,7 +176,7 @@ ssh_gssapi_parse_ename(Gssctxt *ctx, gss_buffer_t ename, gss_buffer_t name) OM_uint32 offset; OM_uint32 oidl; - tok=ename->value; + tok = ename->value; #ifdef GSI /* GSI gss_export_name() is broken. */ if ((ctx->oid->length == gssapi_gsi_mech.oid.length) && @@ -196,7 +194,7 @@ ssh_gssapi_parse_ename(Gssctxt *ctx, gss_buffer_t ename, gss_buffer_t name) * header, and that the initial ID bytes are correct */ - if (ename->length<6 || memcmp(tok,"\x04\x01", 2)!=0) + if (ename->length < 6 || memcmp(tok, "\x04\x01", 2) != 0) return GSS_S_FAILURE; /* @@ -215,7 +213,7 @@ ssh_gssapi_parse_ename(Gssctxt *ctx, gss_buffer_t ename, gss_buffer_t name) */ if (tok[4] != 0x06 || tok[5] != oidl || ename->length < oidl+6 || - !ssh_gssapi_check_oid(ctx,tok+6,oidl)) + !ssh_gssapi_check_oid(ctx, tok+6, oidl)) return GSS_S_FAILURE; offset = oidl+6; @@ -230,7 +228,7 @@ ssh_gssapi_parse_ename(Gssctxt *ctx, gss_buffer_t ename, gss_buffer_t name) return GSS_S_FAILURE; name->value = xmalloc(name->length+1); - memcpy(name->value,tok+offset,name->length); + memcpy(name->value, tok+offset,name->length); ((char *)name->value)[name->length] = 0; return GSS_S_COMPLETE; @@ -239,7 +237,7 @@ ssh_gssapi_parse_ename(Gssctxt *ctx, gss_buffer_t ename, gss_buffer_t name) /* Extract the client details from a given context. This can only reliably * be called once for a context */ -/* Priviledged (called from accept_secure_ctx) */ +/* Privileged (called from accept_secure_ctx) */ OM_uint32 ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client) { @@ -314,15 +312,14 @@ ssh_gssapi_do_child(char ***envp, u_int *envsizep) if (gssapi_client.store.envvar != NULL && gssapi_client.store.envval != NULL) { - debug("Setting %s to %s", gssapi_client.store.envvar, - gssapi_client.store.envval); + gssapi_client.store.envval); child_set_env(envp, envsizep, gssapi_client.store.envvar, gssapi_client.store.envval); } } -/* Priviledged */ +/* Privileged */ int ssh_gssapi_userok(char *user) { diff --git a/openssh/includes.h b/openssh/includes.h index fa65aa3..5208174 100644 --- a/openssh/includes.h +++ b/openssh/includes.h @@ -1,4 +1,4 @@ -/* $OpenBSD: includes.h,v 1.19 2005/05/19 02:42:26 djm Exp $ */ +/* $OpenBSD: includes.h,v 1.22 2006/01/01 08:59:27 stevesk Exp $ */ /* * Author: Tatu Ylonen @@ -21,6 +21,8 @@ static /**/const char *const rcsid[] = { (const char *)rcsid, "\100(#)" msg } #include "config.h" +#define _GNU_SOURCE /* activate extra prototypes for glibc */ + #include #include #include @@ -67,7 +69,6 @@ static /**/const char *const rcsid[] = { (const char *)rcsid, "\100(#)" msg } #ifdef HAVE_NEXT # include #endif -#define __USE_GNU /* before unistd.h, activate extra prototypes for glibc */ #include /* For STDIN_FILENO, etc */ #include /* Struct winsize */ diff --git a/openssh/kex.c b/openssh/kex.c index b49c610..407eec3 100644 --- a/openssh/kex.c +++ b/openssh/kex.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: kex.c,v 1.64 2005/07/25 11:59:39 markus Exp $"); +RCSID("$OpenBSD: kex.c,v 1.65 2005/11/04 05:15:59 djm Exp $"); #include @@ -298,21 +298,27 @@ choose_kex(Kex *k, char *client, char *server) fatal("no kex alg"); if (strcmp(k->name, KEX_DH1) == 0) { k->kex_type = KEX_DH_GRP1_SHA1; + k->evp_md = EVP_sha1(); } else if (strcmp(k->name, KEX_DH14) == 0) { k->kex_type = KEX_DH_GRP14_SHA1; - } else if (strcmp(k->name, KEX_DHGEX) == 0) { + k->evp_md = EVP_sha1(); + } else if (strcmp(k->name, KEX_DHGEX_SHA1) == 0) { k->kex_type = KEX_DH_GEX_SHA1; + k->evp_md = EVP_sha1(); #ifdef GSSAPI } else if (strncmp(k->name, KEX_GSS_GEX_SHA1_ID, sizeof(KEX_GSS_GEX_SHA1_ID)-1) == 0) { k->kex_type = KEX_GSS_GEX_SHA1; + k->evp_md = EVP_sha1(); } else if (strncmp(k->name, KEX_GSS_GRP1_SHA1_ID, sizeof(KEX_GSS_GRP1_SHA1_ID)-1) == 0) { k->kex_type = KEX_GSS_GRP1_SHA1; + k->evp_md = EVP_sha1(); #endif } else fatal("bad kex alg %s", k->name); } + static void choose_hostkeyalg(Kex *k, char *client, char *server) { @@ -416,28 +422,28 @@ kex_choose_conf(Kex *kex) } static u_char * -derive_key(Kex *kex, int id, u_int need, u_char *hash, BIGNUM *shared_secret) +derive_key(Kex *kex, int id, u_int need, u_char *hash, u_int hashlen, + BIGNUM *shared_secret) { Buffer b; - const EVP_MD *evp_md = EVP_sha1(); EVP_MD_CTX md; char c = id; u_int have; - int mdsz = EVP_MD_size(evp_md); + int mdsz; u_char *digest; - if (mdsz < 0) - fatal("derive_key: mdsz < 0"); - digest = xmalloc(roundup(need, mdsz)); + if ((mdsz = EVP_MD_size(kex->evp_md)) <= 0) + fatal("bad kex md size %d", mdsz); + digest = xmalloc(roundup(need, mdsz)); buffer_init(&b); buffer_put_bignum2(&b, shared_secret); /* K1 = HASH(K || H || "A" || session_id) */ - EVP_DigestInit(&md, evp_md); + EVP_DigestInit(&md, kex->evp_md); if (!(datafellows & SSH_BUG_DERIVEKEY)) EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); - EVP_DigestUpdate(&md, hash, mdsz); + EVP_DigestUpdate(&md, hash, hashlen); EVP_DigestUpdate(&md, &c, 1); EVP_DigestUpdate(&md, kex->session_id, kex->session_id_len); EVP_DigestFinal(&md, digest, NULL); @@ -448,10 +454,10 @@ derive_key(Kex *kex, int id, u_int need, u_char *hash, BIGNUM *shared_secret) * Key = K1 || K2 || ... || Kn */ for (have = mdsz; need > have; have += mdsz) { - EVP_DigestInit(&md, evp_md); + EVP_DigestInit(&md, kex->evp_md); if (!(datafellows & SSH_BUG_DERIVEKEY)) EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); - EVP_DigestUpdate(&md, hash, mdsz); + EVP_DigestUpdate(&md, hash, hashlen); EVP_DigestUpdate(&md, digest, have); EVP_DigestFinal(&md, digest + have, NULL); } @@ -467,13 +473,15 @@ Newkeys *current_keys[MODE_MAX]; #define NKEYS 6 void -kex_derive_keys(Kex *kex, u_char *hash, BIGNUM *shared_secret) +kex_derive_keys(Kex *kex, u_char *hash, u_int hashlen, BIGNUM *shared_secret) { u_char *keys[NKEYS]; u_int i, mode, ctos; - for (i = 0; i < NKEYS; i++) - keys[i] = derive_key(kex, 'A'+i, kex->we_need, hash, shared_secret); + for (i = 0; i < NKEYS; i++) { + keys[i] = derive_key(kex, 'A'+i, kex->we_need, hash, hashlen, + shared_secret); + } debug2("kex_derive_keys"); for (mode = 0; mode < MODE_MAX; mode++) { diff --git a/openssh/kex.h b/openssh/kex.h index e3e39aa..9d1823e 100644 --- a/openssh/kex.h +++ b/openssh/kex.h @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.h,v 1.37 2005/07/25 11:59:39 markus Exp $ */ +/* $OpenBSD: kex.h,v 1.38 2005/11/04 05:15:59 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -31,9 +31,9 @@ #include "cipher.h" #include "key.h" -#define KEX_DH1 "diffie-hellman-group1-sha1" -#define KEX_DH14 "diffie-hellman-group14-sha1" -#define KEX_DHGEX "diffie-hellman-group-exchange-sha1" +#define KEX_DH1 "diffie-hellman-group1-sha1" +#define KEX_DH14 "diffie-hellman-group14-sha1" +#define KEX_DHGEX_SHA1 "diffie-hellman-group-exchange-sha1" #define COMP_NONE 0 #define COMP_ZLIB 1 @@ -121,6 +121,7 @@ struct Kex { Buffer peer; int done; int flags; + const EVP_MD *evp_md; #ifdef GSSAPI int gss_deleg_creds; int gss_trust_dns; @@ -142,7 +143,7 @@ void kex_finish(Kex *); void kex_send_kexinit(Kex *); void kex_input_kexinit(int, u_int32_t, void *); -void kex_derive_keys(Kex *, u_char *, BIGNUM *); +void kex_derive_keys(Kex *, u_char *, u_int, BIGNUM *); Newkeys *kex_get_newkeys(int); @@ -156,12 +157,13 @@ void kexgss_client(Kex *); void kexgss_server(Kex *); #endif -u_char * +void kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int, - BIGNUM *, BIGNUM *, BIGNUM *); -u_char * -kexgex_hash(char *, char *, char *, int, char *, int, u_char *, int, - int, int, int, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *); + BIGNUM *, BIGNUM *, BIGNUM *, u_char **, u_int *); +void +kexgex_hash(const EVP_MD *, char *, char *, char *, int, char *, + int, u_char *, int, int, int, int, BIGNUM *, BIGNUM *, BIGNUM *, + BIGNUM *, BIGNUM *, u_char **, u_int *); void derive_ssh1_session_id(BIGNUM *, BIGNUM *, u_int8_t[8], u_int8_t[16]); diff --git a/openssh/kexdhc.c b/openssh/kexdhc.c index f48bd46..d8a2fa3 100644 --- a/openssh/kexdhc.c +++ b/openssh/kexdhc.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: kexdhc.c,v 1.2 2004/06/13 12:53:24 djm Exp $"); +RCSID("$OpenBSD: kexdhc.c,v 1.3 2005/11/04 05:15:59 djm Exp $"); #include "xmalloc.h" #include "key.h" @@ -41,7 +41,7 @@ kexdh_client(Kex *kex) Key *server_host_key; u_char *server_host_key_blob = NULL, *signature = NULL; u_char *kbuf, *hash; - u_int klen, kout, slen, sbloblen; + u_int klen, kout, slen, sbloblen, hashlen; /* generate and send 'e', client DH public key */ switch (kex->kex_type) { @@ -114,7 +114,7 @@ kexdh_client(Kex *kex) xfree(kbuf); /* calc and verify H */ - hash = kex_dh_hash( + kex_dh_hash( kex->client_version_string, kex->server_version_string, buffer_ptr(&kex->my), buffer_len(&kex->my), @@ -122,25 +122,26 @@ kexdh_client(Kex *kex) server_host_key_blob, sbloblen, dh->pub_key, dh_server_pub, - shared_secret + shared_secret, + &hash, &hashlen ); xfree(server_host_key_blob); BN_clear_free(dh_server_pub); DH_free(dh); - if (key_verify(server_host_key, signature, slen, hash, 20) != 1) + if (key_verify(server_host_key, signature, slen, hash, hashlen) != 1) fatal("key_verify failed for server_host_key"); key_free(server_host_key); xfree(signature); /* save session id */ if (kex->session_id == NULL) { - kex->session_id_len = 20; + kex->session_id_len = hashlen; kex->session_id = xmalloc(kex->session_id_len); memcpy(kex->session_id, hash, kex->session_id_len); } - kex_derive_keys(kex, hash, shared_secret); + kex_derive_keys(kex, hash, hashlen, shared_secret); BN_clear_free(shared_secret); kex_finish(kex); } diff --git a/openssh/kexdhs.c b/openssh/kexdhs.c index 225e655..26c8cdf 100644 --- a/openssh/kexdhs.c +++ b/openssh/kexdhs.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: kexdhs.c,v 1.2 2004/06/13 12:53:24 djm Exp $"); +RCSID("$OpenBSD: kexdhs.c,v 1.3 2005/11/04 05:15:59 djm Exp $"); #include "xmalloc.h" #include "key.h" @@ -41,7 +41,7 @@ kexdh_server(Kex *kex) DH *dh; Key *server_host_key; u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; - u_int sbloblen, klen, kout; + u_int sbloblen, klen, kout, hashlen; u_int slen; /* generate server DH public key */ @@ -103,7 +103,7 @@ kexdh_server(Kex *kex) key_to_blob(server_host_key, &server_host_key_blob, &sbloblen); /* calc H */ - hash = kex_dh_hash( + kex_dh_hash( kex->client_version_string, kex->server_version_string, buffer_ptr(&kex->peer), buffer_len(&kex->peer), @@ -111,21 +111,20 @@ kexdh_server(Kex *kex) server_host_key_blob, sbloblen, dh_client_pub, dh->pub_key, - shared_secret + shared_secret, + &hash, &hashlen ); BN_clear_free(dh_client_pub); /* save session id := H */ - /* XXX hashlen depends on KEX */ if (kex->session_id == NULL) { - kex->session_id_len = 20; + kex->session_id_len = hashlen; kex->session_id = xmalloc(kex->session_id_len); memcpy(kex->session_id, hash, kex->session_id_len); } /* sign H */ - /* XXX hashlen depends on KEX */ - PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, 20)); + PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, hashlen)); /* destroy_sensitive_data(); */ @@ -141,7 +140,7 @@ kexdh_server(Kex *kex) /* have keys, free DH */ DH_free(dh); - kex_derive_keys(kex, hash, shared_secret); + kex_derive_keys(kex, hash, hashlen, shared_secret); BN_clear_free(shared_secret); kex_finish(kex); } diff --git a/openssh/kexgexc.c b/openssh/kexgexc.c index 0193183..a6ff875 100644 --- a/openssh/kexgexc.c +++ b/openssh/kexgexc.c @@ -24,7 +24,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: kexgexc.c,v 1.2 2003/12/08 11:00:47 markus Exp $"); +RCSID("$OpenBSD: kexgexc.c,v 1.3 2005/11/04 05:15:59 djm Exp $"); #include "xmalloc.h" #include "key.h" @@ -42,7 +42,7 @@ kexgex_client(Kex *kex) BIGNUM *p = NULL, *g = NULL; Key *server_host_key; u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; - u_int klen, kout, slen, sbloblen; + u_int klen, kout, slen, sbloblen, hashlen; int min, max, nbits; DH *dh; @@ -155,7 +155,8 @@ kexgex_client(Kex *kex) min = max = -1; /* calc and verify H */ - hash = kexgex_hash( + kexgex_hash( + kex->evp_md, kex->client_version_string, kex->server_version_string, buffer_ptr(&kex->my), buffer_len(&kex->my), @@ -165,25 +166,27 @@ kexgex_client(Kex *kex) dh->p, dh->g, dh->pub_key, dh_server_pub, - shared_secret + shared_secret, + &hash, &hashlen ); + /* have keys, free DH */ DH_free(dh); xfree(server_host_key_blob); BN_clear_free(dh_server_pub); - if (key_verify(server_host_key, signature, slen, hash, 20) != 1) + if (key_verify(server_host_key, signature, slen, hash, hashlen) != 1) fatal("key_verify failed for server_host_key"); key_free(server_host_key); xfree(signature); /* save session id */ if (kex->session_id == NULL) { - kex->session_id_len = 20; + kex->session_id_len = hashlen; kex->session_id = xmalloc(kex->session_id_len); memcpy(kex->session_id, hash, kex->session_id_len); } - kex_derive_keys(kex, hash, shared_secret); + kex_derive_keys(kex, hash, hashlen, shared_secret); BN_clear_free(shared_secret); kex_finish(kex); diff --git a/openssh/kexgexs.c b/openssh/kexgexs.c index baebfcf..c48b27a 100644 --- a/openssh/kexgexs.c +++ b/openssh/kexgexs.c @@ -24,7 +24,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: kexgexs.c,v 1.1 2003/02/16 17:09:57 markus Exp $"); +RCSID("$OpenBSD: kexgexs.c,v 1.2 2005/11/04 05:15:59 djm Exp $"); #include "xmalloc.h" #include "key.h" @@ -43,7 +43,7 @@ kexgex_server(Kex *kex) Key *server_host_key; DH *dh; u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; - u_int sbloblen, klen, kout, slen; + u_int sbloblen, klen, kout, slen, hashlen; int min = -1, max = -1, nbits = -1, type; if (kex->load_host_key == NULL) @@ -137,8 +137,9 @@ kexgex_server(Kex *kex) if (type == SSH2_MSG_KEX_DH_GEX_REQUEST_OLD) min = max = -1; - /* calc H */ /* XXX depends on 'kex' */ - hash = kexgex_hash( + /* calc H */ + kexgex_hash( + kex->evp_md, kex->client_version_string, kex->server_version_string, buffer_ptr(&kex->peer), buffer_len(&kex->peer), @@ -148,21 +149,20 @@ kexgex_server(Kex *kex) dh->p, dh->g, dh_client_pub, dh->pub_key, - shared_secret + shared_secret, + &hash, &hashlen ); BN_clear_free(dh_client_pub); /* save session id := H */ - /* XXX hashlen depends on KEX */ if (kex->session_id == NULL) { - kex->session_id_len = 20; + kex->session_id_len = hashlen; kex->session_id = xmalloc(kex->session_id_len); memcpy(kex->session_id, hash, kex->session_id_len); } /* sign H */ - /* XXX hashlen depends on KEX */ - PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, 20)); + PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, hashlen)); /* destroy_sensitive_data(); */ @@ -179,7 +179,7 @@ kexgex_server(Kex *kex) /* have keys, free DH */ DH_free(dh); - kex_derive_keys(kex, hash, shared_secret); + kex_derive_keys(kex, hash, hashlen, shared_secret); BN_clear_free(shared_secret); kex_finish(kex); diff --git a/openssh/kexgssc.c b/openssh/kexgssc.c index acd2045..f5a769c 100644 --- a/openssh/kexgssc.c +++ b/openssh/kexgssc.c @@ -54,6 +54,7 @@ kexgss_client(Kex *kex) { BIGNUM *g = NULL; unsigned char *kbuf; unsigned char *hash; + unsigned int hashlen; unsigned char *serverhostkey = NULL; char *msg; char *lang; @@ -244,7 +245,9 @@ kexgss_client(Kex *kex) { xfree(kbuf); if (gex) { - hash = kexgex_hash( kex->client_version_string, + kexgex_hash( + kex->evp_md, + kex->client_version_string, kex->server_version_string, buffer_ptr(&kex->my), buffer_len(&kex->my), buffer_ptr(&kex->peer), buffer_len(&kex->peer), @@ -253,18 +256,20 @@ kexgss_client(Kex *kex) { dh->p, dh->g, dh->pub_key, dh_server_pub, - shared_secret + shared_secret, + &hash, &hashlen ); } else { /* The GSS hash is identical to the DH one */ - hash = kex_dh_hash( kex->client_version_string, + kex_dh_hash( kex->client_version_string, kex->server_version_string, buffer_ptr(&kex->my), buffer_len(&kex->my), buffer_ptr(&kex->peer), buffer_len(&kex->peer), serverhostkey, slen, /* server host key */ dh->pub_key, /* e */ dh_server_pub, /* f */ - shared_secret /* K */ + shared_secret, /* K */ + &hash, &hashlen ); } @@ -294,7 +299,7 @@ kexgss_client(Kex *kex) { else ssh_gssapi_delete_ctx(&ctxt); - kex_derive_keys(kex, hash, shared_secret); + kex_derive_keys(kex, hash, hashlen, shared_secret); BN_clear_free(shared_secret); kex_finish(kex); } diff --git a/openssh/kexgsss.c b/openssh/kexgsss.c index 52e46e8..a860409 100644 --- a/openssh/kexgsss.c +++ b/openssh/kexgsss.c @@ -58,7 +58,7 @@ kexgss_server(Kex *kex) gss_buffer_desc gssbuf, recv_tok, msg_tok; gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER; Gssctxt *ctxt = NULL; - unsigned int klen, kout; + unsigned int klen, kout, hashlen; unsigned char *kbuf, *hash; DH *dh; int min = -1, max = -1, nbits = -1; @@ -194,7 +194,8 @@ kexgss_server(Kex *kex) xfree(kbuf); if (gex) { - hash = kexgex_hash( + kexgex_hash( + kex->evp_md, kex->client_version_string, kex->server_version_string, buffer_ptr(&kex->peer), buffer_len(&kex->peer), buffer_ptr(&kex->my), buffer_len(&kex->my), @@ -203,17 +204,19 @@ kexgss_server(Kex *kex) dh->p, dh->g, dh_client_pub, dh->pub_key, - shared_secret + shared_secret, + &hash, &hashlen ); } else { /* The GSSAPI hash is identical to the Diffie Helman one */ - hash = kex_dh_hash( + kex_dh_hash( kex->client_version_string, kex->server_version_string, buffer_ptr(&kex->peer), buffer_len(&kex->peer), buffer_ptr(&kex->my), buffer_len(&kex->my), NULL, 0, /* Change this if we start sending host keys */ - dh_client_pub, dh->pub_key, shared_secret + dh_client_pub, dh->pub_key, shared_secret, + &hash, &hashlen ); } BN_free(dh_client_pub); @@ -252,7 +255,7 @@ kexgss_server(Kex *kex) DH_free(dh); - kex_derive_keys(kex, hash, shared_secret); + kex_derive_keys(kex, hash, hashlen, shared_secret); BN_clear_free(shared_secret); kex_finish(kex); } diff --git a/openssh/misc.c b/openssh/misc.c index 3f04786..fd9c392 100644 --- a/openssh/misc.c +++ b/openssh/misc.c @@ -24,7 +24,11 @@ */ #include "includes.h" -RCSID("$OpenBSD: misc.c,v 1.34 2005/07/08 09:26:18 dtucker Exp $"); +RCSID("$OpenBSD: misc.c,v 1.42 2006/01/31 10:19:02 djm Exp $"); + +#ifdef SSH_TUN_OPENBSD +#include +#endif #include "misc.h" #include "log.h" @@ -212,6 +216,37 @@ a2port(const char *s) return port; } +int +a2tun(const char *s, int *remote) +{ + const char *errstr = NULL; + char *sp, *ep; + int tun; + + if (remote != NULL) { + *remote = SSH_TUNID_ANY; + sp = xstrdup(s); + if ((ep = strchr(sp, ':')) == NULL) { + xfree(sp); + return (a2tun(s, NULL)); + } + ep[0] = '\0'; ep++; + *remote = a2tun(ep, NULL); + tun = a2tun(sp, NULL); + xfree(sp); + return (*remote == SSH_TUNID_ERR ? *remote : tun); + } + + if (strcasecmp(s, "any") == 0) + return (SSH_TUNID_ANY); + + tun = strtonum(s, 0, SSH_TUNID_MAX, &errstr); + if (errstr != NULL) + return (SSH_TUNID_ERR); + + return (tun); +} + #define SECONDS 1 #define MINUTES (SECONDS * 60) #define HOURS (MINUTES * 60) @@ -374,12 +409,15 @@ void addargs(arglist *args, char *fmt, ...) { va_list ap; - char buf[1024]; + char *cp; u_int nalloc; + int r; va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); + r = vasprintf(&cp, fmt, ap); va_end(ap); + if (r == -1) + fatal("addargs: argument too long"); nalloc = args->nalloc; if (args->list == NULL) { @@ -390,10 +428,44 @@ addargs(arglist *args, char *fmt, ...) args->list = xrealloc(args->list, nalloc * sizeof(char *)); args->nalloc = nalloc; - args->list[args->num++] = xstrdup(buf); + args->list[args->num++] = cp; args->list[args->num] = NULL; } +void +replacearg(arglist *args, u_int which, char *fmt, ...) +{ + va_list ap; + char *cp; + int r; + + va_start(ap, fmt); + r = vasprintf(&cp, fmt, ap); + va_end(ap); + if (r == -1) + fatal("replacearg: argument too long"); + + if (which >= args->num) + fatal("replacearg: tried to replace invalid arg %d >= %d", + which, args->num); + xfree(args->list[which]); + args->list[which] = cp; +} + +void +freeargs(arglist *args) +{ + u_int i; + + if (args->list != NULL) { + for (i = 0; i < args->num; i++) + xfree(args->list[i]); + xfree(args->list); + args->nalloc = args->num = 0; + args->list = NULL; + } +} + /* * Expands tildes in the file name. Returns data allocated by xmalloc. * Warning: this calls getpw*. @@ -525,6 +597,99 @@ read_keyfile_line(FILE *f, const char *filename, char *buf, size_t bufsz, return -1; } +int +tun_open(int tun, int mode) +{ +#if defined(CUSTOM_SYS_TUN_OPEN) + return (sys_tun_open(tun, mode)); +#elif defined(SSH_TUN_OPENBSD) + struct ifreq ifr; + char name[100]; + int fd = -1, sock; + + /* Open the tunnel device */ + if (tun <= SSH_TUNID_MAX) { + snprintf(name, sizeof(name), "/dev/tun%d", tun); + fd = open(name, O_RDWR); + } else if (tun == SSH_TUNID_ANY) { + for (tun = 100; tun >= 0; tun--) { + snprintf(name, sizeof(name), "/dev/tun%d", tun); + if ((fd = open(name, O_RDWR)) >= 0) + break; + } + } else { + debug("%s: invalid tunnel %u", __func__, tun); + return (-1); + } + + if (fd < 0) { + debug("%s: %s open failed: %s", __func__, name, strerror(errno)); + return (-1); + } + + debug("%s: %s mode %d fd %d", __func__, name, mode, fd); + + /* Set the tunnel device operation mode */ + snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "tun%d", tun); + if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) + goto failed; + + if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) + goto failed; + + /* Set interface mode */ + ifr.ifr_flags &= ~IFF_UP; + if (mode == SSH_TUNMODE_ETHERNET) + ifr.ifr_flags |= IFF_LINK0; + else + ifr.ifr_flags &= ~IFF_LINK0; + if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) + goto failed; + + /* Bring interface up */ + ifr.ifr_flags |= IFF_UP; + if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) + goto failed; + + close(sock); + return (fd); + + failed: + if (fd >= 0) + close(fd); + if (sock >= 0) + close(sock); + debug("%s: failed to set %s mode %d: %s", __func__, name, + mode, strerror(errno)); + return (-1); +#else + error("Tunnel interfaces are not supported on this platform"); + return (-1); +#endif +} + +void +sanitise_stdfd(void) +{ + int nullfd, dupfd; + + if ((nullfd = dupfd = open(_PATH_DEVNULL, O_RDWR)) == -1) { + fprintf(stderr, "Couldn't open /dev/null: %s", strerror(errno)); + exit(1); + } + while (++dupfd <= 2) { + /* Only clobber closed fds */ + if (fcntl(dupfd, F_GETFL, 0) >= 0) + continue; + if (dup2(nullfd, dupfd) == -1) { + fprintf(stderr, "dup2: %s", strerror(errno)); + exit(1); + } + } + if (nullfd > 2) + close(nullfd); +} + char * tohex(const u_char *d, u_int l) { diff --git a/openssh/monitor.c b/openssh/monitor.c index 346bbd2..0c93d7d 100644 --- a/openssh/monitor.c +++ b/openssh/monitor.c @@ -25,7 +25,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: monitor.c,v 1.63 2005/03/10 22:01:05 deraadt Exp $"); +RCSID("$OpenBSD: monitor.c,v 1.64 2005/10/13 22:24:31 stevesk Exp $"); #include @@ -871,9 +871,7 @@ mm_answer_pam_account(int sock, Buffer *m) ret = do_pam_account(); buffer_put_int(m, ret); - buffer_append(&loginmsg, "\0", 1); - buffer_put_cstring(m, buffer_ptr(&loginmsg)); - buffer_clear(&loginmsg); + buffer_put_string(m, buffer_ptr(&loginmsg), buffer_len(&loginmsg)); mm_request_send(sock, MONITOR_ANS_PAM_ACCOUNT, m); @@ -1872,7 +1870,7 @@ mm_answer_gss_setup_ctx(int sock, Buffer *m) buffer_clear(m); buffer_put_int(m, major); - mm_request_send(sock,MONITOR_ANS_GSSSETUP, m); + mm_request_send(sock, MONITOR_ANS_GSSSETUP, m); /* Now we have a context, enable the step */ monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 1); @@ -1885,7 +1883,7 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m) { gss_buffer_desc in; gss_buffer_desc out = GSS_C_EMPTY_BUFFER; - OM_uint32 major,minor; + OM_uint32 major, minor; OM_uint32 flags = 0; /* GSI needs this */ u_int len; @@ -1902,7 +1900,7 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m) gss_release_buffer(&minor, &out); - if (major==GSS_S_COMPLETE) { + if (major == GSS_S_COMPLETE) { monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); monitor_permit(mon_dispatch, MONITOR_REQ_GSSSIGN, 1); @@ -1953,7 +1951,7 @@ mm_answer_gss_userok(int sock, Buffer *m) debug3("%s: sending result %d", __func__, authenticated); mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); - auth_method="gssapi-with-mic"; + auth_method = "gssapi-with-mic"; /* Monitor loop will terminate if authenticated */ return (authenticated); diff --git a/openssh/monitor_wrap.c b/openssh/monitor_wrap.c index 83f7b2c..efd13f9 100644 --- a/openssh/monitor_wrap.c +++ b/openssh/monitor_wrap.c @@ -72,7 +72,6 @@ extern struct monitor *pmonitor; extern Buffer input, output; extern Buffer loginmsg; extern ServerOptions options; -extern Buffer loginmsg; int mm_is_monitor(void) diff --git a/openssh/openbsd-compat/basename.c b/openssh/openbsd-compat/basename.c index 552dc1e..ad040e1 100644 --- a/openssh/openbsd-compat/basename.c +++ b/openssh/openbsd-compat/basename.c @@ -1,9 +1,7 @@ -/* OPENBSD ORIGINAL: lib/libc/gen/basename.c */ - -/* $OpenBSD: basename.c,v 1.11 2003/06/17 21:56:23 millert Exp $ */ +/* $OpenBSD: basename.c,v 1.14 2005/08/08 08:05:33 espie Exp $ */ /* - * Copyright (c) 1997 Todd C. Miller + * Copyright (c) 1997, 2004 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -18,34 +16,35 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +/* OPENBSD ORIGINAL: lib/libc/gen/basename.c */ + #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; + size_t len; + const char *endp, *startp; /* Empty or NULL string gets treated as "." */ if (path == NULL || *path == '\0') { - (void)strlcpy(bname, ".", sizeof bname); - return(bname); + bname[0] = '.'; + bname[1] = '\0'; + return (bname); } - /* Strip trailing slashes */ + /* Strip any trailing slashes */ endp = path + strlen(path) - 1; while (endp > path && *endp == '/') endp--; - /* All slashes become "/" */ + /* All slashes becomes "/" */ if (endp == path && *endp == '/') { - (void)strlcpy(bname, "/", sizeof bname); - return(bname); + bname[0] = '/'; + bname[1] = '\0'; + return (bname); } /* Find the start of the base */ @@ -53,12 +52,14 @@ basename(const char *path) while (startp > path && *(startp - 1) != '/') startp--; - if (endp - startp + 2 > sizeof(bname)) { + len = endp - startp + 1; + if (len >= sizeof(bname)) { errno = ENAMETOOLONG; - return(NULL); + return (NULL); } - strlcpy(bname, startp, endp - startp + 2); - return(bname); + memcpy(bname, startp, len); + bname[len] = '\0'; + return (bname); } #endif /* !defined(HAVE_BASENAME) */ diff --git a/openssh/openbsd-compat/getopt.c b/openssh/openbsd-compat/getopt.c index f5ee677..5450e43 100644 --- a/openssh/openbsd-compat/getopt.c +++ b/openssh/openbsd-compat/getopt.c @@ -1,5 +1,3 @@ -/* OPENBSD ORIGINAL: lib/libc/stdlib/getopt.c */ - /* * Copyright (c) 1987, 1993, 1994 * The Regents of the University of California. All rights reserved. @@ -29,6 +27,8 @@ * SUCH DAMAGE. */ +/* OPENBSD ORIGINAL: lib/libc/stdlib/getopt.c */ + #include "includes.h" #if !defined(HAVE_GETOPT) || !defined(HAVE_GETOPT_OPTRESET) diff --git a/openssh/openbsd-compat/getrrsetbyname.c b/openssh/openbsd-compat/getrrsetbyname.c index 2016ffe..bea6aea 100644 --- a/openssh/openbsd-compat/getrrsetbyname.c +++ b/openssh/openbsd-compat/getrrsetbyname.c @@ -1,6 +1,4 @@ -/* OPENBSD ORIGINAL: lib/libc/net/getrrsetbyname.c */ - -/* $OpenBSD: getrrsetbyname.c,v 1.7 2003/03/07 07:34:14 itojun Exp $ */ +/* $OpenBSD: getrrsetbyname.c,v 1.10 2005/03/30 02:58:28 tedu Exp $ */ /* * Copyright (c) 2001 Jakob Schlyter. All rights reserved. @@ -45,54 +43,26 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +/* OPENBSD ORIGINAL: lib/libc/net/getrrsetbyname.c */ + #include "includes.h" #ifndef HAVE_GETRRSETBYNAME #include "getrrsetbyname.h" -#define ANSWER_BUFFER_SIZE 1024*64 - #if defined(HAVE_DECL_H_ERRNO) && !HAVE_DECL_H_ERRNO extern int h_errno; #endif -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 *); +/* We don't need multithread support here */ +#ifdef _THREAD_PRIVATE +# undef _THREAD_PRIVATE +#endif +#define _THREAD_PRIVATE(a,b,c) (c) +struct __res_state _res; -static int count_dns_rr(struct dns_rr *, u_int16_t, u_int16_t); +/* Necessary functions and macros */ /* * Inline versions of get/put short/long. Pointer is advanced. @@ -162,14 +132,56 @@ _getlong(msgp) u_int32_t _getlong(register const u_char *); #endif +/* ************** */ + +#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); + int getrrsetbyname(const char *hostname, unsigned int rdclass, unsigned int rdtype, unsigned int flags, struct rrsetinfo **res) { + struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res); int result; struct rrsetinfo *rrset = NULL; - struct dns_response *response; + struct dns_response *response = NULL; struct dns_rr *rr; struct rdatainfo *rdata; int length; @@ -195,19 +207,19 @@ getrrsetbyname(const char *hostname, unsigned int rdclass, } /* initialize resolver */ - if ((_res.options & RES_INIT) == 0 && res_init() == -1) { + if ((_resp->options & RES_INIT) == 0 && res_init() == -1) { result = ERRSET_FAIL; goto fail; } #ifdef DEBUG - _res.options |= RES_DEBUG; + _resp->options |= RES_DEBUG; #endif /* DEBUG */ #ifdef RES_USE_DNSSEC /* turn on DNSSEC if EDNS0 is configured */ - if (_res.options & RES_USE_EDNS0) - _res.options |= RES_USE_DNSSEC; + if (_resp->options & RES_USE_EDNS0) + _resp->options |= RES_USE_DNSSEC; #endif /* RES_USE_DNSEC */ /* make query */ @@ -257,13 +269,11 @@ getrrsetbyname(const char *hostname, unsigned int rdclass, #endif /* copy name from answer section */ - length = strlen(response->answer->name); - rrset->rri_name = malloc(length + 1); + rrset->rri_name = strdup(response->answer->name); 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, @@ -281,7 +291,7 @@ getrrsetbyname(const char *hostname, unsigned int rdclass, /* allocate memory for signatures */ rrset->rri_sigs = calloc(rrset->rri_nsigs, sizeof(struct rdatainfo)); - if (rrset->rri_nsigs > 0 && rrset->rri_sigs == NULL) { + if (rrset->rri_sigs == NULL) { result = ERRSET_NOMEMORY; goto fail; } @@ -311,6 +321,7 @@ getrrsetbyname(const char *hostname, unsigned int rdclass, memcpy(rdata->rdi_data, rr->rdata, rr->size); } } + free_dns_response(response); *res = rrset; return (ERRSET_SUCCESS); @@ -318,6 +329,8 @@ getrrsetbyname(const char *hostname, unsigned int rdclass, fail: if (rrset != NULL) freerrset(rrset); + if (response != NULL) + free_dns_response(response); return (result); } @@ -467,7 +480,8 @@ parse_dns_qsection(const u_char *answer, int size, const u_char **cp, int count) } static struct dns_rr * -parse_dns_rrsection(const u_char *answer, int size, const u_char **cp, int count) +parse_dns_rrsection(const u_char *answer, int size, const u_char **cp, + int count) { struct dns_rr *head, *curr, *prev; int i, length; diff --git a/openssh/openbsd-compat/strtoul.c b/openssh/openbsd-compat/strtoul.c index 24d0e25..8219c83 100644 --- a/openssh/openbsd-compat/strtoul.c +++ b/openssh/openbsd-compat/strtoul.c @@ -1,5 +1,4 @@ -/* OPENBSD ORIGINAL: lib/libc/stdlib/strtoul.c */ - +/* $OpenBSD: strtoul.c,v 1.7 2005/08/08 08:05:37 espie Exp $ */ /* * Copyright (c) 1990 Regents of the University of California. * All rights reserved. @@ -29,13 +28,11 @@ * SUCH DAMAGE. */ +/* OPENBSD ORIGINAL: lib/libc/stdlib/strtoul.c */ + #include "includes.h" #ifndef HAVE_STRTOUL -#if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: strtoul.c,v 1.5 2003/06/02 20:18:38 millert Exp $"; -#endif /* LIBC_SCCS and not lint */ - #include #include #include @@ -48,15 +45,12 @@ static char *rcsid = "$OpenBSD: strtoul.c,v 1.5 2003/06/02 20:18:38 millert Exp * alphabets and digits are each contiguous. */ unsigned long -strtoul(nptr, endptr, base) - const char *nptr; - char **endptr; - register int base; +strtoul(const char *nptr, char **endptr, int base) { - register const char *s; - register unsigned long acc, cutoff; - register int c; - register int neg, any, cutlim; + const char *s; + unsigned long acc, cutoff; + int c; + int neg, any, cutlim; /* * See strtol for comments as to the logic used. diff --git a/openssh/openbsd-compat/sys-queue.h b/openssh/openbsd-compat/sys-queue.h index c49a946..4023433 100644 --- a/openssh/openbsd-compat/sys-queue.h +++ b/openssh/openbsd-compat/sys-queue.h @@ -1,5 +1,3 @@ -/* OPENBSD ORIGINAL: sys/sys/queue.h */ - /* $OpenBSD: queue.h,v 1.25 2004/04/08 16:08:21 henning Exp $ */ /* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */ @@ -34,6 +32,8 @@ * @(#)queue.h 8.5 (Berkeley) 8/20/94 */ +/* OPENBSD ORIGINAL: sys/sys/queue.h */ + #ifndef _FAKE_QUEUE_H_ #define _FAKE_QUEUE_H_ diff --git a/openssh/openbsd-compat/sys-tree.h b/openssh/openbsd-compat/sys-tree.h index 73cfbe7..c80b90b 100644 --- a/openssh/openbsd-compat/sys-tree.h +++ b/openssh/openbsd-compat/sys-tree.h @@ -1,5 +1,3 @@ -/* OPENBSD ORIGINAL: sys/sys/tree.h */ - /* $OpenBSD: tree.h,v 1.7 2002/10/17 21:51:54 art Exp $ */ /* * Copyright 2002 Niels Provos @@ -26,6 +24,8 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* OPENBSD ORIGINAL: sys/sys/tree.h */ + #ifndef _SYS_TREE_H_ #define _SYS_TREE_H_ diff --git a/openssh/openbsd-compat/vis.c b/openssh/openbsd-compat/vis.c index 1fb7a01..3a087b3 100644 --- a/openssh/openbsd-compat/vis.c +++ b/openssh/openbsd-compat/vis.c @@ -1,5 +1,4 @@ -/* OPENBSD ORIGINAL: lib/libc/gen/vis.c */ - +/* $OpenBSD: vis.c,v 1.19 2005/09/01 17:15:49 millert Exp $ */ /*- * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. @@ -28,36 +27,34 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ + +/* OPENBSD ORIGINAL: lib/libc/gen/vis.c */ + #include "includes.h" #if !defined(HAVE_STRNVIS) -#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))))) +#define isvisible(c) \ + (((u_int)(c) <= UCHAR_MAX && isascii((u_char)(c)) && \ + (((c) != '*' && (c) != '?' && (c) != '[' && (c) != '#') || \ + (flag & VIS_GLOB) == 0) && isgraph((u_char)(c))) || \ + ((flag & VIS_SP) == 0 && (c) == ' ') || \ + ((flag & VIS_TAB) == 0 && (c) == '\t') || \ + ((flag & VIS_NL) == 0 && (c) == '\n') || \ + ((flag & VIS_SAFE) && ((c) == '\b' || \ + (c) == '\007' || (c) == '\r' || \ + isgraph((u_char)(c))))) /* * vis - visually encode characters */ char * -vis(dst, c, flag, nextc) - register char *dst; - int c, nextc; - register int flag; +vis(char *dst, int c, int flag, int nextc) { if (isvisible(c)) { *dst++ = c; @@ -111,7 +108,8 @@ vis(dst, c, flag, nextc) goto done; } } - if (((c & 0177) == ' ') || (flag & VIS_OCTAL)) { + if (((c & 0177) == ' ') || (flag & VIS_OCTAL) || + ((flag & VIS_GLOB) && (c == '*' || c == '?' || c == '[' || c == '#'))) { *dst++ = '\\'; *dst++ = ((u_char)c >> 6 & 07) + '0'; *dst++ = ((u_char)c >> 3 & 07) + '0'; @@ -124,7 +122,7 @@ vis(dst, c, flag, nextc) c &= 0177; *dst++ = 'M'; } - if (iscntrl(c)) { + if (iscntrl((u_char)c)) { *dst++ = '^'; if (c == 0177) *dst++ = '?'; @@ -153,12 +151,9 @@ done: * This is useful for encoding a block of data. */ int -strvis(dst, src, flag) - register char *dst; - register const char *src; - int flag; +strvis(char *dst, const char *src, int flag) { - register char c; + char c; char *start; for (start = dst; (c = *src);) @@ -168,16 +163,11 @@ strvis(dst, src, flag) } int -strnvis(dst, src, siz, flag) - char *dst; - const char *src; - size_t siz; - int flag; +strnvis(char *dst, const char *src, size_t siz, int flag) { - char c; char *start, *end; char tbuf[5]; - int i; + int c, i; i = 0; for (start = dst, end = start + siz - 1; (c = *src) && dst < end; ) { @@ -217,13 +207,9 @@ strnvis(dst, src, siz, flag) } int -strvisx(dst, src, len, flag) - register char *dst; - register const char *src; - register size_t len; - int flag; +strvisx(char *dst, const char *src, size_t len, int flag) { - register char c; + char c; char *start; for (start = dst; len > 1; len--) { diff --git a/openssh/openbsd-compat/vis.h b/openssh/openbsd-compat/vis.h index 663355a..3898a9e 100644 --- a/openssh/openbsd-compat/vis.h +++ b/openssh/openbsd-compat/vis.h @@ -1,6 +1,4 @@ -/* OPENBSD ORIGINAL: include/vis.h */ - -/* $OpenBSD: vis.h,v 1.6 2003/06/02 19:34:12 millert Exp $ */ +/* $OpenBSD: vis.h,v 1.11 2005/08/09 19:38:31 millert Exp $ */ /* $NetBSD: vis.h,v 1.4 1994/10/26 00:56:41 cgd Exp $ */ /*- @@ -34,6 +32,8 @@ * @(#)vis.h 5.9 (Berkeley) 4/3/91 */ +/* OPENBSD ORIGINAL: include/vis.h */ + #include "includes.h" #if !defined(HAVE_STRNVIS) @@ -63,6 +63,7 @@ * other */ #define VIS_NOSLASH 0x40 /* inhibit printing '\' */ +#define VIS_GLOB 0x100 /* encode glob(3) magics and '#' */ /* * unvis return codes @@ -80,10 +81,14 @@ 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 strnvis(char *, const char *, size_t, int) + __attribute__ ((__bounded__(__string__,1,3))); +int strvisx(char *, const char *, size_t, int) + __attribute__ ((__bounded__(__string__,1,3))); int strunvis(char *, const char *); int unvis(char *, char, int *, int); +ssize_t strnunvis(char *, const char *, size_t) + __attribute__ ((__bounded__(__string__,1,3))); #endif /* !_VIS_H_ */ diff --git a/openssh/packet.c b/openssh/packet.c index 94bbec3..ee81f68 100644 --- a/openssh/packet.c +++ b/openssh/packet.c @@ -37,7 +37,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: packet.c,v 1.119 2005/07/28 17:36:22 markus Exp $"); +RCSID("$OpenBSD: packet.c,v 1.120 2005/10/30 08:52:17 djm Exp $"); #include "openbsd-compat/sys-queue.h" @@ -572,7 +572,7 @@ packet_send1(void) buffer_clear(&outgoing_packet); /* - * Note that the packet is now only buffered in output. It won\'t be + * Note that the packet is now only buffered in output. It won't be * actually sent until packet_write_wait or packet_write_poll is * called. */ diff --git a/openssh/progressmeter.c b/openssh/progressmeter.c index 3cda090..13c51d8 100644 --- a/openssh/progressmeter.c +++ b/openssh/progressmeter.c @@ -85,8 +85,8 @@ format_rate(char *buf, int size, off_t bytes) bytes = (bytes + 512) / 1024; } snprintf(buf, size, "%3lld.%1lld%c%s", - (int64_t) (bytes + 5) / 100, - (int64_t) (bytes + 5) / 10 % 10, + (long long) (bytes + 5) / 100, + (long long) (bytes + 5) / 10 % 10, unit[i], i ? "B" : " "); } @@ -99,7 +99,7 @@ format_size(char *buf, int size, off_t bytes) for (i = 0; bytes >= 10000 && unit[i] != 'T'; i++) bytes = (bytes + 512) / 1024; snprintf(buf, size, "%4lld%c%s", - (int64_t) bytes, + (long long) bytes, unit[i], i ? "B" : " "); } diff --git a/openssh/readconf.c b/openssh/readconf.c index f9d400a..1585570 100644 --- a/openssh/readconf.c +++ b/openssh/readconf.c @@ -12,7 +12,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: readconf.c,v 1.143 2005/07/30 02:03:47 djm Exp $"); +RCSID("$OpenBSD: readconf.c,v 1.145 2005/12/08 18:34:11 reyk Exp $"); #include "ssh.h" #include "xmalloc.h" @@ -70,6 +70,10 @@ RCSID("$OpenBSD: readconf.c,v 1.143 2005/07/30 02:03:47 djm Exp $"); Cipher none PasswordAuthentication no + Host vpn.fake.com + Tunnel yes + TunnelDevice 3 + # Defaults for various options Host * ForwardAgent no @@ -108,6 +112,7 @@ typedef enum { oGssTrustDns, oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, oSendEnv, oControlPath, oControlMaster, oHashKnownHosts, + oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, oDeprecated, oUnsupported } OpCodes; @@ -203,6 +208,10 @@ static struct { { "controlpath", oControlPath }, { "controlmaster", oControlMaster }, { "hashknownhosts", oHashKnownHosts }, + { "tunnel", oTunnel }, + { "tunneldevice", oTunnelDevice }, + { "localcommand", oLocalCommand }, + { "permitlocalcommand", oPermitLocalCommand }, { NULL, oBadOption } }; @@ -269,6 +278,7 @@ clear_forwardings(Options *options) xfree(options->remote_forwards[i].connect_host); } options->num_remote_forwards = 0; + options->tun_open = SSH_TUNMODE_NO; } /* @@ -301,7 +311,7 @@ process_config_line(Options *options, const char *host, int *activep) { char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256]; - int opcode, *intptr, value; + int opcode, *intptr, value, value2; size_t len; Forward fwd; @@ -566,9 +576,10 @@ parse_string: goto parse_string; case oProxyCommand: + charptr = &options->proxy_command; +parse_command: if (s == NULL) fatal("%.200s line %d: Missing argument.", filename, linenum); - charptr = &options->proxy_command; len = strspn(s, WHITESPACE "="); if (*activep && *charptr == NULL) *charptr = xstrdup(s + len); @@ -835,6 +846,49 @@ parse_int: intptr = &options->hash_known_hosts; goto parse_flag; + case oTunnel: + intptr = &options->tun_open; + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%s line %d: Missing yes/point-to-point/" + "ethernet/no argument.", filename, linenum); + value = 0; /* silence compiler */ + if (strcasecmp(arg, "ethernet") == 0) + value = SSH_TUNMODE_ETHERNET; + else if (strcasecmp(arg, "point-to-point") == 0) + value = SSH_TUNMODE_POINTOPOINT; + else if (strcasecmp(arg, "yes") == 0) + value = SSH_TUNMODE_DEFAULT; + else if (strcasecmp(arg, "no") == 0) + value = SSH_TUNMODE_NO; + else + fatal("%s line %d: Bad yes/point-to-point/ethernet/" + "no argument: %s", filename, linenum, arg); + if (*activep) + *intptr = value; + break; + + case oTunnelDevice: + arg = strdelim(&s); + if (!arg || *arg == '\0') + fatal("%.200s line %d: Missing argument.", filename, linenum); + value = a2tun(arg, &value2); + if (value == SSH_TUNID_ERR) + fatal("%.200s line %d: Bad tun device.", filename, linenum); + if (*activep) { + options->tun_local = value; + options->tun_remote = value2; + } + break; + + case oLocalCommand: + charptr = &options->local_command; + goto parse_command; + + case oPermitLocalCommand: + intptr = &options->permit_local_command; + goto parse_flag; + case oDeprecated: debug("%s line %d: Deprecated option \"%s\"", filename, linenum, keyword); @@ -982,6 +1036,11 @@ initialize_options(Options * options) options->control_path = NULL; options->control_master = -1; options->hash_known_hosts = -1; + options->tun_open = -1; + options->tun_local = -1; + options->tun_remote = -1; + options->local_command = NULL; + options->permit_local_command = -1; } /* @@ -1112,6 +1171,15 @@ fill_default_options(Options * options) options->control_master = 0; if (options->hash_known_hosts == -1) options->hash_known_hosts = 0; + if (options->tun_open == -1) + options->tun_open = SSH_TUNMODE_NO; + if (options->tun_local == -1) + options->tun_local = SSH_TUNID_ANY; + if (options->tun_remote == -1) + options->tun_remote = SSH_TUNID_ANY; + if (options->permit_local_command == -1) + options->permit_local_command = 0; + /* options->local_command should not be set by default */ /* options->proxy_command should not be set by default */ /* options->user will be set in the main program if appropriate */ /* options->hostname will be set in the main program if appropriate */ diff --git a/openssh/readconf.h b/openssh/readconf.h index c72bb62..4a2d095 100644 --- a/openssh/readconf.h +++ b/openssh/readconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.h,v 1.67 2005/06/08 11:25:09 djm Exp $ */ +/* $OpenBSD: readconf.h,v 1.68 2005/12/06 22:38:27 reyk Exp $ */ /* * Author: Tatu Ylonen @@ -120,6 +120,14 @@ typedef struct { int control_master; int hash_known_hosts; + + int tun_open; /* tun(4) */ + int tun_local; /* force tun device (optional) */ + int tun_remote; /* force tun device (optional) */ + + char *local_command; + int permit_local_command; + } Options; #define SSHCTL_MASTER_NO 0 diff --git a/openssh/scp.c b/openssh/scp.c index bd0f648..cf11122 100644 --- a/openssh/scp.c +++ b/openssh/scp.c @@ -71,7 +71,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: scp.c,v 1.125 2005/07/27 10:39:03 dtucker Exp $"); +RCSID("$OpenBSD: scp.c,v 1.130 2006/01/31 10:35:43 djm Exp $"); #include "xmalloc.h" #include "atomicio.h" @@ -118,6 +118,48 @@ killchild(int signo) exit(1); } +static int +do_local_cmd(arglist *a) +{ + u_int i; + int status; + pid_t pid; + + if (a->num == 0) + fatal("do_local_cmd: no arguments"); + + if (verbose_mode) { + fprintf(stderr, "Executing:"); + for (i = 0; i < a->num; i++) + fprintf(stderr, " %s", a->list[i]); + fprintf(stderr, "\n"); + } + if ((pid = fork()) == -1) + fatal("do_local_cmd: fork: %s", strerror(errno)); + + if (pid == 0) { + execvp(a->list[0], a->list); + perror(a->list[0]); + exit(1); + } + + do_cmd_pid = pid; + signal(SIGTERM, killchild); + signal(SIGINT, killchild); + signal(SIGHUP, killchild); + + while (waitpid(pid, &status, 0) == -1) + if (errno != EINTR) + fatal("do_local_cmd: waitpid: %s", strerror(errno)); + + do_cmd_pid = -1; + + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) + return (-1); + + return (0); +} + /* * This function executes the given command as the specified user on the * given host. This returns < 0 if execution fails, and >= 0 otherwise. This @@ -162,7 +204,7 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc) close(pin[0]); close(pout[1]); - args.list[0] = ssh_program; + replacearg(&args, 0, "%s", ssh_program); if (remuser != NULL) addargs(&args, "-l%s", remuser); addargs(&args, "%s", host); @@ -222,12 +264,17 @@ main(int argc, char **argv) extern char *optarg; extern int optind; + /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ + sanitise_stdfd(); + __progname = ssh_get_progname(argv[0]); + memset(&args, '\0', sizeof(args)); args.list = NULL; - addargs(&args, "ssh"); /* overwritten with ssh_program */ + addargs(&args, "%s", ssh_program); addargs(&args, "-x"); addargs(&args, "-oForwardAgent no"); + addargs(&args, "-oPermitLocalCommand no"); addargs(&args, "-oClearAllForwardings yes"); fflag = tflag = 0; @@ -340,9 +387,9 @@ main(int argc, char **argv) if ((targ = colon(argv[argc - 1]))) /* Dest is remote host. */ toremote(targ, argc, argv); else { - tolocal(argc, argv); /* Dest is local host. */ if (targetshouldbedirectory) verifydir(argv[argc - 1]); + tolocal(argc, argv); /* Dest is local host. */ } /* * Finally check the exit status of the ssh process, if one was forked @@ -368,6 +415,10 @@ toremote(char *targ, int argc, char **argv) { int i, len; char *bp, *host, *src, *suser, *thost, *tuser, *arg; + arglist alist; + + memset(&alist, '\0', sizeof(alist)); + alist.list = NULL; *targ++ = 0; if (*targ == 0) @@ -385,56 +436,48 @@ toremote(char *targ, int argc, char **argv) tuser = NULL; } + if (tuser != NULL && !okname(tuser)) { + xfree(arg); + return; + } + for (i = 0; i < argc - 1; i++) { src = colon(argv[i]); if (src) { /* remote to remote */ - static char *ssh_options = - "-x -o'ClearAllForwardings yes'"; + freeargs(&alist); + addargs(&alist, "%s", ssh_program); + if (verbose_mode) + addargs(&alist, "-v"); + addargs(&alist, "-x"); + addargs(&alist, "-oClearAllForwardings yes"); + addargs(&alist, "-n"); + *src++ = 0; if (*src == 0) src = "."; host = strrchr(argv[i], '@'); - len = strlen(ssh_program) + strlen(argv[i]) + - strlen(src) + (tuser ? strlen(tuser) : 0) + - strlen(thost) + strlen(targ) + - strlen(ssh_options) + CMDNEEDS + 20; - bp = xmalloc(len); + if (host) { *host++ = 0; host = cleanhostname(host); suser = argv[i]; if (*suser == '\0') suser = pwd->pw_name; - else if (!okname(suser)) { - xfree(bp); + else if (!okname(suser)) continue; - } - if (tuser && !okname(tuser)) { - xfree(bp); - continue; - } - snprintf(bp, len, - "%s%s %s -n " - "-l %s %s %s %s '%s%s%s:%s'", - ssh_program, verbose_mode ? " -v" : "", - ssh_options, suser, host, cmd, src, - tuser ? tuser : "", tuser ? "@" : "", - thost, targ); + addargs(&alist, "-l"); + addargs(&alist, "%s", suser); } else { host = cleanhostname(argv[i]); - snprintf(bp, len, - "exec %s%s %s -n %s " - "%s %s '%s%s%s:%s'", - ssh_program, verbose_mode ? " -v" : "", - ssh_options, host, cmd, src, - tuser ? tuser : "", tuser ? "@" : "", - thost, targ); } - if (verbose_mode) - fprintf(stderr, "Executing: %s\n", bp); - if (system(bp) != 0) + addargs(&alist, "%s", host); + addargs(&alist, "%s", cmd); + addargs(&alist, "%s", src); + addargs(&alist, "%s%s%s:%s", + tuser ? tuser : "", tuser ? "@" : "", + thost, targ); + if (do_local_cmd(&alist) != 0) errs = 1; - (void) xfree(bp); } else { /* local to remote */ if (remin == -1) { len = strlen(targ) + CMDNEEDS + 20; @@ -458,20 +501,23 @@ tolocal(int argc, char **argv) { int i, len; char *bp, *host, *src, *suser; + arglist alist; + + memset(&alist, '\0', sizeof(alist)); + alist.list = NULL; for (i = 0; i < argc - 1; i++) { if (!(src = colon(argv[i]))) { /* Local to local. */ - len = strlen(_PATH_CP) + strlen(argv[i]) + - strlen(argv[argc - 1]) + 20; - bp = xmalloc(len); - (void) snprintf(bp, len, "exec %s%s%s %s %s", _PATH_CP, - iamrecursive ? " -r" : "", pflag ? " -p" : "", - argv[i], argv[argc - 1]); - if (verbose_mode) - fprintf(stderr, "Executing: %s\n", bp); - if (system(bp)) + freeargs(&alist); + addargs(&alist, "%s", _PATH_CP); + if (iamrecursive) + addargs(&alist, "-r"); + if (pflag) + addargs(&alist, "-p"); + addargs(&alist, "%s", argv[i]); + addargs(&alist, "%s", argv[argc-1]); + if (do_local_cmd(&alist)) ++errs; - (void) xfree(bp); continue; } *src++ = 0; @@ -564,7 +610,7 @@ syserr: run_err("%s: %s", name, strerror(errno)); #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), - (int64_t)stb.st_size, last); + (long long)stb.st_size, last); if (verbose_mode) { fprintf(stderr, "Sending file modes: %s", buf); } @@ -576,7 +622,10 @@ syserr: run_err("%s: %s", name, strerror(errno)); /* buf can actually remain at 2k but increasing both to 16k*/ /* seemed to make sense*/ if ((bp = allocbuf(&buffer, fd, sizeof(buf))) == NULL) { -next: (void) close(fd); +next: if (fd != -1) { + (void) close(fd); + fd = -1; + } continue; } if (showprogress) @@ -605,8 +654,11 @@ next: (void) close(fd); if (showprogress) stop_progress_meter(); - if (close(fd) < 0 && !haderr) - haderr = errno; + if (fd != -1) { + if (close(fd) < 0 && !haderr) + haderr = errno; + fd = -1; + } if (!haderr) (void) atomicio(vwrite, remout, "", 1); else diff --git a/openssh/servconf.c b/openssh/servconf.c index ece97dc..43e5812 100644 --- a/openssh/servconf.c +++ b/openssh/servconf.c @@ -10,7 +10,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: servconf.c,v 1.144 2005/08/06 10:03:12 dtucker Exp $"); +RCSID("$OpenBSD: servconf.c,v 1.146 2005/12/08 18:34:11 reyk Exp $"); #include "ssh.h" #include "log.h" @@ -107,6 +107,7 @@ initialize_server_options(ServerOptions *options) options->authorized_keys_file = NULL; options->authorized_keys_file2 = NULL; options->num_accept_env = 0; + options->permit_tun = -1; /* Needs to be accessable in many places */ use_privsep = -1; @@ -237,6 +238,8 @@ fill_default_server_options(ServerOptions *options) } if (options->authorized_keys_file == NULL) options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS; + if (options->permit_tun == -1) + options->permit_tun = SSH_TUNMODE_NO; /* Turn privilege separation on by default */ if (use_privsep == -1) @@ -281,7 +284,8 @@ typedef enum { sBanner, sUseDNS, sHostbasedAuthentication, sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, - sGssAuthentication, sGssKeyEx, sGssCleanupCreds, sAcceptEnv, + sGssKeyEx, + sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, sUsePrivilegeSeparation, sDeprecated, sUnsupported } ServerOpCodes; @@ -391,6 +395,7 @@ static struct { { "authorizedkeysfile2", sAuthorizedKeysFile2 }, { "useprivilegeseparation", sUsePrivilegeSeparation}, { "acceptenv", sAcceptEnv }, + { "permittunnel", sPermitTunnel }, { NULL, sBadOption } }; @@ -1001,6 +1006,28 @@ parse_flag: } break; + case sPermitTunnel: + intptr = &options->permit_tun; + arg = strdelim(&cp); + if (!arg || *arg == '\0') + fatal("%s line %d: Missing yes/point-to-point/" + "ethernet/no argument.", filename, linenum); + value = 0; /* silence compiler */ + if (strcasecmp(arg, "ethernet") == 0) + value = SSH_TUNMODE_ETHERNET; + else if (strcasecmp(arg, "point-to-point") == 0) + value = SSH_TUNMODE_POINTOPOINT; + else if (strcasecmp(arg, "yes") == 0) + value = SSH_TUNMODE_YES; + else if (strcasecmp(arg, "no") == 0) + value = SSH_TUNMODE_NO; + else + fatal("%s line %d: Bad yes/point-to-point/ethernet/" + "no argument: %s", filename, linenum, arg); + if (*intptr == -1) + *intptr = value; + break; + case sDeprecated: logit("%s line %d: Deprecated option %s", filename, linenum, arg); diff --git a/openssh/servconf.h b/openssh/servconf.h index 1750622..5c784e1 100644 --- a/openssh/servconf.h +++ b/openssh/servconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.h,v 1.71 2004/12/23 23:11:00 djm Exp $ */ +/* $OpenBSD: servconf.h,v 1.72 2005/12/06 22:38:27 reyk Exp $ */ /* * Author: Tatu Ylonen @@ -139,7 +139,10 @@ typedef struct { char *authorized_keys_file; /* File containing public keys */ char *authorized_keys_file2; + int use_pam; /* Enable auth via PAM */ + + int permit_tun; } ServerOptions; void initialize_server_options(ServerOptions *); diff --git a/openssh/serverloop.c b/openssh/serverloop.c index 12f3601..b60932f 100644 --- a/openssh/serverloop.c +++ b/openssh/serverloop.c @@ -35,7 +35,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: serverloop.c,v 1.118 2005/07/17 07:17:55 djm Exp $"); +RCSID("$OpenBSD: serverloop.c,v 1.124 2005/12/13 15:03:02 reyk Exp $"); #include "xmalloc.h" #include "packet.h" @@ -61,6 +61,7 @@ extern ServerOptions options; /* XXX */ extern Kex *xxx_kex; extern Authctxt *the_authctxt; +extern int use_privsep; static Buffer stdin_buffer; /* Buffer for stdin data. */ static Buffer stdout_buffer; /* Buffer for stdout data. */ @@ -90,6 +91,9 @@ static int client_alive_timeouts = 0; static volatile sig_atomic_t child_terminated = 0; /* The child has terminated. */ +/* Cleanup on signals (!use_privsep case only) */ +static volatile sig_atomic_t received_sigterm = 0; + /* prototypes */ static void server_init_dispatch(void); @@ -151,6 +155,12 @@ sigchld_handler(int sig) errno = save_errno; } +static void +sigterm_handler(int sig) +{ + received_sigterm = sig; +} + /* * Make packets from buffered stderr data, and buffer it for sending * to the client. @@ -502,6 +512,12 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) child_terminated = 0; mysignal(SIGCHLD, sigchld_handler); + if (!use_privsep) { + signal(SIGTERM, sigterm_handler); + signal(SIGINT, sigterm_handler); + signal(SIGQUIT, sigterm_handler); + } + /* Initialize our global variables. */ fdin = fdin_arg; fdout = fdout_arg; @@ -548,7 +564,7 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) * If we have no separate fderr (which is the case when we have a pty * - there we cannot make difference between data sent to stdout and * stderr), indicate that we have seen an EOF from stderr. This way - * we don\'t need to check the descriptor everywhere. + * we don't need to check the descriptor everywhere. */ if (fderr == -1) fderr_eof = 1; @@ -629,6 +645,12 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) wait_until_can_do_something(&readset, &writeset, &max_fd, &nalloc, max_time_milliseconds); + if (received_sigterm) { + logit("Exiting on signal %d", received_sigterm); + /* Clean up sessions, utmp, etc. */ + cleanup_exit(255); + } + /* Process any channel events. */ channel_after_select(readset, writeset); @@ -749,6 +771,12 @@ server_loop2(Authctxt *authctxt) connection_in = packet_get_connection_in(); connection_out = packet_get_connection_out(); + if (!use_privsep) { + signal(SIGTERM, sigterm_handler); + signal(SIGINT, sigterm_handler); + signal(SIGQUIT, sigterm_handler); + } + notify_setup(); max_fd = MAX(connection_in, connection_out); @@ -766,6 +794,12 @@ server_loop2(Authctxt *authctxt) wait_until_can_do_something(&readset, &writeset, &max_fd, &nalloc, 0); + if (received_sigterm) { + logit("Exiting on signal %d", received_sigterm); + /* Clean up sessions, utmp, etc. */ + cleanup_exit(255); + } + collect_children(); if (!rekeying) { channel_after_select(readset, writeset); @@ -879,6 +913,52 @@ server_request_direct_tcpip(void) return c; } +static Channel * +server_request_tun(void) +{ + Channel *c = NULL; + int mode, tun; + int sock; + + mode = packet_get_int(); + switch (mode) { + case SSH_TUNMODE_POINTOPOINT: + case SSH_TUNMODE_ETHERNET: + break; + default: + packet_send_debug("Unsupported tunnel device mode."); + return NULL; + } + if ((options.permit_tun & mode) == 0) { + packet_send_debug("Server has rejected tunnel device " + "forwarding"); + return NULL; + } + + tun = packet_get_int(); + if (forced_tun_device != -1) { + if (tun != SSH_TUNID_ANY && forced_tun_device != tun) + goto done; + tun = forced_tun_device; + } + sock = tun_open(tun, mode); + if (sock < 0) + goto done; + c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1, + CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); + c->datagram = 1; +#if defined(SSH_TUN_FILTER) + if (mode == SSH_TUNMODE_POINTOPOINT) + channel_register_filter(c->self, sys_tun_infilter, + sys_tun_outfilter); +#endif + + done: + if (c == NULL) + packet_send_debug("Failed to open the tunnel device."); + return c; +} + static Channel * server_request_session(void) { @@ -902,7 +982,7 @@ server_request_session(void) channel_free(c); return NULL; } - channel_register_cleanup(c->self, session_close_by_channel); + channel_register_cleanup(c->self, session_close_by_channel, 0); return c; } @@ -926,6 +1006,8 @@ server_input_channel_open(int type, u_int32_t seq, void *ctxt) c = server_request_session(); } else if (strcmp(ctype, "direct-tcpip") == 0) { c = server_request_direct_tcpip(); + } else if (strcmp(ctype, "tun@openssh.com") == 0) { + c = server_request_tun(); } if (c != NULL) { debug("server_input_channel_open: confirm %s", ctype); diff --git a/openssh/session.c b/openssh/session.c index 9de2097..ecd2007 100644 --- a/openssh/session.c +++ b/openssh/session.c @@ -33,7 +33,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: session.c,v 1.186 2005/07/25 11:59:40 markus Exp $"); +RCSID("$OpenBSD: session.c,v 1.191 2005/12/24 02:27:41 djm Exp $"); #include "ssh.h" #include "ssh1.h" @@ -214,15 +214,6 @@ do_authenticated(Authctxt *authctxt) { setproctitle("%s", authctxt->pw->pw_name); - /* - * Cancel the alarm we set to limit the time taken for - * authentication. - */ - alarm(0); - if (startup_pipe != -1) { - close(startup_pipe); - startup_pipe = -1; - } /* setup the channel layer */ if (!no_port_forwarding_flag && options.allow_tcp_forwarding) channel_permit_all_opens(); @@ -1587,7 +1578,7 @@ child_close_fds(void) endpwent(); /* - * Close any extra open file descriptors so that we don\'t have them + * Close any extra open file descriptors so that we don't have them * hanging around in clients. Note that we want to do this after * initgroups, because at least on Solaris 2.3 it leaves file * descriptors open. @@ -1651,7 +1642,9 @@ do_child(Session *s, const char *command) if (!check_quietlogin(s, command)) do_motd(); #else /* HAVE_OSF_SIA */ - do_nologin(pw); + /* When PAM is enabled we rely on it to do the nologin check */ + if (!options.use_pam) + do_nologin(pw); do_setusercontext(pw); /* * PAM session modules in do_setusercontext may have @@ -1767,7 +1760,7 @@ do_child(Session *s, const char *command) } #endif - /* Change current directory to the user\'s home directory. */ + /* Change current directory to the user's home directory. */ if (chdir(pw->pw_dir) < 0) { fprintf(stderr, "Could not chdir to home directory %s: %s\n", pw->pw_dir, strerror(errno)); @@ -2082,7 +2075,7 @@ session_x11_req(Session *s) if (s->auth_proto != NULL || s->auth_data != NULL) { error("session_x11_req: session %d: " - "x11 fowarding already active", s->self); + "x11 forwarding already active", s->self); return 0; } s->single_connection = packet_get_char(); @@ -2314,7 +2307,7 @@ session_close_x11(int id) { Channel *c; - if ((c = channel_lookup(id)) == NULL) { + if ((c = channel_by_id(id)) == NULL) { debug("session_close_x11: x11 channel %d missing", id); } else { /* Detach X11 listener */ @@ -2369,7 +2362,6 @@ static void session_exit_message(Session *s, int status) { Channel *c; - u_int i; if ((c = channel_lookup(s->chanid)) == NULL) fatal("session_exit_message: session %d: no channel %d", @@ -2399,7 +2391,15 @@ session_exit_message(Session *s, int status) /* disconnect channel */ debug("session_exit_message: release channel %d", s->chanid); - channel_cancel_cleanup(s->chanid); + s->pid = 0; + + /* + * Adjust cleanup callback attachment to send close messages when + * the channel gets EOF. The session will be then be closed + * by session_close_by_channel when the childs close their fds. + */ + channel_register_cleanup(c->self, session_close_by_channel, 1); + /* * emulate a write failure with 'chan_write_failed', nobody will be * interested in data we write. @@ -2408,15 +2408,6 @@ session_exit_message(Session *s, int status) */ if (c->ostate != CHAN_OUTPUT_CLOSED) chan_write_failed(c); - s->chanid = -1; - - /* Close any X11 listeners associated with this session */ - if (s->x11_chanids != NULL) { - for (i = 0; s->x11_chanids[i] != -1; i++) { - session_close_x11(s->x11_chanids[i]); - s->x11_chanids[i] = -1; - } - } } void @@ -2460,7 +2451,8 @@ session_close_by_pid(pid_t pid, int status) } if (s->chanid != -1) session_exit_message(s, status); - session_close(s); + if (s->ttyfd != -1) + session_pty_cleanup(s); } /* @@ -2471,6 +2463,7 @@ void session_close_by_channel(int id, void *arg) { Session *s = session_by_channel(id); + u_int i; if (s == NULL) { debug("session_close_by_channel: no session for id %d", id); @@ -2490,6 +2483,15 @@ session_close_by_channel(int id, void *arg) } /* detach by removing callback */ channel_cancel_cleanup(s->chanid); + + /* Close any X11 listeners associated with this session */ + if (s->x11_chanids != NULL) { + for (i = 0; s->x11_chanids[i] != -1; i++) { + session_close_x11(s->x11_chanids[i]); + s->x11_chanids[i] = -1; + } + } + s->chanid = -1; session_close(s); } @@ -2584,7 +2586,7 @@ session_setup_x11fwd(Session *s) } for (i = 0; s->x11_chanids[i] != -1; i++) { channel_register_cleanup(s->x11_chanids[i], - session_close_single_x11); + session_close_single_x11, 0); } /* Set up a suitable value for the DISPLAY variable. */ diff --git a/openssh/ssh-agent.c b/openssh/ssh-agent.c index dd7e22a..a69c25e 100644 --- a/openssh/ssh-agent.c +++ b/openssh/ssh-agent.c @@ -35,7 +35,7 @@ #include "includes.h" #include "openbsd-compat/sys-queue.h" -RCSID("$OpenBSD: ssh-agent.c,v 1.122 2004/10/29 22:53:56 djm Exp $"); +RCSID("$OpenBSD: ssh-agent.c,v 1.124 2005/10/30 08:52:18 djm Exp $"); #include #include @@ -355,7 +355,7 @@ process_remove_identity(SocketEntry *e, int version) if (id != NULL) { /* * We have this key. Free the old key. Since we - * don\'t want to leave empty slots in the middle of + * don't want to leave empty slots in the middle of * the array, we actually free the key there and move * all the entries between the empty slot and the end * of the array. @@ -1008,6 +1008,9 @@ main(int ac, char **av) pid_t pid; char pidstrbuf[1 + 3 * sizeof pid]; + /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ + sanitise_stdfd(); + /* drop */ setegid(getgid()); setgid(getgid()); diff --git a/openssh/ssh-keyscan.c b/openssh/ssh-keyscan.c index 46f0636..6915102 100644 --- a/openssh/ssh-keyscan.c +++ b/openssh/ssh-keyscan.c @@ -7,7 +7,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh-keyscan.c,v 1.55 2005/06/17 02:44:33 djm Exp $"); +RCSID("$OpenBSD: ssh-keyscan.c,v 1.57 2005/10/30 04:01:03 djm Exp $"); #include "openbsd-compat/sys-queue.h" @@ -499,12 +499,18 @@ congreet(int s) size_t bufsiz; con *c = &fdcon[s]; - bufsiz = sizeof(buf); - cp = buf; - while (bufsiz-- && (n = atomicio(read, s, cp, 1)) == 1 && *cp != '\n') { - if (*cp == '\r') - *cp = '\n'; - cp++; + for (;;) { + memset(buf, '\0', sizeof(buf)); + bufsiz = sizeof(buf); + cp = buf; + while (bufsiz-- && + (n = atomicio(read, s, cp, 1)) == 1 && *cp != '\n') { + if (*cp == '\r') + *cp = '\n'; + cp++; + } + if (n != 1 || strncmp(buf, "SSH-", 4) == 0) + break; } if (n == 0) { switch (errno) { @@ -712,6 +718,9 @@ main(int argc, char **argv) seed_rng(); TAILQ_INIT(&tq); + /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ + sanitise_stdfd(); + if (argc <= 1) usage(); diff --git a/openssh/ssh-keysign.c b/openssh/ssh-keysign.c index 04597a9..dae3a2e 100644 --- a/openssh/ssh-keysign.c +++ b/openssh/ssh-keysign.c @@ -22,7 +22,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$OpenBSD: ssh-keysign.c,v 1.18 2004/08/23 14:29:23 dtucker Exp $"); +RCSID("$OpenBSD: ssh-keysign.c,v 1.19 2005/09/13 23:40:07 djm Exp $"); #include #include @@ -148,6 +148,13 @@ main(int argc, char **argv) u_int slen, dlen; u_int32_t rnd[256]; + /* Ensure that stdin and stdout are connected */ + if ((fd = open(_PATH_DEVNULL, O_RDWR)) < 2) + exit(1); + /* Leave /dev/null fd iff it is attached to stderr */ + if (fd > 2) + close(fd); + key_fd[0] = open(_PATH_HOST_RSA_KEY_FILE, O_RDONLY); key_fd[1] = open(_PATH_HOST_DSA_KEY_FILE, O_RDONLY); diff --git a/openssh/ssh.1 b/openssh/ssh.1 index b074976..f4c6776 100644 --- a/openssh/ssh.1 +++ b/openssh/ssh.1 @@ -34,7 +34,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. .\" -.\" $OpenBSD: ssh.1,v 1.209 2005/07/06 09:33:05 dtucker Exp $ +.\" $OpenBSD: ssh.1,v 1.253 2006/01/30 13:37:49 jmc Exp $ .Dd September 25, 1999 .Dt SSH 1 .Os @@ -43,21 +43,29 @@ .Nd OpenSSH SSH client (remote login program) .Sh SYNOPSIS .Nm ssh -.Bk -words .Op Fl 1246AaCfgkMNnqsTtVvXxY .Op Fl b Ar bind_address .Op Fl c Ar cipher_spec -.Op Fl D Ar port +.Oo Fl D\ \& +.Sm off +.Oo Ar bind_address : Oc +.Ar port +.Sm on +.Oc .Op Fl e Ar escape_char .Op Fl F Ar configfile +.Bk -words .Op Fl i Ar identity_file +.Ek .Oo Fl L\ \& .Sm off .Oo Ar bind_address : Oc .Ar port : host : hostport .Sm on .Oc +.Bk -words .Op Fl l Ar login_name +.Ek .Op Fl m Ar mac_spec .Op Fl O Ar ctl_cmd .Op Fl o Ar option @@ -69,6 +77,8 @@ .Sm on .Oc .Op Fl S Ar ctl_path +.Bk -words +.Op Fl w Ar tunnel : Ns Ar tunnel .Oo Ar user Ns @ Oc Ns Ar hostname .Op Ar command .Ek @@ -79,7 +89,7 @@ executing commands on 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 +X11 connections and arbitrary TCP ports can also be forwarded over the secure channel. .Pp .Nm @@ -90,306 +100,12 @@ connects and logs into the specified name). The user must prove his/her identity to the remote machine using one of several methods -depending on the protocol version used. +depending on the protocol version used (see below). .Pp If .Ar command is specified, -.Ar command -is executed on the remote host instead of a login shell. -.Ss SSH protocol version 1 -The first authentication method is the -.Em rhosts -or -.Em hosts.equiv -method combined with RSA-based host authentication. -If the machine the user logs in from is listed in -.Pa /etc/hosts.equiv -or -.Pa /etc/shosts.equiv -on the remote machine, and the user names are -the same on both sides, or if the files -.Pa ~/.rhosts -or -.Pa ~/.shosts -exist in the user's home directory on the -remote machine and contain a line containing the name of the client -machine and the name of the user on that machine, the user is -considered for log in. -Additionally, if the server can verify the client's -host key (see -.Pa /etc/ssh/ssh_known_hosts -and -.Pa ~/.ssh/known_hosts -in the -.Sx FILES -section), only then is login permitted. -This authentication method closes security holes due to IP -spoofing, DNS spoofing and routing spoofing. -[Note to the administrator: -.Pa /etc/hosts.equiv , -.Pa ~/.rhosts , -and the rlogin/rsh protocol in general, are inherently insecure and should be -disabled if security is desired.] -.Pp -As a second authentication method, -.Nm -supports RSA based authentication. -The scheme is based on public-key cryptography: there are cryptosystems -where encryption and decryption are done using separate keys, and it -is not possible to derive the decryption key from the encryption key. -RSA is one such system. -The idea is that each user creates a public/private -key pair for authentication purposes. -The server knows the public key, and only the user knows the private key. -.Pp -The file -.Pa ~/.ssh/authorized_keys -lists the public keys that are permitted for logging in. -When the user logs in, the -.Nm -program tells the server which key pair it would like to use for -authentication. -The server checks if this key is permitted, and if so, -sends the user (actually the -.Nm -program running on behalf of the user) a challenge, a random number, -encrypted by the user's public key. -The challenge can only be decrypted using the proper private key. -The user's client then decrypts the challenge using the private key, -proving that he/she knows the private key -but without disclosing it to the server. -.Pp -.Nm -implements the RSA authentication protocol automatically. -The user creates his/her RSA key pair by running -.Xr ssh-keygen 1 . -This stores the private key in -.Pa ~/.ssh/identity -and stores the public key in -.Pa ~/.ssh/identity.pub -in the user's home directory. -The user should then copy the -.Pa identity.pub -to -.Pa ~/.ssh/authorized_keys -in his/her home directory on the remote machine (the -.Pa authorized_keys -file corresponds to the conventional -.Pa ~/.rhosts -file, and has one key -per line, though the lines can be very long). -After this, the user can log in without giving the password. -.Pp -The most convenient way to use RSA authentication may be with an -authentication agent. -See -.Xr ssh-agent 1 -for more information. -.Pp -If other authentication methods fail, -.Nm -prompts the user for a password. -The password is sent to the remote -host for checking; however, since all communications are encrypted, -the password cannot be seen by someone listening on the network. -.Ss SSH protocol version 2 -When a user connects using protocol version 2, -similar authentication methods are available. -Using the default values for -.Cm PreferredAuthentications , -the client will try to authenticate first using the hostbased method; -if this method fails, public key authentication is attempted, -and finally if this method fails, keyboard-interactive and -password authentication are tried. -.Pp -The public key method is similar to RSA authentication described -in the previous section and allows the RSA or DSA algorithm to be used: -The client uses his private key, -.Pa ~/.ssh/id_dsa -or -.Pa ~/.ssh/id_rsa , -to sign the session identifier and sends the result to the server. -The server checks whether the matching public key is listed in -.Pa ~/.ssh/authorized_keys -and grants access if both the key is found and the signature is correct. -The session identifier is derived from a shared Diffie-Hellman value -and is only known to the client and the server. -.Pp -If public key authentication fails or is not available, a password -can be sent encrypted to the remote host to prove the user's identity. -.Pp -Additionally, -.Nm -supports hostbased or challenge response authentication. -.Pp -Protocol 2 provides additional mechanisms for confidentiality -(the traffic is encrypted using AES, 3DES, Blowfish, CAST128 or Arcfour) -and integrity (hmac-md5, hmac-sha1, hmac-ripemd160). -Note that protocol 1 lacks a strong mechanism for ensuring the -integrity of the connection. -.Ss Login session and remote execution -When the user's identity has been accepted by the server, the server -either executes the given command, or logs into the machine and gives -the user a normal shell on the remote machine. -All communication with -the remote command or shell will be automatically encrypted. -.Pp -If a pseudo-terminal has been allocated (normal login session), the -user may use the escape characters noted below. -.Pp -If no pseudo-tty has been allocated, -the session is transparent and can be used to reliably transfer binary data. -On most systems, setting the escape character to -.Dq none -will also make the session transparent even if a tty is used. -.Pp -The session terminates when the command or shell on the remote -machine exits and all X11 and TCP/IP connections have been closed. -The exit status of the remote program is returned as the exit status of -.Nm ssh . -.Ss Escape Characters -When a pseudo-terminal has been requested, -.Nm -supports a number of functions through the use of an escape character. -.Pp -A single tilde character can be sent as -.Ic ~~ -or by following the tilde by a character other than those described below. -The escape character must always follow a newline to be interpreted as -special. -The escape character can be changed in configuration files using the -.Cm EscapeChar -configuration directive or on the command line by the -.Fl e -option. -.Pp -The supported escapes (assuming the default -.Ql ~ ) -are: -.Bl -tag -width Ds -.It Cm ~. -Disconnect. -.It Cm ~^Z -Background -.Nm ssh . -.It Cm ~# -List forwarded connections. -.It Cm ~& -Background -.Nm -at logout when waiting for forwarded connection / X11 sessions to terminate. -.It Cm ~? -Display a list of escape characters. -.It Cm ~B -Send a BREAK to the remote system -(only useful for SSH protocol version 2 and if the peer supports it). -.It Cm ~C -Open command line. -Currently this allows the addition of port forwardings using the -.Fl L -and -.Fl R -options (see below). -It also allows the cancellation of existing remote port-forwardings -using -.Fl KR Ar hostport . -Basic help is available, using the -.Fl h -option. -.It Cm ~R -Request rekeying of the connection -(only useful for SSH protocol version 2 and if the peer supports it). -.El -.Ss X11 and TCP forwarding -If the -.Cm ForwardX11 -variable is set to -.Dq yes -(or see the description of the -.Fl X -and -.Fl x -options described later) -and the user is using X11 (the -.Ev DISPLAY -environment variable is set), the connection to the X11 display is -automatically forwarded to the remote side in such a way that any X11 -programs started from the shell (or command) will go through the -encrypted channel, and the connection to the real X server will be made -from the local machine. -The user should not manually set -.Ev DISPLAY . -Forwarding of X11 connections can be -configured on the command line or in configuration files. -.Pp -The -.Ev DISPLAY -value set by -.Nm -will point to the server machine, but with a display number greater than zero. -This is normal, and happens because -.Nm -creates a -.Dq proxy -X server on the server machine for forwarding the -connections over the encrypted channel. -.Pp -.Nm -will also automatically set up Xauthority data on the server machine. -For this purpose, it will generate a random authorization cookie, -store it in Xauthority on the server, and verify that any forwarded -connections carry this cookie and replace it by the real cookie when -the connection is opened. -The real authentication cookie is never -sent to the server machine (and no cookies are sent in the plain). -.Pp -If the -.Cm ForwardAgent -variable is set to -.Dq yes -(or see the description of the -.Fl A -and -.Fl a -options described later) and -the user is using an authentication agent, the connection to the agent -is automatically forwarded to the remote side. -.Pp -Forwarding of arbitrary TCP/IP connections over the secure channel can -be specified either on the command line or in a configuration file. -One possible application of TCP/IP forwarding is a secure connection to an -electronic purse; another is going through firewalls. -.Ss Server authentication -.Nm -automatically maintains and checks a database containing -identifications for all hosts it has ever been used with. -Host keys are stored in -.Pa ~/.ssh/known_hosts -in the user's home directory. -Additionally, the file -.Pa /etc/ssh/ssh_known_hosts -is automatically checked for known hosts. -Any new hosts are automatically added to the user's file. -If a host's identification ever changes, -.Nm -warns about this and disables password authentication to prevent a -trojan horse from getting the user's password. -Another purpose of this mechanism is to prevent man-in-the-middle attacks -which could otherwise be used to circumvent the encryption. -The -.Cm StrictHostKeyChecking -option can be used to prevent logins to machines whose -host key is not known or has changed. -.Pp -.Nm -can be configured to verify host identification using fingerprint resource -records (SSHFP) published in DNS. -The -.Cm VerifyHostKeyDNS -option can be used to control how DNS lookups are performed. -SSHFP resource records can be generated using -.Xr ssh-keygen 1 . +it is executed on the remote host instead of a login shell. .Pp The options are as follows: .Bl -tag -width Ds @@ -430,7 +146,7 @@ of the connection. Only useful on systems with more than one address. .It Fl C Requests compression of all data (including stdin, stdout, stderr, and -data for forwarded X11 and TCP/IP connections). +data for forwarded X11 and TCP connections). The compression algorithm is the same used by .Xr gzip 1 , and the @@ -448,9 +164,9 @@ option. Selects the cipher specification for encrypting the session. .Pp Protocol version 1 allows specification of a single cipher. -The suported values are +The supported values are .Dq 3des , -.Dq blowfish +.Dq blowfish , and .Dq des . .Ar 3des @@ -470,37 +186,44 @@ Its use is strongly discouraged due to cryptographic weaknesses. The default is .Dq 3des . .Pp -For protocol version 2 +For protocol version 2, .Ar cipher_spec is a comma-separated list of ciphers listed in order of preference. -The supported ciphers are -.Dq 3des-cbc , -.Dq aes128-cbc , -.Dq aes192-cbc , -.Dq aes256-cbc , -.Dq aes128-ctr , -.Dq aes192-ctr , -.Dq aes256-ctr , -.Dq arcfour128 , -.Dq arcfour256 , -.Dq arcfour , -.Dq blowfish-cbc , +The supported ciphers are: +3des-cbc, +aes128-cbc, +aes192-cbc, +aes256-cbc, +aes128-ctr, +aes192-ctr, +aes256-ctr, +arcfour128, +arcfour256, +arcfour, +blowfish-cbc, and -.Dq cast128-cbc . -The default is -.Bd -literal - ``aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour128, - arcfour256,arcfour,aes192-cbc,aes256-cbc,aes128-ctr, - aes192-ctr,aes256-ctr'' +cast128-cbc. +The default is: +.Bd -literal -offset indent +aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour128, +arcfour256,arcfour,aes192-cbc,aes256-cbc,aes128-ctr, +aes192-ctr,aes256-ctr .Ed -.It Fl D Ar port +.It Fl D Xo +.Sm off +.Oo Ar bind_address : Oc +.Ar port +.Sm on +.Xc Specifies a local .Dq dynamic application-level port forwarding. This works by allocating a socket to listen to .Ar port -on the local side, and whenever a connection is made to this port, the +on the local side, optionally bound to the specified +.Ar bind_address . +Whenever a connection is made to this port, the connection is forwarded over the secure channel, and the application protocol is then used to determine where to connect to from the remote machine. @@ -509,7 +232,31 @@ Currently the SOCKS4 and SOCKS5 protocols are supported, and will act as a SOCKS server. Only root can forward privileged ports. Dynamic port forwardings can also be specified in the configuration file. -.It Fl e Ar ch | ^ch | none +.Pp +IPv6 addresses can be specified with an alternative syntax: +.Sm off +.Xo +.Op Ar bind_address No / +.Ar port +.Xc +.Sm on +or by enclosing the address in square brackets. +Only the superuser can forward privileged ports. +By default, the local port is bound in accordance with the +.Cm GatewayPorts +setting. +However, an explicit +.Ar bind_address +may be used to bind the connection to a specific address. +The +.Ar bind_address +of +.Dq localhost +indicates that the listening port be bound for local use only, while an +empty address or +.Sq * +indicates that the port should be available from all interfaces. +.It Fl e Ar escape_char Sets the escape character for sessions with a pty (default: .Ql ~ ) . The escape character is only recognized at the beginning of a line. @@ -545,11 +292,12 @@ something like .It Fl g Allows remote hosts to connect to local forwarded ports. .It Fl I Ar smartcard_device -Specifies which smartcard device to use. -The argument is the device +Specify the device .Nm should use to communicate with a smartcard used for storing the user's private RSA key. +This option is only available if support for smartcard devices +is compiled in (default is no support). .It Fl i Ar identity_file Selects a file from which the identity (private key) for RSA or DSA authentication is read. @@ -621,6 +369,13 @@ Places the client into .Dq master mode for connection sharing. +Multiple +.Fl M +options places +.Nm +into +.Dq master +mode with confirmation required before slave connections are accepted. Refer to the description of .Cm ControlMaster in @@ -709,17 +464,20 @@ For full details of the options listed below, and their possible values, see .It IdentityFile .It IdentitiesOnly .It KbdInteractiveDevices +.It LocalCommand .It LocalForward .It LogLevel .It MACs .It NoHostAuthenticationForLocalhost .It NumberOfPasswordPrompts .It PasswordAuthentication +.It PermitLocalCommand .It Port .It PreferredAuthentications .It Protocol .It ProxyCommand .It PubkeyAuthentication +.It RekeyLimit .It RemoteForward .It RhostsRSAAuthentication .It RSAAuthentication @@ -729,6 +487,8 @@ For full details of the options listed below, and their possible values, see .It SmartcardDevice .It StrictHostKeyChecking .It TCPKeepAlive +.It Tunnel +.It TunnelDevice .It UsePrivilegedPort .It User .It UserKnownHostsFile @@ -828,6 +588,24 @@ Multiple .Fl v options increase the verbosity. The maximum is 3. +.It Fl w Ar tunnel : Ns Ar tunnel +Requests a +.Xr tun 4 +device on the client +(first +.Ar tunnel +arg) +and server +(second +.Ar tunnel +arg). +The devices may be specified by numerical ID or the keyword +.Dq any , +which uses the next available tunnel device. +See also the +.Cm Tunnel +directive in +.Xr ssh_config 5 . .It Fl X Enables X11 forwarding. This can also be specified on a per-host basis in a configuration file. @@ -855,16 +633,474 @@ Enables trusted X11 forwarding. Trusted X11 forwardings are not subjected to the X11 SECURITY extension controls. .El -.Sh CONFIGURATION FILES +.Pp .Nm may additionally obtain configuration data from a per-user configuration file and a system-wide configuration file. The file format and configuration options are described in .Xr ssh_config 5 . +.Pp +.Nm +exits with the exit status of the remote command or with 255 +if an error occurred. +.Sh AUTHENTICATION +The OpenSSH SSH client supports SSH protocols 1 and 2. +Protocol 2 is the default, with +.Nm +falling back to protocol 1 if it detects protocol 2 is unsupported. +These settings may be altered using the +.Cm Protocol +option in +.Xr ssh_config 5 , +or enforced using the +.Fl 1 +and +.Fl 2 +options (see above). +Both protocols support similar authentication methods, +but protocol 2 is preferred since +it provides additional mechanisms for confidentiality +(the traffic is encrypted using AES, 3DES, Blowfish, CAST128, or Arcfour) +and integrity (hmac-md5, hmac-sha1, hmac-ripemd160). +Protocol 1 lacks a strong mechanism for ensuring the +integrity of the connection. +.Pp +The methods available for authentication are: +host-based authentication, +public key authentication, +challenge-response authentication, +and password authentication. +Authentication methods are tried in the order specified above, +though protocol 2 has a configuration option to change the default order: +.Cm PreferredAuthentications . +.Pp +Host-based authentication works as follows: +If the machine the user logs in from is listed in +.Pa /etc/hosts.equiv +or +.Pa /etc/shosts.equiv +on the remote machine, and the user names are +the same on both sides, or if the files +.Pa ~/.rhosts +or +.Pa ~/.shosts +exist in the user's home directory on the +remote machine and contain a line containing the name of the client +machine and the name of the user on that machine, the user is +considered for login. +Additionally, the server +.Em must +be able to verify the client's +host key (see the description of +.Pa /etc/ssh/ssh_known_hosts +and +.Pa ~/.ssh/known_hosts , +below) +for login to be permitted. +This authentication method closes security holes due to IP +spoofing, DNS spoofing, and routing spoofing. +[Note to the administrator: +.Pa /etc/hosts.equiv , +.Pa ~/.rhosts , +and the rlogin/rsh protocol in general, are inherently insecure and should be +disabled if security is desired.] +.Pp +Public key authentication works as follows: +The scheme is based on public-key cryptography, +using cryptosystems +where encryption and decryption are done using separate keys, +and it is unfeasible to derive the decryption key from the encryption key. +The idea is that each user creates a public/private +key pair for authentication purposes. +The server knows the public key, and only the user knows the private key. +.Nm +implements public key authentication protocol automatically, +using either the RSA or DSA algorithms. +Protocol 1 is restricted to using only RSA keys, +but protocol 2 may use either. +The +.Sx HISTORY +section of +.Xr ssl 8 +contains a brief discussion of the two algorithms. +.Pp +The file +.Pa ~/.ssh/authorized_keys +lists the public keys that are permitted for logging in. +When the user logs in, the +.Nm +program tells the server which key pair it would like to use for +authentication. +The client proves that it has access to the private key +and the server checks that the corresponding public key +is authorized to accept the account. +.Pp +The user creates his/her key pair by running +.Xr ssh-keygen 1 . +This stores the private key in +.Pa ~/.ssh/identity +(protocol 1), +.Pa ~/.ssh/id_dsa +(protocol 2 DSA), +or +.Pa ~/.ssh/id_rsa +(protocol 2 RSA) +and stores the public key in +.Pa ~/.ssh/identity.pub +(protocol 1), +.Pa ~/.ssh/id_dsa.pub +(protocol 2 DSA), +or +.Pa ~/.ssh/id_rsa.pub +(protocol 2 RSA) +in the user's home directory. +The user should then copy the public key +to +.Pa ~/.ssh/authorized_keys +in his/her home directory on the remote machine. +The +.Pa authorized_keys +file corresponds to the conventional +.Pa ~/.rhosts +file, and has one key +per line, though the lines can be very long. +After this, the user can log in without giving the password. +.Pp +The most convenient way to use public key authentication may be with an +authentication agent. +See +.Xr ssh-agent 1 +for more information. +.Pp +Challenge-response authentication works as follows: +The server sends an arbitrary +.Qq challenge +text, and prompts for a response. +Protocol 2 allows multiple challenges and responses; +protocol 1 is restricted to just one challenge/response. +Examples of challenge-response authentication include +BSD Authentication (see +.Xr login.conf 5 ) +and PAM (some non-OpenBSD systems). +.Pp +Finally, if other authentication methods fail, +.Nm +prompts the user for a password. +The password is sent to the remote +host for checking; however, since all communications are encrypted, +the password cannot be seen by someone listening on the network. +.Pp +.Nm +automatically maintains and checks a database containing +identification for all hosts it has ever been used with. +Host keys are stored in +.Pa ~/.ssh/known_hosts +in the user's home directory. +Additionally, the file +.Pa /etc/ssh/ssh_known_hosts +is automatically checked for known hosts. +Any new hosts are automatically added to the user's file. +If a host's identification ever changes, +.Nm +warns about this and disables password authentication to prevent +server spoofing or man-in-the-middle attacks, +which could otherwise be used to circumvent the encryption. +The +.Cm StrictHostKeyChecking +option can be used to control logins to machines whose +host key is not known or has changed. +.Pp +When the user's identity has been accepted by the server, the server +either executes the given command, or logs into the machine and gives +the user a normal shell on the remote machine. +All communication with +the remote command or shell will be automatically encrypted. +.Pp +If a pseudo-terminal has been allocated (normal login session), the +user may use the escape characters noted below. +.Pp +If no pseudo-tty has been allocated, +the session is transparent and can be used to reliably transfer binary data. +On most systems, setting the escape character to +.Dq none +will also make the session transparent even if a tty is used. +.Pp +The session terminates when the command or shell on the remote +machine exits and all X11 and TCP connections have been closed. +.Sh ESCAPE CHARACTERS +When a pseudo-terminal has been requested, +.Nm +supports a number of functions through the use of an escape character. +.Pp +A single tilde character can be sent as +.Ic ~~ +or by following the tilde by a character other than those described below. +The escape character must always follow a newline to be interpreted as +special. +The escape character can be changed in configuration files using the +.Cm EscapeChar +configuration directive or on the command line by the +.Fl e +option. +.Pp +The supported escapes (assuming the default +.Ql ~ ) +are: +.Bl -tag -width Ds +.It Cm ~. +Disconnect. +.It Cm ~^Z +Background +.Nm . +.It Cm ~# +List forwarded connections. +.It Cm ~& +Background +.Nm +at logout when waiting for forwarded connection / X11 sessions to terminate. +.It Cm ~? +Display a list of escape characters. +.It Cm ~B +Send a BREAK to the remote system +(only useful for SSH protocol version 2 and if the peer supports it). +.It Cm ~C +Open command line. +Currently this allows the addition of port forwardings using the +.Fl L +and +.Fl R +options (see above). +It also allows the cancellation of existing remote port-forwardings +using +.Fl KR Ar hostport . +.Ic !\& Ns Ar command +allows the user to execute a local command if the +.Ic PermitLocalCommand +option is enabled in +.Xr ssh_config 5 . +Basic help is available, using the +.Fl h +option. +.It Cm ~R +Request rekeying of the connection +(only useful for SSH protocol version 2 and if the peer supports it). +.El +.Sh TCP FORWARDING +Forwarding of arbitrary TCP connections over the secure channel can +be specified either on the command line or in a configuration file. +One possible application of TCP forwarding is a secure connection to a +mail server; another is going through firewalls. +.Pp +In the example below, we look at encrypting communication between +an IRC client and server, even though the IRC server does not directly +support encrypted communications. +This works as follows: +the user connects to the remote host using +.Nm , +specifying a port to be used to forward connections +to the remote server. +After that it is possible to start the service which is to be encrypted +on the client machine, +connecting to the same local port, +and +.Nm +will encrypt and forward the connection. +.Pp +The following example tunnels an IRC session from client machine +.Dq 127.0.0.1 +(localhost) +to remote server +.Dq server.example.com : +.Bd -literal -offset 4n +$ ssh -f -L 1234:localhost:6667 server.example.com sleep 10 +$ irc -c '#users' -p 1234 pinky 127.0.0.1 +.Ed +.Pp +This tunnels a connection to IRC server +.Dq server.example.com , +joining channel +.Dq #users , +nickname +.Dq pinky , +using port 1234. +It doesn't matter which port is used, +as long as it's greater than 1023 +(remember, only root can open sockets on privileged ports) +and doesn't conflict with any ports already in use. +The connection is forwarded to port 6667 on the remote server, +since that's the standard port for IRC services. +.Pp +The +.Fl f +option backgrounds +.Nm +and the remote command +.Dq sleep 10 +is specified to allow an amount of time +(10 seconds, in the example) +to start the service which is to be tunnelled. +If no connections are made within the time specified, +.Nm +will exit. +.Sh X11 FORWARDING +If the +.Cm ForwardX11 +variable is set to +.Dq yes +(or see the description of the +.Fl X , +.Fl x , +and +.Fl Y +options above) +and the user is using X11 (the +.Ev DISPLAY +environment variable is set), the connection to the X11 display is +automatically forwarded to the remote side in such a way that any X11 +programs started from the shell (or command) will go through the +encrypted channel, and the connection to the real X server will be made +from the local machine. +The user should not manually set +.Ev DISPLAY . +Forwarding of X11 connections can be +configured on the command line or in configuration files. +.Pp +The +.Ev DISPLAY +value set by +.Nm +will point to the server machine, but with a display number greater than zero. +This is normal, and happens because +.Nm +creates a +.Dq proxy +X server on the server machine for forwarding the +connections over the encrypted channel. +.Pp +.Nm +will also automatically set up Xauthority data on the server machine. +For this purpose, it will generate a random authorization cookie, +store it in Xauthority on the server, and verify that any forwarded +connections carry this cookie and replace it by the real cookie when +the connection is opened. +The real authentication cookie is never +sent to the server machine (and no cookies are sent in the plain). +.Pp +If the +.Cm ForwardAgent +variable is set to +.Dq yes +(or see the description of the +.Fl A +and +.Fl a +options above) and +the user is using an authentication agent, the connection to the agent +is automatically forwarded to the remote side. +.Sh VERIFYING HOST KEYS +When connecting to a server for the first time, +a fingerprint of the server's public key is presented to the user +(unless the option +.Cm StrictHostKeyChecking +has been disabled). +Fingerprints can be determined using +.Xr ssh-keygen 1 : +.Pp +.Dl $ ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key +.Pp +If the fingerprint is already known, +it can be matched and verified, +and the key can be accepted. +If the fingerprint is unknown, +an alternative method of verification is available: +SSH fingerprints verified by DNS. +An additional resource record (RR), +SSHFP, +is added to a zonefile +and the connecting client is able to match the fingerprint +with that of the key presented. +.Pp +In this example, we are connecting a client to a server, +.Dq host.example.com . +The SSHFP resource records should first be added to the zonefile for +host.example.com: +.Bd -literal -offset indent +$ ssh-keygen -f /etc/ssh/ssh_host_rsa_key.pub -r host.example.com. +$ ssh-keygen -f /etc/ssh/ssh_host_dsa_key.pub -r host.example.com. +.Ed +.Pp +The output lines will have to be added to the zonefile. +To check that the zone is answering fingerprint queries: +.Pp +.Dl $ dig -t SSHFP host.example.com +.Pp +Finally the client connects: +.Bd -literal -offset indent +$ ssh -o "VerifyHostKeyDNS ask" host.example.com +[...] +Matching host key fingerprint found in DNS. +Are you sure you want to continue connecting (yes/no)? +.Ed +.Pp +See the +.Cm VerifyHostKeyDNS +option in +.Xr ssh_config 5 +for more information. +.Sh SSH-BASED VIRTUAL PRIVATE NETWORKS +.Nm +contains support for Virtual Private Network (VPN) tunnelling +using the +.Xr tun 4 +network pseudo-device, +allowing two networks to be joined securely. +The +.Xr sshd_config 5 +configuration option +.Cm PermitTunnel +controls whether the server supports this, +and at what level (layer 2 or 3 traffic). +.Pp +The following example would connect client network 10.0.50.0/24 +with remote network 10.0.99.0/24, provided that the SSH server +running on the gateway to the remote network, +at 192.168.1.15, allows it: +.Bd -literal -offset indent +# ssh -f -w 0:1 192.168.1.15 true +# ifconfig tun0 10.0.50.1 10.0.99.1 netmask 255.255.255.252 +.Ed +.Pp +Client access may be more finely tuned via the +.Pa /root/.ssh/authorized_keys +file (see below) and the +.Cm PermitRootLogin +server option. +The following entry would permit connections on the first +.Xr tun 4 +device from user +.Dq jane +and on the second device from user +.Dq john , +if +.Cm PermitRootLogin +is set to +.Dq forced-commands-only : +.Bd -literal -offset 2n +tunnel="1",command="sh /etc/netstart tun1" ssh-rsa ... jane +tunnel="2",command="sh /etc/netstart tun1" ssh-rsa ... john +.Ed +.Pp +Since a SSH-based setup entails a fair amount of overhead, +it may be more suited to temporary setups, +such as for wireless VPNs. +More permanent VPNs are better provided by tools such as +.Xr ipsecctl 8 +and +.Xr isakmpd 8 . .Sh ENVIRONMENT .Nm will normally set the following environment variables: -.Bl -tag -width LOGNAME +.Bl -tag -width "SSH_ORIGINAL_COMMAND" .It Ev DISPLAY The .Ev DISPLAY @@ -872,9 +1108,12 @@ variable indicates the location of the X11 server. It is automatically set by .Nm to point to a value of the form -.Dq hostname:n -where hostname indicates -the host where the shell runs, and n is an integer \*(Ge 1. +.Dq hostname:n , +where +.Dq hostname +indicates the host where the shell runs, and +.Sq n +is an integer \*(Ge 1. .Nm uses this special value to forward X11 connections over the secure channel. @@ -895,7 +1134,7 @@ Set to the path of the user's mailbox. Set to the default .Ev PATH , as specified when compiling -.Nm ssh . +.Nm . .It Ev SSH_ASKPASS If .Nm @@ -920,15 +1159,16 @@ may be necessary to redirect the input from .Pa /dev/null to make this work.) .It Ev SSH_AUTH_SOCK -Identifies the path of a unix-domain socket used to communicate with the -agent. +Identifies the path of a +.Ux Ns -domain +socket used to communicate with the agent. .It Ev SSH_CONNECTION Identifies the client and server ends of the connection. The variable contains -four space-separated values: client ip-address, client port number, -server ip-address and server port number. +four space-separated values: client IP address, client port number, +server IP address, and server port number. .It Ev SSH_ORIGINAL_COMMAND -The variable contains the original command line if a forced command +This variable contains the original command line if a forced command is executed. It can be used to extract the original arguments. .It Ev SSH_TTY @@ -937,7 +1177,7 @@ with the current shell or command. If the current session has no tty, this variable is not set. .It Ev TZ -The timezone variable is set to indicate the present timezone if it +This variable is set to indicate the present time zone if it was set when the daemon was started (i.e., the daemon passes the value on to new connections). .It Ev USER @@ -950,221 +1190,150 @@ reads .Pa ~/.ssh/environment , and adds lines of the format .Dq VARNAME=value -to the environment if the file exists and if users are allowed to +to the environment if the file exists and users are allowed to change their environment. For more information, see the .Cm PermitUserEnvironment option in .Xr sshd_config 5 . .Sh FILES -.Bl -tag -width Ds -.It Pa ~/.ssh/known_hosts -Records host keys for all hosts the user has logged into that are not -in -.Pa /etc/ssh/ssh_known_hosts . -See -.Xr sshd 8 . -.It Pa ~/.ssh/identity, ~/.ssh/id_dsa, ~/.ssh/id_rsa -Contains the authentication identity of the user. -They are for protocol 1 RSA, protocol 2 DSA, and protocol 2 RSA, respectively. +.Bl -tag -width Ds -compact +.It ~/.rhosts +This file is used for host-based authentication (see above). +On some machines this file may need to be +world-readable if the user's home directory is on an NFS partition, +because +.Xr sshd 8 +reads it as root. +Additionally, this file must be owned by the user, +and must not have write permissions for anyone else. +The recommended +permission for most machines is read/write for the user, and not +accessible by others. +.Pp +.It ~/.shosts +This file is used in exactly the same way as +.Pa .rhosts , +but allows host-based authentication without permitting login with +rlogin/rsh. +.Pp +.It ~/.ssh/authorized_keys +Lists the public keys (RSA/DSA) that can be used for logging in as this user. +The format of this file is described in the +.Xr sshd 8 +manual page. +This file is not highly sensitive, but the recommended +permissions are read/write for the user, and not accessible by others. +.Pp +.It ~/.ssh/config +This is the per-user configuration file. +The file format and configuration options are described in +.Xr ssh_config 5 . +Because of the potential for abuse, this file must have strict permissions: +read/write for the user, and not accessible by others. +.Pp +.It ~/.ssh/environment +Contains additional definitions for environment variables; see +.Sx ENVIRONMENT , +above. +.Pp +.It ~/.ssh/identity +.It ~/.ssh/id_dsa +.It ~/.ssh/id_rsa +Contains the private key for authentication. These files contain sensitive data and should be readable by the user but not accessible by others (read/write/execute). -Note that .Nm -ignores a private key file if it is accessible by others. +will simply ignore a private key file if it is accessible by others. It is possible to specify a passphrase when -generating the key; the passphrase will be used to encrypt the +generating the key which will be used to encrypt the sensitive part of this file using 3DES. -.It Pa ~/.ssh/identity.pub, ~/.ssh/id_dsa.pub, ~/.ssh/id_rsa.pub -Contains the public key for authentication (public part of the -identity file in human-readable form). -The contents of the -.Pa ~/.ssh/identity.pub -file should be added to the file -.Pa ~/.ssh/authorized_keys -on all machines -where the user wishes to log in using protocol version 1 RSA authentication. -The contents of the -.Pa ~/.ssh/id_dsa.pub -and -.Pa ~/.ssh/id_rsa.pub -file should be added to -.Pa ~/.ssh/authorized_keys -on all machines -where the user wishes to log in using protocol version 2 DSA/RSA authentication. +.Pp +.It ~/.ssh/identity.pub +.It ~/.ssh/id_dsa.pub +.It ~/.ssh/id_rsa.pub +Contains the public key for authentication. These files are not sensitive and can (but need not) be readable by anyone. -These files are -never used automatically and are not necessary; they are only provided for -the convenience of the user. -.It Pa ~/.ssh/config -This is the per-user configuration file. -The file format and configuration options are described in -.Xr ssh_config 5 . -Because of the potential for abuse, this file must have strict permissions: -read/write for the user, and not accessible by others. -.It Pa ~/.ssh/authorized_keys -Lists the public keys (RSA/DSA) that can be used for logging in as this user. -The format of this file is described in the -.Xr sshd 8 -manual page. -In the simplest form the format is the same as the -.Pa .pub -identity files. -This file is not highly sensitive, but the recommended -permissions are read/write for the user, and not accessible by others. -.It Pa /etc/ssh/ssh_known_hosts -Systemwide list of known host keys. -This file should be prepared by the -system administrator to contain the public host keys of all machines in the -organization. -This file should be world-readable. -This file contains -public keys, one per line, in the following format (fields separated -by spaces): system name, public key and optional comment field. -When different names are used -for the same machine, all such names should be listed, separated by -commas. -The format is described in the -.Xr sshd 8 -manual page. .Pp -The canonical system name (as returned by name servers) is used by +.It ~/.ssh/known_hosts +Contains a list of host keys for all hosts the user has logged into +that are not already in the systemwide list of known host keys. +See .Xr sshd 8 -to verify the client host when logging in; other names are needed because +for further details of the format of this file. +.Pp +.It ~/.ssh/rc +Commands in this file are executed by .Nm -does not convert the user-supplied name to a canonical name before -checking the key, because someone with access to the name servers -would then be able to fool host authentication. +when the user logs in, just before the user's shell (or command) is +started. +See the +.Xr sshd 8 +manual page for more information. +.Pp +.It /etc/hosts.equiv +This file is for host-based authentication (see above). +It should only be writable by root. +.Pp +.It /etc/shosts.equiv +This file is used in exactly the same way as +.Pa hosts.equiv , +but allows host-based authentication without permitting login with +rlogin/rsh. +.Pp .It Pa /etc/ssh/ssh_config Systemwide configuration file. The file format and configuration options are described in .Xr ssh_config 5 . -.It Pa /etc/ssh/ssh_host_key, /etc/ssh/ssh_host_dsa_key, /etc/ssh/ssh_host_rsa_key +.Pp +.It /etc/ssh/ssh_host_key +.It /etc/ssh/ssh_host_dsa_key +.It /etc/ssh/ssh_host_rsa_key These three files contain the private parts of the host keys -and are used for -.Cm RhostsRSAAuthentication -and -.Cm HostbasedAuthentication . -If the protocol version 1 -.Cm RhostsRSAAuthentication -method is used, +and are used for host-based authentication. +If protocol version 1 is used, .Nm must be setuid root, since the host key is readable only by root. For protocol version 2, .Nm uses .Xr ssh-keysign 8 -to access the host keys for -.Cm HostbasedAuthentication . -This eliminates the requirement that +to access the host keys, +eliminating the requirement that .Nm -be setuid root when that authentication method is used. +be setuid root when host-based authentication is used. By default .Nm is not setuid root. -.It Pa ~/.rhosts -This file is used in -.Cm RhostsRSAAuthentication -and -.Cm HostbasedAuthentication -authentication to list the -host/user pairs that are permitted to log in. -(Note that this file is -also used by rlogin and rsh, which makes using this file insecure.) -Each line of the file contains a host name (in the canonical form -returned by name servers), and then a user name on that host, -separated by a space. -On some machines this file may need to be -world-readable if the user's home directory is on a NFS partition, -because -.Xr sshd 8 -reads it as root. -Additionally, this file must be owned by the user, -and must not have write permissions for anyone else. -The recommended -permission for most machines is read/write for the user, and not -accessible by others. .Pp -Note that -.Xr sshd 8 -allows authentication only in combination with client host key -authentication before permitting log in. -If the server machine does not have the client's host key in -.Pa /etc/ssh/ssh_known_hosts , -it can be stored in -.Pa ~/.ssh/known_hosts . -The easiest way to do this is to -connect back to the client from the server machine using ssh; this -will automatically add the host key to -.Pa ~/.ssh/known_hosts . -.It Pa ~/.shosts -This file is used exactly the same way as -.Pa .rhosts . -The purpose for -having this file is to be able to use -.Cm RhostsRSAAuthentication -and -.Cm HostbasedAuthentication -authentication without permitting login with -.Xr rlogin -or -.Xr rsh 1 . -.It Pa /etc/hosts.equiv -This file is used during -.Cm RhostsRSAAuthentication -and -.Cm HostbasedAuthentication -authentication. -It contains -canonical hosts names, one per line (the full format is described in the -.Xr sshd 8 -manual page). -If the client host is found in this file, login is -automatically permitted provided client and server user names are the -same. -Additionally, successful client host key authentication is required. -This file should only be writable by root. -.It Pa /etc/shosts.equiv -This file is processed exactly as -.Pa /etc/hosts.equiv . -This file may be useful to permit logins using -.Nm -but not using rsh/rlogin. -.It Pa /etc/ssh/sshrc -Commands in this file are executed by -.Nm -when the user logs in just before the user's shell (or command) is started. -See the +.It /etc/ssh/ssh_known_hosts +Systemwide list of known host keys. +This file should be prepared by the +system administrator to contain the public host keys of all machines in the +organization. +It should be world-readable. +See .Xr sshd 8 -manual page for more information. -.It Pa ~/.ssh/rc +for further details of the format of this file. +.Pp +.It /etc/ssh/sshrc Commands in this file are executed by .Nm -when the user logs in just before the user's shell (or command) is -started. +when the user logs in, just before the user's shell (or command) is started. See the .Xr sshd 8 manual page for more information. -.It Pa ~/.ssh/environment -Contains additional definitions for environment variables, see section -.Sx ENVIRONMENT -above. .El -.Sh DIAGNOSTICS -.Nm -exits with the exit status of the remote command or with 255 -if an error occurred. .Sh SEE ALSO -.Xr gzip 1 , -.Xr rsh 1 , .Xr scp 1 , .Xr sftp 1 , .Xr ssh-add 1 , .Xr ssh-agent 1 , .Xr ssh-keygen 1 , -.Xr telnet 1 , +.Xr ssh-keyscan 1 , +.Xr tun 4 , .Xr hosts.equiv 5 , .Xr ssh_config 5 , .Xr ssh-keysign 8 , diff --git a/openssh/ssh.c b/openssh/ssh.c index fa23bec..ec7a08e 100644 --- a/openssh/ssh.c +++ b/openssh/ssh.c @@ -40,7 +40,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh.c,v 1.249 2005/07/30 01:26:16 djm Exp $"); +RCSID("$OpenBSD: ssh.c,v 1.257 2005/12/20 04:41:07 dtucker Exp $"); #include #include @@ -158,13 +158,13 @@ usage(void) { fprintf(stderr, "usage: ssh [-1246AaCfgkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]\n" -" [-D port] [-e escape_char] [-F configfile] [-w receive buffer size]\n" +" [-D [bind_address:]port] [-e escape_char] [-F configfile]\n" " [-i identity_file] [-L [bind_address:]port:host:hostport]\n" " [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n" " [-R [bind_address:]port:host:hostport] [-S ctl_path]\n" -" [user@]hostname [command]\n" +" [-w tunnel:tunnel] [user@]hostname [command]\n" ); - exit(1); + exit(255); } static int ssh_session(void); @@ -188,6 +188,9 @@ main(int ac, char **av) struct servent *sp; Forward fwd; + /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ + sanitise_stdfd(); + __progname = ssh_get_progname(av[0]); init_rng(); @@ -220,7 +223,7 @@ main(int ac, char **av) pw = getpwuid(original_real_uid); if (!pw) { logit("You don't exist, go away!"); - exit(1); + exit(255); } /* Take a copy of the returned structure. */ pw = pwcopy(pw); @@ -244,7 +247,7 @@ main(int ac, char **av) again: while ((opt = getopt(ac, av, - "1246ab:c:e:fgi:kl:m:no:p:qstvw:xzACD:F:I:L:MNO:PR:S:TVXY")) != -1) { + "1246ab:c:e:fgi:kl:m:no:p:qstvxzACD:F:I:L:MNO:PR:S:TVw:XY")) != -1) { switch (opt) { case '1': options.protocol = SSH_PROTO_1; @@ -340,6 +343,15 @@ again: if (opt == 'V') exit(0); break; + case 'w': + if (options.tun_open == -1) + options.tun_open = SSH_TUNMODE_DEFAULT; + options.tun_local = a2tun(optarg, &options.tun_remote); + if (options.tun_local == SSH_TUNID_ERR) { + fprintf(stderr, "Bad tun device '%s'\n", optarg); + exit(255); + } + break; case 'q': options.log_level = SYSLOG_LEVEL_QUIET; break; @@ -355,7 +367,7 @@ again: else { fprintf(stderr, "Bad escape character '%s'.\n", optarg); - exit(1); + exit(255); } break; case 'c': @@ -370,7 +382,7 @@ again: fprintf(stderr, "Unknown cipher type '%s'\n", optarg); - exit(1); + exit(255); } if (options.cipher == SSH_CIPHER_3DES) options.ciphers = "3des-cbc"; @@ -386,7 +398,7 @@ again: else { fprintf(stderr, "Unknown mac type '%s'\n", optarg); - exit(1); + exit(255); } break; case 'M': @@ -399,7 +411,7 @@ again: options.port = a2port(optarg); if (options.port == 0) { fprintf(stderr, "Bad port '%s'\n", optarg); - exit(1); + exit(255); } break; case 'l': @@ -413,7 +425,7 @@ again: fprintf(stderr, "Bad local forwarding specification '%s'\n", optarg); - exit(1); + exit(255); } break; @@ -424,7 +436,7 @@ again: fprintf(stderr, "Bad remote forwarding specification " "'%s'\n", optarg); - exit(1); + exit(255); } break; @@ -435,7 +447,7 @@ again: if ((fwd.listen_host = hpdelim(&cp)) == NULL) { fprintf(stderr, "Bad dynamic forwarding " "specification '%.100s'\n", optarg); - exit(1); + exit(255); } if (cp != NULL) { fwd.listen_port = a2port(cp); @@ -448,7 +460,7 @@ again: if (fwd.listen_port == 0) { fprintf(stderr, "Bad dynamic port '%s'\n", optarg); - exit(1); + exit(255); } add_local_forward(&options, &fwd); xfree(p); @@ -470,7 +482,7 @@ again: line = xstrdup(optarg); if (process_config_line(&options, host ? host : "", line, "command-line", 0, &dummy) != 0) - exit(1); + exit(255); xfree(line); break; case 's': @@ -487,9 +499,6 @@ again: case 'F': config = optarg; break; - case 'w': - options.tcp_rcv_buf = atoi(optarg); - break; case 'z': /* make sure we can't turn on the none_switch */ /* if they try to force a no tty flag on a tty session */ @@ -683,7 +692,7 @@ again: original_effective_uid == 0 && options.use_privileged_port, #endif options.proxy_command) != 0) - exit(1); + exit(255); /* * If we successfully made the connection, load the host private key @@ -736,7 +745,7 @@ again: /* * Now that we are back to our own permissions, create ~/.ssh - * directory if it doesn\'t already exist. + * directory if it doesn't already exist. */ snprintf(buf, sizeof buf, "%.100s%s%.100s", pw->pw_dir, strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR); if (stat(buf, &st) < 0) @@ -832,8 +841,7 @@ ssh_init_forwarding(void) debug("Remote connections from %.200s:%d forwarded to " "local address %.200s:%d", (options.remote_forwards[i].listen_host == NULL) ? - (options.gateway_ports ? "*" : "LOCALHOST") : - options.remote_forwards[i].listen_host, + "LOCALHOST" : options.remote_forwards[i].listen_host, options.remote_forwards[i].listen_port, options.remote_forwards[i].connect_host, options.remote_forwards[i].connect_port); @@ -849,7 +857,7 @@ static void check_agent_present(void) { if (options.forward_agent) { - /* Clear agent forwarding if we don\'t have an agent. */ + /* Clear agent forwarding if we don't have an agent. */ if (!ssh_agent_present()) options.forward_agent = 0; } @@ -1051,7 +1059,7 @@ ssh_control_listener(void) fatal("ControlPath too long"); if ((control_fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) - fatal("%s socket(): %s\n", __func__, strerror(errno)); + fatal("%s socket(): %s", __func__, strerror(errno)); old_umask = umask(0177); if (bind(control_fd, (struct sockaddr*)&addr, addr_len) == -1) { @@ -1060,12 +1068,12 @@ ssh_control_listener(void) fatal("ControlSocket %s already exists", options.control_path); else - fatal("%s bind(): %s\n", __func__, strerror(errno)); + fatal("%s bind(): %s", __func__, strerror(errno)); } umask(old_umask); if (listen(control_fd, 64) == -1) - fatal("%s listen(): %s\n", __func__, strerror(errno)); + fatal("%s listen(): %s", __func__, strerror(errno)); set_nonblock(control_fd); } @@ -1098,6 +1106,33 @@ ssh_session2_setup(int id, void *arg) packet_send(); } + if (options.tun_open != SSH_TUNMODE_NO) { + Channel *c; + int fd; + + debug("Requesting tun."); + if ((fd = tun_open(options.tun_local, + options.tun_open)) >= 0) { + c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1, + CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, + 0, "tun", 1); + c->datagram = 1; +#if defined(SSH_TUN_FILTER) + if (options.tun_open == SSH_TUNMODE_POINTOPOINT) + channel_register_filter(c->self, sys_tun_infilter, + sys_tun_outfilter); +#endif + packet_start(SSH2_MSG_CHANNEL_OPEN); + packet_put_cstring("tun@openssh.com"); + packet_put_int(c->self); + packet_put_int(c->local_window_max); + packet_put_int(c->local_maxpacket); + packet_put_int(options.tun_open); + packet_put_int(options.tun_remote); + packet_send(); + } + } + client_session2_setup(id, tty_flag, subsystem_flag, getenv("TERM"), NULL, fileno(stdin), &command, environ, &ssh_subsystem_reply); @@ -1165,6 +1200,11 @@ ssh_session2(void) if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN)) id = ssh_session2_open(); + /* Execute a local command */ + if (options.local_command != NULL && + options.permit_local_command) + ssh_local_cmd(options.local_command); + /* If requested, let ssh continue in the background. */ if (fork_after_authentication_flag) if (daemon(1, 1) < 0) diff --git a/openssh/ssh_config.5 b/openssh/ssh_config.5 index 9d37d58..38889bf 100644 --- a/openssh/ssh_config.5 +++ b/openssh/ssh_config.5 @@ -34,7 +34,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. .\" -.\" $OpenBSD: ssh_config.5,v 1.61 2005/07/08 12:53:10 jmc Exp $ +.\" $OpenBSD: ssh_config.5,v 1.76 2006/01/20 11:21:45 jmc Exp $ .Dd September 25, 1999 .Dt SSH_CONFIG 5 .Os @@ -269,8 +269,10 @@ with set to .Dq no (the default). -These sessions will reuse the master instance's network connection rather -than initiating new ones. +These sessions will try to reuse the master instance's network connection +rather than initiating new ones, but will fall back to connecting normally +if the control socket does not exist, or is not listening. +.Pp Setting this to .Dq ask will cause @@ -289,7 +291,7 @@ will continue without connecting to a master instance. X11 and .Xr ssh-agent 1 forwarding is supported over these multiplexed connections, however the -display and agent fowarded will be the one belonging to the master +display and agent forwarded will be the one belonging to the master connection i.e. it is not possible to forward multiple displays or agents. .Pp Two additional options allow for opportunistic multiplexing: try to use a @@ -322,11 +324,33 @@ used for opportunistic connection sharing include all three of these escape sequences. This ensures that shared connections are uniquely identified. .It Cm DynamicForward -Specifies that a TCP/IP port on the local machine be forwarded +Specifies that a TCP port on the local machine be forwarded over the secure channel, and the application protocol is then used to determine where to connect to from the remote machine. -The argument must be a port number. +.Pp +The argument must be +.Sm off +.Oo Ar bind_address : Oc Ar port . +.Sm on +IPv6 addresses can be specified by enclosing addresses in square brackets or +by using an alternative syntax: +.Oo Ar bind_address Ns / Oc Ns Ar port . +By default, the local port is bound in accordance with the +.Cm GatewayPorts +setting. +However, an explicit +.Ar bind_address +may be used to bind the connection to a specific address. +The +.Ar bind_address +of +.Dq localhost +indicates that the listening port be bound for local use only, while an +empty address or +.Sq * +indicates that the port should be available from all interfaces. +.Pp Currently the SOCKS4 and SOCKS5 protocols are supported, and .Nm ssh will act as a SOCKS server. @@ -515,23 +539,6 @@ Default is the name given on the command line. Numeric IP addresses are also permitted (both on the command line and in .Cm HostName specifications). -.It Cm IdentityFile -Specifies a file from which the user's RSA or DSA authentication identity -is read. -The default is -.Pa ~/.ssh/identity -for protocol version 1, and -.Pa ~/.ssh/id_rsa -and -.Pa ~/.ssh/id_dsa -for protocol version 2. -Additionally, any identities represented by the authentication agent -will be used for authentication. -The file name may use the tilde -syntax to refer to a user's home directory. -It is possible to have -multiple identity files specified in configuration files; all these -identities will be tried in sequence. .It Cm IdentitiesOnly Specifies that .Nm ssh @@ -545,17 +552,42 @@ The argument to this keyword must be .Dq yes or .Dq no . -This option is intented for situations where +This option is intended for situations where .Nm ssh-agent offers many different identities. The default is .Dq no . +.It Cm IdentityFile +Specifies a file from which the user's RSA or DSA authentication identity +is read. +The default is +.Pa ~/.ssh/identity +for protocol version 1, and +.Pa ~/.ssh/id_rsa +and +.Pa ~/.ssh/id_dsa +for protocol version 2. +Additionally, any identities represented by the authentication agent +will be used for authentication. +The file name may use the tilde +syntax to refer to a user's home directory. +It is possible to have +multiple identity files specified in configuration files; all these +identities will be tried in sequence. .It Cm KbdInteractiveDevices Specifies the list of methods to use in keyboard-interactive authentication. Multiple method names must be comma-separated. The default is to use the server specified list. +.It Cm LocalCommand +Specifies a command to execute on the local machine after successfully +connecting to the server. +The command string extends to the end of the line, and is executed with +.Pa /bin/sh . +This directive is ignored unless +.Cm PermitLocalCommand +has been enabled. .It Cm LocalForward -Specifies that a TCP/IP port on the local machine be forwarded over +Specifies that a TCP port on the local machine be forwarded over the secure channel to the specified host and port from the remote machine. The first argument must be .Sm off @@ -623,6 +655,19 @@ or .Dq no . The default is .Dq yes . +.It Cm PermitLocalCommand +Allow local command execution via the +.Ic LocalCommand +option or using the +.Ic !\& Ns Ar command +escape sequence in +.Xr ssh 1 . +The argument must be +.Dq yes +or +.Dq no . +The default is +.Dq no . .It Cm Port Specifies the port number to connect on the remote host. Default is 22. @@ -695,8 +740,23 @@ or The default is .Dq yes . This option applies to protocol version 2 only. +.It Cm RekeyLimit +Specifies the maximum amount of data that may be transmitted before the +session key is renegotiated. +The argument is the number of bytes, with an optional suffix of +.Sq K , +.Sq M , +or +.Sq G +to indicate Kilobytes, Megabytes, or Gigabytes, respectively. +The default is between +.Dq 1G +and +.Dq 4G , +depending on the cipher. +This option applies to protocol version 2 only. .It Cm RemoteForward -Specifies that a TCP/IP port on the remote machine be forwarded over +Specifies that a TCP port on the remote machine be forwarded over the secure channel to the specified host and port from the local machine. The first argument must be .Sm off @@ -773,17 +833,8 @@ across multiple .Cm SendEnv directives. The default is not to send any environment variables. -.It Cm ServerAliveInterval -Sets a timeout interval in seconds after which if no data has been received -from the server, -.Nm ssh -will send a message through the encrypted -channel to request a response from the server. -The default -is 0, indicating that these messages will not be sent to the server. -This option applies to protocol version 2 only. .It Cm ServerAliveCountMax -Sets the number of server alive messages (see above) which may be +Sets the number of server alive messages (see below) which may be sent without .Nm ssh receiving any messages back from the server. @@ -805,10 +856,19 @@ server depend on knowing when a connection has become inactive. The default value is 3. If, for example, .Cm ServerAliveInterval -(above) is set to 15, and +(see below) is set to 15, and .Cm ServerAliveCountMax is left at the default, if the server becomes unresponsive ssh will disconnect after approximately 45 seconds. +.It Cm ServerAliveInterval +Sets a timeout interval in seconds after which if no data has been received +from the server, +.Nm ssh +will send a message through the encrypted +channel to request a response from the server. +The default +is 0, indicating that these messages will not be sent to the server. +This option applies to protocol version 2 only. .It Cm SmartcardDevice Specifies which smartcard device to use. The argument to this keyword is the device @@ -868,6 +928,25 @@ This is important in scripts, and many users want it too. .Pp To disable TCP keepalive messages, the value should be set to .Dq no . +.It Cm Tunnel +Request starting +.Xr tun 4 +device forwarding between the client and the server. +This option also allows requesting layer 2 (ethernet) +instead of layer 3 (point-to-point) tunneling from the server. +The argument must be +.Dq yes , +.Dq point-to-point , +.Dq ethernet +or +.Dq no . +The default is +.Dq no . +.It Cm TunnelDevice +Force a specified +.Xr tun 4 +device on the client. +Without this option, the next available device will be used. .It Cm UsePrivilegedPort Specifies whether to use a privileged port for outgoing connections. The argument must be diff --git a/openssh/sshconnect.c b/openssh/sshconnect.c index d236a9b..711d693 100644 --- a/openssh/sshconnect.c +++ b/openssh/sshconnect.c @@ -13,7 +13,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect.c,v 1.168 2005/07/17 07:17:55 djm Exp $"); +RCSID("$OpenBSD: sshconnect.c,v 1.171 2005/12/06 22:38:27 reyk Exp $"); #include @@ -31,13 +31,12 @@ RCSID("$OpenBSD: sshconnect.c,v 1.168 2005/07/17 07:17:55 djm Exp $"); #include "readconf.h" #include "atomicio.h" #include "misc.h" - #include "dns.h" char *client_version_string = NULL; char *server_version_string = NULL; -int matching_host_key_dns = 0; +static int matching_host_key_dns = 0; /* import */ extern Options options; @@ -649,7 +648,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key, file_key = key_new(host_key->type); /* - * Check if the host key is present in the user\'s list of known + * Check if the host key is present in the user's list of known * hosts or in the systemwide list. */ host_file = user_hostfile; @@ -1080,3 +1079,39 @@ warn_changed_key(Key *host_key) xfree(fp); } + +/* + * Execute a local command + */ +int +ssh_local_cmd(const char *args) +{ + char *shell; + pid_t pid; + int status; + + if (!options.permit_local_command || + args == NULL || !*args) + return (1); + + if ((shell = getenv("SHELL")) == NULL) + shell = _PATH_BSHELL; + + pid = fork(); + if (pid == 0) { + debug3("Executing %s -c \"%s\"", shell, args); + execl(shell, shell, "-c", args, (char *)NULL); + error("Couldn't execute %s -c \"%s\": %s", + shell, args, strerror(errno)); + _exit(1); + } else if (pid == -1) + fatal("fork failed: %.100s", strerror(errno)); + while (waitpid(pid, &status, 0) == -1) + if (errno != EINTR) + fatal("Couldn't wait for child: %s", strerror(errno)); + + if (!WIFEXITED(status)) + return (1); + + return (WEXITSTATUS(status)); +} diff --git a/openssh/sshconnect1.c b/openssh/sshconnect1.c index bd05723..440d7c5 100644 --- a/openssh/sshconnect1.c +++ b/openssh/sshconnect1.c @@ -13,7 +13,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect1.c,v 1.61 2005/06/17 02:44:33 djm Exp $"); +RCSID("$OpenBSD: sshconnect1.c,v 1.62 2005/10/30 08:52:18 djm Exp $"); #include #include @@ -84,7 +84,7 @@ try_agent_authentication(void) /* Wait for server's response. */ type = packet_read(); - /* The server sends failure if it doesn\'t like our key or + /* The server sends failure if it doesn't like our key or does not support RSA authentication. */ if (type == SSH_SMSG_FAILURE) { debug("Server refused our key."); @@ -215,8 +215,8 @@ try_rsa_authentication(int idx) type = packet_read(); /* - * The server responds with failure if it doesn\'t like our key or - * doesn\'t support RSA authentication. + * The server responds with failure if it doesn't like our key or + * doesn't support RSA authentication. */ if (type == SSH_SMSG_FAILURE) { debug("Server refused our key."); diff --git a/openssh/sshconnect2.c b/openssh/sshconnect2.c index a2c06f7..0e3a7c0 100644 --- a/openssh/sshconnect2.c +++ b/openssh/sshconnect2.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect2.c,v 1.142 2005/08/30 22:08:05 djm Exp $"); +RCSID("$OpenBSD: sshconnect2.c,v 1.143 2005/10/14 02:17:59 stevesk Exp $"); #include "openbsd-compat/sys-queue.h" @@ -798,7 +798,7 @@ input_gssapi_error(int type, u_int32_t plen, void *ctxt) packet_check_eom(); - debug("Server GSSAPI Error:\n%s\n", msg); + debug("Server GSSAPI Error:\n%s", msg); xfree(msg); xfree(lang); } diff --git a/openssh/sshd.8 b/openssh/sshd.8 index fdff4ac..51d339b 100644 --- a/openssh/sshd.8 +++ b/openssh/sshd.8 @@ -34,7 +34,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. .\" -.\" $OpenBSD: sshd.8,v 1.208 2005/06/08 03:50:00 djm Exp $ +.\" $OpenBSD: sshd.8,v 1.215 2006/02/01 09:11:41 jmc Exp $ .Dd September 25, 1999 .Dt SSHD 8 .Os @@ -56,16 +56,14 @@ .Ek .Sh DESCRIPTION .Nm -(SSH Daemon) is the daemon program for +(OpenSSH Daemon) is the daemon program for .Xr ssh 1 . Together these programs replace rlogin and rsh, and provide secure encrypted communications between two untrusted hosts over an insecure network. -The programs are intended to be as easy to -install and use as possible. .Pp .Nm -is the daemon that listens for connections from clients. +listens for connections from clients. It is normally started at boot from .Pa /etc/rc . It forks a new @@ -73,119 +71,13 @@ daemon for each incoming connection. The forked daemons handle key exchange, encryption, authentication, command execution, and data exchange. -This implementation of -.Nm -supports both SSH protocol version 1 and 2 simultaneously. -.Nm -works as follows: -.Ss SSH protocol version 1 -Each host has a host-specific RSA key -(normally 2048 bits) used to identify the host. -Additionally, when -the daemon starts, it generates a server RSA key (normally 768 bits). -This key is normally regenerated every hour if it has been used, and -is never stored on disk. -.Pp -Whenever a client connects, the daemon responds with its public -host and server keys. -The client compares the -RSA host key against its own database to verify that it has not changed. -The client then generates a 256-bit random number. -It encrypts this -random number using both the host key and the server key, and sends -the encrypted number to the server. -Both sides then use this -random number as a session key which is used to encrypt all further -communications in the session. -The rest of the session is encrypted -using a conventional cipher, currently Blowfish or 3DES, with 3DES -being used by default. -The client selects the encryption algorithm -to use from those offered by the server. -.Pp -Next, the server and the client enter an authentication dialog. -The client tries to authenticate itself using -.Em .rhosts -authentication combined with RSA host -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 -.Nm rshd , -.Nm rlogind , -and -.Nm rexecd -are disabled (thus completely disabling -.Xr rlogin -and -.Xr rsh -into the machine). -.Ss SSH protocol version 2 -Version 2 works similarly: -Each host has a host-specific key (RSA or DSA) used to identify the host. -However, when the daemon starts, it does not generate a server key. -Forward security is provided through a Diffie-Hellman key agreement. -This key agreement results in a shared session key. -.Pp -The rest of the session is encrypted using a symmetric cipher, currently -128-bit AES, Blowfish, 3DES, CAST128, Arcfour, 192-bit AES, or 256-bit AES. -The client selects the encryption algorithm -to use from those offered by the server. -Additionally, session integrity is provided -through a cryptographic message authentication code -(hmac-sha1 or hmac-md5). -.Pp -Protocol version 2 provides a public key based -user (PubkeyAuthentication) or -client host (HostbasedAuthentication) authentication method, -conventional password authentication and challenge response based methods. -.Ss Command execution and data forwarding -If the client successfully authenticates itself, a dialog for -preparing the session is entered. -At this time the client may request -things like allocating a pseudo-tty, forwarding X11 connections, -forwarding TCP/IP connections, or forwarding the authentication agent -connection over the secure channel. -.Pp -Finally, the client either requests a shell or execution of a command. -The sides then enter session mode. -In this mode, either side may send -data at any time, and such data is forwarded to/from the shell or -command on the server side, and the user terminal in the client side. -.Pp -When the user program terminates and all forwarded X11 and other -connections have been closed, the server sends command exit status to -the client, and both sides exit. .Pp .Nm can be configured using command-line options or a configuration file (by default -.Xr sshd_config 5 ) . -Command-line options override values specified in the +.Xr sshd_config 5 ) ; +command-line options override values specified in the configuration file. -.Pp .Nm rereads its configuration file when it receives a hangup signal, .Dv SIGHUP , @@ -285,8 +177,12 @@ For full details of the options, and their values, see Specifies the port on which the server listens for connections (default 22). Multiple port options are permitted. -Ports specified in the configuration file are ignored when a -command-line port is specified. +Ports specified in the configuration file with the +.Cm Port +option are ignored when a command-line port is specified. +Ports specified using the +.Cm ListenAddress +option override command-line ports. .It Fl q Quiet mode. Nothing is sent to the system log. @@ -321,7 +217,7 @@ from making DNS requests unless the authentication mechanism or configuration requires it. Authentication mechanisms that may require DNS include .Cm RhostsRSAAuthentication , -.Cm HostbasedAuthentication +.Cm HostbasedAuthentication , and using a .Cm from="pattern-list" option in a key file. @@ -331,15 +227,114 @@ USER@HOST pattern in or .Cm DenyUsers . .El -.Sh CONFIGURATION FILE -.Nm -reads configuration data from -.Pa /etc/ssh/sshd_config -(or the file specified with -.Fl f -on the command line). -The file format and configuration options are described in +.Sh AUTHENTICATION +The OpenSSH SSH daemon supports SSH protocols 1 and 2. +Both protocols are supported by default, +though this can be changed via the +.Cm Protocol +option in .Xr sshd_config 5 . +Protocol 2 supports both RSA and DSA keys; +protocol 1 only supports RSA keys. +For both protocols, +each host has a host-specific key, +normally 2048 bits, +used to identify the host. +.Pp +Forward security for protocol 1 is provided through +an additional server key, +normally 768 bits, +generated when the server starts. +This key is normally regenerated every hour if it has been used, and +is never stored on disk. +Whenever a client connects, the daemon responds with its public +host and server keys. +The client compares the +RSA host key against its own database to verify that it has not changed. +The client then generates a 256-bit random number. +It encrypts this +random number using both the host key and the server key, and sends +the encrypted number to the server. +Both sides then use this +random number as a session key which is used to encrypt all further +communications in the session. +The rest of the session is encrypted +using a conventional cipher, currently Blowfish or 3DES, with 3DES +being used by default. +The client selects the encryption algorithm +to use from those offered by the server. +.Pp +For protocol 2, +forward security is provided through a Diffie-Hellman key agreement. +This key agreement results in a shared session key. +The rest of the session is encrypted using a symmetric cipher, currently +128-bit AES, Blowfish, 3DES, CAST128, Arcfour, 192-bit AES, or 256-bit AES. +The client selects the encryption algorithm +to use from those offered by the server. +Additionally, session integrity is provided +through a cryptographic message authentication code +(hmac-sha1 or hmac-md5). +.Pp +Finally, the server and the client enter an authentication dialog. +The client tries to authenticate itself using +host-based authentication, +public key authentication, +challenge-response authentication, +or password authentication. +.Pp +Regardless of the authentication type, the account is checked to +ensure that it is accessible. An account is not accessible if it is +locked, listed in +.Cm DenyUsers +or its group is listed in +.Cm DenyGroups +\&. The definition of a locked account is system dependant. Some platforms +have their own account database (eg AIX) and some modify the passwd field ( +.Ql \&*LK\&* +on Solaris and UnixWare, +.Ql \&* +on HP-UX, containing +.Ql Nologin +on Tru64, +a leading +.Ql \&*LOCKED\&* +on FreeBSD and a leading +.Ql \&!! +on 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 +System security is not improved unless +.Nm rshd , +.Nm rlogind , +and +.Nm rexecd +are disabled (thus completely disabling +.Xr rlogin +and +.Xr rsh +into the machine). +.Sh COMMAND EXECUTION AND DATA FORWARDING +If the client successfully authenticates itself, a dialog for +preparing the session is entered. +At this time the client may request +things like allocating a pseudo-tty, forwarding X11 connections, +forwarding TCP connections, or forwarding the authentication agent +connection over the secure channel. +.Pp +Finally, the client either requests a shell or execution of a command. +The sides then enter session mode. +In this mode, either side may send +data at any time, and such data is forwarded to/from the shell or +command on the server side, and the user terminal in the client side. +.Pp +When the user program terminates and all forwarded X11 and other +connections have been closed, the server sends command exit status to +the client, and both sides exit. .Sh LOGIN PROCESS When a user successfully logs in, .Nm @@ -473,7 +468,7 @@ A quote may be included in the command by quoting it with a backslash. This option might be useful to restrict certain public keys to perform just a specific operation. An example might be a key that permits remote backups but nothing else. -Note that the client may specify TCP/IP and/or X11 +Note that the client may specify TCP and/or X11 forwarding unless they are explicitly prohibited. Note that this option applies to shell, command or subsystem execution. .It Cm environment="NAME=value" @@ -490,7 +485,7 @@ This option is automatically disabled if .Cm UseLogin is enabled. .It Cm no-port-forwarding -Forbids TCP/IP forwarding when this key is used for authentication. +Forbids TCP forwarding when this key is used for authentication. Any port forward requests by the client will return an error. This might be used, e.g., in connection with the .Cm command @@ -515,6 +510,12 @@ Multiple options may be applied separated by commas. No pattern matching is performed on the specified hostnames, they must be literal domains or addresses. +.It Cm tunnel="n" +Force a +.Xr tun 4 +device on the server. +Without this option, the next available device will be used if +the client requests a tunnel. .El .Ss Examples 1024 33 12121...312314325 ylo@foo.bar @@ -524,6 +525,8 @@ from="*.niksula.hut.fi,!pc.niksula.hut.fi" 1024 35 23...2334 ylo@niksula command="dump /home",no-pty,no-port-forwarding 1024 33 23...2323 backup.hut.fi .Pp permitopen="10.2.1.55:80",permitopen="10.2.1.56:25" 1024 33 23...2323 +.Pp +tunnel="0",command="sh /etc/netstart tun0" ssh-rsa AAAA...== reyk@openbsd.org .Sh SSH_KNOWN_HOSTS FILE FORMAT The .Pa /etc/ssh/ssh_known_hosts diff --git a/openssh/sshd.c b/openssh/sshd.c index 87d0734..8077c97 100644 --- a/openssh/sshd.c +++ b/openssh/sshd.c @@ -42,7 +42,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshd.c,v 1.312 2005/07/25 11:59:40 markus Exp $"); +RCSID("$OpenBSD: sshd.c,v 1.318 2005/12/24 02:27:41 djm Exp $"); #include #include @@ -637,16 +637,8 @@ privsep_postauth(Authctxt *authctxt) 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; - return; - } - - /* Authentication complete */ - alarm(0); - if (startup_pipe != -1) { - close(startup_pipe); - startup_pipe = -1; + goto skip; } /* New socket pair */ @@ -673,6 +665,7 @@ privsep_postauth(Authctxt *authctxt) /* Drop privileges */ do_setusercontext(authctxt->pw); + skip: /* It is safe now to apply the key state */ monitor_apply_keystate(pmonitor); @@ -804,6 +797,7 @@ send_rexec_state(int fd, Buffer *conf) * bignum iqmp " * bignum p " * bignum q " + * string rngseed (only if OpenSSL is not self-seeded) */ buffer_init(&m); buffer_put_cstring(&m, buffer_ptr(conf)); @@ -820,6 +814,10 @@ send_rexec_state(int fd, Buffer *conf) } else buffer_put_int(&m, 0); +#ifndef OPENSSL_PRNG_ONLY + rexec_send_rng_seed(&m); +#endif + if (ssh_msg_send(fd, 0, &m) == -1) fatal("%s: ssh_msg_send failed", __func__); @@ -862,6 +860,11 @@ recv_rexec_state(int fd, Buffer *conf) rsa_generate_additional_parameters( sensitive_data.server_key->rsa); } + +#ifndef OPENSSL_PRNG_ONLY + rexec_recv_rng_seed(&m); +#endif + buffer_free(&m); debug3("%s: done", __func__); @@ -918,6 +921,9 @@ main(int ac, char **av) if (geteuid() == 0 && setgroups(0, NULL) == -1) debug("setgroups(): %.200s", strerror(errno)); + /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ + sanitise_stdfd(); + /* Initialize configuration options to their default values. */ initialize_server_options(&options); @@ -1055,8 +1061,6 @@ main(int ac, char **av) drop_cray_privs(); #endif - seed_rng(); - sensitive_data.server_key = NULL; sensitive_data.ssh1_host_key = NULL; sensitive_data.have_ssh1_key = 0; @@ -1075,6 +1079,8 @@ main(int ac, char **av) if (!rexec_flag) buffer_free(&cfg); + seed_rng(); + /* Fill in default values for those options not explicitly set. */ fill_default_server_options(&options); @@ -1645,7 +1651,12 @@ main(int ac, char **av) debug("get_remote_port failed"); cleanup_exit(255); } - remote_ip = get_remote_ipaddr(); + + /* + * We use get_canonical_hostname with usedns = 0 instead of + * get_remote_ipaddr here so IP options will be checked. + */ + remote_ip = get_canonical_hostname(0); #ifdef SSH_AUDIT_EVENTS audit_connection_from(remote_ip, remote_port); @@ -1725,10 +1736,10 @@ main(int ac, char **av) #endif /* - * We don\'t want to listen forever unless the other side + * 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 + * 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. */ @@ -1782,6 +1793,17 @@ main(int ac, char **av) } authenticated: + /* + * Cancel the alarm we set to limit the time taken for + * authentication. + */ + alarm(0); + signal(SIGALRM, SIG_DFL); + if (startup_pipe != -1) { + close(startup_pipe); + startup_pipe = -1; + } + #ifdef SSH_AUDIT_EVENTS audit_event(SSH_AUTH_SUCCESS); #endif diff --git a/openssh/sshd_config b/openssh/sshd_config index 4521084..314bb6d 100644 --- a/openssh/sshd_config +++ b/openssh/sshd_config @@ -1,4 +1,4 @@ -# $OpenBSD: sshd_config,v 1.72 2005/07/25 11:59:40 markus Exp $ +# $OpenBSD: sshd_config,v 1.73 2005/12/06 22:38:28 reyk Exp $ # This is the sshd server system-wide configuration file. See # sshd_config(5) for more information. @@ -101,6 +101,7 @@ #UseDNS yes #PidFile /var/run/sshd.pid #MaxStartups 10 +#PermitTunnel no # no default banner path #Banner /some/path diff --git a/openssh/sshd_config.5 b/openssh/sshd_config.5 index a9c59f4..6b7724d 100644 --- a/openssh/sshd_config.5 +++ b/openssh/sshd_config.5 @@ -34,7 +34,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. .\" -.\" $OpenBSD: sshd_config.5,v 1.44 2005/07/25 11:59:40 markus Exp $ +.\" $OpenBSD: sshd_config.5,v 1.48 2006/01/02 17:09:49 jmc Exp $ .Dd September 25, 1999 .Dt SSHD_CONFIG 5 .Os @@ -181,7 +181,7 @@ The default is aes192-ctr,aes256-ctr'' .Ed .It Cm ClientAliveCountMax -Sets the number of client alive messages (see above) which may be +Sets the number of client alive messages (see below) which may be sent without .Nm sshd receiving any messages back from the client. @@ -203,7 +203,7 @@ server depend on knowing when a connection has become inactive. The default value is 3. If .Cm ClientAliveInterval -(above) is set to 15, and +(see below) is set to 15, and .Cm ClientAliveCountMax is left at the default, unresponsive ssh clients will be disconnected after approximately 45 seconds. @@ -354,7 +354,7 @@ Kerberos servtab which allows the verification of the KDC's identity. Default is .Dq no . .It Cm KerberosGetAFSToken -If AFS is active and the user has a Kerberos 5 TGT, attempt to aquire +If AFS is active and the user has a Kerberos 5 TGT, attempt to acquire an AFS token before accessing the user's home directory. Default is .Dq no . @@ -508,6 +508,18 @@ All other authentication methods are disabled for root. If this option is set to .Dq no root is not allowed to log in. +.It Cm PermitTunnel +Specifies whether +.Xr tun 4 +device forwarding is allowed. +The argument must be +.Dq yes , +.Dq point-to-point , +.Dq ethernet +or +.Dq no . +The default is +.Dq no . .It Cm PermitUserEnvironment Specifies whether .Pa ~/.ssh/environment diff --git a/openssh/version.h b/openssh/version.h index cbb82c4..76ba9a8 100644 --- a/openssh/version.h +++ b/openssh/version.h @@ -1,4 +1,4 @@ -/* $OpenBSD: version.h,v 1.45 2005/08/31 09:28:42 markus Exp $ */ +/* $OpenBSD: version.h,v 1.46 2006/02/01 11:27:22 markus Exp $ */ #ifdef GSI #define GSI_VERSION " GSI" @@ -18,10 +18,10 @@ #define MGLUE_VERSION "" #endif -#define SSH_VERSION "OpenSSH_4.2" +#define SSH_VERSION "OpenSSH_4.3" #define SSH_PORTABLE "p1" #define SSH_HPN "-hpn" #define SSH_RELEASE SSH_VERSION SSH_PORTABLE SSH_HPN \ - " NCSA_GSSAPI_20051220" \ + " NCSA_GSSAPI_20060202" \ GSI_VERSION KRB5_VERSION MGLUE_VERSION -- 2.45.1