]> andersk Git - gssapi-openssh.git/commitdiff
merged OpenSSH 4.4p1 to trunk OPENSSH_4_4p1_GSSAPI20060928
authorjbasney <jbasney>
Thu, 28 Sep 2006 20:24:05 +0000 (20:24 +0000)
committerjbasney <jbasney>
Thu, 28 Sep 2006 20:24:05 +0000 (20:24 +0000)
113 files changed:
openssh/Makefile.in
openssh/README.platform
openssh/acss.c
openssh/auth-krb5.c
openssh/auth-pam.c
openssh/auth-shadow.c
openssh/auth.c
openssh/auth.h
openssh/auth1.c
openssh/auth2-gss.c
openssh/auth2-hostbased.c
openssh/auth2-kbdint.c
openssh/auth2-none.c
openssh/auth2-passwd.c
openssh/auth2-pubkey.c
openssh/auth2.c
openssh/buffer.c
openssh/buffer.h
openssh/canohost.c
openssh/canohost.h
openssh/channels.c
openssh/channels.h
openssh/cipher-3des1.c
openssh/cipher-acss.c
openssh/cipher-aes.c
openssh/cipher-bf1.c
openssh/cipher-ctr.c
openssh/cipher.c
openssh/cleanup.c
openssh/clientloop.c
openssh/clientloop.h
openssh/compat.c
openssh/compat.h
openssh/configure.ac
openssh/contrib/aix/buildbff.sh
openssh/defines.h
openssh/dns.c
openssh/dns.h
openssh/fatal.c
openssh/getput.h [deleted file]
openssh/gss-genr.c
openssh/gss-serv-gsi.c
openssh/gss-serv-krb5.c
openssh/gss-serv.c
openssh/includes.h
openssh/kex.c
openssh/kex.h
openssh/kexdhc.c
openssh/kexdhs.c
openssh/kexgexc.c
openssh/kexgexs.c
openssh/kexgssc.c
openssh/kexgsss.c
openssh/key.c
openssh/key.h
openssh/log.c
openssh/misc.c
openssh/moduli.c
openssh/monitor.c
openssh/monitor.h
openssh/monitor_fdpass.c
openssh/monitor_fdpass.h
openssh/monitor_mm.c
openssh/monitor_mm.h
openssh/monitor_wrap.c
openssh/monitor_wrap.h
openssh/msg.c
openssh/msg.h
openssh/myproposal.h
openssh/openbsd-compat/basename.c
openssh/openbsd-compat/bsd-getpeereid.c
openssh/openbsd-compat/bsd-openpty.c
openssh/openbsd-compat/fake-rfc2553.c
openssh/openbsd-compat/fake-rfc2553.h
openssh/openbsd-compat/getrrsetbyname.c
openssh/openbsd-compat/port-aix.c
openssh/openbsd-compat/port-aix.h
openssh/openbsd-compat/port-irix.c
openssh/openbsd-compat/xcrypt.c
openssh/openbsd-compat/xmmap.c
openssh/packet.c
openssh/packet.h
openssh/progressmeter.c
openssh/progressmeter.h
openssh/readconf.c
openssh/readconf.h
openssh/scard-opensc.c
openssh/scard/Ssh.bin [new file with mode: 0644]
openssh/scp.c
openssh/servconf.c
openssh/servconf.h
openssh/serverloop.c
openssh/session.c
openssh/session.h
openssh/sftp.c
openssh/ssh-agent.c
openssh/ssh-gss.h
openssh/ssh-keyscan.c
openssh/ssh-keysign.8
openssh/ssh-keysign.c
openssh/ssh-rand-helper.c
openssh/ssh.1
openssh/ssh.c
openssh/ssh1.h
openssh/ssh_config.5
openssh/sshconnect.c
openssh/sshconnect1.c
openssh/sshconnect2.c
openssh/sshd.8
openssh/sshd.c
openssh/sshd_config
openssh/sshd_config.5
openssh/version.h

index 4d7f6e8c062a8c9c84a4fda6d2795bbe4c8a9968..f58eb8cc531a8156a525f2cd3636883bf7524fff 100644 (file)
@@ -43,6 +43,8 @@ LD=@LD@
 CFLAGS=@CFLAGS@
 CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@
 LIBS=@LIBS@
+LIBSELINUX=@LIBSELINUX@
+SSHDLIBS=@SSHDLIBS@
 LIBEDIT=@LIBEDIT@
 LIBPAM=@LIBPAM@
 LIBWRAP=@LIBWRAP@
@@ -63,11 +65,11 @@ INSTALL_GSISSH=@INSTALL_GSISSH@
 
 TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-agent$(EXEEXT) scp$(EXEEXT) ssh-rand-helper${EXEEXT} sftp-server$(EXEEXT) sftp$(EXEEXT)
 
-LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o buffer.o \
+LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \
        canohost.o channels.o cipher.o cipher-acss.o cipher-aes.o \
        cipher-bf1.o cipher-ctr.o cipher-3des1.o cleanup.o \
        compat.o compress.o crc32.o deattack.o fatal.o hostfile.o \
-       log.o match.o moduli.o nchan.o packet.o \
+       log.o match.o md-sha256.o moduli.o nchan.o packet.o \
        readpass.o rsa.o ttymodes.o xmalloc.o \
        atomicio.o key.o dispatch.o kex.o mac.o uidswap.o uuencode.o misc.o \
        monitor_fdpass.o rijndael.o ssh-dss.o ssh-rsa.o dh.o kexdh.o \
@@ -88,7 +90,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
        auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o\
        gss-serv-gsi.o \
        loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \
-       audit.o audit-bsm.o
+       audit.o audit-bsm.o platform.o
 
 MANPAGES       = scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-rand-helper.8.out ssh-keysign.8.out sshd_config.5.out ssh_config.5.out
 MANPAGES_IN    = scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-rand-helper.8 ssh-keysign.8 sshd_config.5 ssh_config.5
@@ -109,7 +111,7 @@ PATHSUBS    = \
        -e 's|/etc/ssh/ssh_host_rsa_key|$(sysconfdir)/ssh_host_rsa_key|g' \
        -e 's|/var/run/sshd.pid|$(piddir)/sshd.pid|g' \
        -e 's|/etc/ssh/moduli|$(sysconfdir)/moduli|g' \
-       -e 's|/etc/sshrc|$(sysconfdir)/sshrc|g' \
+       -e 's|/etc/ssh/sshrc|$(sysconfdir)/sshrc|g' \
        -e 's|/usr/X11R6/bin/xauth|$(XAUTH_PATH)|g' \
        -e 's|/var/empty|$(PRIVSEP_PATH)|g' \
        -e 's|/usr/bin:/bin:/usr/sbin:/sbin|@user_path@|g'
@@ -138,7 +140,7 @@ ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS)
        $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
 
 sshd$(EXEEXT): libssh.a        $(LIBCOMPAT) $(SSHDOBJS)
-       $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBWRAP) $(LIBPAM) $(LIBS)
+       $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBWRAP) $(LIBPAM) $(LIBSELINUX) $(SSHDLIBS) $(LIBS)
 
 scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o
        $(LD) -o $@ scp.o progressmeter.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
@@ -203,8 +205,9 @@ clean:      regressclean
 
 distclean:     regressclean
        rm -f *.o *.a $(TARGETS) logintest config.cache config.log
-       rm -f *.out core opensshd.init
-       rm -f Makefile buildpkg.sh config.h config.status ssh_prng_cmds survey.sh *~
+       rm -f *.out core opensshd.init openssh.xml
+       rm -f Makefile buildpkg.sh config.h config.status ssh_prng_cmds
+       rm -f survey.sh openbsd-compat/regress/Makefile *~ 
        rm -rf autom4te.cache
        (cd openbsd-compat && $(MAKE) distclean)
        (cd scard && $(MAKE) distclean)
@@ -436,6 +439,9 @@ tests:      $(TARGETS)
                EXEEXT="$(EXEEXT)" \
                $@
 
+compat-tests: $(LIBCOMPAT)
+       (cd openbsd-compat/regress && $(MAKE))
+
 regressclean:
        if [ -f regress/Makefile ] && [ -r regress/Makefile ]; then \
                (cd regress && $(MAKE) clean) \
index 7356c1057d6dc852f70a21b97dfc5d553f9ee71b..5724b688f965df7e70bf8b30ba4af36fb24e253f 100644 (file)
@@ -30,6 +30,18 @@ gcc, gcc-mingw-core, mingw-runtime, binutils, make, openssl,
 openssl-devel, zlib, minres, minires-devel.
 
 
+Darwin and MacOS X
+------------------
+Darwin does not provide a tun(4) driver required for OpenSSH-based
+virtual private networks. The BSD manpage still exists, but the driver
+has been removed in recent releases of Darwin and MacOS X.
+
+Nevertheless, tunnel support is known to work with Darwin 8 and
+MacOS X 10.4 in Point-to-Point (Layer 3) and Ethernet (Layer 2) mode
+using a third party driver. More information is available at:
+       http://www-user.rhrk.uni-kl.de/~nissler/tuntap/
+
+
 Solaris
 -------
 If you enable BSM auditing on Solaris, you need to update audit_event(4)
index c46d28bb49758c17112bc503873d0854526d26ee..37a07dd5d25b703dd5507e98128a0cc436b72ef7 100644 (file)
@@ -16,6 +16,9 @@
  */
 
 #include "includes.h"
+
+#include <string.h>
+
 #include <openssl/evp.h>
 
 #if !defined(EVP_CTRL_SET_ACSS_MODE) && (OPENSSL_VERSION_NUMBER >= 0x00906000L)
index bc37675a2486879b5ffdbe6e78556cca0dff092d..38164fda87168603f103edbae3f17be6ca68e29b 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: auth-krb5.c,v 1.19 2006/08/03 03:34:41 deraadt Exp $ */
 /*
  *    Kerberos v5 authentication and ticket-passing routines.
  *
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth-krb5.c,v 1.16 2005/11/21 09:42:10 dtucker Exp $");
 
+#include <sys/types.h>
+#include <pwd.h>
+#include <stdarg.h>
+
+#include "xmalloc.h"
 #include "ssh.h"
 #include "ssh1.h"
 #include "packet.h"
-#include "xmalloc.h"
 #include "log.h"
+#include "buffer.h"
 #include "servconf.h"
 #include "uidswap.h"
+#include "key.h"
+#include "hostfile.h"
 #include "auth.h"
 
 #ifdef KRB5
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
 #include <krb5.h>
 
 extern ServerOptions    options;
index 8ff3320d30f44cfcff3f234e4519b2c5bc47e715..c08d4722912da474a5a6b8951310b168d9c161c1 100644 (file)
 
 /* Based on $FreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des Exp $ */
 #include "includes.h"
-RCSID("$Id$");
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <errno.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
 
 #ifdef USE_PAM
 #if defined(HAVE_SECURITY_PAM_APPL_H)
@@ -63,20 +72,31 @@ RCSID("$Id$");
 # define sshpam_const  const   /* LinuxPAM, OpenPAM */
 #endif
 
+/* Ambiguity in spec: is it an array of pointers or a pointer to an array? */
+#ifdef PAM_SUN_CODEBASE
+# define PAM_MSG_MEMBER(msg, n, member) ((*(msg))[(n)].member)
+#else
+# define PAM_MSG_MEMBER(msg, n, member) ((msg)[(n)]->member)
+#endif
+
+#include "xmalloc.h"
+#include "buffer.h"
+#include "key.h"
+#include "hostfile.h"
 #include "auth.h"
 #include "auth-pam.h"
-#include "buffer.h"
-#include "bufaux.h"
 #include "canohost.h"
 #include "log.h"
-#include "monitor_wrap.h"
 #include "msg.h"
 #include "packet.h"
 #include "misc.h"
 #include "servconf.h"
 #include "ssh2.h"
-#include "xmalloc.h"
 #include "auth-options.h"
+#ifdef GSSAPI
+#include "ssh-gss.h"
+#endif
+#include "monitor_wrap.h"
 
 extern ServerOptions options;
 extern Buffer loginmsg;
@@ -146,14 +166,16 @@ sshpam_sigchld_handler(int sig)
                fatal("PAM: authentication thread exited uncleanly");
 }
 
+/* ARGSUSED */
 static void
-pthread_exit(void *value __unused)
+pthread_exit(void *value)
 {
        _exit(0);
 }
 
+/* ARGSUSED */
 static int
-pthread_create(sp_pthread_t *thread, const void *attr __unused,
+pthread_create(sp_pthread_t *thread, const void *attr,
     void *(*thread_start)(void *), void *arg)
 {
        pid_t pid;
@@ -185,8 +207,9 @@ pthread_cancel(sp_pthread_t thread)
        return (kill(thread, SIGTERM));
 }
 
+/* ARGSUSED */
 static int
-pthread_join(sp_pthread_t thread, void **value __unused)
+pthread_join(sp_pthread_t thread, void **value)
 {
        int status;
 
@@ -284,7 +307,10 @@ import_environments(Buffer *b)
 
        /* Import environment from subprocess */
        num_env = buffer_get_int(b);
-       sshpam_env = xmalloc((num_env + 1) * sizeof(*sshpam_env));
+       if (num_env > 1024)
+               fatal("%s: received %u environment variables, expected <= 1024",
+                   __func__, num_env);
+       sshpam_env = xcalloc(num_env + 1, sizeof(*sshpam_env));
        debug3("PAM: num env strings %d", num_env);
        for(i = 0; i < num_env; i++)
                sshpam_env[i] = buffer_get_string(b, NULL);
@@ -331,9 +357,8 @@ sshpam_thread_conv(int n, sshpam_const struct pam_message **msg,
        if (n <= 0 || n > PAM_MAX_NUM_MSG)
                return (PAM_CONV_ERR);
 
-       if ((reply = malloc(n * sizeof(*reply))) == NULL)
+       if ((reply = calloc(n, sizeof(*reply))) == NULL)
                return (PAM_CONV_ERR);
-       memset(reply, 0, n * sizeof(*reply));
 
        buffer_init(&buffer);
        for (i = 0; i < n; ++i) {
@@ -412,10 +437,16 @@ sshpam_thread(void *ctxtp)
        u_int i;
        const char *pam_user;
        const char **ptr_pam_user = &pam_user;
+       char *tz = getenv("TZ");
 
        pam_get_item(sshpam_handle, PAM_USER,
            (sshpam_const void **)ptr_pam_user);
+
        environ[0] = NULL;
+       if (tz != NULL)
+               if (setenv("TZ", tz, 1) == -1)
+                       error("PAM: could not set TZ environment: %s",
+                           strerror(errno));
 
        if (sshpam_authctxt != NULL) {
                setproctitle("%s [pam]",
@@ -439,8 +470,10 @@ sshpam_thread(void *ctxtp)
                goto auth_fail;
 
        if (compat20) {
-               if (!do_pam_account())
+               if (!do_pam_account()) {
+                       sshpam_err = PAM_ACCT_EXPIRED;
                        goto auth_fail;
+               }
                if (sshpam_authctxt->force_pwchange) {
                        sshpam_err = pam_chauthtok(sshpam_handle,
                            PAM_CHANGE_EXPIRED_AUTHTOK);
@@ -482,7 +515,10 @@ sshpam_thread(void *ctxtp)
        buffer_put_cstring(&buffer,
            pam_strerror(sshpam_handle, sshpam_err));
        /* XXX - can't do much about an error here */
-       ssh_msg_send(ctxt->pam_csock, PAM_AUTH_ERR, &buffer);
+       if (sshpam_err == PAM_ACCT_EXPIRED)
+               ssh_msg_send(ctxt->pam_csock, PAM_ACCT_EXPIRED, &buffer);
+       else
+               ssh_msg_send(ctxt->pam_csock, PAM_AUTH_ERR, &buffer);
        buffer_free(&buffer);
        pthread_exit(NULL);
 
@@ -529,9 +565,8 @@ sshpam_store_conv(int n, sshpam_const struct pam_message **msg,
        if (n <= 0 || n > PAM_MAX_NUM_MSG)
                return (PAM_CONV_ERR);
 
-       if ((reply = malloc(n * sizeof(*reply))) == NULL)
+       if ((reply = calloc(n, sizeof(*reply))) == NULL)
                return (PAM_CONV_ERR);
-       memset(reply, 0, n * sizeof(*reply));
 
        for (i = 0; i < n; ++i) {
                switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
@@ -638,8 +673,11 @@ sshpam_init_ctx(Authctxt *authctxt)
        int socks[2];
 
        debug3("PAM: %s entering", __func__);
-       /* Refuse to start if we don't have PAM enabled */
-       if (!options.use_pam)
+       /*
+        * Refuse to start if we don't have PAM enabled or do_pam_account
+        * has previously failed.
+        */
+       if (!options.use_pam || sshpam_account_status == 0)
                return NULL;
 
        /* Initialize PAM */
@@ -699,7 +737,7 @@ sshpam_query(void *ctx, char **name, char **info,
                case PAM_PROMPT_ECHO_OFF:
                        *num = 1;
                        len = plen + mlen + 1;
-                       **prompts = xrealloc(**prompts, len);
+                       **prompts = xrealloc(**prompts, 1, len);
                        strlcpy(**prompts + plen, msg, len - plen);
                        plen += mlen;
                        **echo_on = (type == PAM_PROMPT_ECHO_ON);
@@ -709,21 +747,25 @@ sshpam_query(void *ctx, char **name, char **info,
                case PAM_TEXT_INFO:
                        /* accumulate messages */
                        len = plen + mlen + 2;
-                       **prompts = xrealloc(**prompts, len);
+                       **prompts = xrealloc(**prompts, 1, len);
                        strlcpy(**prompts + plen, msg, len - plen);
                        plen += mlen;
                        strlcat(**prompts + plen, "\n", len - plen);
                        plen++;
                        xfree(msg);
                        break;
+               case PAM_ACCT_EXPIRED:
+                       sshpam_account_status = 0;
+                       /* FALLTHROUGH */
                case PAM_AUTH_ERR:
-                       debug3("PAM: PAM_AUTH_ERR");
+                       debug3("PAM: %s", pam_strerror(sshpam_handle, type));
                        if (**prompts != NULL && strlen(**prompts) != 0) {
                                *info = **prompts;
                                **prompts = NULL;
                                *num = 0;
                                **echo_on = 0;
                                ctxt->pam_done = -1;
+                               xfree(msg);
                                return 0;
                        }
                        /* FALLTHROUGH */
@@ -930,9 +972,8 @@ sshpam_tty_conv(int n, sshpam_const struct pam_message **msg,
        if (n <= 0 || n > PAM_MAX_NUM_MSG || !isatty(STDIN_FILENO))
                return (PAM_CONV_ERR);
 
-       if ((reply = malloc(n * sizeof(*reply))) == NULL)
+       if ((reply = calloc(n, sizeof(*reply))) == NULL)
                return (PAM_CONV_ERR);
-       memset(reply, 0, n * sizeof(*reply));
 
        for (i = 0; i < n; ++i) {
                switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
index 3e27b46c0924c442fdc564491309ded4ae821b16..8b3160aeedb7d06674f1104bc134bf8c67d4980b 100644 (file)
  */
 
 #include "includes.h"
-RCSID("$Id$");
 
 #if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE)
 #include <shadow.h>
+#include <stdarg.h>
+#include <string.h>
 
+#include "key.h"
+#include "hostfile.h"
 #include "auth.h"
 #include "buffer.h"
 #include "log.h"
index 7bcbfad3a5b6f4d3a4f457b15f79731e7ce38111..dbee00855b422dc0dfdfe72d6d68d67055809789 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: auth.c,v 1.75 2006/08/03 03:34:41 deraadt Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth.c,v 1.60 2005/06/17 02:44:32 djm Exp $");
 
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+
+#include <netinet/in.h>
+
+#include <errno.h>
+#ifdef HAVE_PATHS_H
+# include <paths.h>
+#endif
+#include <pwd.h>
 #ifdef HAVE_LOGIN_H
 #include <login.h>
 #endif
 #ifdef USE_SHADOW
 #include <shadow.h>
 #endif
-
 #ifdef HAVE_LIBGEN_H
 #include <libgen.h>
 #endif
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
 
 #include "xmalloc.h"
 #include "match.h"
 #include "groupaccess.h"
 #include "log.h"
+#include "buffer.h"
 #include "servconf.h"
+#include "key.h"
+#include "hostfile.h"
 #include "auth.h"
 #include "auth-options.h"
 #include "canohost.h"
-#include "buffer.h"
-#include "bufaux.h"
 #include "uidswap.h"
 #include "misc.h"
-#include "bufaux.h"
 #include "packet.h"
 #include "loginrec.h"
+#ifdef GSSAPI
+#include "ssh-gss.h"
+#endif
 #include "monitor_wrap.h"
 
 /* import */
 extern ServerOptions options;
+extern int use_privsep;
 extern Buffer loginmsg;
+extern struct passwd *privsep_pw;
 
 /* Debugging messages */
 Buffer auth_debug;
@@ -231,6 +249,9 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
        void (*authlog) (const char *fmt,...) = verbose;
        char *authmsg;
 
+       if (use_privsep && !mm_is_monitor() && !authctxt->postponed)
+               return;
+
        /* Raise logging level */
        if (authenticated == 1 ||
            !authctxt->valid ||
@@ -260,44 +281,15 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
            strcmp(method, "challenge-response") == 0))
                record_failed_login(authctxt->user,
                    get_canonical_hostname(options.use_dns), "ssh");
+# ifdef WITH_AIXAUTHENTICATE
+       if (authenticated)
+               sys_auth_record_login(authctxt->user,
+                   get_canonical_hostname(options.use_dns), "ssh", &loginmsg);
+# endif
 #endif
 #ifdef SSH_AUDIT_EVENTS
-       if (authenticated == 0 && !authctxt->postponed) {
-               ssh_audit_event_t event;
-
-               debug3("audit failed auth attempt, method %s euid %d",
-                   method, (int)geteuid());
-               /*
-                * Because the auth loop is used in both monitor and slave,
-                * we must be careful to send each event only once and with
-                * enough privs to write the event.
-                */
-               event = audit_classify_auth(method);
-               switch(event) {
-               case SSH_AUTH_FAIL_NONE:
-               case SSH_AUTH_FAIL_PASSWD:
-               case SSH_AUTH_FAIL_KBDINT:
-                       if (geteuid() == 0)
-                               audit_event(event);
-                       break;
-               case SSH_AUTH_FAIL_PUBKEY:
-               case SSH_AUTH_FAIL_HOSTBASED:
-               case SSH_AUTH_FAIL_GSSAPI:
-                       /*
-                        * This is required to handle the case where privsep
-                        * is enabled but it's root logging in, since
-                        * use_privsep won't be cleared until after a
-                        * successful login.
-                        */
-                       if (geteuid() == 0)
-                               audit_event(event);
-                       else
-                               PRIVSEP(audit_event(event));
-                       break;
-               default:
-                       error("unknown authentication audit event %d", event);
-               }
-       }
+       if (authenticated == 0 && !authctxt->postponed)
+               audit_event(audit_classify_auth(method));
 #endif
 }
 
@@ -310,7 +302,6 @@ auth_root_allowed(char *method)
        switch (options.permit_root_login) {
        case PERMIT_YES:
                return 1;
-               break;
        case PERMIT_NO_PASSWD:
                if (strcmp(method, "password") != 0)
                        return 1;
@@ -337,7 +328,8 @@ auth_root_allowed(char *method)
 static char *
 expand_authorized_keys(const char *filename, struct passwd *pw)
 {
-       char *file, *ret;
+       char *file, ret[MAXPATHLEN];
+       int i;
 
        file = percent_expand(filename, "h", pw->pw_dir,
            "u", pw->pw_name, (char *)NULL);
@@ -349,14 +341,11 @@ expand_authorized_keys(const char *filename, struct passwd *pw)
        if (*file == '/')
                return (file);
 
-       ret = xmalloc(MAXPATHLEN);
-       if (strlcpy(ret, pw->pw_dir, MAXPATHLEN) >= MAXPATHLEN ||
-           strlcat(ret, "/", MAXPATHLEN) >= MAXPATHLEN ||
-           strlcat(ret, file, MAXPATHLEN) >= MAXPATHLEN)
+       i = snprintf(ret, sizeof(ret), "%s/%s", pw->pw_dir, file);
+       if (i < 0 || (size_t)i >= sizeof(ret))
                fatal("expand_authorized_keys: path too long");
-
        xfree(file);
-       return (ret);
+       return (xstrdup(ret));
 }
 
 char *
@@ -493,6 +482,9 @@ getpwnamallow(const char *user)
 #endif
        struct passwd *pw;
 
+       parse_server_match_config(&options, user,
+           get_canonical_hostname(options.use_dns), get_remote_ipaddr());
+
        pw = getpwnam(user);
        if (pw == NULL) {
                logit("Invalid user %.100s from %.100s",
@@ -581,6 +573,8 @@ fakepw(void)
        fake.pw_gecos = "NOUSER";
        fake.pw_uid = (uid_t)-1;
        fake.pw_gid = (gid_t)-1;
+       fake.pw_uid = privsep_pw->pw_uid;
+       fake.pw_gid = privsep_pw->pw_gid;
 #ifdef HAVE_PW_CLASS_IN_PASSWD
        fake.pw_class = "";
 #endif
index 4114fa38ec9117189b20d493d25b795a5f4159f0..f63c3ee802e9c516f484de52d2aa6abe4f5afc6a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: auth.h,v 1.51 2005/06/06 11:20:36 djm Exp $   */
+/* $OpenBSD: auth.h,v 1.58 2006/08/18 09:15:20 markus Exp $ */
 
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
@@ -28,9 +28,8 @@
 #ifndef AUTH_H
 #define AUTH_H
 
-#include "key.h"
-#include "hostfile.h"
-#include "buffer.h"
+#include <signal.h>
+
 #include <openssl/rsa.h>
 
 #ifdef HAVE_LOGIN_CAP
@@ -51,7 +50,8 @@ typedef struct Authmethod Authmethod;
 typedef struct KbdintDevice KbdintDevice;
 
 struct Authctxt {
-       int              success;
+       sig_atomic_t     success;
+       int              authenticated; /* authenticated and alarms cancelled */
        int              postponed;     /* authentication needs another step */
        int              valid;         /* user exists and is allowed to login */
        int              attempt;
index 4bc2bf76d62d1d5794dabbb9cfe5b9be225ab37b..b9d6b1115f4f98d778f80186eacc41ee5cc6ce17 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: auth1.c,v 1.70 2006/08/03 03:34:41 deraadt Exp $ */
 /*
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  *                    All rights reserved
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth1.c,v 1.62 2005/07/16 01:35:24 djm Exp $");
+
+#include <sys/types.h>
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <pwd.h>
 
 #include "xmalloc.h"
 #include "rsa.h"
@@ -20,10 +28,15 @@ RCSID("$OpenBSD: auth1.c,v 1.62 2005/07/16 01:35:24 djm Exp $");
 #include "log.h"
 #include "servconf.h"
 #include "compat.h"
+#include "key.h"
+#include "hostfile.h"
 #include "auth.h"
 #include "channels.h"
 #include "session.h"
 #include "uidswap.h"
+#ifdef GSSAPI
+#include "ssh-gss.h"
+#endif
 #include "monitor_wrap.h"
 #include "buffer.h"
 
@@ -77,7 +90,7 @@ static const struct AuthMethod1
 {
        int i;
 
-       for(i = 0; auth1_methods[i].name != NULL; i++)
+       for (i = 0; auth1_methods[i].name != NULL; i++)
                if (auth1_methods[i].type == type)
                        return (&(auth1_methods[i]));
 
@@ -96,6 +109,7 @@ get_authname(int type)
        return (buf);
 }
 
+/*ARGSUSED*/
 static int
 auth1_process_password(Authctxt *authctxt, char *info, size_t infolen)
 {
@@ -120,6 +134,7 @@ auth1_process_password(Authctxt *authctxt, char *info, size_t infolen)
        return (authenticated);
 }
 
+/*ARGSUSED*/
 static int
 auth1_process_rsa(Authctxt *authctxt, char *info, size_t infolen)
 {
@@ -137,6 +152,7 @@ auth1_process_rsa(Authctxt *authctxt, char *info, size_t infolen)
        return (authenticated);
 }
 
+/*ARGSUSED*/
 static int
 auth1_process_rhosts_rsa(Authctxt *authctxt, char *info, size_t infolen)
 {
@@ -175,6 +191,7 @@ auth1_process_rhosts_rsa(Authctxt *authctxt, char *info, size_t infolen)
        return (authenticated);
 }
 
+/*ARGSUSED*/
 static int
 auth1_process_tis_challenge(Authctxt *authctxt, char *info, size_t infolen)
 {
@@ -193,6 +210,7 @@ auth1_process_tis_challenge(Authctxt *authctxt, char *info, size_t infolen)
        return (-1);
 }
 
+/*ARGSUSED*/
 static int
 auth1_process_tis_response(Authctxt *authctxt, char *info, size_t infolen)
 {
index 6fcecb897ebb6e88e9aa6882582ac2e281a0933e..fab7cc239964b6c759f26f64558638763a5c023a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: auth2-gss.c,v 1.12 2005/10/13 22:24:31 stevesk Exp $  */
+/* $OpenBSD: auth2-gss.c,v 1.15 2006/08/03 03:34:41 deraadt Exp $ */
 
 /*
  * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
 
 #ifdef GSSAPI
 
+#include <sys/types.h>
+
+#include <stdarg.h>
+
+#include "xmalloc.h"
+#include "key.h"
+#include "hostfile.h"
 #include "auth.h"
 #include "ssh2.h"
-#include "xmalloc.h"
 #include "log.h"
 #include "dispatch.h"
+#include "buffer.h"
 #include "servconf.h"
 #include "packet.h"
-#include "monitor_wrap.h"
-
 #include "ssh-gss.h"
+#include "monitor_wrap.h"
 
 extern ServerOptions options;
 
@@ -165,6 +171,8 @@ userauth_gssapi(Authctxt *authctxt)
        }
 
        if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, &goid)))) {
+               if (ctxt != NULL)
+                       ssh_gssapi_delete_ctx(&ctxt);
                xfree(doid);
                authctxt->server_caused_failure = 1;
                return (0);
index 1111ed67a643223635f25ae73b528213a74a4099..663dec5d9e9574c8b9c61ccb297958f37e65aa9f 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: auth2-hostbased.c,v 1.11 2006/08/03 03:34:41 deraadt Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth2-hostbased.c,v 1.6 2004/01/19 21:25:15 markus Exp $");
 
-#include "ssh2.h"
+#include <sys/types.h>
+
+#include <pwd.h>
+#include <string.h>
+#include <stdarg.h>
+
 #include "xmalloc.h"
+#include "ssh2.h"
 #include "packet.h"
 #include "buffer.h"
 #include "log.h"
 #include "servconf.h"
 #include "compat.h"
-#include "bufaux.h"
-#include "auth.h"
 #include "key.h"
+#include "hostfile.h"
+#include "auth.h"
 #include "canohost.h"
+#ifdef GSSAPI
+#include "ssh-gss.h"
+#endif
 #include "monitor_wrap.h"
 #include "pathnames.h"
 
index fa83649755a33c817f780cf84f984119dd0f9a8d..a4fc9e6f73f23ea236cda775bedf755f84562d06 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: auth2-kbdint.c,v 1.5 2006/08/03 03:34:41 deraadt Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth2-kbdint.c,v 1.2 2002/05/31 11:35:15 markus Exp $");
 
+#include <sys/types.h>
+
+#include <stdarg.h>
+
+#include "xmalloc.h"
 #include "packet.h"
+#include "key.h"
+#include "hostfile.h"
 #include "auth.h"
 #include "log.h"
+#include "buffer.h"
 #include "servconf.h"
-#include "xmalloc.h"
 
 /* import */
 extern ServerOptions options;
index 1c30a3203e1f94c528a88590d7141d677a40eeb6..952b448248e94cd21d6ce76a6d11db0e0eccee88 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: auth2-none.c,v 1.13 2006/08/05 07:52:52 dtucker Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth2-none.c,v 1.7 2004/05/11 19:01:43 deraadt Exp $");
 
-#include "auth.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/uio.h>
+
+#include <fcntl.h>
+#include <stdarg.h>
+#include <unistd.h>
+
 #include "xmalloc.h"
+#include "key.h"
+#include "hostfile.h"
+#include "auth.h"
 #include "packet.h"
 #include "log.h"
+#include "buffer.h"
 #include "servconf.h"
 #include "atomicio.h"
 #include "compat.h"
 #include "ssh2.h"
+#ifdef GSSAPI
+#include "ssh-gss.h"
+#endif
 #include "monitor_wrap.h"
 
 /* import */
index 2321ef47be38145250fc16b51354d3d7d2a44cd5..421c5c25d018ab64c45b9b12a770af8a5d8925b8 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: auth2-passwd.c,v 1.9 2006/08/03 03:34:41 deraadt Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth2-passwd.c,v 1.5 2003/12/31 00:24:50 dtucker Exp $");
+
+#include <sys/types.h>
+
+#include <string.h>
+#include <stdarg.h>
 
 #include "xmalloc.h"
 #include "packet.h"
 #include "log.h"
+#include "key.h"
+#include "hostfile.h"
 #include "auth.h"
+#include "buffer.h"
+#ifdef GSSAPI
+#include "ssh-gss.h"
+#endif
 #include "monitor_wrap.h"
 #include "servconf.h"
 
index a97d0f430b93f298b0111ac6e8eeb8d78db15caf..9863cd9e6e544aaca327495230fad44d5a18ede2 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: auth2-pubkey.c,v 1.15 2006/08/03 03:34:41 deraadt Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth2-pubkey.c,v 1.9 2004/12/11 01:48:56 dtucker Exp $");
 
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <pwd.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "xmalloc.h"
 #include "ssh.h"
 #include "ssh2.h"
-#include "xmalloc.h"
 #include "packet.h"
 #include "buffer.h"
 #include "log.h"
 #include "servconf.h"
 #include "compat.h"
-#include "bufaux.h"
-#include "auth.h"
 #include "key.h"
+#include "hostfile.h"
+#include "auth.h"
 #include "pathnames.h"
 #include "uidswap.h"
 #include "auth-options.h"
 #include "canohost.h"
+#ifdef GSSAPI
+#include "ssh-gss.h"
+#endif
 #include "monitor_wrap.h"
 #include "misc.h"
 
index 65c1dc8bd28730ce378cced4db8ff341f5ddb423..a660c83f71360737bedf598eb92eff17e9a6adff 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: auth2.c,v 1.113 2006/08/03 03:34:41 deraadt Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth2.c,v 1.107 2004/07/28 09:40:29 markus Exp $");
 
-#include "ssh2.h"
+#include <sys/types.h>
+
+#include <pwd.h>
+#include <stdarg.h>
+#include <string.h>
+
 #include "xmalloc.h"
+#include "ssh2.h"
 #include "packet.h"
 #include "log.h"
+#include "buffer.h"
 #include "servconf.h"
 #include "compat.h"
+#include "key.h"
+#include "hostfile.h"
 #include "auth.h"
 #include "dispatch.h"
 #include "pathnames.h"
-#include "monitor_wrap.h"
 #include "buffer.h"
 
 #ifdef GSSAPI
 #include "ssh-gss.h"
 #endif
+#include "monitor_wrap.h"
 
 /* import */
 extern ServerOptions options;
@@ -102,6 +111,7 @@ do_authentication2(Authctxt *authctxt)
        dispatch_run(DISPATCH_BLOCK, &authctxt->success, authctxt);
 }
 
+/*ARGSUSED*/
 static void
 input_service_request(int type, u_int32_t seq, void *ctxt)
 {
@@ -135,6 +145,7 @@ input_service_request(int type, u_int32_t seq, void *ctxt)
        xfree(service);
 }
 
+/*ARGSUSED*/
 static void
 input_userauth_request(int type, u_int32_t seq, void *ctxt)
 {
index 83e388178a769b7c64d740602061e700b7323ffa..bdeb069db1c2b463b2237399cea312a1514b4a8f 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: buffer.c,v 1.31 2006/08/03 03:34:41 deraadt Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: buffer.c,v 1.23 2005/03/14 11:46:56 markus Exp $");
+
+#include <sys/param.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
 
 #include "xmalloc.h"
 #include "buffer.h"
 #include "log.h"
 
+#define        BUFFER_MAX_CHUNK        0x100000
+#define        BUFFER_MAX_LEN          0xa00000
+#define        BUFFER_ALLOCSZ          0x008000
+
+/* this value for BUFFER_MAX_HPN_LEN is */
+/* still undersized for the faster networks */
+/* it might make sense to have yet another */
+/* MAX_LEN for 10+GB networks. Something closer to */
+/* 128MB or 192MB -cjr*/
+#define        BUFFER_MAX_HPN_LEN      0x2000000 /*32MB*/
+
 /* Initializes the buffer structure. */
 
 void
@@ -66,6 +83,23 @@ buffer_append(Buffer *buffer, const void *data, u_int len)
        memcpy(p, data, len);
 }
 
+static int
+buffer_compact(Buffer *buffer)
+{
+       /*
+        * If the buffer is quite empty, but all data is at the end, move the
+        * data to the beginning.
+        */
+       if (buffer->offset > MIN(buffer->alloc, BUFFER_MAX_CHUNK)) {
+               memmove(buffer->buf, buffer->buf + buffer->offset,
+                       buffer->end - buffer->offset);
+               buffer->end -= buffer->offset;
+               buffer->offset = 0;
+               return (1);
+       }
+       return (0);
+}
+
 /*
  * Appends space to the buffer, expanding the buffer if necessary. This does
  * not actually copy the data into the buffer, but instead returns a pointer
@@ -93,29 +127,43 @@ restart:
                buffer->end += len;
                return p;
        }
-       /*
-        * If the buffer is quite empty, but all data is at the end, move the
-        * data to the beginning and retry.
-        */
-       if (buffer->offset > MIN(buffer->alloc, BUFFER_MAX_CHUNK)) {
-               memmove(buffer->buf, buffer->buf + buffer->offset,
-                       buffer->end - buffer->offset);
-               buffer->end -= buffer->offset;
-               buffer->offset = 0;
+
+       /* Compact data back to the start of the buffer if necessary */
+       if (buffer_compact(buffer))
                goto restart;
-       }
-       /* Increase the size of the buffer and retry. */
 
-       newlen = buffer->alloc + len + 32768;
+       /* Increase the size of the buffer and retry. */
+       newlen = roundup(buffer->alloc + len, BUFFER_ALLOCSZ);
        if (newlen > BUFFER_MAX_HPN_LEN)
                fatal("buffer_append_space: alloc %u not supported",
                    newlen);
-       buffer->buf = xrealloc(buffer->buf, newlen);
+       buffer->buf = xrealloc(buffer->buf, 1, newlen);
        buffer->alloc = newlen;
        goto restart;
        /* NOTREACHED */
 }
 
+/*
+ * Check whether an allocation of 'len' will fit in the buffer
+ * This must follow the same math as buffer_append_space
+ */
+int
+buffer_check_alloc(Buffer *buffer, u_int len)
+{
+       if (buffer->offset == buffer->end) {
+               buffer->offset = 0;
+               buffer->end = 0;
+       }
+ restart:
+       if (buffer->end + len < buffer->alloc)
+               return (1);
+       if (buffer_compact(buffer))
+               goto restart;
+       if (roundup(buffer->alloc + len, BUFFER_ALLOCSZ) <= BUFFER_MAX_LEN)
+               return (1);
+       return (0);
+}
+
 /* Returns the number of bytes of data in the buffer. */
 
 u_int
index 62e43d1a716fe803e65ddcc9144b5a796aada75b..ecc4aea83193405b762397c6d47918e2369eb5ae 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: buffer.h,v 1.13 2005/03/14 11:46:56 markus Exp $      */
+/* $OpenBSD: buffer.h,v 1.16 2006/08/03 03:34:41 deraadt Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -23,16 +23,6 @@ typedef struct {
        u_int    end;           /* Offset of last byte containing data. */
 }       Buffer;
 
-#define        BUFFER_MAX_CHUNK        0x100000  /*1MB*/
-#define        BUFFER_MAX_LEN          0xa00000  /*10MB*/
-
-/* this value for BUFFER_MAX_HPN_LEN is */
-/* still undersized for the faster networks */
-/* it might make sense to have yet another */
-/* MAX_LEN for 10+GB networks. Something closer to */
-/* 128MB or 192MB -cjr*/
-#define        BUFFER_MAX_HPN_LEN      0x2000000 /*32MB*/
-
 void    buffer_init(Buffer *);
 void    buffer_clear(Buffer *);
 void    buffer_free(Buffer *);
@@ -43,6 +33,8 @@ void  *buffer_ptr(Buffer *);
 void    buffer_append(Buffer *, const void *, u_int);
 void   *buffer_append_space(Buffer *, u_int);
 
+int     buffer_check_alloc(Buffer *, u_int);
+
 void    buffer_get(Buffer *, void *, u_int);
 
 void    buffer_consume(Buffer *, u_int);
@@ -54,4 +46,40 @@ int   buffer_get_ret(Buffer *, void *, u_int);
 int     buffer_consume_ret(Buffer *, u_int);
 int     buffer_consume_end_ret(Buffer *, u_int);
 
+#include <openssl/bn.h>
+
+void    buffer_put_bignum(Buffer *, const BIGNUM *);
+void    buffer_put_bignum2(Buffer *, const BIGNUM *);
+void   buffer_get_bignum(Buffer *, BIGNUM *);
+void   buffer_get_bignum2(Buffer *, BIGNUM *);
+
+u_short        buffer_get_short(Buffer *);
+void   buffer_put_short(Buffer *, u_short);
+
+u_int  buffer_get_int(Buffer *);
+void    buffer_put_int(Buffer *, u_int);
+
+u_int64_t buffer_get_int64(Buffer *);
+void   buffer_put_int64(Buffer *, u_int64_t);
+
+int     buffer_get_char(Buffer *);
+void    buffer_put_char(Buffer *, int);
+
+void   *buffer_get_string(Buffer *, u_int *);
+void    buffer_put_string(Buffer *, const void *, u_int);
+void   buffer_put_cstring(Buffer *, const char *);
+
+#define buffer_skip_string(b) \
+    do { u_int l = buffer_get_int(b); buffer_consume(b, l); } while (0)
+
+int    buffer_put_bignum_ret(Buffer *, const BIGNUM *);
+int    buffer_get_bignum_ret(Buffer *, BIGNUM *);
+int    buffer_put_bignum2_ret(Buffer *, const BIGNUM *);
+int    buffer_get_bignum2_ret(Buffer *, BIGNUM *);
+int    buffer_get_short_ret(u_short *, Buffer *);
+int    buffer_get_int_ret(u_int *, Buffer *);
+int    buffer_get_int64_ret(u_int64_t *, Buffer *);
+void   *buffer_get_string_ret(Buffer *, u_int *);
+int    buffer_get_char_ret(char *, Buffer *);
+
 #endif                         /* BUFFER_H */
index 3e6f482d25d33f1c1b17ebe46d8e7db23800f1ab..99da72d41e10d291dc8081ff9881636ea4867fc8 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: canohost.c,v 1.61 2006/08/03 03:34:41 deraadt Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: canohost.c,v 1.48 2005/12/28 22:46:06 stevesk Exp $");
 
-#include "packet.h"
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+
 #include "xmalloc.h"
+#include "packet.h"
 #include "log.h"
 #include "canohost.h"
 
@@ -43,6 +58,9 @@ 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)
@@ -52,9 +70,6 @@ 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);
 
@@ -87,7 +102,7 @@ get_remote_hostname(int sock, int use_dns)
         */
        for (i = 0; name[i]; i++)
                if (isupper(name[i]))
-                       name[i] = tolower(name[i]);
+                       name[i] = (char)tolower(name[i]);
        /*
         * Map it back to an IP address and check that the given
         * address actually is an address of this host.  This is
@@ -102,7 +117,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 BREAK-IN ATTEMPT!", name);
+                   "[%s] failed - POSSIBLE BREAK-IN ATTEMPT!", name, ntop);
                return xstrdup(ntop);
        }
        /* Look for the address from the list of addresses. */
index 937abd2b572a3542de2c081350af542d338b3016..0a293e778951b25187e28d4f861cf78ac5ead415 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: canohost.h,v 1.8 2001/06/26 17:27:23 markus Exp $     */
+/* $OpenBSD: canohost.h,v 1.9 2006/03/25 22:22:42 djm Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
index 9311643b4ecbb702c599aec099ff5a2a32efea78..b4617cd8496cbb6d44a90457b316d650b19d9990 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: channels.c,v 1.266 2006/08/29 10:40:18 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: channels.c,v 1.232 2006/01/30 12:22:22 reyk Exp $");
 
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/un.h>
+#include <sys/socket.h>
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <errno.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+#include <stdarg.h>
+
+#include "xmalloc.h"
 #include "ssh.h"
 #include "ssh1.h"
 #include "ssh2.h"
 #include "packet.h"
-#include "xmalloc.h"
 #include "log.h"
 #include "misc.h"
+#include "buffer.h"
 #include "channels.h"
 #include "compat.h"
 #include "canohost.h"
 #include "key.h"
 #include "authfd.h"
 #include "pathnames.h"
-#include "bufaux.h"
-
 
 /* -- channel core */
 
@@ -92,11 +111,18 @@ typedef struct {
        u_short listen_port;            /* Remote side should listen port number. */
 } ForwardPermission;
 
-/* List of all permitted host/port pairs to connect. */
+/* List of all permitted host/port pairs to connect by the user. */
 static ForwardPermission permitted_opens[SSH_MAX_FORWARDS_PER_DIRECTION];
 
-/* Number of permitted host/port pairs in the array. */
+/* List of all permitted host/port pairs to connect by the admin. */
+static ForwardPermission permitted_adm_opens[SSH_MAX_FORWARDS_PER_DIRECTION];
+
+/* Number of permitted host/port pairs in the array permitted by the user. */
 static int num_permitted_opens = 0;
+
+/* Number of permitted host/port pair in the array permitted by the admin. */
+static int num_adm_permitted_opens = 0;
+
 /*
  * If this is true, all opens are permitted.  This is the case on the server
  * on which we have to trust the client anyway, and the user could do
@@ -124,7 +150,7 @@ static u_int x11_saved_data_len = 0;
  * Fake X11 authentication data.  This is what the server will be sending us;
  * we should replace any occurrences of this by the real data.
  */
-static char *x11_fake_data = NULL;
+static u_char *x11_fake_data = NULL;
 static u_int x11_fake_data_len;
 
 
@@ -169,7 +195,7 @@ channel_lookup(int id)
        if ((c = channel_by_id(id)) == NULL)
                return (NULL);
 
-       switch(c->type) {
+       switch (c->type) {
        case SSH_CHANNEL_X11_OPEN:
        case SSH_CHANNEL_LARVAL:
        case SSH_CHANNEL_CONNECTING:
@@ -179,7 +205,6 @@ channel_lookup(int id)
        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);
@@ -189,7 +214,6 @@ channel_lookup(int id)
  * Register filedescriptors for a channel, used when allocating a channel or
  * when the channel consumer/producer is ready, e.g. shell exec'd
  */
-
 static void
 channel_register_fds(Channel *c, int rfd, int wfd, int efd,
     int extusage, int nonblock)
@@ -236,7 +260,6 @@ channel_register_fds(Channel *c, int rfd, int wfd, int efd,
  * Allocate a new channel object and set its type and socket. This will cause
  * remote_name to be freed.
  */
-
 Channel *
 channel_new(char *ctype, int type, int rfd, int wfd, int efd,
     u_int window, u_int maxpack, int extusage, char *remote_name, int nonblock)
@@ -248,7 +271,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
        /* Do initial allocation if this is the first call. */
        if (channels_alloc == 0) {
                channels_alloc = 10;
-               channels = xmalloc(channels_alloc * sizeof(Channel *));
+               channels = xcalloc(channels_alloc, sizeof(Channel *));
                for (i = 0; i < channels_alloc; i++)
                        channels[i] = NULL;
        }
@@ -265,16 +288,15 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
                if (channels_alloc > 10000)
                        fatal("channel_new: internal error: channels_alloc %d "
                            "too big.", channels_alloc);
-               channels = xrealloc(channels,
-                   (channels_alloc + 10) * sizeof(Channel *));
+               channels = xrealloc(channels, channels_alloc + 10,
+                   sizeof(Channel *));
                channels_alloc += 10;
                debug2("channel: expanding %d", channels_alloc);
                for (i = found; i < channels_alloc; i++)
                        channels[i] = NULL;
        }
        /* Initialize and return new channel. */
-       c = channels[found] = xmalloc(sizeof(Channel));
-       memset(c, 0, sizeof(Channel));
+       c = channels[found] = xcalloc(1, sizeof(Channel));
        buffer_init(&c->input);
        buffer_init(&c->output);
        buffer_init(&c->extended);
@@ -339,7 +361,6 @@ channel_close_fd(int *fdp)
 }
 
 /* Close all channel fd/socket. */
-
 static void
 channel_close_fds(Channel *c)
 {
@@ -354,7 +375,6 @@ channel_close_fds(Channel *c)
 }
 
 /* Free the channel and close its fd/socket. */
-
 void
 channel_free(Channel *c)
 {
@@ -401,7 +421,6 @@ channel_free_all(void)
  * Closes the sockets/fds of all channels.  This is used to close extra file
  * descriptors after a fork.
  */
-
 void
 channel_close_all(void)
 {
@@ -415,7 +434,6 @@ channel_close_all(void)
 /*
  * Stop listening to channels.
  */
-
 void
 channel_stop_listening(void)
 {
@@ -442,7 +460,6 @@ channel_stop_listening(void)
  * Returns true if no channel has too much buffered data, and false if one or
  * more channel is overfull.
  */
-
 int
 channel_not_very_much_buffered_data(void)
 {
@@ -472,7 +489,6 @@ channel_not_very_much_buffered_data(void)
 }
 
 /* Returns true if any channel is still open. */
-
 int
 channel_still_open(void)
 {
@@ -515,7 +531,6 @@ channel_still_open(void)
 }
 
 /* Returns the id of an open channel suitable for keepaliving */
-
 int
 channel_find_open(void)
 {
@@ -560,7 +575,6 @@ channel_find_open(void)
  * suitable for sending to the client.  The message contains crlf pairs for
  * newlines.
  */
-
 char *
 channel_open_message(void)
 {
@@ -645,6 +659,7 @@ channel_request_start(int id, char *service, int wantconfirm)
        packet_put_cstring(service);
        packet_put_char(wantconfirm);
 }
+
 void
 channel_register_confirm(int id, channel_callback_fn *fn, void *ctx)
 {
@@ -657,6 +672,7 @@ channel_register_confirm(int id, channel_callback_fn *fn, void *ctx)
        c->confirm = fn;
        c->confirm_ctx = ctx;
 }
+
 void
 channel_register_cleanup(int id, channel_callback_fn *fn, int do_close)
 {
@@ -669,6 +685,7 @@ channel_register_cleanup(int id, channel_callback_fn *fn, int do_close)
        c->detach_user = fn;
        c->detach_close = do_close;
 }
+
 void
 channel_cancel_cleanup(int id)
 {
@@ -681,6 +698,7 @@ channel_cancel_cleanup(int id)
        c->detach_user = NULL;
        c->detach_close = 0;
 }
+
 void
 channel_register_filter(int id, channel_infilter_fn *ifn,
     channel_outfilter_fn *ofn)
@@ -720,25 +738,27 @@ channel_set_fds(int id, int rfd, int wfd, int efd,
  * 'channel_post*': perform any appropriate operations for channels which
  * have events pending.
  */
-typedef void chan_fn(Channel *c, fd_set * readset, fd_set * writeset);
+typedef void chan_fn(Channel *c, fd_set *readset, fd_set *writeset);
 chan_fn *channel_pre[SSH_CHANNEL_MAX_TYPE];
 chan_fn *channel_post[SSH_CHANNEL_MAX_TYPE];
 
+/* ARGSUSED */
 static void
-channel_pre_listener(Channel *c, fd_set * readset, fd_set * writeset)
+channel_pre_listener(Channel *c, fd_set *readset, fd_set *writeset)
 {
        FD_SET(c->sock, readset);
 }
 
+/* ARGSUSED */
 static void
-channel_pre_connecting(Channel *c, fd_set * readset, fd_set * writeset)
+channel_pre_connecting(Channel *c, fd_set *readset, fd_set *writeset)
 {
        debug3("channel %d: waiting for connection", c->self);
        FD_SET(c->sock, writeset);
 }
 
 static void
-channel_pre_open_13(Channel *c, fd_set * readset, fd_set * writeset)
+channel_pre_open_13(Channel *c, fd_set *readset, fd_set *writeset)
 {
        if (buffer_len(&c->input) < packet_get_maxsize())
                FD_SET(c->sock, readset);
@@ -746,36 +766,15 @@ channel_pre_open_13(Channel *c, fd_set * readset, fd_set * writeset)
                FD_SET(c->sock, writeset);
 }
 
-int channel_tcpwinsz () {
-        u_int32_t tcpwinsz = 0;
-        socklen_t optsz = sizeof(tcpwinsz);
-        int ret = -1;
-       if(!packet_connection_is_on_socket()) 
-               return(131072);
-        ret = getsockopt(packet_get_connection_in(),
-                        SOL_SOCKET, SO_RCVBUF, &tcpwinsz, &optsz);
-        if ((ret == 0) && tcpwinsz > BUFFER_MAX_HPN_LEN)
-                          tcpwinsz = BUFFER_MAX_HPN_LEN;
-       debug2("tcpwinsz: %d for connection: %d", tcpwinsz, packet_get_connection_in());
-       return(tcpwinsz);
-}
-
 static void
-channel_pre_open(Channel *c, fd_set * readset, fd_set * writeset)
+channel_pre_open(Channel *c, fd_set *readset, fd_set *writeset)
 {
        u_int limit = compat20 ? c->remote_window : packet_get_maxsize();
 
-       /* check buffer limits */
-       if (!c->tcpwinsz) 
-               c->tcpwinsz = channel_tcpwinsz();
-       if (c->dynamic_window > 0)
-               c->tcpwinsz = channel_tcpwinsz();
-
-       limit = MIN(limit, 2 * c->tcpwinsz);
-
        if (c->istate == CHAN_INPUT_OPEN &&
            limit > 0 &&
-           buffer_len(&c->input) < limit)
+           buffer_len(&c->input) < limit &&
+           buffer_check_alloc(&c->input, CHAN_RBUF))
                FD_SET(c->rfd, readset);
        if (c->ostate == CHAN_OUTPUT_OPEN ||
            c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
@@ -805,8 +804,9 @@ channel_pre_open(Channel *c, fd_set * readset, fd_set * writeset)
                FD_SET(c->ctl_fd, readset);
 }
 
+/* ARGSUSED */
 static void
-channel_pre_input_draining(Channel *c, fd_set * readset, fd_set * writeset)
+channel_pre_input_draining(Channel *c, fd_set *readset, fd_set *writeset)
 {
        if (buffer_len(&c->input) == 0) {
                packet_start(SSH_MSG_CHANNEL_CLOSE);
@@ -817,8 +817,9 @@ channel_pre_input_draining(Channel *c, fd_set * readset, fd_set * writeset)
        }
 }
 
+/* ARGSUSED */
 static void
-channel_pre_output_draining(Channel *c, fd_set * readset, fd_set * writeset)
+channel_pre_output_draining(Channel *c, fd_set *readset, fd_set *writeset)
 {
        if (buffer_len(&c->output) == 0)
                chan_mark_dead(c);
@@ -894,7 +895,7 @@ x11_open_helper(Buffer *b)
 }
 
 static void
-channel_pre_x11_open_13(Channel *c, fd_set * readset, fd_set * writeset)
+channel_pre_x11_open_13(Channel *c, fd_set *readset, fd_set *writeset)
 {
        int ret = x11_open_helper(&c->output);
 
@@ -920,7 +921,7 @@ channel_pre_x11_open_13(Channel *c, fd_set * readset, fd_set * writeset)
 }
 
 static void
-channel_pre_x11_open(Channel *c, fd_set * readset, fd_set * writeset)
+channel_pre_x11_open(Channel *c, fd_set *readset, fd_set *writeset)
 {
        int ret = x11_open_helper(&c->output);
 
@@ -946,8 +947,9 @@ channel_pre_x11_open(Channel *c, fd_set * readset, fd_set * writeset)
 }
 
 /* try to decode a socks4 header */
+/* ARGSUSED */
 static int
-channel_decode_socks4(Channel *c, fd_set * readset, fd_set * writeset)
+channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset)
 {
        char *p, *host;
        u_int len, have, i, found;
@@ -1011,7 +1013,7 @@ channel_decode_socks4(Channel *c, fd_set * readset, fd_set * writeset)
        s4_rsp.command = 90;                    /* cd: req granted */
        s4_rsp.dest_port = 0;                   /* ignored */
        s4_rsp.dest_addr.s_addr = INADDR_ANY;   /* ignored */
-       buffer_append(&c->output, (char *)&s4_rsp, sizeof(s4_rsp));
+       buffer_append(&c->output, &s4_rsp, sizeof(s4_rsp));
        return 1;
 }
 
@@ -1024,8 +1026,9 @@ channel_decode_socks4(Channel *c, fd_set * readset, fd_set * writeset)
 #define SSH_SOCKS5_CONNECT     0x01
 #define SSH_SOCKS5_SUCCESS     0x00
 
+/* ARGSUSED */
 static int
-channel_decode_socks5(Channel *c, fd_set * readset, fd_set * writeset)
+channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset)
 {
        struct {
                u_int8_t version;
@@ -1035,7 +1038,7 @@ channel_decode_socks5(Channel *c, fd_set * readset, fd_set * writeset)
        } s5_req, s5_rsp;
        u_int16_t dest_port;
        u_char *p, dest_addr[255+1];
-       u_int have, i, found, nmethods, addrlen, af;
+       u_int have, need, i, found, nmethods, addrlen, af;
 
        debug2("channel %d: decode socks5", c->self);
        p = buffer_ptr(&c->input);
@@ -1051,7 +1054,7 @@ channel_decode_socks5(Channel *c, fd_set * readset, fd_set * writeset)
                        return 0;
                /* look for method: "NO AUTHENTICATION REQUIRED" */
                for (found = 0, i = 2 ; i < nmethods + 2; i++) {
-                       if (p[i] == SSH_SOCKS5_NOAUTH ) {
+                       if (p[i] == SSH_SOCKS5_NOAUTH) {
                                found = 1;
                                break;
                        }
@@ -1072,7 +1075,7 @@ channel_decode_socks5(Channel *c, fd_set * readset, fd_set * writeset)
        debug2("channel %d: socks5 post auth", c->self);
        if (have < sizeof(s5_req)+1)
                return 0;                       /* need more */
-       memcpy((char *)&s5_req, p, sizeof(s5_req));
+       memcpy(&s5_req, p, sizeof(s5_req));
        if (s5_req.version != 0x05 ||
            s5_req.command != SSH_SOCKS5_CONNECT ||
            s5_req.reserved != 0x00) {
@@ -1096,7 +1099,10 @@ channel_decode_socks5(Channel *c, fd_set * readset, fd_set * writeset)
                debug2("channel %d: bad socks5 atyp %d", c->self, s5_req.atyp);
                return -1;
        }
-       if (have < 4 + addrlen + 2)
+       need = sizeof(s5_req) + addrlen + 2;
+       if (s5_req.atyp == SSH_SOCKS5_DOMAIN)
+               need++;
+       if (have < need)
                return 0;
        buffer_consume(&c->input, sizeof(s5_req));
        if (s5_req.atyp == SSH_SOCKS5_DOMAIN)
@@ -1120,15 +1126,15 @@ channel_decode_socks5(Channel *c, fd_set * readset, fd_set * writeset)
        ((struct in_addr *)&dest_addr)->s_addr = INADDR_ANY;
        dest_port = 0;                          /* ignored */
 
-       buffer_append(&c->output, (char *)&s5_rsp, sizeof(s5_rsp));
-       buffer_append(&c->output, (char *)&dest_addr, sizeof(struct in_addr));
-       buffer_append(&c->output, (char *)&dest_port, sizeof(dest_port));
+       buffer_append(&c->output, &s5_rsp, sizeof(s5_rsp));
+       buffer_append(&c->output, &dest_addr, sizeof(struct in_addr));
+       buffer_append(&c->output, &dest_port, sizeof(dest_port));
        return 1;
 }
 
 /* dynamic port forwarding */
 static void
-channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset)
+channel_pre_dynamic(Channel *c, fd_set *readset, fd_set *writeset)
 {
        u_char *p;
        u_int have;
@@ -1171,8 +1177,9 @@ channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset)
 }
 
 /* This is our fake X11 server socket. */
+/* ARGSUSED */
 static void
-channel_post_x11_listener(Channel *c, fd_set * readset, fd_set * writeset)
+channel_post_x11_listener(Channel *c, fd_set *readset, fd_set *writeset)
 {
        Channel *nc;
        struct sockaddr addr;
@@ -1296,8 +1303,9 @@ channel_set_reuseaddr(int fd)
 /*
  * This socket is listening for connections to a forwarded TCP/IP port.
  */
+/* ARGSUSED */
 static void
-channel_post_port_listener(Channel *c, fd_set * readset, fd_set * writeset)
+channel_post_port_listener(Channel *c, fd_set *readset, fd_set *writeset)
 {
        Channel *nc;
        struct sockaddr addr;
@@ -1353,8 +1361,9 @@ channel_post_port_listener(Channel *c, fd_set * readset, fd_set * writeset)
  * This is the authentication agent socket listening for connections from
  * clients.
  */
+/* ARGSUSED */
 static void
-channel_post_auth_listener(Channel *c, fd_set * readset, fd_set * writeset)
+channel_post_auth_listener(Channel *c, fd_set *readset, fd_set *writeset)
 {
        Channel *nc;
        int newsock;
@@ -1386,8 +1395,9 @@ channel_post_auth_listener(Channel *c, fd_set * readset, fd_set * writeset)
        }
 }
 
+/* ARGSUSED */
 static void
-channel_post_connecting(Channel *c, fd_set * readset, fd_set * writeset)
+channel_post_connecting(Channel *c, fd_set *readset, fd_set *writeset)
 {
        int err = 0;
        socklen_t sz = sizeof(err);
@@ -1432,18 +1442,25 @@ channel_post_connecting(Channel *c, fd_set * readset, fd_set * writeset)
        }
 }
 
+/* ARGSUSED */
 static int
-channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset)
+channel_handle_rfd(Channel *c, fd_set *readset, fd_set *writeset)
 {
        char buf[CHAN_RBUF];
        int len;
 
        if (c->rfd != -1 &&
            FD_ISSET(c->rfd, readset)) {
+               errno = 0;
                len = read(c->rfd, buf, sizeof(buf));
                if (len < 0 && (errno == EINTR || errno == EAGAIN))
                        return 1;
+#ifndef PTY_ZEROREAD
                if (len <= 0) {
+#else
+               if ((!c->isatty && len <= 0) ||
+                   (c->isatty && (len < 0 || (len == 0 && errno != 0)))) {
+#endif
                        debug2("channel %d: read<=0 rfd %d len %d",
                            c->self, c->rfd, len);
                        if (c->type != SSH_CHANNEL_OPEN) {
@@ -1472,8 +1489,10 @@ channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset)
        }
        return 1;
 }
+
+/* ARGSUSED */
 static int
-channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset)
+channel_handle_wfd(Channel *c, fd_set *readset, fd_set *writeset)
 {
        struct termios tio;
        u_char *data = NULL, *buf;
@@ -1559,8 +1578,9 @@ channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset)
        }
        return 1;
 }
+
 static int
-channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset)
+channel_handle_efd(Channel *c, fd_set *readset, fd_set *writeset)
 {
        char buf[CHAN_RBUF];
        int len;
@@ -1602,8 +1622,10 @@ channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset)
        }
        return 1;
 }
+
+/* ARGSUSED */
 static int
-channel_handle_ctl(Channel *c, fd_set * readset, fd_set * writeset)
+channel_handle_ctl(Channel *c, fd_set *readset, fd_set *writeset)
 {
        char buf[16];
        int len;
@@ -1629,6 +1651,7 @@ channel_handle_ctl(Channel *c, fd_set * readset, fd_set * writeset)
        }
        return 1;
 }
+
 static int
 channel_check_window(Channel *c)
 {
@@ -1656,7 +1679,7 @@ channel_check_window(Channel *c)
 }
 
 static void
-channel_post_open(Channel *c, fd_set * readset, fd_set * writeset)
+channel_post_open(Channel *c, fd_set *readset, fd_set *writeset)
 {
        if (c->delayed)
                return;
@@ -1669,8 +1692,9 @@ channel_post_open(Channel *c, fd_set * readset, fd_set * writeset)
        channel_check_window(c);
 }
 
+/* ARGSUSED */
 static void
-channel_post_output_drain_13(Channel *c, fd_set * readset, fd_set * writeset)
+channel_post_output_drain_13(Channel *c, fd_set *readset, fd_set *writeset)
 {
        int len;
 
@@ -1787,7 +1811,7 @@ channel_garbage_collect(Channel *c)
 }
 
 static void
-channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset)
+channel_handler(chan_fn *ftab[], fd_set *readset, fd_set *writeset)
 {
        static int did_init = 0;
        u_int i;
@@ -1815,15 +1839,20 @@ void
 channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
     u_int *nallocp, int rekeying)
 {
-       u_int n, sz;
+       u_int n, sz, nfdset;
 
        n = MAX(*maxfdp, channel_max_fd);
 
-       sz = howmany(n+1, NFDBITS) * sizeof(fd_mask);
+       nfdset = howmany(n+1, NFDBITS);
+       /* Explicitly test here, because xrealloc isn't always called */
+       if (nfdset && SIZE_T_MAX / nfdset < sizeof(fd_mask))
+               fatal("channel_prepare_select: max_fd (%d) is too large", n);
+       sz = nfdset * sizeof(fd_mask);
+
        /* perhaps check sz < nalloc/2 and shrink? */
        if (*readsetp == NULL || sz > *nallocp) {
-               *readsetp = xrealloc(*readsetp, sz);
-               *writesetp = xrealloc(*writesetp, sz);
+               *readsetp = xrealloc(*readsetp, nfdset, sizeof(fd_mask));
+               *writesetp = xrealloc(*writesetp, nfdset, sizeof(fd_mask));
                *nallocp = sz;
        }
        *maxfdp = n;
@@ -1839,14 +1868,13 @@ channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
  * events pending.
  */
 void
-channel_after_select(fd_set * readset, fd_set * writeset)
+channel_after_select(fd_set *readset, fd_set *writeset)
 {
        channel_handler(channel_post, readset, writeset);
 }
 
 
 /* If there is data to send to the connection, enqueue some of it now. */
-
 void
 channel_output_poll(void)
 {
@@ -1967,6 +1995,7 @@ channel_output_poll(void)
 
 /* -- protocol input */
 
+/* ARGSUSED */
 void
 channel_input_data(int type, u_int32_t seq, void *ctxt)
 {
@@ -2026,6 +2055,7 @@ channel_input_data(int type, u_int32_t seq, void *ctxt)
        xfree(data);
 }
 
+/* ARGSUSED */
 void
 channel_input_extended_data(int type, u_int32_t seq, void *ctxt)
 {
@@ -2072,6 +2102,7 @@ channel_input_extended_data(int type, u_int32_t seq, void *ctxt)
        xfree(data);
 }
 
+/* ARGSUSED */
 void
 channel_input_ieof(int type, u_int32_t seq, void *ctxt)
 {
@@ -2095,6 +2126,7 @@ channel_input_ieof(int type, u_int32_t seq, void *ctxt)
 
 }
 
+/* ARGSUSED */
 void
 channel_input_close(int type, u_int32_t seq, void *ctxt)
 {
@@ -2133,6 +2165,7 @@ channel_input_close(int type, u_int32_t seq, void *ctxt)
 }
 
 /* proto version 1.5 overloads CLOSE_CONFIRMATION with OCLOSE */
+/* ARGSUSED */
 void
 channel_input_oclose(int type, u_int32_t seq, void *ctxt)
 {
@@ -2145,6 +2178,7 @@ channel_input_oclose(int type, u_int32_t seq, void *ctxt)
        chan_rcvd_oclose(c);
 }
 
+/* ARGSUSED */
 void
 channel_input_close_confirmation(int type, u_int32_t seq, void *ctxt)
 {
@@ -2161,6 +2195,7 @@ channel_input_close_confirmation(int type, u_int32_t seq, void *ctxt)
        channel_free(c);
 }
 
+/* ARGSUSED */
 void
 channel_input_open_confirmation(int type, u_int32_t seq, void *ctxt)
 {
@@ -2208,6 +2243,7 @@ reason2txt(int reason)
        return "unknown reason";
 }
 
+/* ARGSUSED */
 void
 channel_input_open_failure(int type, u_int32_t seq, void *ctxt)
 {
@@ -2239,6 +2275,7 @@ channel_input_open_failure(int type, u_int32_t seq, void *ctxt)
        channel_free(c);
 }
 
+/* ARGSUSED */
 void
 channel_input_window_adjust(int type, u_int32_t seq, void *ctxt)
 {
@@ -2263,6 +2300,7 @@ channel_input_window_adjust(int type, u_int32_t seq, void *ctxt)
        c->remote_window += adjust;
 }
 
+/* ARGSUSED */
 void
 channel_input_port_open(int type, u_int32_t seq, void *ctxt)
 {
@@ -2490,7 +2528,7 @@ channel_setup_remote_fwd_listener(const char *listen_address,
  * the secure channel to host:port from local side.
  */
 
-void
+int
 channel_request_remote_forwarding(const char *listen_host, u_short listen_port,
     const char *host_to_connect, u_short port_to_connect)
 {
@@ -2534,7 +2572,6 @@ channel_request_remote_forwarding(const char *listen_host, u_short listen_port,
                        success = 1;
                        break;
                case SSH_SMSG_FAILURE:
-                       logit("Warning: Server denied remote port forwarding.");
                        break;
                default:
                        /* Unknown packet */
@@ -2548,6 +2585,7 @@ channel_request_remote_forwarding(const char *listen_host, u_short listen_port,
                permitted_opens[num_permitted_opens].listen_port = listen_port;
                num_permitted_opens++;
        }
+       return (success ? 0 : -1);
 }
 
 /*
@@ -2587,14 +2625,14 @@ channel_request_rforward_cancel(const char *host, u_short port)
 /*
  * This is called after receiving CHANNEL_FORWARDING_REQUEST.  This initates
  * listening for the port, and sends back a success reply (or disconnect
- * message if there was an error).  This never returns if there was an error.
+ * message if there was an error).
  */
-
-void
+int
 channel_input_port_forward_request(int is_root, int gateway_ports, 
        int hpn_disabled, int hpn_buffer_size)
 {
        u_short port, host_port;
+       int success = 0;
        char *hostname;
 
        /* Get arguments from the packet. */
@@ -2616,11 +2654,13 @@ channel_input_port_forward_request(int is_root, int gateway_ports,
 #endif
 
        /* Initiate forwarding */
-       channel_setup_local_fwd_listener(NULL, port, hostname,
+       success = channel_setup_local_fwd_listener(NULL, port, hostname,
            host_port, gateway_ports, hpn_disabled, hpn_buffer_size);
 
        /* Free the argument string. */
        xfree(hostname);
+
+       return (success ? 0 : -1);
 }
 
 /*
@@ -2639,7 +2679,7 @@ void
 channel_add_permitted_opens(char *host, int port)
 {
        if (num_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION)
-               fatal("channel_request_remote_forwarding: too many forwards");
+               fatal("channel_add_permitted_opens: too many forwards");
        debug("allow port forwarding to host %s port %d", host, port);
 
        permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host);
@@ -2649,6 +2689,19 @@ channel_add_permitted_opens(char *host, int port)
        all_opens_permitted = 0;
 }
 
+int
+channel_add_adm_permitted_opens(char *host, int port)
+{
+       if (num_adm_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION)
+               fatal("channel_add_adm_permitted_opens: too many forwards");
+       debug("config allows port forwarding to host %s port %d", host, port);
+
+       permitted_adm_opens[num_adm_permitted_opens].host_to_connect
+            = xstrdup(host);
+       permitted_adm_opens[num_adm_permitted_opens].port_to_connect = port;
+       return ++num_adm_permitted_opens;
+}
+
 void
 channel_clear_permitted_opens(void)
 {
@@ -2658,9 +2711,18 @@ channel_clear_permitted_opens(void)
                if (permitted_opens[i].host_to_connect != NULL)
                        xfree(permitted_opens[i].host_to_connect);
        num_permitted_opens = 0;
-
 }
 
+void
+channel_clear_adm_permitted_opens(void)
+{
+       int i;
+
+       for (i = 0; i < num_adm_permitted_opens; i++)
+               if (permitted_adm_opens[i].host_to_connect != NULL)
+                       xfree(permitted_adm_opens[i].host_to_connect);
+       num_adm_permitted_opens = 0;
+}
 
 /* return socket to remote host, port */
 static int
@@ -2738,7 +2800,7 @@ channel_connect_by_listen_address(u_short listen_port)
 int
 channel_connect_to(const char *host, u_short port)
 {
-       int i, permit;
+       int i, permit, permit_adm = 1;
 
        permit = all_opens_permitted;
        if (!permit) {
@@ -2747,9 +2809,19 @@ channel_connect_to(const char *host, u_short port)
                            permitted_opens[i].port_to_connect == port &&
                            strcmp(permitted_opens[i].host_to_connect, host) == 0)
                                permit = 1;
+       }
 
+       if (num_adm_permitted_opens > 0) {
+               permit_adm = 0;
+               for (i = 0; i < num_adm_permitted_opens; i++)
+                       if (permitted_adm_opens[i].host_to_connect != NULL &&
+                           permitted_adm_opens[i].port_to_connect == port &&
+                           strcmp(permitted_adm_opens[i].host_to_connect, host)
+                           == 0)
+                               permit_adm = 1;
        }
-       if (!permit) {
+
+       if (!permit || !permit_adm) {
                logit("Received request to connect to host %.100s port %d, "
                    "but the request was denied.", host, port);
                return -1;
@@ -2770,10 +2842,10 @@ channel_send_window_changes(void)
                if (ioctl(channels[i]->rfd, TIOCGWINSZ, &ws) < 0)
                        continue;
                channel_request_start(i, "window-change", 0);
-               packet_put_int(ws.ws_col);
-               packet_put_int(ws.ws_row);
-               packet_put_int(ws.ws_xpixel);
-               packet_put_int(ws.ws_ypixel);
+               packet_put_int((u_int)ws.ws_col);
+               packet_put_int((u_int)ws.ws_row);
+               packet_put_int((u_int)ws.ws_xpixel);
+               packet_put_int((u_int)ws.ws_ypixel);
                packet_send();
        }
 }
@@ -2882,7 +2954,7 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
        }
 
        /* Allocate a channel for each socket. */
-       *chanids = xmalloc(sizeof(**chanids) * (num_socks + 1));
+       *chanids = xcalloc(num_socks + 1, sizeof(**chanids));
        for (n = 0; n < num_socks; n++) {
                sock = socks[n];
                if (hpn_disabled) 
@@ -2917,7 +2989,7 @@ connect_local_xsocket(u_int dnr)
        memset(&addr, 0, sizeof(addr));
        addr.sun_family = AF_UNIX;
        snprintf(addr.sun_path, sizeof addr.sun_path, _PATH_UNIX_X, dnr);
-       if (connect(sock, (struct sockaddr *) & addr, sizeof(addr)) == 0)
+       if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0)
                return sock;
        close(sock);
        error("connect %.100s: %.100s", addr.sun_path, strerror(errno));
@@ -2927,12 +2999,12 @@ connect_local_xsocket(u_int dnr)
 int
 x11_connect_display(void)
 {
-       int display_number, sock = 0;
+       u_int display_number;
        const char *display;
        char buf[1024], *cp;
        struct addrinfo hints, *ai, *aitop;
        char strport[NI_MAXSERV];
-       int gaierr;
+       int gaierr, sock = 0;
 
        /* Try to open a socket for the local X server. */
        display = getenv("DISPLAY");
@@ -2952,7 +3024,7 @@ x11_connect_display(void)
        if (strncmp(display, "unix:", 5) == 0 ||
            display[0] == ':') {
                /* Connect to the unix domain socket. */
-               if (sscanf(strrchr(display, ':') + 1, "%d", &display_number) != 1) {
+               if (sscanf(strrchr(display, ':') + 1, "%u", &display_number) != 1) {
                        error("Could not parse display number from DISPLAY: %.100s",
                            display);
                        return -1;
@@ -2977,7 +3049,7 @@ x11_connect_display(void)
        }
        *cp = 0;
        /* buf now contains the host name.  But first we parse the display number. */
-       if (sscanf(cp + 1, "%d", &display_number) != 1) {
+       if (sscanf(cp + 1, "%u", &display_number) != 1) {
                error("Could not parse display number from DISPLAY: %.100s",
                    display);
                return -1;
@@ -2987,7 +3059,7 @@ x11_connect_display(void)
        memset(&hints, 0, sizeof(hints));
        hints.ai_family = IPv4or6;
        hints.ai_socktype = SOCK_STREAM;
-       snprintf(strport, sizeof strport, "%d", 6000 + display_number);
+       snprintf(strport, sizeof strport, "%u", 6000 + display_number);
        if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) {
                error("%.100s: unknown host. (%s)", buf, gai_strerror(gaierr));
                return -1;
@@ -3001,7 +3073,7 @@ x11_connect_display(void)
                }
                /* Connect it to the display. */
                if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
-                       debug2("connect %.100s port %d: %.100s", buf,
+                       debug2("connect %.100s port %u: %.100s", buf,
                            6000 + display_number, strerror(errno));
                        close(sock);
                        continue;
@@ -3011,7 +3083,7 @@ x11_connect_display(void)
        }
        freeaddrinfo(aitop);
        if (!ai) {
-               error("connect %.100s port %d: %.100s", buf, 6000 + display_number,
+               error("connect %.100s port %u: %.100s", buf, 6000 + display_number,
                    strerror(errno));
                return -1;
        }
@@ -3025,6 +3097,7 @@ x11_connect_display(void)
  * with either SSH_MSG_OPEN_CONFIRMATION or SSH_MSG_OPEN_FAILURE.
  */
 
+/* ARGSUSED */
 void
 x11_input_open(int type, u_int32_t seq, void *ctxt)
 {
@@ -3068,6 +3141,7 @@ x11_input_open(int type, u_int32_t seq, void *ctxt)
 }
 
 /* dummy protocol handler that denies SSH-1 requests (agent/x11) */
+/* ARGSUSED */
 void
 deny_input_open(int type, u_int32_t seq, void *ctxt)
 {
@@ -3114,13 +3188,11 @@ x11_request_forwarding_with_spoofing(int client_session_id, const char *disp,
                return;
        }
 
-       cp = disp;
-       if (disp)
-               cp = strchr(disp, ':');
+       cp = strchr(disp, ':');
        if (cp)
                cp = strchr(cp, '.');
        if (cp)
-               screen_number = atoi(cp + 1);
+               screen_number = (u_int)strtonum(cp + 1, 0, 400, NULL);
        else
                screen_number = 0;
 
index f380531dcb7dce69fd1540c49dabdf05b894a2a3..91bc0ae0087b850e7175c07bb5f44e089fb1f97e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: channels.h,v 1.83 2005/12/30 15:56:37 reyk Exp $      */
+/* $OpenBSD: channels.h,v 1.88 2006/08/03 03:34:42 deraadt Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -38,8 +38,6 @@
 #ifndef CHANNEL_H
 #define CHANNEL_H
 
-#include "buffer.h"
-
 /* Definitions for channel types. */
 #define SSH_CHANNEL_X11_LISTENER       1       /* Listening for inet X11 conn. */
 #define SSH_CHANNEL_PORT_LISTENER      2       /* Listening on a port. */
@@ -214,11 +212,13 @@ int        channel_find_open(void);
 void    channel_set_af(int af);
 void     channel_permit_all_opens(void);
 void    channel_add_permitted_opens(char *, int);
+int     channel_add_adm_permitted_opens(char *, int);
 void    channel_clear_permitted_opens(void);
-void     channel_input_port_forward_request(int, int, int, int);
+void    channel_clear_adm_permitted_opens(void);
+int      channel_input_port_forward_request(int, int, int, int);
 int     channel_connect_to(const char *, u_short);
 int     channel_connect_by_listen_address(u_short);
-void    channel_request_remote_forwarding(const char *, u_short,
+int     channel_request_remote_forwarding(const char *, u_short,
             const char *, u_short);
 int     channel_setup_local_fwd_listener(const char *, u_short,
             const char *, u_short, int, int, int);
index f815e8ae524e786439da56a5f59fa940ef3f5732..fc16e20d7e790762ec7af1e73918e68577d28f0c 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: cipher-3des1.c,v 1.6 2006/08/03 03:34:42 deraadt Exp $ */
 /*
  * Copyright (c) 2003 Markus Friedl.  All rights reserved.
  *
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: cipher-3des1.c,v 1.2 2003/12/22 20:29:55 markus Exp $");
+
+#include <sys/types.h>
 
 #include <openssl/evp.h>
+
+#include <stdarg.h>
+#include <string.h>
+
 #include "xmalloc.h"
 #include "log.h"
 
index 103f2d6c62898aa03a23d607a431e0ca6718f545..cb0bf736c39dfa08bea33e6951da909b4a16d7ec 100644 (file)
  */
 
 #include "includes.h"
+
 #include <openssl/evp.h>
 
-RCSID("$Id$");
+#include <string.h>
 
 #if !defined(EVP_CTRL_SET_ACSS_MODE) && (OPENSSL_VERSION_NUMBER >= 0x00907000L)
 
index 228ddb1044174990ce80e9b2f97aee4ef1134ee0..3ea594969eab382f1a5b5ad683d74d64ee7c3a73 100644 (file)
 #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 <sys/types.h>
 
 #include <openssl/evp.h>
+
+#include <stdarg.h>
+#include <string.h>
+
 #include "rijndael.h"
 #include "xmalloc.h"
 #include "log.h"
index 5af695c1740623a5b4f74efd78b0acd979104f0e..292488c5c61778bb4a1fd15577e40ae5a2c80266 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: cipher-bf1.c,v 1.5 2006/08/03 03:34:42 deraadt Exp $ */
 /*
  * Copyright (c) 2003 Markus Friedl.  All rights reserved.
  *
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: cipher-bf1.c,v 1.1 2003/05/15 03:08:29 markus Exp $");
+
+#include <sys/types.h>
 
 #include <openssl/evp.h>
+
+#include <stdarg.h>
+#include <string.h>
+
 #include "xmalloc.h"
 #include "log.h"
 
index 8a98f3c42559148a188ba813fe525098826f9e3d..b24f3a4288662108d0aa67e99e0b4cc86df22d61 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: cipher-ctr.c,v 1.10 2006/08/03 03:34:42 deraadt Exp $ */
 /*
  * Copyright (c) 2003 Markus Friedl <markus@openbsd.org>
  *
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 #include "includes.h"
-RCSID("$OpenBSD: cipher-ctr.c,v 1.6 2005/07/17 07:17:55 djm Exp $");
+
+#include <sys/types.h>
+
+#include <stdarg.h>
+#include <string.h>
 
 #include <openssl/evp.h>
 
-#include "log.h"
 #include "xmalloc.h"
+#include "log.h"
 
 /* compatibility with old or broken OpenSSL versions */
 #include "openbsd-compat/openssl-compat.h"
index 9a5f9849cf7f76e9ab7419e1561d17b374d46923..ddbf97c6b1486138f0da5d18d16ba6301fd622b8 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: cipher.c,v 1.81 2006/08/03 03:34:42 deraadt Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: cipher.c,v 1.77 2005/07/16 01:35:24 djm Exp $");
+
+#include <sys/types.h>
+
+#include <openssl/md5.h>
+
+#include <string.h>
+#include <stdarg.h>
 
 #include "xmalloc.h"
 #include "log.h"
 #include "cipher.h"
 
-#include <openssl/md5.h>
-
 /* compatibility with old or broken OpenSSL versions */
 #include "openbsd-compat/openssl-compat.h"
 
index 11d1d4d9aed29e1a9ff0d2428c217babe3105664..238f965e64461e9d6199f39c43d7349064f77b63 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: cleanup.c,v 1.5 2006/08/03 03:34:42 deraadt Exp $ */
 /*
  * Copyright (c) 2003 Markus Friedl <markus@openbsd.org>
  *
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
+
 #include "includes.h"
-RCSID("$OpenBSD: cleanup.c,v 1.1 2003/09/23 20:17:11 markus Exp $");
+
+#include <sys/types.h>
+
+#include <unistd.h>
+#include <stdarg.h>
 
 #include "log.h"
 
index 3089bcf9cf784689537a23a5248b6c9d2b37030e..4a614d9ee13d221fad4d367916ff3c8e76258610 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: clientloop.c,v 1.175 2006/08/03 03:34:42 deraadt Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: clientloop.c,v 1.149 2005/12/30 15:56:37 reyk Exp $");
 
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/param.h>
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+#include <sys/socket.h>
+
+#include <ctype.h>
+#include <errno.h>
+#ifdef HAVE_PATHS_H
+#include <paths.h>
+#endif
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <termios.h>
+#include <pwd.h>
+#include <unistd.h>
+
+#include "xmalloc.h"
 #include "ssh.h"
 #include "ssh1.h"
 #include "ssh2.h"
-#include "xmalloc.h"
 #include "packet.h"
 #include "buffer.h"
 #include "compat.h"
 #include "channels.h"
 #include "dispatch.h"
-#include "buffer.h"
-#include "bufaux.h"
 #include "key.h"
+#include "cipher.h"
 #include "kex.h"
 #include "log.h"
 #include "readconf.h"
@@ -118,7 +142,7 @@ static volatile sig_atomic_t received_signal = 0;
 static int in_non_blocking_mode = 0;
 
 /* Common data for the client loop code. */
-static int quit_pending;       /* Set to non-zero to quit the client loop. */
+static volatile sig_atomic_t quit_pending; /* Set non-zero to quit the loop. */
 static int escape_char;                /* Escape character. */
 static int escape_pending;     /* Last character was the escape character */
 static int last_was_cr;                /* Last character was a newline. */
@@ -178,7 +202,7 @@ enter_non_blocking(void)
  * Signal handler for the window change signal (SIGWINCH).  This just sets a
  * flag indicating that the window has changed.
  */
-
+/*ARGSUSED */
 static void
 window_change_handler(int sig)
 {
@@ -190,7 +214,7 @@ window_change_handler(int sig)
  * Signal handler for signals that cause the program to terminate.  These
  * signals must be trapped to restore terminal modes.
  */
-
+/*ARGSUSED */
 static void
 signal_handler(int sig)
 {
@@ -422,10 +446,10 @@ client_check_window_change(void)
                if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0)
                        return;
                packet_start(SSH_CMSG_WINDOW_SIZE);
-               packet_put_int(ws.ws_row);
-               packet_put_int(ws.ws_col);
-               packet_put_int(ws.ws_xpixel);
-               packet_put_int(ws.ws_ypixel);
+               packet_put_int((u_int)ws.ws_row);
+               packet_put_int((u_int)ws.ws_col);
+               packet_put_int((u_int)ws.ws_xpixel);
+               packet_put_int((u_int)ws.ws_ypixel);
                packet_send();
        }
 }
@@ -569,7 +593,7 @@ client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr)
 }
 
 static void
-client_process_net_input(fd_set * readset)
+client_process_net_input(fd_set *readset)
 {
        int len;
        char buf[8192];
@@ -677,7 +701,7 @@ client_extra_session2_setup(int id, void *arg)
 }
 
 static void
-client_process_control(fd_set * readset)
+client_process_control(fd_set *readset)
 {
        Buffer m;
        Channel *c;
@@ -844,8 +868,7 @@ client_process_control(fd_set * readset)
                return;
        }
 
-       cctx = xmalloc(sizeof(*cctx));
-       memset(cctx, 0, sizeof(*cctx));
+       cctx = xcalloc(1, sizeof(*cctx));
        cctx->want_tty = (flags & SSHMUX_FLAG_TTY) != 0;
        cctx->want_subsys = (flags & SSHMUX_FLAG_SUBSYS) != 0;
        cctx->want_x_fwd = (flags & SSHMUX_FLAG_X11_FWD) != 0;
@@ -860,7 +883,7 @@ client_process_control(fd_set * readset)
        env_len = MIN(env_len, 4096);
        debug3("%s: receiving %d env vars", __func__, env_len);
        if (env_len != 0) {
-               cctx->env = xmalloc(sizeof(*cctx->env) * (env_len + 1));
+               cctx->env = xcalloc(env_len + 1, sizeof(*cctx->env));
                for (i = 0; i < env_len; i++)
                        cctx->env[i] = buffer_get_string(&m, &len);
                cctx->env[i] = NULL;
@@ -868,6 +891,7 @@ client_process_control(fd_set * readset)
 
        debug2("%s: accepted tty %d, subsys %d, cmd %s", __func__,
            cctx->want_tty, cctx->want_subsys, cmd);
+       xfree(cmd);
 
        /* Gather fds from client */
        new_fd[0] = mm_receive_fd(client_fd);
@@ -953,12 +977,16 @@ process_cmdline(void)
 
        if (*s == 'h' || *s == 'H' || *s == '?') {
                logit("Commands:");
-               logit("      -Lport:host:hostport    Request local forward");
-               logit("      -Rport:host:hostport    Request remote forward");
-               logit("      -KRhostport             Cancel remote forward");
+               logit("      -L[bind_address:]port:host:hostport    "
+                   "Request local forward");
+               logit("      -R[bind_address:]port:host:hostport    "
+                   "Request remote forward");
+               logit("      -KR[bind_address:]port                 "
+                   "Cancel remote forward");
                if (!options.permit_local_command)
                        goto out;
-               logit("      !args                   Execute local command");
+               logit("      !args                                  "
+                   "Execute local command");
                goto out;
        }
 
@@ -1020,9 +1048,12 @@ process_cmdline(void)
                                goto out;
                        }
                } else {
-                       channel_request_remote_forwarding(fwd.listen_host,
+                       if (channel_request_remote_forwarding(fwd.listen_host,
                            fwd.listen_port, fwd.connect_host,
-                           fwd.connect_port);
+                           fwd.connect_port) < 0) {
+                               logit("Port forwarding failed.");
+                               goto out;
+                       }
                }
 
                logit("Forwarding port.");
@@ -1214,7 +1245,7 @@ Supported escape sequences:\r\n\
 }
 
 static void
-client_process_input(fd_set * readset)
+client_process_input(fd_set *readset)
 {
        int len;
        char buf[8192];
@@ -1267,7 +1298,7 @@ client_process_input(fd_set * readset)
 }
 
 static void
-client_process_output(fd_set * writeset)
+client_process_output(fd_set *writeset)
 {
        int len;
        char buf[100];
@@ -1928,10 +1959,10 @@ client_session2_setup(int id, int want_tty, int want_subsystem,
 
                channel_request_start(id, "pty-req", 0);
                packet_put_cstring(term != NULL ? term : "");
-               packet_put_int(ws.ws_col);
-               packet_put_int(ws.ws_row);
-               packet_put_int(ws.ws_xpixel);
-               packet_put_int(ws.ws_ypixel);
+               packet_put_int((u_int)ws.ws_col);
+               packet_put_int((u_int)ws.ws_row);
+               packet_put_int((u_int)ws.ws_xpixel);
+               packet_put_int((u_int)ws.ws_ypixel);
                tio = get_saved_tio();
                tty_make_modes(-1, tiop != NULL ? tiop : &tio);
                packet_send();
index 1845663376f3a1415047ad46bf954d6482f7da78..0be32b460d1d51d2f5a88440efc286cf5cf594af 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: clientloop.h,v 1.14 2005/07/04 00:58:43 djm Exp $     */
+/* $OpenBSD: clientloop.h,v 1.16 2006/03/25 22:22:42 djm Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -35,6 +35,8 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <termios.h>
+
 /* Client side main loop for the interactive session. */
 int     client_loop(int, int, int);
 void    client_x11_get_proto(const char *, const char *, u_int,
index a331014111343a8f004255657523df9e172ea14b..692f8bb411f9a749c65aa6f715eece2307ad7779 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: compat.c,v 1.76 2006/08/03 03:34:42 deraadt Exp $ */
 /*
  * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl.  All rights reserved.
  *
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: compat.c,v 1.71 2005/03/01 10:09:52 djm Exp $");
 
+#include <sys/types.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#include "xmalloc.h"
 #include "buffer.h"
 #include "packet.h"
-#include "xmalloc.h"
 #include "compat.h"
 #include "log.h"
 #include "match.h"
index 9c0f0625386471adada3f0c8795ff1bb71a5ead1..91232013b18381624410e445faa762332b541190 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: compat.h,v 1.39 2005/03/01 10:09:52 djm Exp $ */
+/* $OpenBSD: compat.h,v 1.40 2006/03/25 22:22:43 djm Exp $ */
 
 /*
  * Copyright (c) 1999, 2000, 2001 Markus Friedl.  All rights reserved.
index 3c9da33491d9d6f8bd5128f96c1e8226fc784eeb..06f34a8d14636b2db0c757455c9b93a83fce8db6 100644 (file)
@@ -127,15 +127,45 @@ AC_ARG_WITH(rpath,
        ]
 )
 
+# Messages for features tested for in target-specific section
+SIA_MSG="no"
+SPC_MSG="no"
+
 # Check for some target-specific stuff
 case "$host" in
 *-*-aix*)
+       # Some versions of VAC won't allow macro redefinitions at
+       # -qlanglevel=ansi, and autoconf 2.60 sometimes insists on using that
+       # particularly with older versions of vac or xlc.
+       # It also throws errors about null macro argments, but these are
+       # not fatal.
+       AC_MSG_CHECKING(if compiler allows macro redefinitions)
+       AC_COMPILE_IFELSE(
+           [AC_LANG_SOURCE([[
+#define testmacro foo
+#define testmacro bar
+int main(void) { exit(0); }
+           ]])],
+           [ AC_MSG_RESULT(yes) ],
+           [ AC_MSG_RESULT(no)
+             CC="`echo $CC | sed 's/-qlanglvl\=ansi//g'`"
+             LD="`echo $LD | sed 's/-qlanglvl\=ansi//g'`"
+             CFLAGS="`echo $CFLAGS | sed 's/-qlanglvl\=ansi//g'`"
+             CPPFLAGS="`echo $CPPFLAGS | sed 's/-qlanglvl\=ansi//g'`"
+           ]
+       )
+
        AC_MSG_CHECKING([how to specify blibpath for linker ($LD)])
        if (test -z "$blibpath"); then
                blibpath="/usr/lib:/lib"
        fi
        saved_LDFLAGS="$LDFLAGS"
-       for tryflags in -blibpath: -Wl,-blibpath: -Wl,-rpath, ;do
+       if test "$GCC" = "yes"; then
+               flags="-Wl,-blibpath: -Wl,-rpath, -blibpath:"
+       else
+               flags="-blibpath: -Wl,-blibpath: -Wl,-rpath,"
+       fi
+       for tryflags in $flags ;do
                if (test -z "$blibflags"); then
                        LDFLAGS="$saved_LDFLAGS $tryflags$blibpath"
                        AC_TRY_LINK([], [], [blibflags=$tryflags])
@@ -175,6 +205,12 @@ case "$host" in
                [#include <usersec.h>]
        )
        AC_CHECK_FUNCS(setauthdb)
+       AC_CHECK_DECL(F_CLOSEM,
+           AC_DEFINE(HAVE_FCNTL_CLOSEM, 1, [Use F_CLOSEM fcntl for closefrom]),
+           [],
+           [ #include <limits.h>
+             #include <fcntl.h> ]
+       )
        check_for_aix_broken_getaddrinfo=1
        AC_DEFINE(BROKEN_REALPATH, 1, [Define if you have a broken realpath.])
        AC_DEFINE(SETEUID_BREAKS_SETUID, 1,
@@ -190,6 +226,7 @@ case "$host" in
                supported by bsd-setproctitle.c])
        AC_DEFINE(SSHPAM_CHAUTHTOK_NEEDS_RUID, 1,
            [AIX 5.2 and 5.3 (and presumably newer) require this])
+       AC_DEFINE(PTY_ZEROREAD, 1, [read(1) can return 0 for a non-closed fd])
        ;;
 *-*-cygwin*)
        check_for_libcrypt_later=1
@@ -246,6 +283,14 @@ case "$host" in
                fi],
                [AC_MSG_RESULT(no)]
        )
+       AC_DEFINE(SSH_TUN_FREEBSD, 1, [Open tunnel devices the FreeBSD way])
+       AC_DEFINE(SSH_TUN_COMPAT_AF, 1,
+           [Use tunnel device compatibility to OpenBSD])
+       AC_DEFINE(SSH_TUN_PREPEND_AF, 1,
+           [Prepend the address family to IP tunnel traffic])
+       ;;
+*-*-dragonfly*)
+       SSHDLIBS="$SSHDLIBS -lcrypt"
        ;;
 *-*-hpux*)
        # first we define all of the options common to all HP-UX releases
@@ -400,6 +445,8 @@ mips-sony-bsd|mips-sony-newsos4)
        AC_DEFINE(HAVE_ATTRIBUTE__SENTINEL__, 1, [OpenBSD's gcc has sentinel])
        AC_DEFINE(HAVE_ATTRIBUTE__BOUNDED__, 1, [OpenBSD's gcc has bounded])
        AC_DEFINE(SSH_TUN_OPENBSD, 1, [Open tunnel devices the OpenBSD way])
+       AC_DEFINE(SYSLOG_R_SAFE_IN_SIGHAND, 1,
+           [syslog_r function is safe to use in in a signal handler])
        ;;
 *-*-solaris*)
        if test "x$withval" != "xno" ; then
@@ -419,6 +466,8 @@ mips-sony-bsd|mips-sony-newsos4)
        AC_DEFINE(SSHD_ACQUIRES_CTTY, 1,
                [Define if sshd somehow reacquires a controlling TTY
                after setsid()])
+       AC_DEFINE(PASSWD_NEEDS_USERNAME, 1, [must supply username to passwd
+               in case the name is longer than 8 chars])
        external_path_file=/etc/default/login
        # hardwire lastlog location (can't detect it on some versions)
        conf_lastlog_location="/var/adm/lastlog"
@@ -432,6 +481,17 @@ mips-sony-bsd|mips-sony-newsos4)
        else
                AC_MSG_RESULT(no)
        fi
+       AC_ARG_WITH(solaris-contracts,
+               [  --with-solaris-contracts Enable Solaris process contracts (experimental)],
+               [
+               AC_CHECK_LIB(contract, ct_tmpl_activate,
+                       [ AC_DEFINE(USE_SOLARIS_PROCESS_CONTRACTS, 1,
+                               [Define if you have Solaris process contracts])
+                         SSHDLIBS="$SSHDLIBS -lcontract"
+                         AC_SUBST(SSHDLIBS)
+                         SPC_MSG="yes" ], )
+               ],
+       )
        ;;
 *-*-sunos4*)
        CPPFLAGS="$CPPFLAGS -DSUNOS4"
@@ -469,7 +529,6 @@ 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)
@@ -491,6 +550,7 @@ mips-sony-bsd|mips-sony-newsos4)
                TEST_SHELL=/u95/bin/sh
                AC_DEFINE(BROKEN_LIBIAF, 1,
                        [ia_uinfo routines not supported by OS yet])
+               AC_DEFINE(BROKEN_UPDWTMPX)
                ;;
        *)      AC_DEFINE(LOCKED_PASSWD_STRING, "*LK*")
                ;;
@@ -580,6 +640,7 @@ mips-sony-bsd|mips-sony-newsos4)
                                system's login() call])
                        AC_DEFINE(DISABLE_FD_PASSING)
                        LIBS="$LIBS -lsecurity -ldb -lm -laud"
+                       SIA_MSG="yes"
                else
                        AC_MSG_RESULT(no)
                        AC_DEFINE(LOCKED_PASSWD_SUBSTR, "Nologin",
@@ -599,6 +660,8 @@ mips-sony-bsd|mips-sony-newsos4)
        AC_DEFINE(MISSING_HOWMANY, 1, [Define on *nto-qnx systems])
        AC_DEFINE(MISSING_FD_MASK, 1, [Define on *nto-qnx systems])
        AC_DEFINE(DISABLE_LASTLOG)
+       AC_DEFINE(SSHD_ACQUIRES_CTTY)
+       enable_etc_default_login=no     # has incompatible /etc/default/login
        ;;
 
 *-*-ultrix*)
@@ -682,9 +745,11 @@ dnl Checks for header files.
 AC_CHECK_HEADERS( \
        bstring.h \
        crypt.h \
+       crypto/sha2.h \
        dirent.h \
        endian.h \
        features.h \
+       fcntl.h \
        floatingpoint.h \
        getopt.h \
        glob.h \
@@ -692,9 +757,9 @@ AC_CHECK_HEADERS( \
        iaf.h \
        limits.h \
        login.h \
-       login_cap.h \
        maillock.h \
        ndir.h \
+       net/if_tun.h \
        netdb.h \
        netgroup.h \
        pam/pam_appl.h \
@@ -703,6 +768,7 @@ AC_CHECK_HEADERS( \
        readpassphrase.h \
        rpc/types.h \
        security/pam_appl.h \
+       sha2.h \
        shadow.h \
        stddef.h \
        stdint.h \
@@ -752,6 +818,11 @@ AC_CHECK_HEADERS(sys/ptms.h, [], [], [
 #endif
 ])
 
+# login_cap.h requires sys/types.h on NetBSD
+AC_CHECK_HEADERS(login_cap.h, [], [], [
+#include <sys/types.h>
+])
+
 # Checks for libraries.
 AC_CHECK_FUNC(yp_match, , AC_CHECK_LIB(nsl, yp_match))
 AC_CHECK_FUNC(setsockopt, , AC_CHECK_LIB(socket, setsockopt))
@@ -936,11 +1007,9 @@ AC_EGREP_CPP(FOUNDIT,
 
 # Check for g.gl_matchc glob() extension
 AC_MSG_CHECKING(for gl_matchc field in glob_t)
-AC_EGREP_CPP(FOUNDIT,
-       [
-               #include <glob.h>
-               int main(void){glob_t g; g.gl_matchc = 1;}
-       ],
+AC_TRY_COMPILE(
+       [ #include <glob.h> ],
+       [glob_t g; g.gl_matchc = 1;],
        [
                AC_DEFINE(GLOB_HAS_GL_MATCHC, 1,
                        [Define if your system glob() function has
@@ -952,6 +1021,8 @@ AC_EGREP_CPP(FOUNDIT,
        ]
 )
 
+AC_CHECK_DECLS(GLOB_NOMATCH, , , [#include <glob.h>])
+
 AC_MSG_CHECKING([whether struct dirent allocates space for d_name])
 AC_RUN_IFELSE(
        [AC_LANG_SOURCE([[
@@ -1280,7 +1351,13 @@ AC_ARG_WITH(audit,
                AUDIT_MODULE=bsm
                dnl    Checks for headers, libs and functions
                AC_CHECK_HEADERS(bsm/audit.h, [],
-                   [AC_MSG_ERROR(BSM enabled and bsm/audit.h not found)])
+                   [AC_MSG_ERROR(BSM enabled and bsm/audit.h not found)],
+                   [
+#ifdef HAVE_TIME_H
+# include <time.h>
+#endif
+                   ]
+)
                AC_CHECK_LIB(bsm, getaudit, [],
                    [AC_MSG_ERROR(BSM enabled and required library not found)])
                AC_CHECK_FUNCS(getaudit, [],
@@ -1426,6 +1503,29 @@ AC_CHECK_DECL(tcsendbreak,
 
 AC_CHECK_DECLS(h_errno, , ,[#include <netdb.h>])
 
+AC_CHECK_DECLS(SHUT_RD, , ,
+       [
+#include <sys/types.h>
+#include <sys/socket.h>
+       ])
+
+AC_CHECK_DECLS(O_NONBLOCK, , ,
+       [
+#include <sys/types.h>
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+       ])
+
+AC_CHECK_DECLS(writev, , , [
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <unistd.h>
+       ])
+
 AC_CHECK_FUNCS(setresuid, [
        dnl Some platorms have setresuid that isn't implemented, test for this
        AC_MSG_CHECKING(if setresuid seems to work)
@@ -1770,6 +1870,7 @@ main(void)
                        AC_MSG_RESULT(no)
                        AC_DEFINE(BROKEN_GETADDRINFO)
                ],
+               [
                        AC_MSG_RESULT(cross-compiling, assuming no)
                ]
        )
@@ -1795,61 +1896,6 @@ fi
 
 AC_FUNC_GETPGRP
 
-# Check for PAM libs
-PAM_MSG="no"
-AC_ARG_WITH(pam,
-       [  --with-pam              Enable PAM support ],
-       [
-               if test "x$withval" != "xno" ; then
-                       if test "x$ac_cv_header_security_pam_appl_h" != "xyes" && \
-                          test "x$ac_cv_header_pam_pam_appl_h" != "xyes" ; then
-                               AC_MSG_ERROR([PAM headers not found])
-                       fi
-
-                       AC_CHECK_LIB(dl, dlopen, , )
-                       AC_CHECK_LIB(pam, pam_set_item, , AC_MSG_ERROR([*** libpam missing]))
-                       AC_CHECK_FUNCS(pam_getenvlist)
-                       AC_CHECK_FUNCS(pam_putenv)
-
-                       PAM_MSG="yes"
-
-                       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
-                               LIBPAM="-lpam"
-                       fi
-                       AC_SUBST(LIBPAM)
-               fi
-       ]
-)
-
-# Check for older PAM
-if test "x$PAM_MSG" = "xyes" ; then
-       # Check PAM strerror arguments (old PAM)
-       AC_MSG_CHECKING([whether pam_strerror takes only one argument])
-       AC_TRY_COMPILE(
-               [
-#include <stdlib.h>
-#if defined(HAVE_SECURITY_PAM_APPL_H)
-#include <security/pam_appl.h>
-#elif defined (HAVE_PAM_PAM_APPL_H)
-#include <pam/pam_appl.h>
-#endif
-               ],
-               [(void)pam_strerror((pam_handle_t *)NULL, -1);],
-               [AC_MSG_RESULT(no)],
-               [
-                       AC_DEFINE(HAVE_OLD_PAM, 1,
-                               [Define if you have an old version of PAM
-                               which takes only one argument to pam_strerror])
-                       AC_MSG_RESULT(yes)
-                       PAM_MSG="yes (old library)"
-               ]
-       )
-fi
-
 # Search for OpenSSL
 saved_CPPFLAGS="$CPPFLAGS"
 saved_LDFLAGS="$LDFLAGS"
@@ -1997,9 +2043,57 @@ Also see contrib/findssl.sh for help identifying header/library mismatches.])
        ]
 )
 
+AC_MSG_CHECKING([if programs using OpenSSL functions will link])
+AC_LINK_IFELSE(
+       [AC_LANG_SOURCE([[
+#include <openssl/evp.h>
+int main(void) { SSLeay_add_all_algorithms(); }
+       ]])],
+       [
+               AC_MSG_RESULT(yes)
+       ],
+       [
+               AC_MSG_RESULT(no)
+               saved_LIBS="$LIBS"
+               LIBS="$LIBS -ldl"
+               AC_MSG_CHECKING([if programs using OpenSSL need -ldl])
+               AC_LINK_IFELSE(
+                       [AC_LANG_SOURCE([[
+#include <openssl/evp.h>
+int main(void) { SSLeay_add_all_algorithms(); }
+                       ]])],
+                       [
+                               AC_MSG_RESULT(yes)
+                       ],
+                       [
+                               AC_MSG_RESULT(no)
+                               LIBS="$saved_LIBS"
+                       ]
+               )
+       ]
+)
+
+AC_ARG_WITH(ssl-engine,
+       [  --with-ssl-engine       Enable OpenSSL (hardware) ENGINE support ],
+       [ if test "x$withval" != "xno" ; then
+               AC_MSG_CHECKING(for OpenSSL ENGINE support)
+               AC_TRY_COMPILE(
+                       [ #include <openssl/engine.h>],
+                       [
+int main(void){ENGINE_load_builtin_engines();ENGINE_register_all_complete();}
+                       ],
+                       [ AC_MSG_RESULT(yes)
+                         AC_DEFINE(USE_OPENSSL_ENGINE, 1,
+                            [Enable OpenSSL engine support])
+                       ],
+                       [ AC_MSG_ERROR(OpenSSL ENGINE support not found)]
+               )
+         fi ]
+)
+
 # Check for OpenSSL without EVP_aes_{192,256}_cbc
 AC_MSG_CHECKING([whether OpenSSL has crippled AES support])
-AC_COMPILE_IFELSE(
+AC_LINK_IFELSE(
        [AC_LANG_SOURCE([[
 #include <string.h>
 #include <openssl/evp.h>
@@ -2027,6 +2121,9 @@ if test "x$check_for_libcrypt_later" = "x1"; then
        AC_CHECK_LIB(crypt, crypt, LIBS="$LIBS -lcrypt")
 fi
 
+# Search for SHA256 support in libc and/or OpenSSL
+AC_CHECK_FUNCS(SHA256_Update EVP_sha256)
+
 AC_CHECK_LIB(iaf, ia_openinfo)
 
 ### Configure cryptographic random number support
@@ -2057,6 +2154,69 @@ int main(void) { exit(RAND_status() == 1 ? 0 : 1); }
        ]
 )
 
+# Check for PAM libs
+PAM_MSG="no"
+AC_ARG_WITH(pam,
+       [  --with-pam              Enable PAM support ],
+       [
+               if test "x$withval" != "xno" ; then
+                       if test "x$ac_cv_header_security_pam_appl_h" != "xyes" && \
+                          test "x$ac_cv_header_pam_pam_appl_h" != "xyes" ; then
+                               AC_MSG_ERROR([PAM headers not found])
+                       fi
+
+                       saved_LIBS="$LIBS"
+                       AC_CHECK_LIB(dl, dlopen, , )
+                       AC_CHECK_LIB(pam, pam_set_item, , AC_MSG_ERROR([*** libpam missing]))
+                       AC_CHECK_FUNCS(pam_getenvlist)
+                       AC_CHECK_FUNCS(pam_putenv)
+                       LIBS="$saved_LIBS"
+
+                       PAM_MSG="yes"
+
+                       LIBPAM="-lpam"
+                       AC_DEFINE(USE_PAM, 1,
+                               [Define if you want to enable PAM support])
+
+                       if test $ac_cv_lib_dl_dlopen = yes; then
+                               case "$LIBS" in
+                               *-ldl*)
+                                       # libdl already in LIBS
+                                       ;;
+                               *)
+                                       LIBPAM="$LIBPAM -ldl"
+                                       ;;
+                               esac
+                       fi
+                       AC_SUBST(LIBPAM)
+               fi
+       ]
+)
+
+# Check for older PAM
+if test "x$PAM_MSG" = "xyes" ; then
+       # Check PAM strerror arguments (old PAM)
+       AC_MSG_CHECKING([whether pam_strerror takes only one argument])
+       AC_TRY_COMPILE(
+               [
+#include <stdlib.h>
+#if defined(HAVE_SECURITY_PAM_APPL_H)
+#include <security/pam_appl.h>
+#elif defined (HAVE_PAM_PAM_APPL_H)
+#include <pam/pam_appl.h>
+#endif
+               ],
+               [(void)pam_strerror((pam_handle_t *)NULL, -1);],
+               [AC_MSG_RESULT(no)],
+               [
+                       AC_DEFINE(HAVE_OLD_PAM, 1,
+                               [Define if you have an old version of PAM
+                               which takes only one argument to pam_strerror])
+                       AC_MSG_RESULT(yes)
+                       PAM_MSG="yes (old library)"
+               ]
+       )
+fi
 
 # Do we want to force the use of the rand helper?
 AC_ARG_WITH(rand-helper,
@@ -2276,6 +2436,34 @@ if test -z "$have_llong_max"; then
 #define __USE_ISOC99
 #include <limits.h>
 #define DATA "conftest.llminmax"
+#define my_abs(a) ((a) < 0 ? ((a) * -1) : (a))
+
+/*
+ * printf in libc on some platforms (eg old Tru64) does not understand %lld so
+ * we do this the hard way.
+ */
+static int
+fprint_ll(FILE *f, long long n)
+{
+       unsigned int i;
+       int l[sizeof(long long) * 8];
+
+       if (n < 0)
+               if (fprintf(f, "-") < 0)
+                       return -1;
+       for (i = 0; n != 0; i++) {
+               l[i] = my_abs(n % 10);
+               n /= 10;
+       }
+       do {
+               if (fprintf(f, "%d", l[--i]) < 0)
+                       return -1;
+       } while (i != 0);
+       if (fprintf(f, " ") < 0)
+               return -1;
+       return 0;
+}
+
 int main(void) {
        FILE *f;
        long long i, llmin, llmax = 0;
@@ -2297,14 +2485,18 @@ int main(void) {
 
        /* Sanity check */
        if (llmin + 1 < llmin || llmin - 1 < llmin || llmax + 1 > llmax
-           || llmax - 1 > llmax) {
+           || llmax - 1 > llmax || llmin == llmax || llmin == 0
+           || llmax == 0 || llmax < LONG_MAX || llmin > LONG_MIN) {
                fprintf(f, "unknown unknown\n");
                exit(2);
        }
 
-       if (fprintf(f ,"%lld %lld", llmin, llmax) < 0)
+       if (fprint_ll(f, llmin) < 0)
                exit(3);
-
+       if (fprint_ll(f, llmax) < 0)
+               exit(4);
+       if (fclose(f) < 0)
+               exit(5);
        exit(0);
 }
                ]])],
@@ -2312,17 +2504,6 @@ int main(void) {
                        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])
@@ -3068,7 +3249,7 @@ AC_ARG_WITH(opensc,
                        LIBOPENSC_CFLAGS=`$OPENSC_CONFIG --cflags`
                        LIBOPENSC_LIBS=`$OPENSC_CONFIG --libs`
                        CPPFLAGS="$CPPFLAGS $LIBOPENSC_CFLAGS"
-                       LDFLAGS="$LDFLAGS $LIBOPENSC_LIBS"
+                       LIBS="$LIBS $LIBOPENSC_LIBS"
                        AC_DEFINE(SMARTCARD)
                        AC_DEFINE(USE_OPENSC, 1,
                                [Define if you want smartcard support
@@ -3116,6 +3297,23 @@ int main()
                        [#include <arpa/nameser.h>])
        ])
 
+# Check whether user wants SELinux support
+SELINUX_MSG="no"
+LIBSELINUX=""
+AC_ARG_WITH(selinux,
+       [  --with-selinux   Enable SELinux support],
+       [ if test "x$withval" != "xno" ; then
+               AC_DEFINE(WITH_SELINUX,1,[Define if you want SELinux support.])
+               SELINUX_MSG="yes"
+               AC_CHECK_HEADER([selinux/selinux.h], ,
+                   AC_MSG_ERROR(SELinux support requires selinux.h header))
+               AC_CHECK_LIB(selinux, setexeccon, [ LIBSELINUX="-lselinux" ],
+                   AC_MSG_ERROR(SELinux support requires libselinux library))
+               AC_CHECK_FUNCS(getseuserbyname get_default_context_with_level)
+       fi ]
+)
+AC_SUBST(LIBSELINUX)
+
 # Check whether user wants Kerberos 5 support
 KRB5_MSG="no"
 AC_ARG_WITH(kerberos5,
@@ -3928,20 +4126,13 @@ if test ! -z "$blibpath" ; then
        AC_MSG_WARN([Please check and edit blibpath in LDFLAGS in Makefile])
 fi
 
-dnl remove pam and dl because they are in $LIBPAM
-if test "$PAM_MSG" = yes ; then
-       LIBS=`echo $LIBS | sed 's/-lpam //'`
-fi
-if test "$ac_cv_lib_pam_pam_set_item" = yes ; then
-       LIBS=`echo $LIBS | sed 's/-ldl //'`
-fi
-
 dnl Adding -Werror to CFLAGS early prevents configure tests from running.
 dnl Add now.
 CFLAGS="$CFLAGS $werror_flags"
 
 AC_EXEEXT
-AC_CONFIG_FILES([Makefile buildpkg.sh opensshd.init openbsd-compat/Makefile \
+AC_CONFIG_FILES([Makefile buildpkg.sh opensshd.init openssh.xml \
+       openbsd-compat/Makefile openbsd-compat/regress/Makefile \
        scard/Makefile ssh_prng_cmds survey.sh])
 AC_OUTPUT
 
@@ -3983,12 +4174,15 @@ echo "          sshd superuser user PATH: $J"
 fi
 echo "                    Manpage format: $MANTYPE"
 echo "                       PAM support: $PAM_MSG"
+echo "                   OSF SIA support: $SIA_MSG"
 echo "                 KerberosV support: $KRB5_MSG"
+echo "                   SELinux support: $SELINUX_MSG"
 echo "                 Smartcard support: $SCARD_MSG"
 echo "                     S/KEY support: $SKEY_MSG"
 echo "              TCP Wrappers support: $TCPW_MSG"
 echo "              MD5 password support: $MD5_MSG"
 echo "                   libedit support: $LIBEDIT_MSG"
+echo "  Solaris process contract support: $SPC_MSG"
 echo "       IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG"
 echo "           Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG"
 echo "                  BSD Auth support: $BSD_AUTH_MSG"
index 5410fea0c86885268455d3965a25f8f67f551bbb..6b283a1ff72d6a486581a61b4bd6fd7ce3a4f465 100755 (executable)
@@ -23,6 +23,8 @@ umask 022
 
 startdir=`pwd`
 
+perl -v >/dev/null || (echo perl required; exit 1)
+
 # Path to inventory.sh: same place as buildbff.sh
 if  echo $0 | egrep '^/'
 then
@@ -200,33 +202,29 @@ do
 done
 echo
 
-# Create PrivSep user if PrivSep not disabled in config
-echo Creating PrivSep prereqs if required.
-if egrep '^[ \t]*UsePrivilegeSeparation[ \t]+no' $sysconfdir/sshd_config >/dev/null
+# Create PrivilegeSeparation user and group if not present
+echo Checking for PrivilegeSeparation user and group.
+if cut -f1 -d: /etc/group | egrep '^'$SSH_PRIVSEP_USER'\$' >/dev/null
 then
-       echo "UsePrivilegeSeparation disabled in config, not creating PrivSep user,"
-       echo "group or chroot directory."
+       echo "PrivSep group $SSH_PRIVSEP_USER already exists."
 else
-       echo "UsePrivilegeSeparation enabled in config (or defaulting to on)."
-
-       # create group if required
-       if cut -f1 -d: /etc/group | egrep '^'$SSH_PRIVSEP_USER'\$' >/dev/null
-       then
-               echo "PrivSep group $SSH_PRIVSEP_USER already exists."
-       else
-               echo "Creating PrivSep group $SSH_PRIVSEP_USER."
-               mkgroup -A $SSH_PRIVSEP_USER
-       fi
+       echo "Creating PrivSep group $SSH_PRIVSEP_USER."
+       mkgroup -A $SSH_PRIVSEP_USER
+fi
 
-       # Create user if required
-       if lsuser "$SSH_PRIVSEP_USER" >/dev/null
-       then
-               echo "PrivSep user $SSH_PRIVSEP_USER already exists."
-       else
-               echo "Creating PrivSep user $SSH_PRIVSEP_USER."
-               mkuser gecos='SSHD PrivSep User' login=false rlogin=false account_locked=true pgrp=$SSH_PRIVSEP_USER $SSH_PRIVSEP_USER
-       fi
+# Create user if required
+if lsuser "$SSH_PRIVSEP_USER" >/dev/null
+then
+       echo "PrivSep user $SSH_PRIVSEP_USER already exists."
+else
+       echo "Creating PrivSep user $SSH_PRIVSEP_USER."
+       mkuser gecos='SSHD PrivSep User' login=false rlogin=false account_locked=true pgrp=$SSH_PRIVSEP_USER $SSH_PRIVSEP_USER
+fi
 
+if egrep '^[ \t]*UsePrivilegeSeparation[ \t]+no' $sysconfdir/sshd_config >/dev/null
+then
+       echo UsePrivilegeSeparation not enabled, privsep directory not required.
+else
        # create chroot directory if required
        if [ -d $PRIVSEP_PATH ]
        then
index 3a24eaa08816ef9cf73746ad31bafbc3decfbd4a..143ede9f36b9814aea3bc6896a48020a005752b1 100644 (file)
@@ -30,7 +30,7 @@
 
 /* Constants */
 
-#ifndef SHUT_RDWR
+#if defined(HAVE_DECL_SHUT_RD) && HAVE_DECL_SHUT_RD == 0
 enum
 {
   SHUT_RD = 0,         /* No more receptions.  */
@@ -90,8 +90,8 @@ enum
 #endif
 #endif
 
-#ifndef O_NONBLOCK     /* Non Blocking Open */
-# define O_NONBLOCK      00004
+#if defined(HAVE_DECL_O_NONBLOCK) && HAVE_DECL_O_NONBLOCK == 0
+# define O_NONBLOCK      00004 /* Non Blocking Open */
 #endif
 
 #ifndef S_ISDIR
@@ -143,16 +143,11 @@ including rpc/rpc.h breaks Solaris 6
 #define INADDR_LOOPBACK ((u_long)0x7f000001)
 #endif
 
-#ifndef __unused
-#define __unused
-#endif
-
 /* Types */
 
 /* If sys/types.h does not supply intXX_t, supply them ourselves */
 /* (or die trying) */
 
-
 #ifndef HAVE_U_INT
 typedef unsigned int u_int;
 #endif
@@ -496,6 +491,22 @@ struct winsize {
 # define offsetof(type, member) ((size_t) &((type *)0)->member)
 #endif
 
+/* Set up BSD-style BYTE_ORDER definition if it isn't there already */
+/* XXX: doesn't try to cope with strange byte orders (PDP_ENDIAN) */
+#ifndef BYTE_ORDER
+# ifndef LITTLE_ENDIAN
+#  define LITTLE_ENDIAN  1234
+# endif /* LITTLE_ENDIAN */
+# ifndef BIG_ENDIAN
+#  define BIG_ENDIAN     4321
+# endif /* BIG_ENDIAN */
+# ifdef WORDS_BIGENDIAN
+#  define BYTE_ORDER BIG_ENDIAN
+# else /* WORDS_BIGENDIAN */
+#  define BYTE_ORDER LITTLE_ENDIAN
+# endif /* WORDS_BIGENDIAN */
+#endif /* BYTE_ORDER */
+
 /* Function replacement / compatibility hacks */
 
 #if !defined(HAVE_GETADDRINFO) && (defined(HAVE_OGETADDRINFO) || defined(HAVE_NGETADDRINFO))
@@ -517,19 +528,6 @@ struct winsize {
 # define optarg             BSDoptarg
 #endif
 
-/* In older versions of libpam, pam_strerror takes a single argument */
-#ifdef HAVE_OLD_PAM
-# define PAM_STRERROR(a,b) pam_strerror((b))
-#else
-# define PAM_STRERROR(a,b) pam_strerror((a),(b))
-#endif
-
-#ifdef PAM_SUN_CODEBASE
-# define PAM_MSG_MEMBER(msg, n, member) ((*(msg))[(n)].member)
-#else
-# define PAM_MSG_MEMBER(msg, n, member) ((msg)[(n)]->member)
-#endif
-
 #if defined(BROKEN_GETADDRINFO) && defined(HAVE_GETADDRINFO)
 # undef HAVE_GETADDRINFO
 #endif
@@ -544,6 +542,11 @@ struct winsize {
 # undef HAVE_UPDWTMPX
 #endif
 
+#if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) && \
+    defined(SYSLOG_R_SAFE_IN_SIGHAND)
+# define DO_LOG_SAFE_IN_SIGHAND
+#endif
+
 #if !defined(HAVE_MEMMOVE) && defined(HAVE_BCOPY)
 # define memmove(s1, s2, n) bcopy((s2), (s1), (n))
 #endif /* !defined(HAVE_MEMMOVE) && defined(HAVE_BCOPY) */
@@ -553,6 +556,7 @@ struct winsize {
 #endif /* defined(HAVE_VHANGUP) && !defined(HAVE_DEV_PTMX) */
 
 #ifndef GETPGRP_VOID
+# include <unistd.h>
 # define getpgrp() getpgrp(0)
 #endif
 
@@ -715,12 +719,14 @@ struct winsize {
 # undef HAVE_MMAP
 #endif
 
-/* some system headers on HP-UX define YES/NO */
-#ifdef YES
-# undef YES
-#endif
-#ifdef NO
-# undef NO
+#ifndef IOV_MAX
+# if defined(_XOPEN_IOV_MAX)
+#  define      IOV_MAX         _XOPEN_IOV_MAX
+# elif defined(DEF_IOV_MAX)
+#  define      IOV_MAX         DEF_IOV_MAX
+# else
+#  define      IOV_MAX         16
+# endif
 #endif
 
 #endif /* _DEFINES_H */
index a71dd9bff1209ae5df6861a534df9b10fb1798b6..92623de72863877b949cd51b436c3250d3b4e958 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dns.c,v 1.16 2005/10/17 14:13:35 stevesk Exp $        */
+/* $OpenBSD: dns.c,v 1.23 2006/08/03 03:34:42 deraadt Exp $ */
 
 /*
  * Copyright (c) 2003 Wesley Griffin. All rights reserved.
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: dns.c,v 1.16 2005/10/17 14:13:35 stevesk Exp $");
+
+#include <sys/types.h>
+#include <sys/socket.h>
 
 #include <netdb.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
 
 #include "xmalloc.h"
 #include "key.h"
@@ -122,7 +127,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 = xstrdup("");
+                       *digest = (u_char *)xstrdup("");
                }
 
                success = 1;
index 0aa1c28f2845724d023bc7bf6dcd2bbaaa755d5c..b2633a1fe984fe950710a3f3d897a2ad6e8cdb83 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dns.h,v 1.6 2005/10/17 14:13:35 stevesk Exp $ */
+/* $OpenBSD: dns.h,v 1.10 2006/08/03 03:34:42 deraadt Exp $ */
 
 /*
  * Copyright (c) 2003 Wesley Griffin. All rights reserved.
@@ -25,8 +25,6 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "includes.h"
-
 #ifndef DNS_H
 #define DNS_H
 
index ae1aaac6edd0c6b491f6f8bd708fc99c776c08b1..5e5aa3fe18dfd229c6427d02c638584cfbf2514f 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: fatal.c,v 1.7 2006/08/03 03:34:42 deraadt Exp $ */
 /*
  * Copyright (c) 2002 Markus Friedl.  All rights reserved.
  *
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: fatal.c,v 1.2 2003/09/23 20:17:11 markus Exp $");
+
+#include <sys/types.h>
+
+#include <stdarg.h>
 
 #include "log.h"
 
@@ -33,6 +37,7 @@ void
 fatal(const char *fmt,...)
 {
        va_list args;
+
        va_start(args, fmt);
        do_log(SYSLOG_LEVEL_FATAL, fmt, args);
        va_end(args);
diff --git a/openssh/getput.h b/openssh/getput.h
deleted file mode 100644 (file)
index 1a19d22..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Author: Tatu Ylonen <ylo@cs.hut.fi>
- * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
- *                    All rights reserved
- * Macros for storing and retrieving data in msb first and lsb first order.
- *
- * As far as I am concerned, the code I have written for this software
- * can be used freely for any purpose.  Any derived versions of this
- * software must be clearly marked as such, and if the derived work is
- * incompatible with the protocol description in the RFC file, it must be
- * called by a name other than "ssh" or "Secure Shell".
- */
-
-/* RCSID("$OpenBSD: getput.h,v 1.7 2001/01/10 22:56:22 markus Exp $"); */
-
-#ifndef GETPUT_H
-#define GETPUT_H
-
-/*------------ macros for storing/extracting msb first words -------------*/
-
-#define GET_64BIT(cp) (((u_int64_t)(u_char)(cp)[0] << 56) | \
-                      ((u_int64_t)(u_char)(cp)[1] << 48) | \
-                      ((u_int64_t)(u_char)(cp)[2] << 40) | \
-                      ((u_int64_t)(u_char)(cp)[3] << 32) | \
-                      ((u_int64_t)(u_char)(cp)[4] << 24) | \
-                      ((u_int64_t)(u_char)(cp)[5] << 16) | \
-                      ((u_int64_t)(u_char)(cp)[6] << 8) | \
-                      ((u_int64_t)(u_char)(cp)[7]))
-
-#define GET_32BIT(cp) (((u_long)(u_char)(cp)[0] << 24) | \
-                      ((u_long)(u_char)(cp)[1] << 16) | \
-                      ((u_long)(u_char)(cp)[2] << 8) | \
-                      ((u_long)(u_char)(cp)[3]))
-
-#define GET_16BIT(cp) (((u_long)(u_char)(cp)[0] << 8) | \
-                      ((u_long)(u_char)(cp)[1]))
-
-#define PUT_64BIT(cp, value) do { \
-  (cp)[0] = (value) >> 56; \
-  (cp)[1] = (value) >> 48; \
-  (cp)[2] = (value) >> 40; \
-  (cp)[3] = (value) >> 32; \
-  (cp)[4] = (value) >> 24; \
-  (cp)[5] = (value) >> 16; \
-  (cp)[6] = (value) >> 8; \
-  (cp)[7] = (value); } while (0)
-
-#define PUT_32BIT(cp, value) do { \
-  (cp)[0] = (value) >> 24; \
-  (cp)[1] = (value) >> 16; \
-  (cp)[2] = (value) >> 8; \
-  (cp)[3] = (value); } while (0)
-
-#define PUT_16BIT(cp, value) do { \
-  (cp)[0] = (value) >> 8; \
-  (cp)[1] = (value); } while (0)
-
-#endif                         /* GETPUT_H */
index 9bc2a84a3bde3df18c573bf2b688f9e53caa5744..96c5a09663d10daaf4bacc2b436227a43e1f0947 100644 (file)
@@ -1,7 +1,7 @@
-/*     $OpenBSD: gss-genr.c,v 1.6 2005/10/13 22:24:31 stevesk Exp $    */
+/* $OpenBSD: gss-genr.c,v 1.17 2006/08/29 12:02:30 dtucker Exp $ */
 
 /*
- * Copyright (c) 2001-2005 Simon Wilkinson. All rights reserved.
+ * Copyright (c) 2001-2006 Simon Wilkinson. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #ifdef GSSAPI
 
+#include <sys/types.h>
+#include <sys/param.h>
+
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+
 #include "xmalloc.h"
-#include "bufaux.h"
+#include "buffer.h"
 #include "log.h"
 #include "canohost.h"
 #include "ssh2.h"
@@ -89,6 +96,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check,
        char deroid[2];
        const EVP_MD *evp_md = EVP_md5();
        EVP_MD_CTX md;
+       Gssctxt *gssctxt = NULL;
 
        if (gss_enc2oid != NULL) {
                for (i=0;gss_enc2oid[i].encoded!=NULL;i++)
@@ -104,7 +112,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check,
        oidpos = 0;
        for (i = 0;i < gss_supported->count;i++) {
                if (gss_supported->elements[i].length < 128 &&
-                   (*check)(&(gss_supported->elements[i]), data)) {
+                   (*check)(&gssctxt, &(gss_supported->elements[i]), data)) {
 
                        deroid[0] = SSH_GSS_OIDTYPE;
                        deroid[1] = gss_supported->elements[i].length;
@@ -150,6 +158,10 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check,
                mechs = NULL;
        }
        
+    if (gssctxt) {
+        ssh_gssapi_delete_ctx(&gssctxt);
+    }
+
        return (mechs);
 }
 
@@ -214,7 +226,11 @@ ssh_gssapi_set_oid(Gssctxt *ctx, gss_OID oid)
 void
 ssh_gssapi_error(Gssctxt *ctxt)
 {
-       debug("%s", ssh_gssapi_last_error(ctxt, NULL, NULL));
+       char *s;
+
+       s = ssh_gssapi_last_error(ctxt, NULL, NULL);
+       debug("%s", s);
+       xfree(s);
 }
 
 char *
@@ -273,9 +289,7 @@ ssh_gssapi_last_error(Gssctxt *ctxt, OM_uint32 *major_status,
 void
 ssh_gssapi_build_ctx(Gssctxt **ctx)
 {
-       *ctx = xmalloc(sizeof (Gssctxt));
-       (*ctx)->major = 0;
-       (*ctx)->minor = 0;
+       *ctx = xcalloc(1, sizeof (Gssctxt));
        (*ctx)->context = GSS_C_NO_CONTEXT;
        (*ctx)->name = GSS_C_NO_NAME;
        (*ctx)->oid = GSS_C_NO_OID;
@@ -350,6 +364,7 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host)
 {
        gss_buffer_desc gssbuf;
        char *xhost;
+       char *val;
 
        /* Make a copy of the host name, in case it was returned by a
         * previous call to gethostbyname(). */ 
@@ -359,9 +374,9 @@ ssh_gssapi_import_name(Gssctxt *ctx, const char *host)
         * this for us themselves */
        resolve_localhost(&xhost);
        
-       gssbuf.length = sizeof("host@") + strlen(xhost);
-       gssbuf.value = xmalloc(gssbuf.length);
-       snprintf(gssbuf.value, gssbuf.length, "host@%s", xhost);
+       xasprintf(&val, "host@%s", xhost);
+       gssbuf.value = val;
+       gssbuf.length = strlen(gssbuf.value);
 
        if ((ctx->major = gss_import_name(&ctx->minor,
            &gssbuf, GSS_C_NT_HOSTBASED_SERVICE, &ctx->name)))
@@ -387,11 +402,15 @@ ssh_gssapi_acquire_cred(Gssctxt *ctx)
        gss_create_empty_oid_set(&status, &oidset);
        gss_add_oid_set_member(&status, ctx->oid, &oidset);
 
-       if (gethostname(lname, MAXHOSTNAMELEN))
+       if (gethostname(lname, MAXHOSTNAMELEN)) {
+               gss_release_oid_set(&status, &oidset);
                return (-1);
+       }
 
-       if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname)))
+       if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) {
+               gss_release_oid_set(&status, &oidset);
                return (ctx->major);
+       }
 
        if ((ctx->major = gss_acquire_cred(&ctx->minor,
            ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, NULL, NULL)))
@@ -450,17 +469,32 @@ ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid)
 }
 
 int
-ssh_gssapi_check_mechanism(gss_OID oid, void *host) {
-       Gssctxt * ctx = NULL;
+ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host)
+{
        gss_buffer_desc token = GSS_C_EMPTY_BUFFER;
        OM_uint32 major, minor;
-       
-       ssh_gssapi_build_ctx(&ctx);
-       ssh_gssapi_set_oid(ctx, oid);
-       ssh_gssapi_import_name(ctx, host);
-       major = ssh_gssapi_init_ctx(ctx, 0, GSS_C_NO_BUFFER, &token, NULL);
-       gss_release_buffer(&minor, &token);
-       ssh_gssapi_delete_ctx(&ctx);
+       gss_OID_desc spnego_oid = {6, (void *)"\x2B\x06\x01\x05\x05\x02"};
+
+       /* RFC 4462 says we MUST NOT do SPNEGO */
+       if (oid->length == spnego_oid.length && 
+           (memcmp(oid->elements, spnego_oid.elements, oid->length) == 0))
+               return 0; /* false */
+
+       ssh_gssapi_build_ctx(ctx);
+       ssh_gssapi_set_oid(*ctx, oid);
+       major = ssh_gssapi_import_name(*ctx, host);
+       if (!GSS_ERROR(major)) {
+               major = ssh_gssapi_init_ctx(*ctx, 0, GSS_C_NO_BUFFER, &token, 
+                   NULL);
+               gss_release_buffer(&minor, &token);
+               if ((*ctx)->context != GSS_C_NO_CONTEXT)
+                       gss_delete_sec_context(&minor, &(*ctx)->context,
+                           GSS_C_NO_BUFFER);
+       }
+
+       if (GSS_ERROR(major)) 
+               ssh_gssapi_delete_ctx(ctx);
+
        return (!GSS_ERROR(major));
 }
 
index c152e79ffd24983f51a2659d8039a2b3377851c1..9fdd9254df10cb21cd08599a146ce0803ef03cfa 100644 (file)
 #ifdef GSSAPI
 #ifdef GSI
 
-#include "auth.h"
-#include "auth-pam.h"
+#include <sys/types.h>
+
+#include <stdarg.h>
+#include <string.h>
+
 #include "xmalloc.h"
+#include "key.h"
+#include "hostfile.h"
+#include "auth.h"
 #include "log.h"
 #include "servconf.h"
 
+#include "buffer.h"
 #include "ssh-gss.h"
 
 extern ServerOptions options;
index 17e7ab6c8c4d0d9acfb654ed299c679921f305ee..a49eaf59d88f2a71fb430e91ceae5a7e5c77981b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: gss-serv-krb5.c,v 1.4 2005/10/13 19:08:08 stevesk Exp $       */
+/* $OpenBSD: gss-serv-krb5.c,v 1.7 2006/08/03 03:34:42 deraadt Exp $ */
 
 /*
  * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
 #ifdef GSSAPI
 #ifdef KRB5
 
-#include "auth.h"
+#include <sys/types.h>
+
+#include <stdarg.h>
+#include <string.h>
+
 #include "xmalloc.h"
+#include "key.h"
+#include "hostfile.h"
+#include "auth.h"
 #include "log.h"
 #include "servconf.h"
 
+#include "buffer.h"
 #include "ssh-gss.h"
 
 extern ServerOptions options;
index 90c3ef1e28cb7cdbaa0076ea30c9f8c05e587742..999894d1b1bf24179de0240aeedc6111b5d8cf3a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: gss-serv.c,v 1.13 2005/10/13 22:24:31 stevesk Exp $   */
+/* $OpenBSD: gss-serv.c,v 1.20 2006/08/03 03:34:42 deraadt Exp $ */
 
 /*
  * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
 
 #ifdef GSSAPI
 
-#include "bufaux.h"
+#include <sys/types.h>
+
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "xmalloc.h"
+#include "buffer.h"
+#include "key.h"
+#include "hostfile.h"
 #include "auth.h"
 #include "log.h"
 #include "channels.h"
 #include "session.h"
 #include "servconf.h"
 #include "xmalloc.h"
-#include "getput.h"
-#include "monitor_wrap.h"
-
 #include "ssh-gss.h"
+#include "monitor_wrap.h"
+#include "misc.h"
 
 extern ServerOptions options;
 
@@ -82,12 +90,12 @@ ssh_gssapi_server_mechanisms() {
 
 /* Unprivileged */
 int
-ssh_gssapi_server_check_mech(gss_OID oid, void *data) {
-       Gssctxt * ctx = NULL;
+ssh_gssapi_server_check_mech(Gssctxt **ctx, gss_OID oid, const char *data) {
        int res;
  
-       res = !GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctx, oid)));
-       ssh_gssapi_delete_ctx(&ctx);
+       res = !GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(ctx, oid)));
+       if (!res)
+               ssh_gssapi_delete_ctx(ctx);
 
        return (res);
 }
@@ -114,6 +122,8 @@ ssh_gssapi_supported_oids(gss_OID_set *oidset)
                            &supported_mechs[i]->oid, oidset);
                i++;
        }
+
+       gss_release_oid_set(&min_status, &supported);
 }
 
 
@@ -202,7 +212,7 @@ ssh_gssapi_parse_ename(Gssctxt *ctx, gss_buffer_t ename, gss_buffer_t name)
         * second without.
         */
 
-       oidl = GET_16BIT(tok+2); /* length including next two bytes */
+       oidl = get_u16(tok+2); /* length including next two bytes */
        oidl = oidl-2; /* turn it into the _real_ length of the variable OID */
 
        /*
@@ -219,14 +229,14 @@ ssh_gssapi_parse_ename(Gssctxt *ctx, gss_buffer_t ename, gss_buffer_t name)
        if (ename->length < offset+4)
                return GSS_S_FAILURE;
 
-       name->length = GET_32BIT(tok+offset);
+       name->length = get_u32(tok+offset);
        offset += 4;
 
        if (ename->length < offset+name->length)
                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;
@@ -289,7 +299,8 @@ ssh_gssapi_cleanup_creds(void)
 {
        if (gssapi_client.store.filename != NULL) {
                /* Unlink probably isn't sufficient */
-               debug("removing gssapi cred file\"%s\"", gssapi_client.store.filename);
+               debug("removing gssapi cred file\"%s\"",
+                   gssapi_client.store.filename);
                unlink(gssapi_client.store.filename);
        }
 }
index 520817400b5f4e0b224aad534df9f1383e0b2e90..967fcc26c84b385840f34428ef5bdcb06fe31586 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: includes.h,v 1.22 2006/01/01 08:59:27 stevesk Exp $   */
+/* $OpenBSD: includes.h,v 1.54 2006/07/22 20:48:23 stevesk Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
 #ifndef INCLUDES_H
 #define INCLUDES_H
 
-#define RCSID(msg) \
-static /**/const char *const rcsid[] = { (const char *)rcsid, "\100(#)" msg }
-
 #include "config.h"
 
 #define _GNU_SOURCE /* activate extra prototypes for glibc */
 
-#include <stdarg.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h> /* For O_NONBLOCK */
-#include <signal.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <pwd.h>
-#include <grp.h>
-#include <time.h>
-#include <dirent.h>
-#include <stddef.h>
+#include <sys/types.h>
+#include <sys/socket.h> /* For CMSG_* */
 
 #ifdef HAVE_LIMITS_H
 # include <limits.h> /* For PATH_MAX */
 #endif
-#ifdef HAVE_GETOPT_H
-# include <getopt.h>
-#endif
 #ifdef HAVE_BSTRING_H
 # include <bstring.h>
 #endif
 #if defined(HAVE_GLOB_H) && defined(GLOB_HAS_ALTDIRFUNC) && \
-    defined(GLOB_HAS_GL_MATCHC)
+    defined(GLOB_HAS_GL_MATCHC) && \
+    defined(HAVE_DECL_GLOB_NOMATCH) &&  HAVE_DECL_GLOB_NOMATCH != 0
 # include <glob.h>
 #endif
-#ifdef HAVE_NETGROUP_H
-# include <netgroup.h>
-#endif
 #ifdef HAVE_ENDIAN_H
 # include <endian.h>
 #endif
@@ -67,10 +47,11 @@ static /**/const char *const rcsid[] = { (const char *)rcsid, "\100(#)" msg }
 # include <maillock.h> /* For _PATH_MAILDIR */
 #endif
 #ifdef HAVE_NEXT
-#  include <libc.h>
+# include <libc.h>
+#endif
+#ifdef HAVE_PATHS
+# include <paths.h>
 #endif
-#include <unistd.h> /* For STDIN_FILENO, etc */
-#include <termios.h> /* Struct winsize */
 
 /*
  *-*-nto-qnx needs these headers for strcasecmp and LASTLOG_FILE respectively
@@ -86,39 +67,22 @@ static /**/const char *const rcsid[] = { (const char *)rcsid, "\100(#)" msg }
 #  include <utmp.h>
 #endif
 #ifdef HAVE_UTMPX_H
-#  ifdef HAVE_TV_IN_UTMPX
-#    include <sys/time.h>
-#  endif
 #  include <utmpx.h>
 #endif
 #ifdef HAVE_LASTLOG_H
 #  include <lastlog.h>
 #endif
-#ifdef HAVE_PATHS_H
-#  include <paths.h> /* For _PATH_XXX */
-#endif
 
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <sys/wait.h>
-#ifdef HAVE_SYS_TIME_H
-# include <sys/time.h> /* For timersub */
-#endif
-#include <sys/resource.h>
 #ifdef HAVE_SYS_SELECT_H
 # include <sys/select.h>
 #endif
 #ifdef HAVE_SYS_BSDTTY_H
 # include <sys/bsdtty.h>
 #endif
-#include <sys/param.h> /* For MAXPATHLEN and roundup() */
-#ifdef HAVE_SYS_UN_H
-# include <sys/un.h> /* For sockaddr_un */
-#endif
 #ifdef HAVE_STDINT_H
 # include <stdint.h>
 #endif
+#include <termios.h>
 #ifdef HAVE_SYS_BITYPES_H
 # include <sys/bitypes.h> /* For u_intXX_t */
 #endif
@@ -144,14 +108,8 @@ static /**/const char *const rcsid[] = { (const char *)rcsid, "\100(#)" msg }
 #include <sys/ptms.h>  /* for grantpt() and friends */
 #endif
 
+#include <netinet/in.h>
 #include <netinet/in_systm.h> /* For typedefs */
-#include <netinet/in.h> /* For IPv6 macros */
-#include <netinet/ip.h> /* For IPTOS macros */
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#if defined(HAVE_NETDB_H)
-# include <netdb.h>
-#endif
 #ifdef HAVE_RPC_TYPES_H
 # include <rpc/types.h> /* For INADDR_LOOPBACK */
 #endif
@@ -205,7 +163,7 @@ static /**/const char *const rcsid[] = { (const char *)rcsid, "\100(#)" msg }
 
 #include "defines.h"
 
-#include "version.h"
+#include "platform.h"
 #include "openbsd-compat/openbsd-compat.h"
 #include "openbsd-compat/bsd-nextstep.h"
 
index 59327f038516adf67056d4e7c8e4219cedfc31f9..b4685a694aff8717a60a788d7aca45efeb3cfb43 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: kex.c,v 1.76 2006/08/03 03:34:42 deraadt Exp $ */
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
  *
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: kex.c,v 1.65 2005/11/04 05:15:59 djm Exp $");
+
+#include <sys/param.h>
+
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 
 #include <openssl/crypto.h>
 
-#include "ssh2.h"
 #include "xmalloc.h"
+#include "ssh2.h"
 #include "buffer.h"
-#include "bufaux.h"
 #include "packet.h"
 #include "compat.h"
 #include "cipher.h"
-#include "kex.h"
 #include "key.h"
+#include "kex.h"
 #include "log.h"
 #include "mac.h"
 #include "match.h"
@@ -48,6 +55,14 @@ RCSID("$OpenBSD: kex.c,v 1.65 2005/11/04 05:15:59 djm Exp $");
 
 #define KEX_COOKIE_LEN 16
 
+#if OPENSSL_VERSION_NUMBER >= 0x00907000L
+# if defined(HAVE_EVP_SHA256)
+# define evp_ssh_sha256 EVP_sha256
+# else
+extern const EVP_MD *evp_ssh_sha256(void);
+# endif
+#endif
+
 /* prototype */
 static void kex_kexinit_finish(Kex *);
 static void kex_choose_conf(Kex *);
@@ -79,7 +94,7 @@ kex_buf2prop(Buffer *raw, int *first_kex_follows)
        int i;
        char **proposal;
 
-       proposal = xmalloc(PROPOSAL_MAX * sizeof(char *));
+       proposal = xcalloc(PROPOSAL_MAX, sizeof(char *));
 
        buffer_init(&b);
        buffer_append(&b, buffer_ptr(raw), buffer_len(raw));
@@ -214,8 +229,7 @@ kex_setup(char *proposal[PROPOSAL_MAX])
 {
        Kex *kex;
 
-       kex = xmalloc(sizeof(*kex));
-       memset(kex, 0, sizeof(*kex));
+       kex = xcalloc(1, sizeof(*kex));
        buffer_init(&kex->peer);
        buffer_init(&kex->my);
        kex_prop2buf(&kex->my, proposal);
@@ -258,6 +272,7 @@ choose_enc(Enc *enc, char *client, char *server)
        enc->key_len = cipher_keylen(enc->cipher);
        enc->block_size = cipher_blocksize(enc->cipher);
 }
+
 static void
 choose_mac(Mac *mac, char *client, char *server)
 {
@@ -273,6 +288,7 @@ choose_mac(Mac *mac, char *client, char *server)
        mac->key = NULL;
        mac->enabled = 0;
 }
+
 static void
 choose_comp(Comp *comp, char *client, char *server)
 {
@@ -290,6 +306,7 @@ choose_comp(Comp *comp, char *client, char *server)
        }
        comp->name = name;
 }
+
 static void
 choose_kex(Kex *k, char *client, char *server)
 {
@@ -314,6 +331,11 @@ choose_kex(Kex *k, char *client, char *server)
            sizeof(KEX_GSS_GRP1_SHA1_ID)-1) == 0) {
                k->kex_type = KEX_GSS_GRP1_SHA1;
                k->evp_md = EVP_sha1();
+#endif
+#if OPENSSL_VERSION_NUMBER >= 0x00907000L
+       } else if (strcmp(k->name, KEX_DHGEX_SHA256) == 0) {
+               k->kex_type = KEX_DH_GEX_SHA256;
+               k->evp_md = evp_ssh_sha256();
 #endif
        } else
                fatal("bad kex alg %s", k->name);
@@ -378,8 +400,7 @@ kex_choose_conf(Kex *kex)
 
        /* Algorithm Negotiation */
        for (mode = 0; mode < MODE_MAX; mode++) {
-               newkeys = xmalloc(sizeof(*newkeys));
-               memset(newkeys, 0, sizeof(*newkeys));
+               newkeys = xcalloc(1, sizeof(*newkeys));
                kex->newkeys[mode] = newkeys;
                ctos = (!kex->server && mode == MODE_OUT) || (kex->server && mode == MODE_IN);
                nenc  = ctos ? PROPOSAL_ENC_ALGS_CTOS  : PROPOSAL_ENC_ALGS_STOC;
@@ -434,7 +455,7 @@ derive_key(Kex *kex, int id, u_int need, u_char *hash, u_int hashlen,
 
        if ((mdsz = EVP_MD_size(kex->evp_md)) <= 0)
                fatal("bad kex md size %d", mdsz);
-       digest = xmalloc(roundup(need, mdsz));
+       digest = xmalloc(roundup(need, mdsz));
 
        buffer_init(&b);
        buffer_put_bignum2(&b, shared_secret);
@@ -487,7 +508,8 @@ kex_derive_keys(Kex *kex, u_char *hash, u_int hashlen, BIGNUM *shared_secret)
        for (mode = 0; mode < MODE_MAX; mode++) {
                current_keys[mode] = kex->newkeys[mode];
                kex->newkeys[mode] = NULL;
-               ctos = (!kex->server && mode == MODE_OUT) || (kex->server && mode == MODE_IN);
+               ctos = (!kex->server && mode == MODE_OUT) ||
+                   (kex->server && mode == MODE_IN);
                current_keys[mode]->enc.iv  = keys[ctos ? 0 : 1];
                current_keys[mode]->enc.key = keys[ctos ? 2 : 3];
                current_keys[mode]->mac.key = keys[ctos ? 4 : 5];
index 6181fde2eba2a50d49226d743e8e6d535955c112..db6253adbb82e6cfc0702dd58a35ff33c7535b6e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kex.h,v 1.38 2005/11/04 05:15:59 djm Exp $    */
+/* $OpenBSD: kex.h,v 1.44 2006/08/03 03:34:42 deraadt Exp $ */
 
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
 #ifndef KEX_H
 #define KEX_H
 
+#include <signal.h>
 #include <openssl/evp.h>
-#include "buffer.h"
-#include "cipher.h"
-#include "key.h"
 
 #define        KEX_DH1                 "diffie-hellman-group1-sha1"
 #define        KEX_DH14                "diffie-hellman-group14-sha1"
 #define        KEX_DHGEX_SHA1          "diffie-hellman-group-exchange-sha1"
+#define        KEX_DHGEX_SHA256        "diffie-hellman-group-exchange-sha256"
 
 #define COMP_NONE      0
 #define COMP_ZLIB      1
@@ -65,6 +64,7 @@ enum kex_exchange {
        KEX_DH_GEX_SHA1,
        KEX_GSS_GRP1_SHA1,
        KEX_GSS_GEX_SHA1,
+       KEX_DH_GEX_SHA256,
        KEX_MAX
 };
 
@@ -115,7 +115,7 @@ struct Kex {
        int     kex_type;
        Buffer  my;
        Buffer  peer;
-       int     done;
+       sig_atomic_t done;
        int     flags;
        const EVP_MD *evp_md;
 #ifdef GSSAPI
@@ -157,7 +157,7 @@ kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int,
     BIGNUM *, BIGNUM *, BIGNUM *, u_char **, u_int *);
 void
 kexgex_hash(const EVP_MD *, char *, char *, char *, int, char *,
-    int, u_char *, int, int, int, int, BIGNUM *, BIGNUM *, BIGNUM *, 
+    int, u_char *, int, int, int, int, BIGNUM *, BIGNUM *, BIGNUM *,
     BIGNUM *, BIGNUM *, u_char **, u_int *);
 
 void
index d8a2fa3b7d8b3ad5eb4c4e24c06bc5ad35cc505b..64de7af3088476903f0d68eb9c380dc561f7aee2 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: kexdhc.c,v 1.9 2006/08/03 03:34:42 deraadt Exp $ */
 /*
  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
  *
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: kexdhc.c,v 1.3 2005/11/04 05:15:59 djm Exp $");
+
+#include <sys/types.h>
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
 
 #include "xmalloc.h"
+#include "buffer.h"
 #include "key.h"
+#include "cipher.h"
 #include "kex.h"
 #include "log.h"
 #include "packet.h"
@@ -82,7 +91,7 @@ kexdh_client(Kex *kex)
        if (kex->verify_host_key(server_host_key) == -1)
                fatal("server_host_key verification failed");
 
-       /* DH paramter f, server public DH key */
+       /* DH parameter f, server public DH key */
        if ((dh_server_pub = BN_new()) == NULL)
                fatal("dh_server_pub == NULL");
        packet_get_bignum2(dh_server_pub);
index 26c8cdfd69505541bb92edf1fc074d9a58085d93..93ec97f931ea839155508dcf004f833f806ca29f 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: kexdhs.c,v 1.7 2006/08/03 03:34:42 deraadt Exp $ */
 /*
  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
  *
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: kexdhs.c,v 1.3 2005/11/04 05:15:59 djm Exp $");
+
+#include <sys/types.h>
+
+#include <stdarg.h>
+#include <string.h>
+#include <signal.h>
 
 #include "xmalloc.h"
+#include "buffer.h"
 #include "key.h"
+#include "cipher.h"
 #include "kex.h"
 #include "log.h"
 #include "packet.h"
 #include "dh.h"
 #include "ssh2.h"
+#ifdef GSSAPI
+#include "ssh-gss.h"
+#endif
 #include "monitor_wrap.h"
 
 void
index a6ff8757d653519f376e12a511c9cbb360c4e6c7..2c19713e11a75dde09d1f4e5779cb91ac0b8fef0 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: kexgexc.c,v 1.9 2006/08/03 03:34:42 deraadt Exp $ */
 /*
  * Copyright (c) 2000 Niels Provos.  All rights reserved.
  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: kexgexc.c,v 1.3 2005/11/04 05:15:59 djm Exp $");
+
+#include <sys/types.h>
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
 
 #include "xmalloc.h"
+#include "buffer.h"
 #include "key.h"
+#include "cipher.h"
 #include "kex.h"
 #include "log.h"
 #include "packet.h"
@@ -120,7 +129,7 @@ kexgex_client(Kex *kex)
        if (kex->verify_host_key(server_host_key) == -1)
                fatal("server_host_key verification failed");
 
-       /* DH paramter f, server public DH key */
+       /* DH parameter f, server public DH key */
        if ((dh_server_pub = BN_new()) == NULL)
                fatal("dh_server_pub == NULL");
        packet_get_bignum2(dh_server_pub);
index c48b27af9deeea08ed6c8c9e0bdd5584a0243c81..5373a633a4dd4c9c66640743c61671624845081b 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: kexgexs.c,v 1.8 2006/08/03 03:34:42 deraadt Exp $ */
 /*
  * Copyright (c) 2000 Niels Provos.  All rights reserved.
  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: kexgexs.c,v 1.2 2005/11/04 05:15:59 djm Exp $");
+
+#include <sys/param.h>
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
 
 #include "xmalloc.h"
+#include "buffer.h"
 #include "key.h"
+#include "cipher.h"
 #include "kex.h"
 #include "log.h"
 #include "packet.h"
 #include "dh.h"
 #include "ssh2.h"
 #include "compat.h"
+#ifdef GSSAPI
+#include "ssh-gss.h"
+#endif
 #include "monitor_wrap.h"
 
 void
index 8793f401359e92ff8e9a50d7397aba6d2cc5b583..0caa6b62d106b51ef7ff954d46d5550ba4184108 100644 (file)
@@ -32,6 +32,8 @@
 #include "xmalloc.h"
 #include "buffer.h"
 #include "bufaux.h"
+#include "cipher.h"
+#include "key.h"
 #include "kex.h"
 #include "log.h"
 #include "packet.h"
index 9f51705b08cf558ddb478dfe4cd0aa7475bbce1a..bcc4b78c8e865765fdbe1cc4d9ebd1aa9d5654e5 100644 (file)
@@ -32,6 +32,8 @@
 #include "xmalloc.h"
 #include "buffer.h"
 #include "bufaux.h"
+#include "cipher.h"
+#include "key.h"
 #include "kex.h"
 #include "log.h"
 #include "packet.h"
index 239a35919536d8234fbd98d03e056f5e99efc39a..d077962dd1c9ea6865c85bead01faae0c658aec5 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: key.c,v 1.67 2006/08/03 03:34:42 deraadt Exp $ */
 /*
  * read_bignum():
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
+
 #include "includes.h"
-RCSID("$OpenBSD: key.c,v 1.58 2005/06/17 02:44:32 djm Exp $");
+
+#include <sys/types.h>
 
 #include <openssl/evp.h>
 
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
 #include "xmalloc.h"
 #include "key.h"
 #include "rsa.h"
 #include "uuencode.h"
 #include "buffer.h"
-#include "bufaux.h"
 #include "log.h"
 
 Key *
@@ -50,9 +56,8 @@ key_new(int type)
        Key *k;
        RSA *rsa;
        DSA *dsa;
-       k = xmalloc(sizeof(*k));
+       k = xcalloc(1, sizeof(*k));
        k->type = type;
-       k->flags = 0;
        k->dsa = NULL;
        k->rsa = NULL;
        switch (k->type) {
@@ -123,6 +128,8 @@ key_new_private(int type)
 void
 key_free(Key *k)
 {
+       if (k == NULL)
+               fatal("key_free: key is NULL");
        switch (k->type) {
        case KEY_RSA1:
        case KEY_RSA:
@@ -155,14 +162,12 @@ key_equal(const Key *a, const Key *b)
                return a->rsa != NULL && b->rsa != NULL &&
                    BN_cmp(a->rsa->e, b->rsa->e) == 0 &&
                    BN_cmp(a->rsa->n, b->rsa->n) == 0;
-               break;
        case KEY_DSA:
                return a->dsa != NULL && b->dsa != NULL &&
                    BN_cmp(a->dsa->p, b->dsa->p) == 0 &&
                    BN_cmp(a->dsa->q, b->dsa->q) == 0 &&
                    BN_cmp(a->dsa->g, b->dsa->g) == 0 &&
                    BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0;
-               break;
        default:
                fatal("key_equal: bad key type %d", a->type);
                break;
@@ -209,7 +214,6 @@ key_fingerprint_raw(const Key *k, enum fp_type dgst_type,
                break;
        case KEY_UNSPEC:
                return retval;
-               break;
        default:
                fatal("key_fingerprint_raw: bad key type %d", k->type);
                break;
@@ -233,8 +237,7 @@ key_fingerprint_hex(u_char *dgst_raw, u_int dgst_raw_len)
        char *retval;
        u_int i;
 
-       retval = xmalloc(dgst_raw_len * 3 + 1);
-       retval[0] = '\0';
+       retval = xcalloc(1, dgst_raw_len * 3 + 1);
        for (i = 0; i < dgst_raw_len; i++) {
                char hex[4];
                snprintf(hex, sizeof(hex), "%02x:", dgst_raw[i]);
@@ -256,7 +259,7 @@ key_fingerprint_bubblebabble(u_char *dgst_raw, u_int dgst_raw_len)
        char *retval;
 
        rounds = (dgst_raw_len / 2) + 1;
-       retval = xmalloc(sizeof(char) * (rounds*6));
+       retval = xcalloc((rounds * 6), sizeof(char));
        retval[j++] = 'x';
        for (i = 0; i < rounds; i++) {
                u_int idx0, idx1, idx2, idx3, idx4;
@@ -530,13 +533,10 @@ key_type(const Key *k)
        switch (k->type) {
        case KEY_RSA1:
                return "RSA1";
-               break;
        case KEY_RSA:
                return "RSA";
-               break;
        case KEY_DSA:
                return "DSA";
-               break;
        }
        return "unknown";
 }
@@ -547,10 +547,8 @@ key_ssh_name(const Key *k)
        switch (k->type) {
        case KEY_RSA:
                return "ssh-rsa";
-               break;
        case KEY_DSA:
                return "ssh-dss";
-               break;
        }
        return "ssh-unknown";
 }
@@ -562,10 +560,8 @@ key_size(const Key *k)
        case KEY_RSA1:
        case KEY_RSA:
                return BN_num_bits(k->rsa->n);
-               break;
        case KEY_DSA:
                return BN_num_bits(k->dsa->p);
-               break;
        }
        return 0;
 }
@@ -574,6 +570,7 @@ static RSA *
 rsa_generate_private_key(u_int bits)
 {
        RSA *private;
+
        private = RSA_generate_key(bits, 35, NULL, NULL);
        if (private == NULL)
                fatal("rsa_generate_private_key: key generation failed.");
@@ -584,6 +581,7 @@ static DSA*
 dsa_generate_private_key(u_int bits)
 {
        DSA *private = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, NULL, NULL);
+
        if (private == NULL)
                fatal("dsa_generate_private_key: DSA_generate_parameters failed");
        if (!DSA_generate_key(private))
@@ -795,14 +793,11 @@ key_sign(
        switch (key->type) {
        case KEY_DSA:
                return ssh_dss_sign(key, sigp, lenp, data, datalen);
-               break;
        case KEY_RSA:
                return ssh_rsa_sign(key, sigp, lenp, data, datalen);
-               break;
        default:
                error("key_sign: invalid key type %d", key->type);
                return -1;
-               break;
        }
 }
 
@@ -822,14 +817,11 @@ key_verify(
        switch (key->type) {
        case KEY_DSA:
                return ssh_dss_verify(key, signature, signaturelen, data, datalen);
-               break;
        case KEY_RSA:
                return ssh_rsa_verify(key, signature, signaturelen, data, datalen);
-               break;
        default:
                error("key_verify: invalid key type %d", key->type);
                return -1;
-               break;
        }
 }
 
@@ -839,7 +831,7 @@ key_demote(const Key *k)
 {
        Key *pk;
 
-       pk = xmalloc(sizeof(*pk));
+       pk = xcalloc(1, sizeof(*pk));
        pk->type = k->type;
        pk->flags = k->flags;
        pk->dsa = NULL;
index 6358e955fc56829d7daace6c399475cc242ed5ff..40576f3d74c9d658b95e83358eeaeee756c35880 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: key.h,v 1.23 2003/11/10 16:23:41 jakob Exp $  */
+/* $OpenBSD: key.h,v 1.26 2006/08/03 03:34:42 deraadt Exp $ */
 
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
index 96ab24b04b43bc1a65275fbbd622cd0aac54c547..7f8867482d95e55d9cd6ff471cf504163c31d775 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: log.c,v 1.39 2006/08/18 09:13:25 deraadt Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: log.c,v 1.29 2003/09/23 20:17:11 markus Exp $");
 
-#include "log.h"
-#include "xmalloc.h"
+#include <sys/types.h>
 
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include <syslog.h>
+#include <unistd.h>
 #if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H)
 # include <vis.h>
 #endif
 
+#include "xmalloc.h"
+#include "log.h"
+
 static LogLevel log_level = SYSLOG_LEVEL_INFO;
 static int log_on_stderr = 1;
 static int log_facility = LOG_AUTH;
@@ -130,6 +137,20 @@ error(const char *fmt,...)
        va_end(args);
 }
 
+void
+sigdie(const char *fmt,...)
+{
+#ifdef DO_LOG_SAFE_IN_SIGHAND
+       va_list args;
+
+       va_start(args, fmt);
+       do_log(SYSLOG_LEVEL_FATAL, fmt, args);
+       va_end(args);
+#endif
+       _exit(1);
+}
+
+
 /* Log this message (information that usually should go to the log). */
 
 void
index fd9c392a45d616e57e8f17257837c1b8a91f87fb..d3f9003b870939b51f2e3aedaa6d1f5aa1470023 100644 (file)
@@ -1,6 +1,7 @@
+/* $OpenBSD: misc.c,v 1.64 2006/08/03 03:34:42 deraadt Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
- * Copyright (c) 2005 Damien Miller.  All rights reserved.
+ * Copyright (c) 2005,2006 Damien Miller.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: misc.c,v 1.42 2006/01/31 10:19:02 djm Exp $");
 
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/param.h>
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#ifdef HAVE_PATHS_H
+# include <paths.h>
+#include <pwd.h>
+#endif
 #ifdef SSH_TUN_OPENBSD
 #include <net/if.h>
 #endif
 
+#include "xmalloc.h"
 #include "misc.h"
 #include "log.h"
-#include "xmalloc.h"
+#include "ssh.h"
 
 /* remove newline at end of string */
 char *
@@ -123,6 +144,7 @@ set_nodelay(int fd)
 
 /* Characters considered whitespace in strsep calls. */
 #define WHITESPACE " \t\r\n"
+#define QUOTE  "\""
 
 /* Characters considered as quotations. */
 #define QUOTES "'\""
@@ -154,15 +176,27 @@ strdelim(char **s)
             return (old);
         }
 
-        *s = strpbrk(*s, WHITESPACE "=");
+       *s = strpbrk(*s, WHITESPACE QUOTE "=");
        if (*s == NULL)
                return (old);
 
+       if (*s[0] == '\"') {
+               memmove(*s, *s + 1, strlen(*s)); /* move nul too */
+               /* Find matching quote */
+               if ((*s = strpbrk(*s, QUOTE)) == NULL) {
+                       return (NULL);          /* no matching quote */
+               } else {
+                       *s[0] = '\0';
+                       return (old);
+               }
+       }
+
        /* Allow only one '=' to be skipped */
        if (*s[0] == '=')
                wspace = 1;
        *s[0] = '\0';
 
+       /* Skip any extra whitespace after first token */
        *s += strspn(*s + 1, WHITESPACE) + 1;
        if (*s[0] == '=' && !wspace)
                *s += strspn(*s + 1, WHITESPACE) + 1;
@@ -173,9 +207,8 @@ strdelim(char **s)
 struct passwd *
 pwcopy(struct passwd *pw)
 {
-       struct passwd *copy = xmalloc(sizeof(*copy));
+       struct passwd *copy = xcalloc(1, sizeof(*copy));
 
-       memset(copy, 0, sizeof(*copy));
        copy->pw_name = xstrdup(pw->pw_name);
        copy->pw_passwd = xstrdup(pw->pw_passwd);
        copy->pw_gecos = xstrdup(pw->pw_gecos);
@@ -298,6 +331,7 @@ convtime(const char *s)
                switch (*endp++) {
                case '\0':
                        endp--;
+                       break;
                case 's':
                case 'S':
                        break;
@@ -329,6 +363,23 @@ convtime(const char *s)
        return total;
 }
 
+/*
+ * Returns a standardized host+port identifier string.
+ * Caller must free returned string.
+ */
+char *
+put_host_port(const char *host, u_short port)
+{
+       char *hoststr;
+
+       if (port == 0 || port == SSH_DEFAULT_PORT)
+               return(xstrdup(host));
+       if (asprintf(&hoststr, "[%s]:%d", host, (int)port) < 0)
+               fatal("put_host_port: asprintf: %s", strerror(errno));
+       debug3("put_host_port: %s", hoststr);
+       return hoststr;
+}
+
 /*
  * Search for next delimiter between hostnames/addresses and ports.
  * Argument may be modified (for termination).
@@ -426,7 +477,7 @@ addargs(arglist *args, char *fmt, ...)
        } else if (args->num+2 >= nalloc)
                nalloc *= 2;
 
-       args->list = xrealloc(args->list, nalloc * sizeof(char *));
+       args->list = xrealloc(args->list, nalloc, sizeof(char *));
        args->nalloc = nalloc;
        args->list[args->num++] = cp;
        args->list[args->num] = NULL;
@@ -691,18 +742,100 @@ sanitise_stdfd(void)
 }
 
 char *
-tohex(const u_char *d, u_int l)
+tohex(const void *vp, size_t l)
 {
+       const u_char *p = (const u_char *)vp;
        char b[3], *r;
-       u_int i, hl;
+       size_t i, hl;
+
+       if (l > 65536)
+               return xstrdup("tohex: length > 65536");
 
        hl = l * 2 + 1;
-       r = xmalloc(hl);
-       *r = '\0';
+       r = xcalloc(1, hl);
        for (i = 0; i < l; i++) {
-               snprintf(b, sizeof(b), "%02x", d[i]);
+               snprintf(b, sizeof(b), "%02x", p[i]);
                strlcat(r, b, hl);
        }
        return (r);
 }
 
+u_int64_t
+get_u64(const void *vp)
+{
+       const u_char *p = (const u_char *)vp;
+       u_int64_t v;
+
+       v  = (u_int64_t)p[0] << 56;
+       v |= (u_int64_t)p[1] << 48;
+       v |= (u_int64_t)p[2] << 40;
+       v |= (u_int64_t)p[3] << 32;
+       v |= (u_int64_t)p[4] << 24;
+       v |= (u_int64_t)p[5] << 16;
+       v |= (u_int64_t)p[6] << 8;
+       v |= (u_int64_t)p[7];
+
+       return (v);
+}
+
+u_int32_t
+get_u32(const void *vp)
+{
+       const u_char *p = (const u_char *)vp;
+       u_int32_t v;
+
+       v  = (u_int32_t)p[0] << 24;
+       v |= (u_int32_t)p[1] << 16;
+       v |= (u_int32_t)p[2] << 8;
+       v |= (u_int32_t)p[3];
+
+       return (v);
+}
+
+u_int16_t
+get_u16(const void *vp)
+{
+       const u_char *p = (const u_char *)vp;
+       u_int16_t v;
+
+       v  = (u_int16_t)p[0] << 8;
+       v |= (u_int16_t)p[1];
+
+       return (v);
+}
+
+void
+put_u64(void *vp, u_int64_t v)
+{
+       u_char *p = (u_char *)vp;
+
+       p[0] = (u_char)(v >> 56) & 0xff;
+       p[1] = (u_char)(v >> 48) & 0xff;
+       p[2] = (u_char)(v >> 40) & 0xff;
+       p[3] = (u_char)(v >> 32) & 0xff;
+       p[4] = (u_char)(v >> 24) & 0xff;
+       p[5] = (u_char)(v >> 16) & 0xff;
+       p[6] = (u_char)(v >> 8) & 0xff;
+       p[7] = (u_char)v & 0xff;
+}
+
+void
+put_u32(void *vp, u_int32_t v)
+{
+       u_char *p = (u_char *)vp;
+
+       p[0] = (u_char)(v >> 24) & 0xff;
+       p[1] = (u_char)(v >> 16) & 0xff;
+       p[2] = (u_char)(v >> 8) & 0xff;
+       p[3] = (u_char)v & 0xff;
+}
+
+
+void
+put_u16(void *vp, u_int16_t v)
+{
+       u_char *p = (u_char *)vp;
+
+       p[0] = (u_char)(v >> 8) & 0xff;
+       p[1] = (u_char)v & 0xff;
+}
index d53806ea6bda0294688a19d49c1c59d6ece06978..e18929badd85ab345e21adf686883226c0973e58 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: moduli.c,v 1.12 2005/07/17 07:17:55 djm Exp $ */
+/* $OpenBSD: moduli.c,v 1.18 2006/08/03 03:34:42 deraadt Exp $ */
 /*
  * Copyright 1994 Phil Karn <karn@qualcomm.com>
  * Copyright 1996-1998, 2003 William Allen Simpson <wsimpson@greendragon.com>
  */
 
 #include "includes.h"
-#include "xmalloc.h"
-#include "log.h"
+
+#include <sys/types.h>
 
 #include <openssl/bn.h>
 
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <time.h>
+
+#include "xmalloc.h"
+#include "log.h"
+
 /*
  * File output defines
  */
@@ -301,21 +310,10 @@ gen_candidates(FILE *out, u_int32_t memory, u_int32_t power, BIGNUM *start)
                largewords = (largememory << SHIFT_MEGAWORD);
        }
 
-       TinySieve = calloc(tinywords, sizeof(u_int32_t));
-       if (TinySieve == NULL) {
-               error("Insufficient memory for tiny sieve: need %u bytes",
-                   tinywords << SHIFT_BYTE);
-               exit(1);
-       }
+       TinySieve = xcalloc(tinywords, sizeof(u_int32_t));
        tinybits = tinywords << SHIFT_WORD;
 
-       SmallSieve = calloc(smallwords, sizeof(u_int32_t));
-       if (SmallSieve == NULL) {
-               error("Insufficient memory for small sieve: need %u bytes",
-                   smallwords << SHIFT_BYTE);
-               xfree(TinySieve);
-               exit(1);
-       }
+       SmallSieve = xcalloc(smallwords, sizeof(u_int32_t));
        smallbits = smallwords << SHIFT_WORD;
 
        /*
index 0c93d7dbc26bfb514d8817c00f0551fd8627c19e..ce6a7f7471a80f84d05c055f7989f5e25153fd6f 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: monitor.c,v 1.88 2006/08/12 20:46:46 miod Exp $ */
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
  * Copyright 2002 Markus Friedl <markus@openbsd.org>
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: monitor.c,v 1.64 2005/10/13 22:24:31 stevesk Exp $");
 
-#include <openssl/dh.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include "openbsd-compat/sys-tree.h"
+#include <sys/wait.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#ifdef HAVE_PATHS_H
+#include <paths.h>
+#endif
+#include <pwd.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
 
 #ifdef SKEY
 #include <skey.h>
 #endif
 
+#include <openssl/dh.h>
+
+#include "xmalloc.h"
 #include "ssh.h"
+#include "key.h"
+#include "buffer.h"
+#include "hostfile.h"
 #include "auth.h"
+#include "cipher.h"
 #include "kex.h"
 #include "dh.h"
 #ifdef TARGET_OS_MAC   /* XXX Broken krb5 headers on Mac */
@@ -55,17 +78,16 @@ RCSID("$OpenBSD: monitor.c,v 1.64 2005/10/13 22:24:31 stevesk Exp $");
 #include "servconf.h"
 #include "monitor.h"
 #include "monitor_mm.h"
+#ifdef GSSAPI
+#include "ssh-gss.h"
+#endif
 #include "monitor_wrap.h"
 #include "monitor_fdpass.h"
-#include "xmalloc.h"
 #include "misc.h"
-#include "buffer.h"
-#include "bufaux.h"
 #include "compat.h"
 #include "ssh2.h"
 
 #ifdef GSSAPI
-#include "ssh-gss.h"
 static Gssctxt *gsscontext = NULL;
 #endif
 
@@ -175,6 +197,7 @@ struct mon_table {
 #define MON_ISAUTH     0x0004  /* Required for Authentication */
 #define MON_AUTHDECIDE 0x0008  /* Decides Authentication */
 #define MON_ONCE       0x0010  /* Disable after calling */
+#define MON_ALOG       0x0020  /* Log auth attempt without authenticating */
 
 #define MON_AUTH       (MON_ISAUTH|MON_AUTHDECIDE)
 
@@ -200,7 +223,7 @@ struct mon_table mon_dispatch_proto20[] = {
 #endif
 #ifdef BSD_AUTH
     {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery},
-    {MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH,mm_answer_bsdauthrespond},
+    {MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH, mm_answer_bsdauthrespond},
 #endif
 #ifdef SKEY
     {MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery},
@@ -246,13 +269,13 @@ struct mon_table mon_dispatch_proto15[] = {
     {MONITOR_REQ_SESSKEY, MON_ONCE, mm_answer_sesskey},
     {MONITOR_REQ_SESSID, MON_ONCE, mm_answer_sessid},
     {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
-    {MONITOR_REQ_RSAKEYALLOWED, MON_ISAUTH, mm_answer_rsa_keyallowed},
-    {MONITOR_REQ_KEYALLOWED, MON_ISAUTH, mm_answer_keyallowed},
+    {MONITOR_REQ_RSAKEYALLOWED, MON_ISAUTH|MON_ALOG, mm_answer_rsa_keyallowed},
+    {MONITOR_REQ_KEYALLOWED, MON_ISAUTH|MON_ALOG, mm_answer_keyallowed},
     {MONITOR_REQ_RSACHALLENGE, MON_ONCE, mm_answer_rsa_challenge},
     {MONITOR_REQ_RSARESPONSE, MON_ONCE|MON_AUTHDECIDE, mm_answer_rsa_response},
 #ifdef BSD_AUTH
     {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery},
-    {MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH,mm_answer_bsdauthrespond},
+    {MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH, mm_answer_bsdauthrespond},
 #endif
 #ifdef SKEY
     {MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery},
@@ -285,7 +308,7 @@ struct mon_table mon_dispatch_postauth15[] = {
     {MONITOR_REQ_TERM, 0, mm_answer_term},
 #ifdef SSH_AUDIT_EVENTS
     {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
-    {MONITOR_REQ_AUDIT_COMMAND, MON_ONCE, mm_answer_audit_command},
+    {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT|MON_ONCE, mm_answer_audit_command},
 #endif
     {0, 0, NULL}
 };
@@ -354,6 +377,7 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
 
        /* The first few requests do not require asynchronous access */
        while (!authenticated) {
+               auth_method = "unknown";
                authenticated = monitor_read(pmonitor, mon_dispatch, &ent);
                if (authenticated) {
                        if (!(ent->flags & MON_AUTHDECIDE))
@@ -376,7 +400,7 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
 #endif
                }
 
-               if (ent->flags & MON_AUTHDECIDE) {
+               if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) {
                        auth_log(authctxt, authenticated, auth_method,
                            compat20 ? " ssh2" : "");
                        if (!authenticated)
@@ -386,6 +410,8 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
 
        if (!authctxt->valid)
                fatal("%s: authenticated invalid user", __func__);
+       if (strcmp(auth_method, "unknown") == 0)
+               fatal("%s: authentication method name unknown", __func__);
 
        debug("%s: %s has been authenticated by privileged process",
            __func__, authctxt->user);
@@ -576,7 +602,11 @@ mm_answer_sign(int sock, Buffer *m)
        keyid = buffer_get_int(m);
        p = buffer_get_string(m, &datlen);
 
-       if (datlen != 20)
+       /*
+        * Supported KEX types will only return SHA1 (20 byte) or
+        * SHA256 (32 byte) hashes
+        */
+       if (datlen != 20 && datlen != 32)
                fatal("%s: data length incorrect: %u", __func__, datlen);
 
        /* save session id, it will be passed on the first call */
@@ -667,9 +697,6 @@ mm_answer_pwnamallow(int sock, Buffer *m)
        if (options.use_pam)
                monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1);
 #endif
-#ifdef SSH_AUDIT_EVENTS
-       monitor_permit(mon_dispatch, MONITOR_REQ_AUDIT_COMMAND, 1);
-#endif
 
        return (0);
 }
@@ -930,6 +957,7 @@ mm_answer_pam_query(int sock, Buffer *m)
                xfree(prompts);
        if (echo_on != NULL)
                xfree(echo_on);
+       auth_method = "keyboard-interactive/pam";
        mm_request_send(sock, MONITOR_ANS_PAM_QUERY, m);
        return (0);
 }
@@ -945,7 +973,7 @@ mm_answer_pam_respond(int sock, Buffer *m)
        sshpam_authok = NULL;
        num = buffer_get_int(m);
        if (num > 0) {
-               resp = xmalloc(num * sizeof(char *));
+               resp = xcalloc(num, sizeof(char *));
                for (i = 0; i < num; ++i)
                        resp[i] = buffer_get_string(m, NULL);
                ret = (sshpam_device.respond)(sshpam_ctxt, num, resp);
@@ -972,6 +1000,7 @@ mm_answer_pam_free_ctx(int sock, Buffer *m)
        (sshpam_device.free_ctx)(sshpam_ctxt);
        buffer_clear(m);
        mm_request_send(sock, MONITOR_ANS_PAM_FREE_CTX, m);
+       auth_method = "keyboard-interactive/pam";
        return (sshpam_authok == sshpam_ctxt);
 }
 #endif
@@ -1017,17 +1046,20 @@ mm_answer_keyallowed(int sock, Buffer *m)
                case MM_USERKEY:
                        allowed = options.pubkey_authentication &&
                            user_key_allowed(authctxt->pw, key);
+                       auth_method = "publickey";
                        break;
                case MM_HOSTKEY:
                        allowed = options.hostbased_authentication &&
                            hostbased_key_allowed(authctxt->pw,
                            cuser, chost, key);
+                       auth_method = "hostbased";
                        break;
                case MM_RSAHOSTKEY:
                        key->type = KEY_RSA1; /* XXX */
                        allowed = options.rhosts_rsa_authentication &&
                            auth_rhosts_rsa_key_allowed(authctxt->pw,
                            cuser, chost, key);
+                       auth_method = "rsa";
                        break;
                default:
                        fatal("%s: unknown key type %d", __func__, type);
@@ -1047,6 +1079,12 @@ mm_answer_keyallowed(int sock, Buffer *m)
                key_blobtype = type;
                hostbased_cuser = cuser;
                hostbased_chost = chost;
+       } else {
+               /* Log failed attempt */
+               auth_log(authctxt, 0, auth_method, compat20 ? " ssh2" : "");
+               xfree(blob);
+               xfree(cuser);
+               xfree(chost);
        }
 
        debug3("%s: key %p is %s",
@@ -1248,7 +1286,7 @@ mm_record_login(Session *s, struct passwd *pw)
        fromlen = sizeof(from);
        if (packet_connection_is_on_socket()) {
                if (getpeername(packet_get_connection_in(),
-                       (struct sockaddr *) & from, &fromlen) < 0) {
+                   (struct sockaddr *)&from, &fromlen) < 0) {
                        debug("getpeername: %.100s", strerror(errno));
                        cleanup_exit(255);
                }
@@ -1264,7 +1302,7 @@ mm_session_close(Session *s)
 {
        debug3("%s: session %d pid %ld", __func__, s->self, (long)s->pid);
        if (s->ttyfd != -1) {
-               debug3("%s: tty %s ptyfd %d",  __func__, s->tty, s->ptyfd);
+               debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd);
                session_pty_cleanup2(s);
        }
        s->used = 0;
@@ -1324,7 +1362,7 @@ mm_answer_pty(int sock, Buffer *m)
        /* no need to dup() because nobody closes ptyfd */
        s->ptymaster = s->ptyfd;
 
-       debug3("%s: tty %s ptyfd %d",  __func__, s->tty, s->ttyfd);
+       debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ttyfd);
 
        return (0);
 
@@ -1411,6 +1449,7 @@ mm_answer_rsa_keyallowed(int sock, Buffer *m)
 
        debug3("%s entering", __func__);
 
+       auth_method = "rsa";
        if (options.rsa_authentication && authctxt->valid) {
                if ((client_n = BN_new()) == NULL)
                        fatal("%s: BN_new", __func__);
@@ -1647,8 +1686,7 @@ mm_get_kex(Buffer *m)
        void *blob;
        u_int bloblen;
 
-       kex = xmalloc(sizeof(*kex));
-       memset(kex, 0, sizeof(*kex));
+       kex = xcalloc(1, sizeof(*kex));
        kex->session_id = buffer_get_string(m, &kex->session_id_len);
        if ((session_id2 == NULL) ||
            (kex->session_id_len != session_id2_len) ||
@@ -1662,6 +1700,7 @@ mm_get_kex(Buffer *m)
        kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
        kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
 #endif
+       kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
        kex->server = 1;
        kex->hostkey_type = buffer_get_int(m);
        kex->kex_type = buffer_get_int(m);
@@ -1821,9 +1860,8 @@ monitor_init(void)
        struct monitor *mon;
        int pair[2];
 
-       mon = xmalloc(sizeof(*mon));
+       mon = xcalloc(1, sizeof(*mon));
 
-       mon->m_pid = 0;
        monitor_socketpair(pair);
 
        mon->m_recvfd = pair[0];
index cb92f141fd78bb7b3b445bc1e6474750cac7d15d..c1b32a33cdd2c42c317505602fa73248a7563fea 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: monitor.h,v 1.13 2003/11/17 11:06:07 markus Exp $     */
+/* $OpenBSD: monitor.h,v 1.14 2006/03/25 22:22:43 djm Exp $ */
 
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
index dd1a139841da40b207d671aeb292c3a36c0afcfd..c5fc4c39702cd3e87afbdc06eeecae8fa9c7d27b 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: monitor_fdpass.c,v 1.12 2006/08/03 03:34:42 deraadt Exp $ */
 /*
  * Copyright 2001 Niels Provos <provos@citi.umich.edu>
  * All rights reserved.
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: monitor_fdpass.c,v 1.6 2004/08/13 02:51:48 djm Exp $");
 
+#include <sys/types.h>
+#include <sys/socket.h>
 #include <sys/uio.h>
 
+#include <errno.h>
+#include <string.h>
+#include <stdarg.h>
+
 #include "log.h"
 #include "monitor_fdpass.h"
 
index 31d080e21ed643ae1066e33401ce42b3b2524d20..12c67ec2d1f22d349ba978a75fbf184591eb79e1 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: monitor_fdpass.h,v 1.2 2002/03/26 03:24:01 stevesk Exp $      */
+/* $OpenBSD: monitor_fdpass.h,v 1.3 2006/03/25 22:22:43 djm Exp $ */
 
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
index b0ec37cff93aca9fd014aeb6ab8a44cc04a39b9a..dab747532a0df2d82d9c30ad1abbeb0522b5ad2b 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: monitor_mm.c,v 1.15 2006/08/03 03:34:42 deraadt Exp $ */
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
  * All rights reserved.
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: monitor_mm.c,v 1.9 2004/05/11 19:01:43 deraadt Exp $");
 
+#include <sys/types.h>
 #ifdef HAVE_SYS_MMAN_H
 #include <sys/mman.h>
 #endif
+#include <sys/param.h>
+#include "openbsd-compat/sys-tree.h"
+
+#include <errno.h>
+#include <stdarg.h>
+#include <string.h>
 
-#include "ssh.h"
 #include "xmalloc.h"
+#include "ssh.h"
 #include "log.h"
 #include "monitor_mm.h"
 
index a1323b9a8d252a90cef9e9e14891aeb6b4ea1da5..36a07a06df6b2aacf144f52aed4a0c37d4be11b9 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: monitor_mm.h,v 1.2 2002/03/26 03:24:01 stevesk Exp $  */
+/* $OpenBSD: monitor_mm.h,v 1.4 2006/08/03 03:34:42 deraadt Exp $ */
 
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
@@ -27,7 +27,6 @@
 
 #ifndef _MM_H_
 #define _MM_H_
-#include "openbsd-compat/sys-tree.h"
 
 struct mm_share {
        RB_ENTRY(mm_share) next;
index efd13f9bbd51dc816b307fcaf7e38398e5505b57..63660753dc1c038253c6b4e7fbfe0fa897a0f24c 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: monitor_wrap.c,v 1.54 2006/08/12 20:46:46 miod Exp $ */
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
  * Copyright 2002 Markus Friedl <markus@openbsd.org>
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: monitor_wrap.c,v 1.40 2005/05/24 17:32:43 avsm Exp $");
+
+#include <sys/types.h>
+#include <sys/uio.h>
+
+#include <errno.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
 
 #include <openssl/bn.h>
 #include <openssl/dh.h>
 
+#include "xmalloc.h"
 #include "ssh.h"
 #include "dh.h"
+#include "buffer.h"
+#include "key.h"
+#include "cipher.h"
 #include "kex.h"
+#include "hostfile.h"
 #include "auth.h"
 #include "auth-options.h"
-#include "buffer.h"
-#include "bufaux.h"
 #include "packet.h"
 #include "mac.h"
 #include "log.h"
@@ -48,21 +62,18 @@ RCSID("$OpenBSD: monitor_wrap.c,v 1.40 2005/05/24 17:32:43 avsm Exp $");
 #include "zlib.h"
 #endif
 #include "monitor.h"
+#ifdef GSSAPI
+#include "ssh-gss.h"
+#endif
 #include "monitor_wrap.h"
-#include "xmalloc.h"
 #include "atomicio.h"
 #include "monitor_fdpass.h"
-#include "getput.h"
+#include "misc.h"
 #include "servconf.h"
 
-#include "auth.h"
 #include "channels.h"
 #include "session.h"
 
-#ifdef GSSAPI
-#include "ssh-gss.h"
-#endif
-
 /* Imports */
 extern int compat20;
 extern Newkeys *newkeys[];
@@ -91,7 +102,7 @@ mm_request_send(int sock, enum monitor_reqtype type, Buffer *m)
 
        debug3("%s entering: type %d", __func__, type);
 
-       PUT_32BIT(buf, mlen + 1);
+       put_u32(buf, mlen + 1);
        buf[4] = (u_char) type;         /* 1st byte of payload is mesg-type */
        if (atomicio(vwrite, sock, buf, sizeof(buf)) != sizeof(buf))
                fatal("%s: write: %s", __func__, strerror(errno));
@@ -112,7 +123,7 @@ mm_request_receive(int sock, Buffer *m)
                        cleanup_exit(255);
                fatal("%s: read: %s", __func__, strerror(errno));
        }
-       msg_len = GET_32BIT(buf);
+       msg_len = get_u32(buf);
        if (msg_len > 256 * 1024)
                fatal("%s: read: bad msg_len %d", __func__, msg_len);
        buffer_clear(m);
@@ -637,7 +648,7 @@ mm_send_keystate(struct monitor *monitor)
 }
 
 int
-mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
+mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen)
 {
        Buffer m;
        char *p, *msg;
@@ -776,8 +787,11 @@ mm_sshpam_query(void *ctx, char **name, char **info,
        *name = buffer_get_string(&m, NULL);
        *info = buffer_get_string(&m, NULL);
        *num = buffer_get_int(&m);
-       *prompts = xmalloc((*num + 1) * sizeof(char *));
-       *echo_on = xmalloc((*num + 1) * sizeof(u_int));
+       if (*num > PAM_MAX_NUM_MSG)
+               fatal("%s: recieved %u PAM messages, expected <= %u",
+                   __func__, *num, PAM_MAX_NUM_MSG);
+       *prompts = xcalloc((*num + 1), sizeof(char *));
+       *echo_on = xcalloc((*num + 1), sizeof(u_int));
        for (i = 0; i < *num; ++i) {
                (*prompts)[i] = buffer_get_string(&m, NULL);
                (*echo_on)[i] = buffer_get_int(&m);
@@ -860,8 +874,8 @@ mm_chall_setup(char **name, char **infotxt, u_int *numprompts,
        *name = xstrdup("");
        *infotxt = xstrdup("");
        *numprompts = 1;
-       *prompts = xmalloc(*numprompts * sizeof(char *));
-       *echo_on = xmalloc(*numprompts * sizeof(u_int));
+       *prompts = xcalloc(*numprompts, sizeof(char *));
+       *echo_on = xcalloc(*numprompts, sizeof(u_int));
        (*echo_on)[0] = 0;
 }
 
@@ -928,9 +942,8 @@ mm_skey_query(void *ctx, char **name, char **infotxt,
    u_int *numprompts, char ***prompts, u_int **echo_on)
 {
        Buffer m;
-       int len;
        u_int success;
-       char *p, *challenge;
+       char *challenge;
 
        debug3("%s: entering", __func__);
 
@@ -954,11 +967,7 @@ mm_skey_query(void *ctx, char **name, char **infotxt,
 
        mm_chall_setup(name, infotxt, numprompts, prompts, echo_on);
 
-       len = strlen(challenge) + strlen(SKEY_PROMPT) + 1;
-       p = xmalloc(len);
-       strlcpy(p, challenge, len);
-       strlcat(p, SKEY_PROMPT, len);
-       (*prompts)[0] = p;
+       xasprintf(*prompts, "%s%s", challenge, SKEY_PROMPT);
        xfree(challenge);
 
        return (0);
index ab05333c9549cc345c4f954e1a8b429ccd14c64e..46fd2a57258a05d99f9240d2e24d2b75c0e2acda 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: monitor_wrap.h,v 1.14 2004/06/21 17:36:31 avsm Exp $  */
+/* $OpenBSD: monitor_wrap.h,v 1.20 2006/08/03 03:34:42 deraadt Exp $ */
 
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
@@ -27,8 +27,6 @@
 
 #ifndef _MM_WRAP_H_
 #define _MM_WRAP_H_
-#include "key.h"
-#include "buffer.h"
 
 extern int use_privsep;
 #define PRIVSEP(x)     (use_privsep ? mm_##x : x)
@@ -37,7 +35,6 @@ enum mm_keytype {MM_NOKEY, MM_HOSTKEY, MM_USERKEY, MM_RSAHOSTKEY, MM_RSAUSERKEY}
 
 struct monitor;
 struct mm_master;
-struct passwd;
 struct Authctxt;
 
 int mm_is_monitor(void);
@@ -57,7 +54,6 @@ int mm_auth_rsa_verify_response(Key *, BIGNUM *, u_char *);
 BIGNUM *mm_auth_rsa_generate_challenge(Key *);
 
 #ifdef GSSAPI
-#include "ssh-gss.h"
 OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID);
 OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *,
    gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *);
@@ -87,7 +83,7 @@ void mm_audit_run_command(const char *);
 
 struct Session;
 void mm_terminate(void);
-int mm_pty_allocate(int *, int *, char *, int);
+int mm_pty_allocate(int *, int *, char *, size_t);
 void mm_session_pty_cleanup2(struct Session *);
 
 /* SSHv1 interfaces */
@@ -116,4 +112,4 @@ void *mm_zalloc(struct mm_master *, u_int, u_int);
 void mm_zfree(struct mm_master *, void *);
 void mm_init_compression(struct mm_master *);
 
-#endif /* _MM_H_ */
+#endif /* _MM_WRAP_H_ */
index 3e4c2882c5f459d5bb1ed4308a44e5c31b146441..cd5f98c4f6cee4b4b20607d0dc7d58036f333602 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: msg.c,v 1.15 2006/08/03 03:34:42 deraadt Exp $ */
 /*
  * Copyright (c) 2002 Markus Friedl.  All rights reserved.
  *
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
+
 #include "includes.h"
-RCSID("$OpenBSD: msg.c,v 1.8 2005/05/24 17:32:43 avsm Exp $");
+
+#include <sys/types.h>
+#include <sys/uio.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdarg.h>
 
 #include "buffer.h"
-#include "getput.h"
 #include "log.h"
 #include "atomicio.h"
 #include "msg.h"
+#include "misc.h"
 
 int
 ssh_msg_send(int fd, u_char type, Buffer *m)
@@ -38,7 +48,7 @@ ssh_msg_send(int fd, u_char type, Buffer *m)
 
        debug3("ssh_msg_send: type %u", (unsigned int)type & 0xff);
 
-       PUT_32BIT(buf, mlen + 1);
+       put_u32(buf, mlen + 1);
        buf[4] = type;          /* 1st byte of payload is mesg-type */
        if (atomicio(vwrite, fd, buf, sizeof(buf)) != sizeof(buf)) {
                error("ssh_msg_send: write");
@@ -64,7 +74,7 @@ ssh_msg_recv(int fd, Buffer *m)
                        error("ssh_msg_recv: read: header");
                return (-1);
        }
-       msg_len = GET_32BIT(buf);
+       msg_len = get_u32(buf);
        if (msg_len > 256 * 1024) {
                error("ssh_msg_recv: read: bad msg_len %u", msg_len);
                return (-1);
index 0d3ea065826ca4eb28d6a123e548999a85fcd09d..b0cb9b52bc2cb4bbb6b5f19f71e0d9f7674a62c7 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: msg.h,v 1.3 2003/11/17 09:45:39 djm Exp $     */
+/* $OpenBSD: msg.h,v 1.4 2006/03/25 22:22:43 djm Exp $ */
 /*
  * Copyright (c) 2002 Markus Friedl.  All rights reserved.
  *
index 129d98cd1bbe0141e1edd0f4c8c8ed1c27e65edf..f56ec503a5610a5e4ca6b049f230318484667270 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: myproposal.h,v 1.18 2005/07/25 11:59:39 markus Exp $  */
+/* $OpenBSD: myproposal.h,v 1.21 2006/03/25 22:22:43 djm Exp $ */
 
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-#define KEX_DEFAULT_KEX                "diffie-hellman-group-exchange-sha1," \
+
+#include <openssl/opensslv.h>
+
+/* Old OpenSSL doesn't support what we need for DHGEX-sha256 */
+#if OPENSSL_VERSION_NUMBER < 0x00907000L
+# define KEX_DEFAULT_KEX               \
+       "diffie-hellman-group-exchange-sha1," \
        "diffie-hellman-group14-sha1," \
        "diffie-hellman-group1-sha1"
+#else
+# define KEX_DEFAULT_KEX               \
+       "diffie-hellman-group-exchange-sha256," \
+       "diffie-hellman-group-exchange-sha1," \
+       "diffie-hellman-group14-sha1," \
+       "diffie-hellman-group1-sha1"
+#endif
+
 #define        KEX_DEFAULT_PK_ALG      "ssh-rsa,ssh-dss"
 #define        KEX_DEFAULT_ENCRYPT \
        "aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc," \
index ad040e1392055be863fc4d8063075ee361cf8ac0..ffa5c898461ef1772948ef97f5d8aa02af79ad61 100644 (file)
@@ -20,6 +20,8 @@
 
 #include "includes.h"
 #ifndef HAVE_BASENAME
+#include <errno.h>
+#include <string.h>
 
 char *
 basename(const char *path)
index 8a3779f3aa91f6e8b7abd4bb39f2d91bbf556364..bdae8b637f47f26c49ca95ca04f961628b075723 100644 (file)
 
 #include "includes.h"
 
-RCSID("$Id$");
-
 #if !defined(HAVE_GETPEEREID)
 
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <unistd.h>
+
 #if defined(SO_PEERCRED)
 int
 getpeereid(int s, uid_t *euid, gid_t *gid)
index 8eb62b7a8b45923ded4206453922cb4aeb971aa0..9777eb556d2d80c96bd2b51bf18fc9551679aa08 100644 (file)
 #include "includes.h"
 #if !defined(HAVE_OPENPTY)
 
+#include <sys/types.h>
+
+#include <stdlib.h>
+
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif
+
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
 #ifdef HAVE_UTIL_H
 # include <util.h>
 #endif /* HAVE_UTIL_H */
 # include <sys/stropts.h>
 #endif
 
+#include <signal.h>
+#include <string.h>
+#include <unistd.h>
+
 #ifndef O_NOCTTY
 #define O_NOCTTY 0
 #endif
index a8a9dd7b3135c200795cee38b5ba9699912612db..b6ea3d21e3425c2a2a070e2ea006e1a562895fff 100644 (file)
 
 #include "includes.h"
 
-RCSID("$Id$");
+#include <stdlib.h>
+#include <string.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
 
 #ifndef HAVE_GETNAMEINFO
 int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, 
index 9a9f756a27e4f98b21dc8e7d7664e4684e43ce01..8431a42f802c6c1fcb9bff4d9c99d79458ef59d3 100644 (file)
 #define _FAKE_RFC2553_H
 
 #include "includes.h"
-#include "sys/types.h"
+#include <sys/types.h>
+#if defined(HAVE_NETDB_H)
+# include <netdb.h>
+#endif
 
 /*
  * First, socket and INET6 related definitions 
index bea6aea3b5bd90524b490299d2da98b62d1885fe..6c86e02c2ab0805dbe8c7629ba47bf3b0d9b0a96 100644 (file)
 
 #ifndef HAVE_GETRRSETBYNAME
 
+#include <stdlib.h>
+#include <string.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
 #include "getrrsetbyname.h"
 
 #if defined(HAVE_DECL_H_ERRNO) && !HAVE_DECL_H_ERRNO
@@ -60,6 +66,13 @@ extern int h_errno;
 # undef _THREAD_PRIVATE
 #endif
 #define _THREAD_PRIVATE(a,b,c) (c)
+
+/* to avoid conflicts where a platform already has _res */
+#ifdef _res
+# undef _res
+#endif
+#define _res   _compat_res
+
 struct __res_state _res;
 
 /* Necessary functions and macros */
index 81d8124e08246d26ed17fa36371959025b044210..b9fabf61f4f15f7d03be18d0817b9a2a734d7290 100644 (file)
  *
  */
 #include "includes.h"
+
+#include "xmalloc.h"
+#include "buffer.h"
+#include "key.h"
+#include "hostfile.h"
 #include "auth.h"
 #include "ssh.h"
 #include "log.h"
-#include "xmalloc.h"
-#include "buffer.h"
 
 #ifdef _AIX
 
+#include <errno.h>
+#if defined(HAVE_NETDB_H)
+# include <netdb.h>
+#endif
 #include <uinfo.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
 #include <sys/socket.h>
+
+#ifdef WITH_AIXAUTHENTICATE
+# include <login.h>
+# include <userpw.h>
+# if defined(HAVE_SYS_AUDIT_H) && defined(AIX_LOGINFAILED_4ARG)
+#  include <sys/audit.h>
+# endif
+# include <usersec.h>
+#endif
+
 #include "port-aix.h"
 
 # ifdef HAVE_SETAUTHDB
@@ -256,15 +276,17 @@ sys_auth_record_login(const char *user, const char *host, const char *ttynm,
     Buffer *loginmsg)
 {
        char *msg = NULL;
+       static int msg_done = 0;
        int success = 0;
 
        aix_setauthdb(user);
        if (loginsuccess((char *)user, (char *)host, (char *)ttynm, &msg) == 0) {
                success = 1;
-               if (msg != NULL) {
+               if (msg != NULL && loginmsg != NULL && !msg_done) {
                        debug("AIX/loginsuccess: msg %s", msg);
                        buffer_append(loginmsg, msg, strlen(msg));
                        xfree(msg);
+                       msg_done = 1;
                }
        }
        aix_restoreauthdb();
index 15bdcf5ecfa6a74cb28373fd1698e59cd7f2e933..eae82a9e0858549faec39a3021f16002e6fb1bb9 100644 (file)
 #ifdef HAVE_SYS_SOCKET_H
 # include <sys/socket.h>
 #endif
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>   /* for seteuid() */
-#endif
-
-#ifdef WITH_AIXAUTHENTICATE
-# include <login.h>
-# include <userpw.h>
-# if defined(HAVE_SYS_AUDIT_H) && defined(AIX_LOGINFAILED_4ARG)
-#  undef T_NULL
-#  include <sys/audit.h>
-# endif
-# include <usersec.h>
-#endif
 
 #include "buffer.h"
 
index aa6db1cf8c6153a3000e66445b7316f93ded3300..ba751a5383f3b8e7d8f6a9dc170465b7922c2a2f 100644 (file)
     defined(WITH_IRIX_JOBS) || \
     defined(WITH_IRIX_ARRAY)
 
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
 #ifdef WITH_IRIX_PROJECT
 # include <proj.h>
 #endif /* WITH_IRIX_PROJECT */
index 9afa0b9f268a77966e3437e3d097b1d83c6c52b6..14899321fe4869f40444a42f8beaaac19b69751b 100644 (file)
 
 #include "includes.h"
 
+#include <sys/types.h>
+#include <unistd.h>
+#include <pwd.h>
+
 # ifdef HAVE_CRYPT_H
 #  include <crypt.h>
 # endif
index d85303132b97c18cfb6752a7ed9f51dec044d8c1..4239d0e964e5f9f658bfeed13db524061426389d 100644 (file)
 
 #include "includes.h"
 
+#include <sys/types.h>
 #ifdef HAVE_SYS_MMAN_H
 #include <sys/mman.h>
 #endif
+#include <sys/stat.h>
+
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+#include <errno.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
 
 #include "log.h"
 
 void *xmmap(size_t size)
 {
+#ifdef HAVE_MMAP
        void *address;
 
-#ifdef HAVE_MMAP
 # ifdef MAP_ANON
        address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_ANON|MAP_SHARED,
            -1, (off_t)0);
index ee81f686e2a6d53025f520a1456cc886149b07e2..64970e8672da3f57df9a9bdc332efd0ad194b6bf 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: packet.c,v 1.145 2006/09/19 21:14:08 markus Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: packet.c,v 1.120 2005/10/30 08:52:17 djm Exp $");
-
+#include <sys/types.h>
 #include "openbsd-compat/sys-queue.h"
+#include <sys/param.h>
+#include <sys/socket.h>
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <arpa/inet.h>
+
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
 
 #include "xmalloc.h"
 #include "buffer.h"
 #include "packet.h"
-#include "bufaux.h"
 #include "crc32.h"
-#include "getput.h"
-
 #include "compress.h"
 #include "deattack.h"
 #include "channels.h"
-
 #include "compat.h"
 #include "ssh1.h"
 #include "ssh2.h"
-
 #include "cipher.h"
+#include "key.h"
 #include "kex.h"
 #include "mac.h"
 #include "log.h"
@@ -258,6 +273,7 @@ packet_get_keyiv_len(int mode)
 
        return (cipher_get_keyiv_len(cc));
 }
+
 void
 packet_set_iv(int mode, u_char *dat)
 {
@@ -270,6 +286,7 @@ packet_set_iv(int mode, u_char *dat)
 
        cipher_set_keyiv(cc, dat);
 }
+
 int
 packet_get_ssh1_cipher(void)
 {
@@ -471,31 +488,37 @@ packet_put_char(int value)
 
        buffer_append(&outgoing_packet, &ch, 1);
 }
+
 void
 packet_put_int(u_int value)
 {
        buffer_put_int(&outgoing_packet, value);
 }
+
 void
 packet_put_string(const void *buf, u_int len)
 {
        buffer_put_string(&outgoing_packet, buf, len);
 }
+
 void
 packet_put_cstring(const char *str)
 {
        buffer_put_cstring(&outgoing_packet, str);
 }
+
 void
 packet_put_raw(const void *buf, u_int len)
 {
        buffer_append(&outgoing_packet, buf, len);
 }
+
 void
 packet_put_bignum(BIGNUM * value)
 {
        buffer_put_bignum(&outgoing_packet, value);
 }
+
 void
 packet_put_bignum2(BIGNUM * value)
 {
@@ -549,7 +572,7 @@ packet_send1(void)
        /* Add check bytes. */
        checksum = ssh_crc32(buffer_ptr(&outgoing_packet),
            buffer_len(&outgoing_packet));
-       PUT_32BIT(buf, checksum);
+       put_u32(buf, checksum);
        buffer_append(&outgoing_packet, buf, 4);
 
 #ifdef PACKET_DEBUG
@@ -558,7 +581,7 @@ packet_send1(void)
 #endif
 
        /* Append to output. */
-       PUT_32BIT(buf, len);
+       put_u32(buf, len);
        buffer_append(&output, buf, 4);
        cp = buffer_append_space(&output, buffer_len(&outgoing_packet));
        cipher_crypt(&send_context, cp, buffer_ptr(&outgoing_packet),
@@ -654,7 +677,7 @@ set_newkeys(int mode)
 
 /*
  * Delayed compression for SSH2 is enabled after authentication:
- * This happans on the server side after a SSH2_MSG_USERAUTH_SUCCESS is sent,
+ * This happens on the server side after a SSH2_MSG_USERAUTH_SUCCESS is sent,
  * and on the client side after a SSH2_MSG_USERAUTH_SUCCESS is received.
  */
 static void
@@ -669,6 +692,9 @@ packet_enable_delayed_compress(void)
         */
        after_authentication = 1;
        for (mode = 0; mode < MODE_MAX; mode++) {
+               /* protocol error: USERAUTH_SUCCESS received before NEWKEYS */
+               if (newkeys[mode] == NULL)
+                       continue;
                comp = &newkeys[mode]->comp;
                if (comp && !comp->enabled && comp->type == COMP_DELAYED) {
                        packet_init_compression();
@@ -761,7 +787,7 @@ packet_send2_wrapped(void)
        /* packet_length includes payload, padding and padding length field */
        packet_length = buffer_len(&outgoing_packet) - 4;
        cp = buffer_ptr(&outgoing_packet);
-       PUT_32BIT(cp, packet_length);
+       put_u32(cp, packet_length);
        cp[4] = padlen;
        DBG(debug("send: len %d (includes padlen %d)", packet_length+4, padlen));
 
@@ -778,7 +804,7 @@ packet_send2_wrapped(void)
            buffer_len(&outgoing_packet));
        /* append unencrypted MAC */
        if (mac && mac->enabled)
-               buffer_append(&output, (char *)macbuf, mac->mac_len);
+               buffer_append(&output, macbuf, mac->mac_len);
 #ifdef PACKET_DEBUG
        fprintf(stderr, "encrypted: ");
        buffer_dump(&output);
@@ -868,7 +894,7 @@ packet_read_seqnr(u_int32_t *seqnr_p)
        char buf[8192];
        DBG(debug("packet_read()"));
 
-       setp = (fd_set *)xmalloc(howmany(connection_in+1, NFDBITS) *
+       setp = (fd_set *)xcalloc(howmany(connection_in+1, NFDBITS),
            sizeof(fd_mask));
 
        /* Since we are blocking, ensure that all written packets have been sent. */
@@ -959,7 +985,7 @@ packet_read_poll1(void)
                return SSH_MSG_NONE;
        /* Get length of incoming packet. */
        cp = buffer_ptr(&input);
-       len = GET_32BIT(cp);
+       len = get_u32(cp);
        if (len < 1 + 2 + 2 || len > 256 * 1024)
                packet_disconnect("Bad packet length %u.", len);
        padded_len = (len + 8) & ~7;
@@ -978,9 +1004,16 @@ packet_read_poll1(void)
         * (C)1998 CORE-SDI, Buenos Aires Argentina
         * Ariel Futoransky(futo@core-sdi.com)
         */
-       if (!receive_context.plaintext &&
-           detect_attack(buffer_ptr(&input), padded_len, NULL) == DEATTACK_DETECTED)
-               packet_disconnect("crc32 compensation attack: network attack detected");
+       if (!receive_context.plaintext) {
+               switch (detect_attack(buffer_ptr(&input), padded_len)) {
+               case DEATTACK_DETECTED:
+                       packet_disconnect("crc32 compensation attack: "
+                           "network attack detected");
+               case DEATTACK_DOS_DETECTED:
+                       packet_disconnect("deattack denial of "
+                           "service detected");
+               }
+       }
 
        /* Decrypt data to incoming_packet. */
        buffer_clear(&incoming_packet);
@@ -1007,7 +1040,7 @@ packet_read_poll1(void)
                    len, buffer_len(&incoming_packet));
 
        cp = (u_char *)buffer_ptr(&incoming_packet) + len - 4;
-       stored_checksum = GET_32BIT(cp);
+       stored_checksum = get_u32(cp);
        if (checksum != stored_checksum)
                packet_disconnect("Corrupted check bytes on input.");
        buffer_consume_end(&incoming_packet, 4);
@@ -1056,7 +1089,7 @@ packet_read_poll2(u_int32_t *seqnr_p)
                cipher_crypt(&receive_context, cp, buffer_ptr(&input),
                    block_size);
                cp = buffer_ptr(&incoming_packet);
-               packet_length = GET_32BIT(cp);
+               packet_length = get_u32(cp);
                if (packet_length < 1 + 4 || packet_length > 256 * 1024) {
 #ifdef PACKET_DEBUG
                        buffer_dump(&incoming_packet);
@@ -1187,7 +1220,6 @@ packet_read_poll_seqnr(u_int32_t *seqnr_p)
                                break;
                        default:
                                return type;
-                               break;
                        }
                } else {
                        type = packet_read_poll1();
@@ -1210,7 +1242,6 @@ packet_read_poll_seqnr(u_int32_t *seqnr_p)
                                if (type)
                                        DBG(debug("received packet type %d", type));
                                return type;
-                               break;
                        }
                }
        }
@@ -1412,7 +1443,7 @@ packet_write_wait(void)
 {
        fd_set *setp;
 
-       setp = (fd_set *)xmalloc(howmany(connection_out + 1, NFDBITS) *
+       setp = (fd_set *)xcalloc(howmany(connection_out + 1, NFDBITS),
            sizeof(fd_mask));
        packet_write_poll();
        while (packet_have_data_to_write()) {
@@ -1480,8 +1511,7 @@ packet_set_interactive(int interactive)
        /* Only set socket options if using a socket.  */
        if (!packet_connection_is_on_socket())
                return;
-       if (interactive)
-               set_nodelay(connection_in);
+       set_nodelay(connection_in);
        packet_set_tos(interactive);
 }
 
@@ -1542,7 +1572,7 @@ packet_send_ignore(int nbytes)
        for (i = 0; i < nbytes; i++) {
                if (i % 4 == 0)
                        rnd = arc4random();
-               packet_put_char(rnd & 0xff);
+               packet_put_char((u_char)rnd & 0xff);
                rnd >>= 8;
        }
 }
index 3b711cdf61ef9691894f04cb508a5a72752ac2d3..6e5cc079e59e85ec34769dcc7c4010807ee3a9da 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: packet.h,v 1.43 2005/07/25 11:59:40 markus Exp $      */
+/* $OpenBSD: packet.h,v 1.45 2006/03/25 22:22:43 djm Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -16,6 +16,8 @@
 #ifndef PACKET_H
 #define PACKET_H
 
+#include <termios.h>
+
 #include <openssl/bn.h>
 
 void
index 13c51d87ef703dd0d1afeb11618d699b4680672a..0f95222d24874f760eb14227fdc772cbb7927b8a 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: progressmeter.c,v 1.37 2006/08/03 03:34:42 deraadt Exp $ */
 /*
  * Copyright (c) 2003 Nils Nordman.  All rights reserved.
  *
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: progressmeter.c,v 1.24 2005/06/07 13:25:23 jaredy Exp $");
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/uio.h>
+
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
 
 #include "progressmeter.h"
 #include "atomicio.h"
@@ -154,7 +165,7 @@ refresh_progress_meter(void)
                        len = 0;
                if (len >= file_len + 1)
                        len = file_len;
-               for (i = len;  i < file_len; i++ )
+               for (i = len; i < file_len; i++)
                        buf[i] = ' ';
                buf[file_len] = '\0';
        }
@@ -215,6 +226,7 @@ refresh_progress_meter(void)
        last_update = now;
 }
 
+/*ARGSUSED*/
 static void
 update_progress_meter(int ignore)
 {
@@ -269,6 +281,7 @@ stop_progress_meter(void)
        atomicio(vwrite, STDOUT_FILENO, "\n", 1);
 }
 
+/*ARGSUSED*/
 static void
 sig_winch(int sig)
 {
index bfb9a0b770fd81a802fee0feac4fe27e4986770c..10bab99ba4c7bc3d3b12d307392ded5629b33a1f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: progressmeter.h,v 1.1 2003/01/10 08:19:07 fgsch Exp $ */
+/* $OpenBSD: progressmeter.h,v 1.2 2006/03/25 22:22:43 djm Exp $ */
 /*
  * Copyright (c) 2002 Nils Nordman.  All rights reserved.
  *
index c5b0b8eef706f19c798474af6ad745967decc17f..c256c2d03672f5b548b803468502bd2e70008e17 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: readconf.c,v 1.159 2006/08/03 03:34:42 deraadt Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: readconf.c,v 1.145 2005/12/08 18:34:11 reyk Exp $");
 
-#include "ssh.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <netdb.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
 #include "xmalloc.h"
+#include "ssh.h"
 #include "compat.h"
 #include "cipher.h"
 #include "pathnames.h"
 #include "log.h"
+#include "key.h"
 #include "readconf.h"
 #include "match.h"
 #include "misc.h"
+#include "buffer.h"
 #include "kex.h"
 #include "mac.h"
 
@@ -94,6 +111,7 @@ RCSID("$OpenBSD: readconf.c,v 1.145 2005/12/08 18:34:11 reyk Exp $");
 typedef enum {
        oBadOption,
        oForwardAgent, oForwardX11, oForwardX11Trusted, oGatewayPorts,
+       oExitOnForwardFailure,
        oPasswordAuthentication, oRSAAuthentication,
        oChallengeResponseAuthentication, oXAuthLocation,
        oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
@@ -128,6 +146,7 @@ static struct {
        { "forwardagent", oForwardAgent },
        { "forwardx11", oForwardX11 },
        { "forwardx11trusted", oForwardX11Trusted },
+       { "exitonforwardfailure", oExitOnForwardFailure },
        { "xauthlocation", oXAuthLocation },
        { "gatewayports", oGatewayPorts },
        { "useprivilegedport", oUsePrivilegedPort },
@@ -320,7 +339,8 @@ process_config_line(Options *options, const char *host,
                    int *activep)
 {
        char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256];
-       int opcode, *intptr, value, value2;
+       int opcode, *intptr, value, value2, scale;
+       long long orig, val64;
        size_t len;
        Forward fwd;
 
@@ -333,7 +353,8 @@ process_config_line(Options *options, const char *host,
 
        s = line;
        /* Get the keyword. (Each line is supposed to begin with a keyword). */
-       keyword = strdelim(&s);
+       if ((keyword = strdelim(&s)) == NULL)
+               return 0;
        /* Ignore leading whitespace. */
        if (*keyword == '\0')
                keyword = strdelim(&s);
@@ -390,6 +411,10 @@ parse_flag:
                intptr = &options->gateway_ports;
                goto parse_flag;
 
+       case oExitOnForwardFailure:
+               intptr = &options->exit_on_forward_failure;
+               goto parse_flag;
+
        case oUsePrivilegedPort:
                intptr = &options->use_privileged_port;
                goto parse_flag;
@@ -522,22 +547,36 @@ parse_yesnoask:
                        fatal("%.200s line %d: Missing argument.", filename, linenum);
                if (arg[0] < '0' || arg[0] > '9')
                        fatal("%.200s line %d: Bad number.", filename, linenum);
-               value = strtol(arg, &endofnumber, 10);
+               orig = val64 = strtoll(arg, &endofnumber, 10);
                if (arg == endofnumber)
                        fatal("%.200s line %d: Bad number.", filename, linenum);
                switch (toupper(*endofnumber)) {
+               case '\0':
+                       scale = 1;
+                       break;
                case 'K':
-                       value *= 1<<10;
+                       scale = 1<<10;
                        break;
                case 'M':
-                       value *= 1<<20;
+                       scale = 1<<20;
                        break;
                case 'G':
-                       value *= 1<<30;
+                       scale = 1<<30;
                        break;
+               default:
+                       fatal("%.200s line %d: Invalid RekeyLimit suffix",
+                           filename, linenum);
                }
+               val64 *= scale;
+               /* detect integer wrap and too-large limits */
+               if ((val64 / scale) != orig || val64 > INT_MAX)
+                       fatal("%.200s line %d: RekeyLimit too large",
+                           filename, linenum);
+               if (val64 < 16)
+                       fatal("%.200s line %d: RekeyLimit too small",
+                           filename, linenum);
                if (*activep && *intptr == -1)
-                       *intptr = value;
+                       *intptr = (int)val64;
                break;
 
        case oIdentityFile:
@@ -1010,6 +1049,7 @@ initialize_options(Options * options)
        options->forward_agent = -1;
        options->forward_x11 = -1;
        options->forward_x11_trusted = -1;
+       options->exit_on_forward_failure = -1;
        options->xauth_location = NULL;
        options->gateway_ports = -1;
        options->use_privileged_port = -1;
@@ -1098,6 +1138,8 @@ fill_default_options(Options * options)
                options->forward_x11 = 0;
        if (options->forward_x11_trusted == -1)
                options->forward_x11_trusted = 0;
+       if (options->exit_on_forward_failure == -1)
+               options->exit_on_forward_failure = 0;
        if (options->xauth_location == NULL)
                options->xauth_location = _PATH_XAUTH;
        if (options->gateway_ports == -1)
index 02486195bef4c4c16e86f74453dd7546093247f9..0a6304c680111c2cbeb45454e97d5660395536a3 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: readconf.h,v 1.68 2005/12/06 22:38:27 reyk Exp $      */
+/* $OpenBSD: readconf.h,v 1.71 2006/08/03 03:34:42 deraadt Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -16,8 +16,6 @@
 #ifndef READCONF_H
 #define READCONF_H
 
-#include "key.h"
-
 /* Data structure for representing a forwarding request. */
 
 typedef struct {
@@ -34,6 +32,7 @@ typedef struct {
        int     forward_agent;  /* Forward authentication agent. */
        int     forward_x11;    /* Forward X11 display. */
        int     forward_x11_trusted;    /* Trust Forward X11 display. */
+       int     exit_on_forward_failure;        /* Exit if bind(2) fails for -L/-R */
        char   *xauth_location; /* Location for xauth program */
        int     gateway_ports;  /* Allow remote connects to forwarded ports. */
        int     use_privileged_port;    /* Don't use privileged port if false. */
index dd2c28df250c13cd4b5f9a8c145341d010ef9f2e..4751ea295ff2fb6a00e7c08fa459bb5fd4a91817 100644 (file)
 #include "includes.h"
 #if defined(SMARTCARD) && defined(USE_OPENSC)
 
+#include <sys/types.h>
+
 #include <openssl/evp.h>
 #include <openssl/x509.h>
 
+#include <stdarg.h>
+
 #include <opensc/opensc.h>
 #include <opensc/pkcs15.h>
 
@@ -455,7 +459,9 @@ sc_get_keys(const char *id, const char *pin)
                }
                key_count = r;
        }
-       keys = xmalloc(sizeof(Key *) * (key_count*2+1));
+       if (key_count > 1024)
+               fatal("Too many keys (%u), expected <= 1024", key_count);
+       keys = xcalloc(key_count * 2 + 1, sizeof(Key *));
        for (i = 0; i < key_count; i++) {
                sc_pkcs15_object_t *tmp_obj = NULL;
                cert_id = ((sc_pkcs15_cert_info_t *)(certs[i]->data))->id;
diff --git a/openssh/scard/Ssh.bin b/openssh/scard/Ssh.bin
new file mode 100644 (file)
index 0000000..edbadc6
Binary files /dev/null and b/openssh/scard/Ssh.bin differ
index 6e81062ee3c8ad17d6c6f2181875407cc3dc5112..6c9dd4d41098a4cc76402d98ce49f5078c91a2bb 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: scp.c,v 1.155 2006/08/03 03:34:42 deraadt Exp $ */
 /*
  * scp - secure remote copy.  This is basically patched BSD rcp which
  * uses ssh to do the data transfer (instead of using rcmd).
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: scp.c,v 1.130 2006/01/31 10:35:43 djm Exp $");
+
+#include <sys/types.h>
+#include <sys/param.h>
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+#include <sys/wait.h>
+#include <sys/uio.h>
+
+#include <ctype.h>
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
 
 #include "xmalloc.h"
 #include "atomicio.h"
@@ -82,6 +106,8 @@ RCSID("$OpenBSD: scp.c,v 1.130 2006/01/31 10:35:43 djm Exp $");
 
 extern char *__progname;
 
+int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout);
+
 void bwlimit(int);
 
 /* Struct for addargs */
@@ -167,7 +193,7 @@ do_local_cmd(arglist *a)
  */
 
 int
-do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc)
+do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout)
 {
        int pin[2], pout[2], reserved[2];
 
@@ -181,7 +207,8 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc)
         * Reserve two descriptors so that the real pipes won't get
         * descriptors 0 and 1 because that will screw up dup2 below.
         */
-       pipe(reserved);
+       if (pipe(reserved) < 0)
+               fatal("pipe: %s", strerror(errno));
 
        /* Create a socket pair for communicating with ssh. */
        if (pipe(pin) < 0)
@@ -234,7 +261,6 @@ typedef struct {
 
 BUF *allocbuf(BUF *, int, int);
 void lostconn(int);
-void nospace(void);
 int okname(char *);
 void run_err(const char *,...);
 void verifydir(char *);
@@ -258,15 +284,21 @@ void usage(void);
 int
 main(int argc, char **argv)
 {
-       int ch, fflag, tflag, status;
+       int ch, fflag, tflag, status, n;
        double speed;
-       char *targ, *endp;
+       char *targ, *endp, **newargv;
        extern char *optarg;
        extern int optind;
 
        /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
        sanitise_stdfd();
 
+       /* Copy argv, because we modify it */
+       newargv = xcalloc(MAX(argc + 1, 1), sizeof(*newargv));
+       for (n = 0; n < argc; n++)
+               newargv[n] = xstrdup(argv[n]);
+       argv = newargv;
+
        __progname = ssh_get_progname(argv[0]);
 
        memset(&args, '\0', sizeof(args));
@@ -413,9 +445,9 @@ main(int argc, char **argv)
 void
 toremote(char *targ, int argc, char **argv)
 {
-       int i, len;
        char *bp, *host, *src, *suser, *thost, *tuser, *arg;
        arglist alist;
+       int i;
 
        memset(&alist, '\0', sizeof(alist));
        alist.list = NULL;
@@ -480,12 +512,10 @@ toremote(char *targ, int argc, char **argv)
                                errs = 1;
                } else {        /* local to remote */
                        if (remin == -1) {
-                               len = strlen(targ) + CMDNEEDS + 20;
-                               bp = xmalloc(len);
-                               (void) snprintf(bp, len, "%s -t %s", cmd, targ);
+                               xasprintf(&bp, "%s -t %s", cmd, targ);
                                host = cleanhostname(thost);
                                if (do_cmd(host, tuser, bp, &remin,
-                                   &remout, argc) < 0)
+                                   &remout) < 0)
                                        exit(1);
                                if (response() < 0)
                                        exit(1);
@@ -494,14 +524,15 @@ toremote(char *targ, int argc, char **argv)
                        source(1, argv + i);
                }
        }
+       xfree(arg);
 }
 
 void
 tolocal(int argc, char **argv)
 {
-       int i, len;
        char *bp, *host, *src, *suser;
        arglist alist;
+       int i;
 
        memset(&alist, '\0', sizeof(alist));
        alist.list = NULL;
@@ -533,10 +564,8 @@ tolocal(int argc, char **argv)
                                suser = pwd->pw_name;
                }
                host = cleanhostname(host);
-               len = strlen(src) + CMDNEEDS + 20;
-               bp = xmalloc(len);
-               (void) snprintf(bp, len, "%s -f %s", cmd, src);
-               if (do_cmd(host, suser, bp, &remin, &remout, argc) < 0) {
+               xasprintf(&bp, "%s -f %s", cmd, src);
+               if (do_cmd(host, suser, bp, &remin, &remout) < 0) {
                        (void) xfree(bp);
                        ++errs;
                        continue;
@@ -781,7 +810,8 @@ sink(int argc, char **argv)
        BUF *bp;
        off_t i;
        size_t j, count;
-       int amt, exists, first, mask, mode, ofd, omode;
+       int amt, exists, first, ofd;
+       mode_t mode, omode, mask;
        off_t size, statbytes;
        int setimes, targisdir, wrerrno = 0;
        char ch, *cp, *np, *targ, *why, *vect[1], buf[16384];
@@ -1101,15 +1131,15 @@ run_err(const char *fmt,...)
        va_list ap;
 
        ++errs;
-       if (fp == NULL && !(fp = fdopen(remout, "w")))
-               return;
-       (void) fprintf(fp, "%c", 0x01);
-       (void) fprintf(fp, "scp: ");
-       va_start(ap, fmt);
-       (void) vfprintf(fp, fmt, ap);
-       va_end(ap);
-       (void) fprintf(fp, "\n");
-       (void) fflush(fp);
+       if (fp != NULL || (remout != -1 && (fp = fdopen(remout, "w")))) {
+               (void) fprintf(fp, "%c", 0x01);
+               (void) fprintf(fp, "scp: ");
+               va_start(ap, fmt);
+               (void) vfprintf(fp, fmt, ap);
+               va_end(ap);
+               (void) fprintf(fp, "\n");
+               (void) fflush(fp);
+       }
 
        if (!iamremote) {
                va_start(ap, fmt);
@@ -1185,7 +1215,7 @@ allocbuf(BUF *bp, int fd, int blksize)
        if (bp->buf == NULL)
                bp->buf = xmalloc(size);
        else
-               bp->buf = xrealloc(bp->buf, size);
+               bp->buf = xrealloc(bp->buf, 1, size);
        memset(bp->buf, 0, size);
        bp->cnt = size;
        return (bp);
index 9442a565a513d95d3303f7200cebbefda7240821..9ddbe9af203ce494e511721138a59535bfd4b6f6 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: servconf.c,v 1.165 2006/08/14 12:40:25 dtucker Exp $ */
 /*
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  *                    All rights reserved
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: servconf.c,v 1.146 2005/12/08 18:34:11 reyk Exp $");
 
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netdb.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+#include <stdarg.h>
+
+#include "xmalloc.h"
 #include "ssh.h"
 #include "log.h"
+#include "buffer.h"
 #include "servconf.h"
-#include "xmalloc.h"
 #include "compat.h"
 #include "pathnames.h"
 #include "misc.h"
 #include "cipher.h"
+#include "key.h"
 #include "kex.h"
 #include "mac.h"
+#include "match.h"
+#include "channels.h"
+#include "groupaccess.h"
 
 static void add_listen_addr(ServerOptions *, char *, u_short);
 static void add_one_listen_addr(ServerOptions *, char *, u_short);
 
 /* Use of privilege separation or not */
 extern int use_privsep;
+extern Buffer cfg;
 
 /* Initializes the server options to their default values. */
 
@@ -109,13 +127,13 @@ initialize_server_options(ServerOptions *options)
        options->authorized_keys_file2 = NULL;
        options->num_accept_env = 0;
        options->permit_tun = -1;
-        options->none_enabled = -1;
-        options->tcp_rcv_buf_poll = -1;
+       options->num_permitted_opens = -1;
+       options->adm_forced_command = NULL;
+
+    options->none_enabled = -1;
+    options->tcp_rcv_buf_poll = -1;
        options->hpn_disabled = -1;
        options->hpn_buffer_size = -1;
-
-       /* Needs to be accessable in many places */
-       use_privsep = -1;
 }
 
 void
@@ -311,125 +329,131 @@ typedef enum {
        sGssKeyEx, 
        sGsiAllowLimitedProxy,
        sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
-       sUsePrivilegeSeparation, sNoneEnabled, sTcpRcvBufPoll, 
+       sMatch, sPermitOpen, sForceCommand,
+       sUsePrivilegeSeparation,
+    sNoneEnabled, sTcpRcvBufPoll, 
        sHPNDisabled, sHPNBufferSize,
        sDeprecated, sUnsupported
 } ServerOpCodes;
 
+#define SSHCFG_GLOBAL  0x01    /* allowed in main section of sshd_config */
+#define SSHCFG_MATCH   0x02    /* allowed inside a Match section */
+#define SSHCFG_ALL     (SSHCFG_GLOBAL|SSHCFG_MATCH)
+
 /* Textual representation of the tokens. */
 static struct {
        const char *name;
        ServerOpCodes opcode;
+       u_int flags;
 } keywords[] = {
        /* Portable-specific options */
 #ifdef USE_PAM
-       { "usepam", sUsePAM },
+       { "usepam", sUsePAM, SSHCFG_GLOBAL },
 #else
-       { "usepam", sUnsupported },
+       { "usepam", sUnsupported, SSHCFG_GLOBAL },
 #endif
-       { "pamauthenticationviakbdint", sDeprecated },
+       { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
        /* Standard Options */
-       { "port", sPort },
-       { "hostkey", sHostKeyFile },
-       { "hostdsakey", sHostKeyFile },                                 /* alias */
-       { "pidfile", sPidFile },
-       { "serverkeybits", sServerKeyBits },
-       { "logingracetime", sLoginGraceTime },
-       { "keyregenerationinterval", sKeyRegenerationTime },
-       { "permitrootlogin", sPermitRootLogin },
-       { "syslogfacility", sLogFacility },
-       { "loglevel", sLogLevel },
-       { "rhostsauthentication", sDeprecated },
-       { "rhostsrsaauthentication", sRhostsRSAAuthentication },
-       { "hostbasedauthentication", sHostbasedAuthentication },
-       { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
-       { "rsaauthentication", sRSAAuthentication },
-       { "pubkeyauthentication", sPubkeyAuthentication },
-       { "dsaauthentication", sPubkeyAuthentication },                 /* alias */
+       { "port", sPort, SSHCFG_GLOBAL },
+       { "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
+       { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL },          /* alias */
+       { "pidfile", sPidFile, SSHCFG_GLOBAL },
+       { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
+       { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
+       { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
+       { "permitrootlogin", sPermitRootLogin, SSHCFG_GLOBAL },
+       { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
+       { "loglevel", sLogLevel, SSHCFG_GLOBAL },
+       { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
+       { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_GLOBAL },
+       { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_GLOBAL },
+       { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_GLOBAL },
+       { "rsaauthentication", sRSAAuthentication, SSHCFG_GLOBAL },
+       { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL },
+       { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL },  /* alias */
 #ifdef KRB5
-       { "kerberosauthentication", sKerberosAuthentication },
-       { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
-       { "kerberosticketcleanup", sKerberosTicketCleanup },
+       { "kerberosauthentication", sKerberosAuthentication, SSHCFG_GLOBAL },
+       { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
+       { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
 #ifdef USE_AFS
-       { "kerberosgetafstoken", sKerberosGetAFSToken },
+       { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
 #else
-       { "kerberosgetafstoken", sUnsupported },
+       { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
 #endif
 #else
-       { "kerberosauthentication", sUnsupported },
-       { "kerberosorlocalpasswd", sUnsupported },
-       { "kerberosticketcleanup", sUnsupported },
-       { "kerberosgetafstoken", sUnsupported },
+       { "kerberosauthentication", sUnsupported, SSHCFG_GLOBAL },
+       { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
+       { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
+       { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
 #endif
-       { "kerberostgtpassing", sUnsupported },
-       { "afstokenpassing", sUnsupported },
+       { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
+       { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
 #ifdef GSSAPI
-       { "gssapiauthentication", sGssAuthentication },
-       { "gssapikeyexchange", sGssKeyEx },
-       { "gssapicleanupcredentials", sGssCleanupCreds },
+       { "gssapiauthentication", sGssAuthentication, SSHCFG_GLOBAL },
+       { "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL },
+       { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
 #ifdef GSI
-       { "gsiallowlimitedproxy", sGsiAllowLimitedProxy },
+       { "gsiallowlimitedproxy", sGsiAllowLimitedProxy, SSHCFG_GLOBAL },
 #endif
 #else
-       { "gssapiauthentication", sUnsupported },
-       { "gssapikeyexchange", sUnsupported },
-       { "gssapicleanupcredentials", sUnsupported },
+       { "gssapiauthentication", sUnsupported, SSHCFG_GLOBAL },
+       { "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL },
+       { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
 #endif
 #ifdef SESSION_HOOKS
-        { "allowsessionhooks", sAllowSessionHooks },
-        { "sessionhookstartupcmd", sSessionHookStartupCmd },
-        { "sessionhookshutdowncmd", sSessionHookShutdownCmd },
+    { "allowsessionhooks", sAllowSessionHooks, SSHCFG_GLOBAL },
+    { "sessionhookstartupcmd", sSessionHookStartupCmd, SSHCFG_GLOBAL },
+    { "sessionhookshutdowncmd", sSessionHookShutdownCmd, SSHCFG_GLOBAL },
 #endif        
-       { "passwordauthentication", sPasswordAuthentication },
-       { "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
-       { "challengeresponseauthentication", sChallengeResponseAuthentication },
-       { "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
-       { "checkmail", sDeprecated },
-       { "listenaddress", sListenAddress },
-       { "addressfamily", sAddressFamily },
-       { "printmotd", sPrintMotd },
-       { "printlastlog", sPrintLastLog },
-       { "ignorerhosts", sIgnoreRhosts },
-       { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
-       { "x11forwarding", sX11Forwarding },
-       { "x11displayoffset", sX11DisplayOffset },
-       { "x11uselocalhost", sX11UseLocalhost },
-       { "xauthlocation", sXAuthLocation },
-       { "strictmodes", sStrictModes },
-       { "permitemptypasswords", sEmptyPasswd },
-       { "permituserenvironment", sPermitUserEnvironment },
-       { "uselogin", sUseLogin },
-       { "compression", sCompression },
-       { "tcpkeepalive", sTCPKeepAlive },
-       { "keepalive", sTCPKeepAlive },                         /* obsolete alias */
-       { "allowtcpforwarding", sAllowTcpForwarding },
-       { "allowusers", sAllowUsers },
-       { "denyusers", sDenyUsers },
-       { "allowgroups", sAllowGroups },
-       { "denygroups", sDenyGroups },
-       { "ciphers", sCiphers },
-       { "macs", sMacs },
-       { "protocol", sProtocol },
-       { "gatewayports", sGatewayPorts },
-       { "subsystem", sSubsystem },
-       { "maxstartups", sMaxStartups },
-       { "maxauthtries", sMaxAuthTries },
-       { "banner", sBanner },
-       { "usedns", sUseDNS },
-       { "verifyreversemapping", sDeprecated },
-       { "reversemappingcheck", sDeprecated },
-       { "clientaliveinterval", sClientAliveInterval },
-       { "clientalivecountmax", sClientAliveCountMax },
-       { "authorizedkeysfile", sAuthorizedKeysFile },
-       { "authorizedkeysfile2", sAuthorizedKeysFile2 },
-       { "useprivilegeseparation", sUsePrivilegeSeparation},
-       { "acceptenv", sAcceptEnv },
-       { "noneenabled", sNoneEnabled },
-       { "hpndisabled", sHPNDisabled },
-       { "hpnbuffersize", sHPNBufferSize },
-       { "tcprcvbufpoll", sTcpRcvBufPoll },
-       { "permittunnel", sPermitTunnel },
-       { NULL, sBadOption }
+       { "passwordauthentication", sPasswordAuthentication, SSHCFG_GLOBAL },
+       { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_GLOBAL },
+       { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
+       { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
+       { "checkmail", sDeprecated, SSHCFG_GLOBAL },
+       { "listenaddress", sListenAddress, SSHCFG_GLOBAL },
+       { "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
+       { "printmotd", sPrintMotd, SSHCFG_GLOBAL },
+       { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
+       { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
+       { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
+       { "x11forwarding", sX11Forwarding, SSHCFG_ALL },
+       { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
+       { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
+       { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
+       { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
+       { "permitemptypasswords", sEmptyPasswd, SSHCFG_GLOBAL },
+       { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
+       { "uselogin", sUseLogin, SSHCFG_GLOBAL },
+       { "compression", sCompression, SSHCFG_GLOBAL },
+       { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
+       { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL },  /* obsolete alias */
+       { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
+       { "allowusers", sAllowUsers, SSHCFG_GLOBAL },
+       { "denyusers", sDenyUsers, SSHCFG_GLOBAL },
+       { "allowgroups", sAllowGroups, SSHCFG_GLOBAL },
+       { "denygroups", sDenyGroups, SSHCFG_GLOBAL },
+       { "ciphers", sCiphers, SSHCFG_GLOBAL },
+       { "macs", sMacs, SSHCFG_GLOBAL },
+       { "protocol", sProtocol, SSHCFG_GLOBAL },
+       { "gatewayports", sGatewayPorts, SSHCFG_ALL },
+       { "subsystem", sSubsystem, SSHCFG_GLOBAL },
+       { "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
+       { "maxauthtries", sMaxAuthTries, SSHCFG_GLOBAL },
+       { "banner", sBanner, SSHCFG_GLOBAL },
+       { "usedns", sUseDNS, SSHCFG_GLOBAL },
+       { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
+       { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
+       { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
+       { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
+       { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
+       { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
+       { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
+       { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
+       { "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
+       { "match", sMatch, SSHCFG_ALL },
+       { "permitopen", sPermitOpen, SSHCFG_ALL },
+       { "forcecommand", sForceCommand, SSHCFG_ALL },
+       { NULL, sBadOption, 0 }
 };
 
 /*
@@ -438,14 +462,16 @@ static struct {
 
 static ServerOpCodes
 parse_token(const char *cp, const char *filename,
-           int linenum)
+           int linenum, u_int *flags)
 {
        u_int i;
 
        for (i = 0; keywords[i].name; i++)
-               if (strcasecmp(cp, keywords[i].name) == 0){
-                       debug ("TOKEN IS %s", keywords[i].name);
-                       return keywords[i].opcode;}
+               if (strcasecmp(cp, keywords[i].name) == 0) {
+                       *flags = keywords[i].flags;
+                       return keywords[i].opcode;
+               }
+
        error("%s: line %d: Bad configuration option: %s",
            filename, linenum, cp);
        return sBadOption;
@@ -489,18 +515,171 @@ add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
        options->listen_addrs = aitop;
 }
 
+/*
+ * The strategy for the Match blocks is that the config file is parsed twice.
+ *
+ * The first time is at startup.  activep is initialized to 1 and the
+ * directives in the global context are processed and acted on.  Hitting a
+ * Match directive unsets activep and the directives inside the block are
+ * checked for syntax only.
+ *
+ * The second time is after a connection has been established but before
+ * authentication.  activep is initialized to 2 and global config directives
+ * are ignored since they have already been processed.  If the criteria in a
+ * Match block is met, activep is set and the subsequent directives
+ * processed and actioned until EOF or another Match block unsets it.  Any
+ * options set are copied into the main server config.
+ *
+ * Potential additions/improvements:
+ *  - Add Match support for pre-kex directives, eg Protocol, Ciphers.
+ *
+ *  - Add a Tag directive (idea from David Leonard) ala pf, eg:
+ *     Match Address 192.168.0.*
+ *             Tag trusted
+ *     Match Group wheel
+ *             Tag trusted
+ *     Match Tag trusted
+ *             AllowTcpForwarding yes
+ *             GatewayPorts clientspecified
+ *             [...]
+ *
+ *  - Add a PermittedChannelRequests directive
+ *     Match Group shell
+ *             PermittedChannelRequests session,forwarded-tcpip
+ */
+
+static int
+match_cfg_line_group(const char *grps, int line, const char *user)
+{
+       int result = 0;
+       u_int ngrps = 0;
+       char *arg, *p, *cp, *grplist[MAX_MATCH_GROUPS];
+       struct passwd *pw;
+
+       /*
+        * Even if we do not have a user yet, we still need to check for
+        * valid syntax.
+        */
+       arg = cp = xstrdup(grps);
+       while ((p = strsep(&cp, ",")) != NULL && *p != '\0') {
+               if (ngrps >= MAX_MATCH_GROUPS) {
+                       error("line %d: too many groups in Match Group", line);
+                       result = -1;
+                       goto out;
+               }
+               grplist[ngrps++] = p;
+       }
+
+       if (user == NULL)
+               goto out;
+
+       if ((pw = getpwnam(user)) == NULL) {
+               debug("Can't match group at line %d because user %.100s does "
+                   "not exist", line, user);
+       } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
+               debug("Can't Match group because user %.100s not in any group "
+                   "at line %d", user, line);
+       } else if (ga_match(grplist, ngrps) != 1) {
+               debug("user %.100s does not match group %.100s at line %d",
+                   user, arg, line);
+       } else {
+               debug("user %.100s matched group %.100s at line %d", user,
+                   arg, line);
+               result = 1;
+       }
+out:
+       ga_free();
+       xfree(arg);
+       return result;
+}
+
+static int
+match_cfg_line(char **condition, int line, const char *user, const char *host,
+    const char *address)
+{
+       int result = 1;
+       char *arg, *attrib, *cp = *condition;
+       size_t len;
+
+       if (user == NULL)
+               debug3("checking syntax for 'Match %s'", cp);
+       else
+               debug3("checking match for '%s' user %s host %s addr %s", cp,
+                   user ? user : "(null)", host ? host : "(null)",
+                   address ? address : "(null)");
+
+       while ((attrib = strdelim(&cp)) && *attrib != '\0') {
+               if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
+                       error("Missing Match criteria for %s", attrib);
+                       return -1;
+               }
+               len = strlen(arg);
+               if (strcasecmp(attrib, "user") == 0) {
+                       if (!user) {
+                               result = 0;
+                               continue;
+                       }
+                       if (match_pattern_list(user, arg, len, 0) != 1)
+                               result = 0;
+                       else
+                               debug("user %.100s matched 'User %.100s' at "
+                                   "line %d", user, arg, line);
+               } else if (strcasecmp(attrib, "group") == 0) {
+                       switch (match_cfg_line_group(arg, line, user)) {
+                       case -1:
+                               return -1;
+                       case 0:
+                               result = 0;
+                       }
+               } else if (strcasecmp(attrib, "host") == 0) {
+                       if (!host) {
+                               result = 0;
+                               continue;
+                       }
+                       if (match_hostname(host, arg, len) != 1)
+                               result = 0;
+                       else
+                               debug("connection from %.100s matched 'Host "
+                                   "%.100s' at line %d", host, arg, line);
+               } else if (strcasecmp(attrib, "address") == 0) {
+                       debug("address '%s' arg '%s'", address, arg);
+                       if (!address) {
+                               result = 0;
+                               continue;
+                       }
+                       if (match_hostname(address, arg, len) != 1)
+                               result = 0;
+                       else
+                               debug("connection from %.100s matched 'Address "
+                                   "%.100s' at line %d", address, arg, line);
+               } else {
+                       error("Unsupported Match attribute %s", attrib);
+                       return -1;
+               }
+       }
+       if (user != NULL)
+               debug3("match %sfound", result ? "" : "not ");
+       *condition = cp;
+       return result;
+}
+
+#define WHITESPACE " \t\r\n"
+
 int
 process_server_config_line(ServerOptions *options, char *line,
-    const char *filename, int linenum)
+    const char *filename, int linenum, int *activep, const char *user,
+    const char *host, const char *address)
 {
        char *cp, **charptr, *arg, *p;
-       int *intptr, value, n;
+       int cmdline = 0, *intptr, value, n;
        ServerOpCodes opcode;
        u_short port;
-       u_int i;
+       u_int i, flags = 0;
+       size_t len;
 
        cp = line;
-       arg = strdelim(&cp);
+       if ((arg = strdelim(&cp)) == NULL)
+               return 0;
        /* Ignore leading whitespace */
        if (*arg == '\0')
                arg = strdelim(&cp);
@@ -508,7 +687,24 @@ process_server_config_line(ServerOptions *options, char *line,
                return 0;
        intptr = NULL;
        charptr = NULL;
-       opcode = parse_token(arg, filename, linenum);
+       opcode = parse_token(arg, filename, linenum, &flags);
+
+       if (activep == NULL) { /* We are processing a command line directive */
+               cmdline = 1;
+               activep = &cmdline;
+       }
+       if (*activep && opcode != sMatch)
+               debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
+       if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
+               if (user == NULL) {
+                       fatal("%s line %d: Directive '%s' is not allowed "
+                           "within a Match block", filename, linenum, arg);
+               } else { /* this is a directive we have already processed */
+                       while (arg)
+                               arg = strdelim(&cp);
+                       return 0;
+               }
+       }
 
        switch (opcode) {
        /* Portable-specific options */
@@ -547,7 +743,7 @@ parse_int:
                        fatal("%s line %d: missing integer value.",
                            filename, linenum);
                value = atoi(arg);
-               if (*intptr == -1)
+               if (*activep && *intptr == -1)
                        *intptr = value;
                break;
 
@@ -627,7 +823,7 @@ parse_filename:
                if (!arg || *arg == '\0')
                        fatal("%s line %d: missing file name.",
                            filename, linenum);
-               if (*charptr == NULL) {
+               if (*activep && *charptr == NULL) {
                        *charptr = tilde_expand_filename(arg, getuid());
                        /* increase optional counter */
                        if (intptr != NULL)
@@ -678,7 +874,7 @@ parse_flag:
                else
                        fatal("%s line %d: Bad yes/no argument: %s",
                                filename, linenum, arg);
-               if (*intptr == -1)
+               if (*activep && *intptr == -1)
                        *intptr = value;
                break;
 
@@ -914,7 +1110,7 @@ parse_flag:
        case sDenyUsers:
                while ((arg = strdelim(&cp)) && *arg != '\0') {
                        if (options->num_deny_users >= MAX_DENY_USERS)
-                               fatal( "%s line %d: too many deny users.",
+                               fatal("%s line %d: too many deny users.",
                                    filename, linenum);
                        options->deny_users[options->num_deny_users++] =
                            xstrdup(arg);
@@ -984,6 +1180,10 @@ parse_flag:
                if (!arg || *arg == '\0')
                        fatal("%s line %d: Missing subsystem name.",
                            filename, linenum);
+               if (!*activep) {
+                       arg = strdelim(&cp);
+                       break;
+               }
                for (i = 0; i < options->num_subsystems; i++)
                        if (strcmp(arg, options->subsystem_name[i]) == 0)
                                fatal("%s line %d: Subsystem '%s' already defined.",
@@ -994,6 +1194,17 @@ parse_flag:
                        fatal("%s line %d: Missing subsystem command.",
                            filename, linenum);
                options->subsystem_command[options->num_subsystems] = xstrdup(arg);
+
+               /* Collect arguments (separate to executable) */
+               p = xstrdup(arg);
+               len = strlen(p) + 1;
+               while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
+                       len += 1 + strlen(arg);
+                       p = xrealloc(p, 1, len);
+                       strlcat(p, " ", len);
+                       strlcat(p, arg, len);
+               }
+               options->subsystem_args[options->num_subsystems] = p;
                options->num_subsystems++;
                break;
 
@@ -1034,7 +1245,7 @@ parse_flag:
         */
        case sAuthorizedKeysFile:
        case sAuthorizedKeysFile2:
-               charptr = (opcode == sAuthorizedKeysFile ) ?
+               charptr = (opcode == sAuthorizedKeysFile) ?
                    &options->authorized_keys_file :
                    &options->authorized_keys_file2;
                goto parse_filename;
@@ -1055,6 +1266,8 @@ parse_flag:
                        if (options->num_accept_env >= MAX_ACCEPT_ENV)
                                fatal("%s line %d: too many allow env.",
                                    filename, linenum);
+                       if (!*activep)
+                               break;
                        options->accept_env[options->num_accept_env++] =
                            xstrdup(arg);
                }
@@ -1082,6 +1295,55 @@ parse_flag:
                        *intptr = value;
                break;
 
+       case sMatch:
+               if (cmdline)
+                       fatal("Match directive not supported as a command-line "
+                          "option");
+               value = match_cfg_line(&cp, linenum, user, host, address);
+               if (value < 0)
+                       fatal("%s line %d: Bad Match condition", filename,
+                           linenum);
+               *activep = value;
+               break;
+
+       case sPermitOpen:
+               arg = strdelim(&cp);
+               if (!arg || *arg == '\0')
+                       fatal("%s line %d: missing PermitOpen specification",
+                           filename, linenum);
+               if (strcmp(arg, "any") == 0) {
+                       if (*activep) {
+                               channel_clear_adm_permitted_opens();
+                               options->num_permitted_opens = 0;
+                       }
+                       break;
+               }
+               for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
+                       p = hpdelim(&arg);
+                       if (p == NULL)
+                               fatal("%s line %d: missing host in PermitOpen",
+                                   filename, linenum);
+                       p = cleanhostname(p);
+                       if (arg == NULL || (port = a2port(arg)) == 0)
+                               fatal("%s line %d: bad port number in "
+                                   "PermitOpen", filename, linenum);
+                       if (*activep && options->num_permitted_opens == -1) {
+                               channel_clear_adm_permitted_opens();
+                               options->num_permitted_opens =
+                                   channel_add_adm_permitted_opens(p, port);
+                       }
+               }
+               break;
+
+       case sForceCommand:
+               if (cp == NULL)
+                       fatal("%.200s line %d: Missing argument.", filename,
+                           linenum);
+               len = strspn(cp, WHITESPACE);
+               if (*activep && options->adm_forced_command == NULL)
+                       options->adm_forced_command = xstrdup(cp + len);
+               return 0;
+
        case sDeprecated:
                logit("%s line %d: Deprecated option %s",
                    filename, linenum, arg);
@@ -1138,18 +1400,52 @@ load_server_config(const char *filename, Buffer *conf)
 }
 
 void
-parse_server_config(ServerOptions *options, const char *filename, Buffer *conf)
+parse_server_match_config(ServerOptions *options, const char *user,
+    const char *host, const char *address)
+{
+       ServerOptions mo;
+
+       initialize_server_options(&mo);
+       parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
+       copy_set_server_options(options, &mo);
+}
+
+/* Copy any (supported) values that are set */
+void
+copy_set_server_options(ServerOptions *dst, ServerOptions *src)
+{
+       if (src->allow_tcp_forwarding != -1)
+               dst->allow_tcp_forwarding = src->allow_tcp_forwarding;
+       if (src->gateway_ports != -1)
+               dst->gateway_ports = src->gateway_ports;
+       if (src->adm_forced_command != NULL) {
+               if (dst->adm_forced_command != NULL)
+                       xfree(dst->adm_forced_command);
+               dst->adm_forced_command = src->adm_forced_command;
+       }
+       if (src->x11_display_offset != -1)
+               dst->x11_display_offset = src->x11_display_offset;
+       if (src->x11_forwarding != -1)
+               dst->x11_forwarding = src->x11_forwarding;
+       if (src->x11_use_localhost != -1)
+               dst->x11_use_localhost = src->x11_use_localhost;
+}
+
+void
+parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
+    const char *user, const char *host, const char *address)
 {
-       int linenum, bad_options = 0;
+       int active, linenum, bad_options = 0;
        char *cp, *obuf, *cbuf;
 
        debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
 
        obuf = cbuf = xstrdup(buffer_ptr(conf));
+       active = user ? 0 : 1;
        linenum = 1;
        while ((cp = strsep(&cbuf, "\n")) != NULL) {
                if (process_server_config_line(options, cp, filename,
-                   linenum++) != 0)
+                   linenum++, &active, user, host, address) != 0)
                        bad_options++;
        }
        xfree(obuf);
index 3cf98c50568b86c5cc30ec157ac827fddfaaf320..3adfd0d0d860b2a31e9a9d9381e1be8f71c5e7a8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: servconf.h,v 1.72 2005/12/06 22:38:27 reyk Exp $      */
+/* $OpenBSD: servconf.h,v 1.79 2006/08/14 12:40:25 dtucker Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -16,8 +16,6 @@
 #ifndef SERVCONF_H
 #define SERVCONF_H
 
-#include "buffer.h"
-
 #define MAX_PORTS              256     /* Max # ports. */
 
 #define MAX_ALLOW_USERS                256     /* Max # users on allow list. */
@@ -27,6 +25,7 @@
 #define MAX_SUBSYSTEMS         256     /* Max # subsystems. */
 #define MAX_HOSTKEYS           256     /* Max # hostkeys. */
 #define MAX_ACCEPT_ENV         256     /* Max # of env vars. */
+#define MAX_MATCH_GROUPS       256     /* Max # of groups for Match. */
 
 /* permit_root_login */
 #define        PERMIT_NOT_SET          -1
@@ -118,6 +117,7 @@ typedef struct {
        u_int num_subsystems;
        char   *subsystem_name[MAX_SUBSYSTEMS];
        char   *subsystem_command[MAX_SUBSYSTEMS];
+       char   *subsystem_args[MAX_SUBSYSTEMS];
 
        u_int num_accept_env;
        char   *accept_env[MAX_ACCEPT_ENV];
@@ -141,6 +141,8 @@ typedef struct {
        char   *authorized_keys_file;   /* File containing public keys */
        char   *authorized_keys_file2;
 
+       char   *adm_forced_command;
+
        int     use_pam;                /* Enable auth via PAM */
         int     none_enabled;           /* enable NONE cipher switch */
         int     tcp_rcv_buf_poll;       /* poll tcp rcv window in autotuning kernels*/
@@ -148,12 +150,19 @@ typedef struct {
        int     hpn_buffer_size;        /* set the hpn buffer size - default 3MB */
 
        int     permit_tun;
+
+       int     num_permitted_opens;
 }       ServerOptions;
 
 void    initialize_server_options(ServerOptions *);
 void    fill_default_server_options(ServerOptions *);
-int     process_server_config_line(ServerOptions *, char *, const char *, int);
+int     process_server_config_line(ServerOptions *, char *, const char *, int,
+            int *, const char *, const char *, const char *);
 void    load_server_config(const char *, Buffer *);
-void    parse_server_config(ServerOptions *, const char *, Buffer *);
+void    parse_server_config(ServerOptions *, const char *, Buffer *,
+            const char *, const char *, const char *);
+void    parse_server_match_config(ServerOptions *, const char *, const char *,
+            const char *);
+void    copy_set_server_options(ServerOptions *, ServerOptions *);
 
 #endif                         /* SERVCONF_H */
index 5eb5fd565cf57c474fd055d1589fc68350809892..731950e3db42134b45b539e3ea84c8fa8a232319 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: serverloop.c,v 1.144 2006/08/03 03:34:42 deraadt Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: serverloop.c,v 1.124 2005/12/13 15:03:02 reyk Exp $");
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+
+#include <netinet/in.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <pwd.h>
+#include <signal.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+#include <stdarg.h>
 
 #include "xmalloc.h"
 #include "packet.h"
@@ -48,13 +67,16 @@ RCSID("$OpenBSD: serverloop.c,v 1.124 2005/12/13 15:03:02 reyk Exp $");
 #include "compat.h"
 #include "ssh1.h"
 #include "ssh2.h"
+#include "key.h"
+#include "cipher.h"
+#include "kex.h"
+#include "hostfile.h"
 #include "auth.h"
 #include "session.h"
 #include "dispatch.h"
 #include "auth-options.h"
 #include "serverloop.h"
 #include "misc.h"
-#include "kex.h"
 
 extern ServerOptions options;
 
@@ -142,11 +164,11 @@ notify_done(fd_set *readset)
                        debug2("notify_done: reading");
 }
 
+/*ARGSUSED*/
 static void
 sigchld_handler(int sig)
 {
        int save_errno = errno;
-       debug("Received SIGCHLD.");
        child_terminated = 1;
 #ifndef _UNICOS
        mysignal(SIGCHLD, sigchld_handler);
@@ -155,6 +177,7 @@ sigchld_handler(int sig)
        errno = save_errno;
 }
 
+/*ARGSUSED*/
 static void
 sigterm_handler(int sig)
 {
@@ -348,7 +371,7 @@ wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
  * in buffers and processed later.
  */
 static void
-process_input(fd_set * readset)
+process_input(fd_set *readset)
 {
        int len;
        char buf[16384];
@@ -380,10 +403,16 @@ process_input(fd_set * readset)
 
        /* Read and buffer any available stdout data from the program. */
        if (!fdout_eof && FD_ISSET(fdout, readset)) {
+               errno = 0;
                len = read(fdout, buf, sizeof(buf));
                if (len < 0 && (errno == EINTR || errno == EAGAIN)) {
                        /* do nothing */
+#ifndef PTY_ZEROREAD
                } else if (len <= 0) {
+#else
+               } else if ((!isatty(fdout) && len <= 0) ||
+                   (isatty(fdout) && (len < 0 || (len == 0 && errno != 0)))) {
+#endif
                        fdout_eof = 1;
                } else {
                        buffer_append(&stdout_buffer, buf, len);
@@ -392,10 +421,16 @@ process_input(fd_set * readset)
        }
        /* Read and buffer any available stderr data from the program. */
        if (!fderr_eof && FD_ISSET(fderr, readset)) {
+               errno = 0;
                len = read(fderr, buf, sizeof(buf));
                if (len < 0 && (errno == EINTR || errno == EAGAIN)) {
                        /* do nothing */
+#ifndef PTY_ZEROREAD
                } else if (len <= 0) {
+#else
+               } else if ((!isatty(fderr) && len <= 0) ||
+                   (isatty(fderr) && (len < 0 || (len == 0 && errno != 0)))) {
+#endif
                        fderr_eof = 1;
                } else {
                        buffer_append(&stderr_buffer, buf, len);
@@ -407,7 +442,7 @@ process_input(fd_set * readset)
  * Sends data from internal buffers to client program stdin.
  */
 static void
-process_output(fd_set * writeset)
+process_output(fd_set *writeset)
 {
        struct termios tio;
        u_char *data;
@@ -749,6 +784,7 @@ collect_children(void)
        sigaddset(&nset, SIGCHLD);
        sigprocmask(SIG_BLOCK, &nset, &oset);
        if (child_terminated) {
+               debug("Received SIGCHLD.");
                while ((pid = waitpid(-1, &status, WNOHANG)) > 0 ||
                    (pid < 0 && errno == EINTR))
                        if (pid > 0)
@@ -873,10 +909,10 @@ server_input_eof(int type, u_int32_t seq, void *ctxt)
 static void
 server_input_window_size(int type, u_int32_t seq, void *ctxt)
 {
-       int row = packet_get_int();
-       int col = packet_get_int();
-       int xpixel = packet_get_int();
-       int ypixel = packet_get_int();
+       u_int row = packet_get_int();
+       u_int col = packet_get_int();
+       u_int xpixel = packet_get_int();
+       u_int ypixel = packet_get_int();
 
        debug("Window change received.");
        packet_check_eom();
@@ -942,7 +978,7 @@ server_request_tun(void)
 
        tun = packet_get_int();
        if (forced_tun_device != -1) {
-               if (tun != SSH_TUNID_ANY && forced_tun_device != tun)
+               if (tun != SSH_TUNID_ANY && forced_tun_device != tun)
                        goto done;
                tun = forced_tun_device;
        }
@@ -1097,6 +1133,7 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt)
 
                success = channel_cancel_rport_listener(cancel_address,
                    cancel_port);
+               xfree(cancel_address);
        }
        if (want_reply) {
                packet_start(success ?
@@ -1106,6 +1143,7 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt)
        }
        xfree(rtype);
 }
+
 static void
 server_input_channel_req(int type, u_int32_t seq, void *ctxt)
 {
index 13f7385260fc77d0517878bd7440e73ebf66f7b3..750a3196d569339523afad1d6ff39ebe094e8820 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: session.c,v 1.219 2006/08/29 10:40:19 djm Exp $ */
 /*
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  *                    All rights reserved
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: session.c,v 1.191 2005/12/24 02:27:41 djm Exp $");
 
+#include <sys/types.h>
+#include <sys/param.h>
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/wait.h>
+
+#include <arpa/inet.h>
+
+#include <errno.h>
+#include <grp.h>
+#ifdef HAVE_PATHS_H
+#include <paths.h>
+#endif
+#include <pwd.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "xmalloc.h"
 #include "ssh.h"
 #include "ssh1.h"
 #include "ssh2.h"
-#include "xmalloc.h"
 #include "sshpty.h"
 #include "packet.h"
 #include "buffer.h"
@@ -46,7 +70,12 @@ RCSID("$OpenBSD: session.c,v 1.191 2005/12/24 02:27:41 djm Exp $");
 #include "uidswap.h"
 #include "compat.h"
 #include "channels.h"
-#include "bufaux.h"
+#include "key.h"
+#include "cipher.h"
+#ifdef GSSAPI
+#include "ssh-gss.h"
+#endif
+#include "hostfile.h"
 #include "auth.h"
 #include "auth-options.h"
 #include "pathnames.h"
@@ -63,10 +92,6 @@ RCSID("$OpenBSD: session.c,v 1.191 2005/12/24 02:27:41 djm Exp $");
 #include <kafs.h>
 #endif
 
-#ifdef GSSAPI
-#include "ssh-gss.h"
-#endif
-
 /* func */
 
 Session *session_new(void);
@@ -180,7 +205,7 @@ auth_input_request_forwarding(struct passwd * pw)
        sunaddr.sun_family = AF_UNIX;
        strlcpy(sunaddr.sun_path, auth_sock_name, sizeof(sunaddr.sun_path));
 
-       if (bind(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0)
+       if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0)
                packet_disconnect("bind: %.100s", strerror(errno));
 
        /* Restore the privileged uid. */
@@ -343,9 +368,12 @@ do_authenticated1(Authctxt *authctxt)
                                break;
                        }
                        debug("Received TCP/IP port forwarding request.");
-                       channel_input_port_forward_request(s->pw->pw_uid == 0, options.gateway_ports, 
-                                                           options.hpn_disabled, 
-                                                          options.hpn_buffer_size);
+                       if (channel_input_port_forward_request(s->pw->pw_uid == 0,
+                options.gateway_ports,
+                options.hpn_disabled, options.hpn_buffer_size) < 0) {
+                               debug("Port forwarding failed.");
+                               break;
+                       }
                        success = 1;
                        break;
 
@@ -655,7 +683,7 @@ do_pre_login(Session *s)
        fromlen = sizeof(from);
        if (packet_connection_is_on_socket()) {
                if (getpeername(packet_get_connection_in(),
-                   (struct sockaddr *) & from, &fromlen) < 0) {
+                   (struct sockaddr *)&from, &fromlen) < 0) {
                        debug("getpeername: %.100s", strerror(errno));
                        cleanup_exit(255);
                }
@@ -674,10 +702,14 @@ do_pre_login(Session *s)
 void
 do_exec(Session *s, const char *command)
 {
-       if (forced_command) {
+       if (options.adm_forced_command) {
+               original_command = command;
+               command = options.adm_forced_command;
+               debug("Forced command (config) '%.900s'", command);
+       } else if (forced_command) {
                original_command = command;
                command = forced_command;
-               debug("Forced command '%.900s'", command);
+               debug("Forced command (key option) '%.900s'", command);
        }
 
 #if defined(SESSION_HOOKS)
@@ -869,7 +901,7 @@ child_set_env(char ***envp, u_int *envsizep, const char *name,
                        if (envsize >= 1000)
                                fatal("child_set_env: too many env vars");
                        envsize += 50;
-                       env = (*envp) = xrealloc(env, envsize * sizeof(char *));
+                       env = (*envp) = xrealloc(env, envsize, sizeof(char *));
                        *envsizep = envsize;
                }
                /* Need to set the NULL pointer at end of array beyond the new slot. */
@@ -1121,12 +1153,15 @@ do_setup_env(Session *s, const char *shell)
 {
        char buf[256];
        u_int i, envsize;
-       char **env, *laddr, *path = NULL;
+       char **env, *laddr;
        struct passwd *pw = s->pw;
+#ifndef HAVE_LOGIN_CAP
+       char *path = NULL;
+#endif
 
        /* Initialize the environment. */
        envsize = 100;
-       env = xmalloc(envsize * sizeof(char *));
+       env = xcalloc(envsize, sizeof(char *));
        env[0] = NULL;
 
 #ifdef HAVE_CYGWIN
@@ -1511,6 +1546,10 @@ do_setusercontext(struct passwd *pw)
 #endif
        if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
                fatal("Failed to set uids to %u.", (u_int) pw->pw_uid);
+
+#ifdef WITH_SELINUX
+       ssh_selinux_setup_exec_context(pw->pw_name);
+#endif
 }
 
 static void
@@ -1777,7 +1816,7 @@ do_child(Session *s, const char *command)
                do_rc_files(s, shell);
 
        /* restore SIGPIPE for child */
-       signal(SIGPIPE,  SIG_DFL);
+       signal(SIGPIPE, SIG_DFL);
 
        if (options.use_login) {
                launch_login(pw, hostname);
@@ -2041,7 +2080,7 @@ session_subsystem_req(Session *s)
        struct stat st;
        u_int len;
        int success = 0;
-       char *cmd, *subsys = packet_get_string(&len);
+       char *prog, *cmd, *subsys = packet_get_string(&len);
        u_int i;
 
        packet_check_eom();
@@ -2049,9 +2088,10 @@ session_subsystem_req(Session *s)
 
        for (i = 0; i < options.num_subsystems; i++) {
                if (strcmp(subsys, options.subsystem_name[i]) == 0) {
-                       cmd = options.subsystem_command[i];
-                       if (stat(cmd, &st) < 0) {
-                               error("subsystem: cannot stat %s: %s", cmd,
+                       prog = options.subsystem_command[i];
+                       cmd = options.subsystem_args[i];
+                       if (stat(prog, &st) < 0) {
+                               error("subsystem: cannot stat %s: %s", prog,
                                    strerror(errno));
                                break;
                        }
@@ -2148,8 +2188,8 @@ session_env_req(Session *s)
        for (i = 0; i < options.num_accept_env; i++) {
                if (match_pattern(name, options.accept_env[i])) {
                        debug2("Setting env %d: %s=%s", s->num_env, name, val);
-                       s->env = xrealloc(s->env, sizeof(*s->env) *
-                           (s->num_env + 1));
+                       s->env = xrealloc(s->env, s->num_env + 1,
+                           sizeof(*s->env));
                        s->env[s->num_env].name = name;
                        s->env[s->num_env].val = val;
                        s->num_env++;
@@ -2404,7 +2444,7 @@ session_exit_message(Session *s, int status)
 
        /*
         * Adjust cleanup callback attachment to send close messages when
-        * the channel gets EOF. The session will be then be closed 
+        * 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);
@@ -2440,12 +2480,13 @@ session_close(Session *s)
        if (s->auth_proto)
                xfree(s->auth_proto);
        s->used = 0;
-       for (i = 0; i < s->num_env; i++) {
-               xfree(s->env[i].name);
-               xfree(s->env[i].val);
-       }
-       if (s->env != NULL)
+       if (s->env != NULL) {
+               for (i = 0; i < s->num_env; i++) {
+                       xfree(s->env[i].name);
+                       xfree(s->env[i].val);
+               }
                xfree(s->env);
+       }
        session_proctitle(s);
 }
 
@@ -2662,7 +2703,7 @@ do_cleanup(Authctxt *authctxt)
                return;
        called = 1;
 
-       if (authctxt == NULL)
+       if (authctxt == NULL || !authctxt->authenticated)
                return;
 #ifdef KRB5
        if (options.kerberos_ticket_cleanup &&
index a2598a99c2ec1d28126e5589ecd08bd106d769d7..ee9338e4f5e71f619c1d996c9062bb623ed2e9b9 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: session.h,v 1.25 2005/07/17 06:49:04 djm Exp $        */
+/* $OpenBSD: session.h,v 1.29 2006/08/03 03:34:42 deraadt Exp $ */
 
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
@@ -34,11 +34,13 @@ struct Session {
        struct passwd *pw;
        Authctxt *authctxt;
        pid_t   pid;
+
        /* tty */
        char    *term;
        int     ptyfd, ttyfd, ptymaster;
        u_int   row, col, xpixel, ypixel;
        char    tty[TTYSZ];
+
        /* X11 */
        u_int   display_number;
        char    *display;
@@ -47,6 +49,7 @@ struct Session {
        char    *auth_proto;
        char    *auth_data;
        int     single_connection;
+
        /* proto 2 */
        int     chanid;
        int     *x11_chanids;
@@ -55,7 +58,7 @@ struct Session {
        struct {
                char    *name;
                char    *val;
-       }       *env;
+       } *env;
 };
 
 void    do_authenticated(Authctxt *);
index a2e3f6aad65f36fcd3e7e2ed79c3e2dbd6596419..c018615ae61b13f27d9884e0755f317e52d37250 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: sftp.c,v 1.92 2006/09/19 05:52:23 otto Exp $ */
 /*
  * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
  *
 
 #include "includes.h"
 
-RCSID("$OpenBSD: sftp.c,v 1.70 2006/01/31 10:19:02 djm Exp $");
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+
+#include <errno.h>
 
+#ifdef HAVE_PATHS_H
+# include <paths.h>
+#endif
 #ifdef USE_LIBEDIT
 #include <histedit.h>
 #else
 typedef void EditLine;
 #endif
+#include <signal.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdarg.h>
 
-#include "buffer.h"
 #include "xmalloc.h"
 #include "log.h"
 #include "pathnames.h"
 #include "misc.h"
 
 #include "sftp.h"
+#include "buffer.h"
 #include "sftp-common.h"
 #include "sftp-client.h"
 
@@ -235,7 +254,7 @@ local_do_shell(const char *args)
                if (errno != EINTR)
                        fatal("Couldn't wait for child: %s", strerror(errno));
        if (!WIFEXITED(status))
-               error("Shell exited abormally");
+               error("Shell exited abnormally");
        else if (WEXITSTATUS(status))
                error("Shell exited with status %d", WEXITSTATUS(status));
 }
@@ -474,7 +493,7 @@ is_dir(char *path)
        if (stat(path, &sb) == -1)
                return(0);
 
-       return(sb.st_mode & S_IFDIR);
+       return(S_ISDIR(sb.st_mode));
 }
 
 static int
@@ -498,7 +517,7 @@ remote_is_dir(struct sftp_conn *conn, char *path)
                return(0);
        if (!(a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS))
                return(0);
-       return(a->perm & S_IFDIR);
+       return(S_ISDIR(a->perm));
 }
 
 static int
@@ -538,6 +557,7 @@ process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag)
 
                if (g.gl_matchc == 1 && dst) {
                        /* If directory specified, append filename */
+                       xfree(tmp);
                        if (is_dir(dst)) {
                                if (infer_path(g.gl_pathv[0], &tmp)) {
                                        err = 1;
@@ -562,8 +582,6 @@ process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag)
 
 out:
        xfree(abs_src);
-       if (abs_dst)
-               xfree(abs_dst);
        globfree(&g);
        return(err);
 }
@@ -1280,6 +1298,7 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
                        if (parse_dispatch_command(conn, cmd, &pwd, 1) != 0) {
                                xfree(dir);
                                xfree(pwd);
+                               xfree(conn);
                                return (-1);
                        }
                } else {
@@ -1292,6 +1311,7 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
                        err = parse_dispatch_command(conn, cmd, &pwd, 1);
                        xfree(dir);
                        xfree(pwd);
+                       xfree(conn);
                        return (err);
                }
                xfree(dir);
@@ -1356,6 +1376,7 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
                        break;
        }
        xfree(pwd);
+       xfree(conn);
 
 #ifdef USE_LIBEDIT
        if (el != NULL)
@@ -1455,7 +1476,7 @@ main(int argc, char **argv)
        __progname = ssh_get_progname(argv[0]);
        memset(&args, '\0', sizeof(args));
        args.list = NULL;
-       addargs(&args, ssh_program);
+       addargs(&args, "%s", ssh_program);
        addargs(&args, "-oForwardX11 no");
        addargs(&args, "-oForwardAgent no");
        addargs(&args, "-oPermitLocalCommand no");
index a69c25eec6bef2548081e54ec1273562b859f0d3..08b07212e048b3ac84c0a2b1ea4e5bf615a9e52a 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: ssh-agent.c,v 1.152 2006/08/04 20:46:05 stevesk Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  */
 
 #include "includes.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_UN_H
+# include <sys/un.h>
+#endif
 #include "openbsd-compat/sys-queue.h"
-RCSID("$OpenBSD: ssh-agent.c,v 1.124 2005/10/30 08:52:18 djm Exp $");
 
 #include <openssl/evp.h>
 #include <openssl/md5.h>
 
+#include <errno.h>
+#include <fcntl.h>
+#ifdef HAVE_PATHS_H
+# include <paths.h>
+#endif
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "xmalloc.h"
 #include "ssh.h"
 #include "rsa.h"
 #include "buffer.h"
-#include "bufaux.h"
-#include "xmalloc.h"
-#include "getput.h"
 #include "key.h"
 #include "authfd.h"
 #include "compat.h"
@@ -99,8 +122,8 @@ int max_fd = 0;
 pid_t parent_pid = -1;
 
 /* pathname and directory for AUTH_SOCKET */
-char socket_name[1024];
-char socket_dir[1024];
+char socket_name[MAXPATHLEN];
+char socket_dir[MAXPATHLEN];
 
 /* locking */
 int locked = 0;
@@ -305,8 +328,8 @@ process_sign_request2(SocketEntry *e)
                Identity *id = lookup_identity(key, 2);
                if (id != NULL && (!id->confirm || confirm_key(id) == 0))
                        ok = key_sign(id->key, &signature, &slen, data, dlen);
+               key_free(key);
        }
-       key_free(key);
        buffer_init(&msg);
        if (ok == 0) {
                buffer_put_char(&msg, SSH2_AGENT_SIGN_RESPONSE);
@@ -681,7 +704,7 @@ process_message(SocketEntry *e)
        if (buffer_len(&e->input) < 5)
                return;         /* Incomplete message. */
        cp = buffer_ptr(&e->input);
-       msg_len = GET_32BIT(cp);
+       msg_len = get_u32(cp);
        if (msg_len > 256 * 1024) {
                close_socket(e);
                return;
@@ -793,10 +816,7 @@ new_socket(sock_type type, int fd)
                }
        old_alloc = sockets_alloc;
        new_alloc = sockets_alloc + 10;
-       if (sockets)
-               sockets = xrealloc(sockets, new_alloc * sizeof(sockets[0]));
-       else
-               sockets = xmalloc(new_alloc * sizeof(sockets[0]));
+       sockets = xrealloc(sockets, new_alloc, sizeof(sockets[0]));
        for (i = old_alloc; i < new_alloc; i++)
                sockets[i].type = AUTH_UNUSED;
        sockets_alloc = new_alloc;
@@ -877,7 +897,7 @@ after_select(fd_set *readset, fd_set *writeset)
                        if (FD_ISSET(sockets[i].fd, readset)) {
                                slen = sizeof(sunaddr);
                                sock = accept(sockets[i].fd,
-                                   (struct sockaddr *) &sunaddr, &slen);
+                                   (struct sockaddr *)&sunaddr, &slen);
                                if (sock < 0) {
                                        error("accept from AUTH_SOCKET: %s",
                                            strerror(errno));
@@ -954,6 +974,7 @@ cleanup_exit(int i)
        _exit(i);
 }
 
+/*ARGSUSED*/
 static void
 cleanup_handler(int sig)
 {
@@ -961,6 +982,7 @@ cleanup_handler(int sig)
        _exit(2);
 }
 
+/*ARGSUSED*/
 static void
 check_parent_exists(int sig)
 {
@@ -994,7 +1016,7 @@ int
 main(int ac, char **av)
 {
        int c_flag = 0, d_flag = 0, k_flag = 0, s_flag = 0;
-       int sock, fd,  ch;
+       int sock, fd, ch;
        u_int nalloc;
        char *shell, *format, *pidstr, *agentsocket = NULL;
        fd_set *readsetp = NULL, *writesetp = NULL;
@@ -1067,20 +1089,24 @@ main(int ac, char **av)
 
        if (ac == 0 && !c_flag && !s_flag) {
                shell = getenv("SHELL");
-               if (shell != NULL && strncmp(shell + strlen(shell) - 3, "csh", 3) == 0)
+               if (shell != NULL &&
+                   strncmp(shell + strlen(shell) - 3, "csh", 3) == 0)
                        c_flag = 1;
        }
        if (k_flag) {
+               const char *errstr = NULL;
+
                pidstr = getenv(SSH_AGENTPID_ENV_NAME);
                if (pidstr == NULL) {
                        fprintf(stderr, "%s not set, cannot kill agent\n",
                            SSH_AGENTPID_ENV_NAME);
                        exit(1);
                }
-               pid = atoi(pidstr);
-               if (pid < 1) {
-                       fprintf(stderr, "%s=\"%s\", which is not a good PID\n",
-                           SSH_AGENTPID_ENV_NAME, pidstr);
+               pid = (int)strtonum(pidstr, 2, INT_MAX, &errstr);
+               if (errstr) {
+                       fprintf(stderr,
+                           "%s=\"%s\", which is not a good PID: %s\n",
+                           SSH_AGENTPID_ENV_NAME, pidstr, errstr);
                        exit(1);
                }
                if (kill(pid, SIGTERM) == -1) {
@@ -1124,7 +1150,7 @@ main(int ac, char **av)
        sunaddr.sun_family = AF_UNIX;
        strlcpy(sunaddr.sun_path, socket_name, sizeof(sunaddr.sun_path));
        prev_mask = umask(0177);
-       if (bind(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0) {
+       if (bind(sock, (struct sockaddr *) &sunaddr, sizeof(sunaddr)) < 0) {
                perror("bind");
                *socket_name = '\0'; /* Don't unlink any existing file */
                umask(prev_mask);
index 8b510ad1e3ea0b003e60ad773ec3c09dc6cb68af..ef21d5eadaca8e7a87eed02110a0fe0be5917d7f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ssh-gss.h,v 1.5 2004/06/21 17:36:31 avsm Exp $        */
+/* $OpenBSD: ssh-gss.h,v 1.9 2006/08/18 14:40:34 djm Exp $ */
 /*
  * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
  *
@@ -28,8 +28,6 @@
 
 #ifdef GSSAPI
 
-#include "buffer.h"
-
 #ifdef HAVE_GSSAPI_H
 #include <gssapi.h>
 #elif defined(HAVE_GSSAPI_GSSAPI_H)
@@ -134,16 +132,16 @@ void ssh_gssapi_delete_ctx(Gssctxt **);
 OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t);
 OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID);
 void ssh_gssapi_buildmic(Buffer *, const char *, const char *, const char *);
+int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *);
 
 int ssh_gssapi_localname(char **name);
 
-typedef int ssh_gssapi_check_fn(gss_OID, void *);
+typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *);
 char *ssh_gssapi_client_mechanisms(const char *host);
 char *ssh_gssapi_kex_mechs(gss_OID_set, ssh_gssapi_check_fn *, void *);
-int ssh_gssapi_check_mechanism(gss_OID, void *);
 gss_OID ssh_gssapi_id_kex(Gssctxt *, char *, int *);
 
-int ssh_gssapi_server_check_mech(gss_OID, void *);
+int ssh_gssapi_server_check_mech(Gssctxt **, gss_OID, const char *);
 int ssh_gssapi_userok(char *name);
 OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t);
 void ssh_gssapi_do_child(char ***, u_int *);
index 6915102ddf3ba7f7665edf96141962db18857f30..416d3f5c14d792676d57784bc4b0b5905fec8f54 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: ssh-keyscan.c,v 1.73 2006/08/03 03:34:42 deraadt Exp $ */
 /*
  * Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
  *
@@ -7,24 +8,39 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: ssh-keyscan.c,v 1.57 2005/10/30 04:01:03 djm Exp $");
-
 #include "openbsd-compat/sys-queue.h"
+#include <sys/resource.h>
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
 
 #include <openssl/bn.h>
 
+#include <netdb.h>
+#include <errno.h>
 #include <setjmp.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <string.h>
+#include <unistd.h>
+
 #include "xmalloc.h"
 #include "ssh.h"
 #include "ssh1.h"
+#include "buffer.h"
 #include "key.h"
+#include "cipher.h"
 #include "kex.h"
 #include "compat.h"
 #include "myproposal.h"
 #include "packet.h"
 #include "dispatch.h"
-#include "buffer.h"
-#include "bufaux.h"
 #include "log.h"
 #include "atomicio.h"
 #include "misc.h"
@@ -54,7 +70,7 @@ int maxfd;
 
 extern char *__progname;
 fd_set *read_wait;
-size_t read_wait_size;
+size_t read_wait_nfdset;
 int ncon;
 int nonfatal_fatal = 0;
 jmp_buf kexjmp;
@@ -128,7 +144,7 @@ Linebuf_alloc(const char *filename, void (*errfun) (const char *,...))
                lb->stream = stdin;
        }
 
-       if (!(lb->buf = malloc(lb->size = LINEBUF_SIZE))) {
+       if (!(lb->buf = malloc((lb->size = LINEBUF_SIZE)))) {
                if (errfun)
                        (*errfun) ("linebuf (%s): malloc failed\n", lb->filename);
                xfree(lb);
@@ -350,6 +366,7 @@ keygrab_ssh2(con *c)
        c->c_kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client;
        c->c_kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client;
        c->c_kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
+       c->c_kex->kex[KEX_DH_GEX_SHA256] = kexgex_client;
        c->c_kex->verify_host_key = hostjump;
 
        if (!(j = setjmp(kexjmp))) {
@@ -602,7 +619,6 @@ conread(int s)
                        keyprint(c, keygrab_ssh1(c));
                        confree(s);
                        return;
-                       break;
                default:
                        fatal("conread: invalid status %d", c->c_status);
                        break;
@@ -634,10 +650,10 @@ conloop(void)
        } else
                seltime.tv_sec = seltime.tv_usec = 0;
 
-       r = xmalloc(read_wait_size);
-       memcpy(r, read_wait, read_wait_size);
-       e = xmalloc(read_wait_size);
-       memcpy(e, read_wait, read_wait_size);
+       r = xcalloc(read_wait_nfdset, sizeof(fd_mask));
+       e = xcalloc(read_wait_nfdset, sizeof(fd_mask));
+       memcpy(r, read_wait, read_wait_nfdset * sizeof(fd_mask));
+       memcpy(e, read_wait, read_wait_nfdset * sizeof(fd_mask));
 
        while (select(maxfd, r, NULL, e, &seltime) == -1 &&
            (errno == EAGAIN || errno == EINTR))
@@ -804,12 +820,10 @@ main(int argc, char **argv)
                fatal("%s: not enough file descriptors", __progname);
        if (maxfd > fdlim_get(0))
                fdlim_set(maxfd);
-       fdcon = xmalloc(maxfd * sizeof(con));
-       memset(fdcon, 0, maxfd * sizeof(con));
+       fdcon = xcalloc(maxfd, sizeof(con));
 
-       read_wait_size = howmany(maxfd, NFDBITS) * sizeof(fd_mask);
-       read_wait = xmalloc(read_wait_size);
-       memset(read_wait, 0, read_wait_size);
+       read_wait_nfdset = howmany(maxfd, NFDBITS);
+       read_wait = xcalloc(read_wait_nfdset, sizeof(fd_mask));
 
        if (fopt_count) {
                Linebuf *lb;
index a17e8d5cf23430f4f35f27a288532cab7cc4c32b..4cdcb7a43d95d0d28ab6e67b6a940ec49243f843 100644 (file)
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ssh-keysign.8,v 1.7 2003/06/10 09:12:11 jmc Exp $
+.\" $OpenBSD: ssh-keysign.8,v 1.8 2006/02/24 20:22:16 jmc Exp $
 .\"
 .\" Copyright (c) 2002 Markus Friedl.  All rights reserved.
 .\"
@@ -27,7 +27,7 @@
 .Os
 .Sh NAME
 .Nm ssh-keysign
-.Nd ssh helper program for hostbased authentication
+.Nd ssh helper program for host-based authentication
 .Sh SYNOPSIS
 .Nm
 .Sh DESCRIPTION
@@ -35,7 +35,7 @@
 is used by
 .Xr ssh 1
 to access the local host keys and generate the digital signature
-required during hostbased authentication with SSH protocol version 2.
+required during host-based authentication with SSH protocol version 2.
 .Pp
 .Nm
 is disabled by default and can only be enabled in the
@@ -53,7 +53,7 @@ See
 .Xr ssh 1
 and
 .Xr sshd 8
-for more information about hostbased authentication.
+for more information about host-based authentication.
 .Sh FILES
 .Bl -tag -width Ds
 .It Pa /etc/ssh/ssh_config
@@ -67,7 +67,7 @@ They should be owned by root, readable only by root, and not
 accessible to others.
 Since they are readable only by root,
 .Nm
-must be set-uid root if hostbased authentication is used.
+must be set-uid root if host-based authentication is used.
 .El
 .Sh SEE ALSO
 .Xr ssh 1 ,
index dae3a2e8c91b811c267b61dfd1deaa8efe62618c..c4bc7e56e56fa839eb87bb6dd1f3ea7bf04df268 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: ssh-keysign.c,v 1.29 2006/08/03 03:34:42 deraadt Exp $ */
 /*
  * Copyright (c) 2002 Markus Friedl.  All rights reserved.
  *
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
+
 #include "includes.h"
-RCSID("$OpenBSD: ssh-keysign.c,v 1.19 2005/09/13 23:40:07 djm Exp $");
+
+#include <fcntl.h>
+#ifdef HAVE_PATHS_H
+#include <paths.h>
+#endif
+#include <pwd.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
 
 #include <openssl/evp.h>
 #include <openssl/rand.h>
 #include <openssl/rsa.h>
 
+#include "xmalloc.h"
 #include "log.h"
 #include "key.h"
 #include "ssh.h"
 #include "ssh2.h"
 #include "misc.h"
-#include "xmalloc.h"
 #include "buffer.h"
-#include "bufaux.h"
 #include "authfile.h"
 #include "msg.h"
 #include "canohost.h"
@@ -64,9 +74,9 @@ valid_request(struct passwd *pw, char *host, Key **ret, u_char *data,
        buffer_init(&b);
        buffer_append(&b, data, datalen);
 
-       /* session id, currently limited to SHA1 (20 bytes) */
+       /* session id, currently limited to SHA1 (20 bytes) or SHA256 (32) */
        p = buffer_get_string(&b, &len);
-       if (len != 20)
+       if (len != 20 && len != 32)
                fail++;
        xfree(p);
 
@@ -140,7 +150,7 @@ main(int argc, char **argv)
 {
        Buffer b;
        Options options;
-       Key *keys[2], *key;
+       Key *keys[2], *key = NULL;
        struct passwd *pw;
        int key_fd[2], i, found, version = 2, fd;
        u_char *signature, *data;
index d8517b1a32a7a0aae6d8840123392db2760ac7de..8520c3a62ee573396ddf36ee86bfb925a7f259f2 100644 (file)
 
 #include "includes.h"
 
+#include <sys/types.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+
+#include <stdarg.h>
+#include <stddef.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#ifdef HAVE_SYS_UN_H
+# include <sys/un.h>
+#endif
+
+#include <errno.h>
+#include <fcntl.h>
+#include <pwd.h>
+#include <signal.h>
+#include <time.h>
+#include <unistd.h>
+
 #include <openssl/rand.h>
 #include <openssl/sha.h>
 #include <openssl/crypto.h>
@@ -39,8 +62,6 @@
 #include "pathnames.h"
 #include "log.h"
 
-RCSID("$Id$");
-
 /* Number of bytes we write out */
 #define OUTPUT_SEED_SIZE       48
 
@@ -564,7 +585,8 @@ prng_write_seedfile(void)
        /* Try to ensure that the parent directory is there */
        snprintf(filename, sizeof(filename), "%.512s/%s", pw->pw_dir,
            _PATH_SSH_USER_DIR);
-       mkdir(filename, 0700);
+       if (mkdir(filename, 0700) < 0 && errno != EEXIST)
+               fatal("mkdir %.200s: %s", filename, strerror(errno));
 
        snprintf(filename, sizeof(filename), "%.512s/%s", pw->pw_dir,
            SSH_PRNG_SEED_FILE);
@@ -665,8 +687,7 @@ prng_read_commands(char *cmdfilename)
        }
 
        num_cmds = 64;
-       entcmd = xmalloc(num_cmds * sizeof(entropy_cmd_t));
-       memset(entcmd, '\0', num_cmds * sizeof(entropy_cmd_t));
+       entcmd = xcalloc(num_cmds, sizeof(entropy_cmd_t));
 
        /* Read in file */
        cur_cmd = linenum = 0;
@@ -759,7 +780,7 @@ prng_read_commands(char *cmdfilename)
                 */
                if (cur_cmd == num_cmds) {
                        num_cmds *= 2;
-                       entcmd = xrealloc(entcmd, num_cmds *
+                       entcmd = xrealloc(entcmd, num_cmds,
                            sizeof(entropy_cmd_t));
                }
        }
@@ -768,12 +789,13 @@ prng_read_commands(char *cmdfilename)
        memset(&entcmd[cur_cmd], '\0', sizeof(entropy_cmd_t));
 
        /* trim to size */
-       entropy_cmds = xrealloc(entcmd, (cur_cmd + 1) *
+       entropy_cmds = xrealloc(entcmd, (cur_cmd + 1),
            sizeof(entropy_cmd_t));
 
        debug("Loaded %d entropy commands from %.100s", cur_cmd,
            cmdfilename);
 
+       fclose(f);
        return cur_cmd < MIN_ENTROPY_SOURCES ? -1 : 0;
 }
 
index f4c677628ce291aafb648d7bd23f9e6b59c171b4..6e41bcd8baea6abd35745859d50469e8edfc0027 100644 (file)
@@ -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.253 2006/01/30 13:37:49 jmc Exp $
+.\" $OpenBSD: ssh.1,v 1.263 2006/07/11 18:50:48 markus Exp $
 .Dd September 25, 1999
 .Dt SSH 1
 .Os
@@ -78,7 +78,8 @@
 .Oc
 .Op Fl S Ar ctl_path
 .Bk -words
-.Op Fl w Ar tunnel : Ns Ar tunnel
+.Oo Fl w Ar local_tun Ns
+.Op : Ns Ar remote_tun Oc
 .Oo Ar user Ns @ Oc Ns Ar hostname
 .Op Ar command
 .Ek
@@ -448,6 +449,7 @@ For full details of the options listed below, and their possible values, see
 .It ControlPath
 .It DynamicForward
 .It EscapeChar
+.It ExitOnForwardFailure
 .It ForwardAgent
 .It ForwardX11
 .It ForwardX11Trusted
@@ -569,7 +571,7 @@ Disable pseudo-tty allocation.
 Force pseudo-tty allocation.
 This can be used to execute arbitrary
 screen-based programs on a remote machine, which can be very useful,
-e.g., when implementing menu services.
+e.g. when implementing menu services.
 Multiple
 .Fl t
 options force tty allocation, even if
@@ -588,24 +590,35 @@ Multiple
 .Fl v
 options increase the verbosity.
 The maximum is 3.
-.It Fl w Ar tunnel : Ns Ar tunnel
-Requests a
+.It Fl w Xo
+.Ar local_tun Ns Op : Ns Ar remote_tun
+.Xc
+Requests
+tunnel
+device forwarding with the specified
 .Xr tun 4
-device on the client
-(first
-.Ar tunnel
-arg)
-and server
-(second
-.Ar tunnel
-arg).
+devices between the client
+.Pq Ar local_tun
+and the server
+.Pq Ar remote_tun .
+.Pp
 The devices may be specified by numerical ID or the keyword
 .Dq any ,
 which uses the next available tunnel device.
+If
+.Ar remote_tun
+is not specified, it defaults to
+.Dq any .
 See also the
 .Cm Tunnel
-directive in
+and
+.Cm TunnelDevice
+directives in
 .Xr ssh_config 5 .
+If the
+.Cm Tunnel
+directive is unset, it is set to the default tunnel mode, which is
+.Dq point-to-point .
 .It Fl X
 Enables X11 forwarding.
 This can also be specified on a per-host basis in a configuration file.
@@ -666,6 +679,7 @@ Protocol 1 lacks a strong mechanism for ensuring the
 integrity of the connection.
 .Pp
 The methods available for authentication are:
+GSSAPI-based authentication,
 host-based authentication,
 public key authentication,
 challenge-response authentication,
@@ -872,7 +886,9 @@ and
 options (see above).
 It also allows the cancellation of existing remote port-forwardings
 using
-.Fl KR Ar hostport .
+.Sm off
+.Fl KR Oo Ar bind_address : Oc Ar port .
+.Sm on
 .Ic !\& Ns Ar command
 allows the user to execute a local command if the
 .Ic PermitLocalCommand
@@ -1025,8 +1041,7 @@ In this example, we are connecting a client to a server,
 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.
+$ ssh-keygen -r host.example.com.
 .Ed
 .Pp
 The output lines will have to be added to the zonefile.
@@ -1075,11 +1090,11 @@ Client access may be more finely tuned via the
 file (see below) and the
 .Cm PermitRootLogin
 server option.
-The following entry would permit connections on the first
+The following entry would permit connections on
 .Xr tun 4
-device from user
+device from user
 .Dq jane
-and on the second device from user
+and on tun device 2 from user
 .Dq john ,
 if
 .Cm PermitRootLogin
@@ -1087,7 +1102,7 @@ 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
+tunnel="2",command="sh /etc/netstart tun2" ssh-rsa ... john
 .Ed
 .Pp
 Since a SSH-based setup entails a fair amount of overhead,
@@ -1178,7 +1193,7 @@ If the current session has no tty,
 this variable is not set.
 .It Ev TZ
 This variable is set to indicate the present time zone if it
-was set when the daemon was started (i.e., the daemon passes the value
+was set when the daemon was started (i.e. the daemon passes the value
 on to new connections).
 .It Ev USER
 Set to the name of the user logging in.
@@ -1339,15 +1354,59 @@ manual page for more information.
 .Xr ssh-keysign 8 ,
 .Xr sshd 8
 .Rs
-.%A T. Ylonen
-.%A T. Kivinen
-.%A M. Saarinen
-.%A T. Rinne
-.%A S. Lehtinen
-.%T "SSH Protocol Architecture"
-.%N draft-ietf-secsh-architecture-12.txt
-.%D January 2002
-.%O work in progress material
+.%R RFC 4250
+.%T "The Secure Shell (SSH) Protocol Assigned Numbers"
+.%D 2006
+.Re
+.Rs
+.%R RFC 4251
+.%T "The Secure Shell (SSH) Protocol Architecture"
+.%D 2006
+.Re
+.Rs
+.%R RFC 4252
+.%T "The Secure Shell (SSH) Authentication Protocol"
+.%D 2006
+.Re
+.Rs
+.%R RFC 4253
+.%T "The Secure Shell (SSH) Transport Layer Protocol"
+.%D 2006
+.Re
+.Rs
+.%R RFC 4254
+.%T "The Secure Shell (SSH) Connection Protocol"
+.%D 2006
+.Re
+.Rs
+.%R RFC 4255
+.%T "Using DNS to Securely Publish Secure Shell (SSH) Key Fingerprints"
+.%D 2006
+.Re
+.Rs
+.%R RFC 4256
+.%T "Generic Message Exchange Authentication for the Secure Shell Protocol (SSH)"
+.%D 2006
+.Re
+.Rs
+.%R RFC 4335
+.%T "The Secure Shell (SSH) Session Channel Break Extension"
+.%D 2006
+.Re
+.Rs
+.%R RFC 4344
+.%T "The Secure Shell (SSH) Transport Layer Encryption Modes"
+.%D 2006
+.Re
+.Rs
+.%R RFC 4345
+.%T "Improved Arcfour Modes for the Secure Shell (SSH) Transport Layer Protocol"
+.%D 2006
+.Re
+.Rs
+.%R RFC 4419
+.%T "Diffie-Hellman Group Exchange for the Secure Shell (SSH) Transport Layer Protocol"
+.%D 2006
 .Re
 .Sh AUTHORS
 OpenSSH is a derivative of the original and free
index 78174647cf85588ede0148eca05accd12641a289..ed03f819ff3c21ed4722174b39f2338823a35d6c 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: ssh.c,v 1.293 2006/08/03 03:34:42 deraadt Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: ssh.c,v 1.257 2005/12/20 04:41:07 dtucker Exp $");
+
+#include <sys/types.h>
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#include <sys/resource.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <netdb.h>
+#ifdef HAVE_PATHS_H
+#include <paths.h>
+#endif
+#include <pwd.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
 
 #include <openssl/evp.h>
 #include <openssl/err.h>
 
+#include "xmalloc.h"
 #include "ssh.h"
 #include "ssh1.h"
 #include "ssh2.h"
 #include "compat.h"
 #include "cipher.h"
-#include "xmalloc.h"
 #include "packet.h"
 #include "buffer.h"
-#include "bufaux.h"
 #include "channels.h"
 #include "key.h"
 #include "authfd.h"
@@ -72,6 +99,7 @@ RCSID("$OpenBSD: ssh.c,v 1.257 2005/12/20 04:41:07 dtucker Exp $");
 #include "msg.h"
 #include "monitor_fdpass.h"
 #include "uidswap.h"
+#include "version.h"
 
 #ifdef SMARTCARD
 #include "scard.h"
@@ -162,7 +190,7 @@ usage(void)
 "           [-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"
-"           [-w tunnel:tunnel] [user@]hostname [command]\n"
+"           [-w local_tun[:remote_tun]] [user@]hostname [command]\n"
        );
        exit(255);
 }
@@ -242,7 +270,7 @@ main(int ac, char **av)
        /* Parse command-line arguments. */
        host = NULL;
 
-again:
+ again:
        while ((opt = getopt(ac, av,
            "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:MNO:PR:S:TVw:XY")) != -1) {
                switch (opt) {
@@ -652,7 +680,7 @@ again:
        if (options.host_key_alias != NULL) {
                for (p = options.host_key_alias; *p; p++)
                        if (isupper(*p))
-                               *p = tolower(*p);
+                               *p = (char)tolower(*p);
        }
 
        /* Get default port if port has not been set. */
@@ -669,11 +697,15 @@ again:
                options.control_path = NULL;
 
        if (options.control_path != NULL) {
+               char thishost[NI_MAXHOST];
+
+               if (gethostname(thishost, sizeof(thishost)) == -1)
+                       fatal("gethostname: %s", strerror(errno));
                snprintf(buf, sizeof(buf), "%d", options.port);
                cp = tilde_expand_filename(options.control_path,
                    original_real_uid);
                options.control_path = percent_expand(cp, "p", buf, "h", host,
-                   "r", options.user, (char *)NULL);
+                   "r", options.user, "l", thishost, (char *)NULL);
                xfree(cp);
        }
        if (mux_command != 0 && options.control_path == NULL)
@@ -706,16 +738,16 @@ again:
        if (options.rhosts_rsa_authentication ||
            options.hostbased_authentication) {
                sensitive_data.nkeys = 3;
-               sensitive_data.keys = xmalloc(sensitive_data.nkeys *
+               sensitive_data.keys = xcalloc(sensitive_data.nkeys,
                    sizeof(Key));
 
                PRIV_START;
                sensitive_data.keys[0] = key_load_private_type(KEY_RSA1,
-                   _PATH_HOST_KEY_FILE, "", NULL);
+                   _PATH_HOST_KEY_FILE, "", NULL, NULL);
                sensitive_data.keys[1] = key_load_private_type(KEY_DSA,
-                   _PATH_HOST_DSA_KEY_FILE, "", NULL);
+                   _PATH_HOST_DSA_KEY_FILE, "", NULL, NULL);
                sensitive_data.keys[2] = key_load_private_type(KEY_RSA,
-                   _PATH_HOST_RSA_KEY_FILE, "", NULL);
+                   _PATH_HOST_RSA_KEY_FILE, "", NULL, NULL);
                PRIV_END;
 
                if (options.hostbased_authentication == 1 &&
@@ -832,6 +864,8 @@ ssh_init_forwarding(void)
                    options.gateway_ports, options.hpn_disabled,
                    options.hpn_buffer_size);
        }
+       if (i > 0 && success != i && options.exit_on_forward_failure)
+               fatal("Could not request local forwarding.");
        if (i > 0 && success == 0)
                error("Could not request local forwarding.");
 
@@ -844,11 +878,17 @@ ssh_init_forwarding(void)
                    options.remote_forwards[i].listen_port,
                    options.remote_forwards[i].connect_host,
                    options.remote_forwards[i].connect_port);
-               channel_request_remote_forwarding(
+               if (channel_request_remote_forwarding(
                    options.remote_forwards[i].listen_host,
                    options.remote_forwards[i].listen_port,
                    options.remote_forwards[i].connect_host,
-                   options.remote_forwards[i].connect_port);
+                   options.remote_forwards[i].connect_port) < 0) {
+                       if (options.exit_on_forward_failure)
+                               fatal("Could not request remote forwarding.");
+                       else
+                               logit("Warning: Could not request remote "
+                                   "forwarding.");
+               }
        }
 }
 
@@ -909,10 +949,10 @@ ssh_session(void)
                /* Store window size in the packet. */
                if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0)
                        memset(&ws, 0, sizeof(ws));
-               packet_put_int(ws.ws_row);
-               packet_put_int(ws.ws_col);
-               packet_put_int(ws.ws_xpixel);
-               packet_put_int(ws.ws_ypixel);
+               packet_put_int((u_int)ws.ws_row);
+               packet_put_int((u_int)ws.ws_col);
+               packet_put_int((u_int)ws.ws_xpixel);
+               packet_put_int((u_int)ws.ws_ypixel);
 
                /* Store tty modes in the packet. */
                tty_make_modes(fileno(stdin), NULL);
@@ -1030,9 +1070,16 @@ client_global_request_reply_fwd(int type, u_int32_t seq, void *ctxt)
            options.remote_forwards[i].listen_port,
            options.remote_forwards[i].connect_host,
            options.remote_forwards[i].connect_port);
-       if (type == SSH2_MSG_REQUEST_FAILURE)
-               logit("Warning: remote port forwarding failed for listen "
-                   "port %d", options.remote_forwards[i].listen_port);
+       if (type == SSH2_MSG_REQUEST_FAILURE) {
+               if (options.exit_on_forward_failure)
+                       fatal("Error: remote port forwarding failed for "
+                           "listen port %d",
+                           options.remote_forwards[i].listen_port);
+               else
+                       logit("Warning: remote port forwarding failed for "
+                           "listen port %d",
+                           options.remote_forwards[i].listen_port);
+       }
 }
 
 static void
@@ -1061,7 +1108,7 @@ ssh_control_listener(void)
                fatal("%s socket(): %s", __func__, strerror(errno));
 
        old_umask = umask(0177);
-       if (bind(control_fd, (struct sockaddr*)&addr, addr_len) == -1) {
+       if (bind(control_fd, (struct sockaddr *)&addr, addr_len) == -1) {
                control_fd = -1;
                if (errno == EINVAL || errno == EADDRINUSE)
                        fatal("ControlSocket %s already exists",
@@ -1225,15 +1272,16 @@ ssh_session2(void)
 static void
 load_public_identity_files(void)
 {
-       char *filename;
+       char *filename, *cp, thishost[NI_MAXHOST];
        int i = 0;
        Key *public;
+       struct passwd *pw;
 #ifdef SMARTCARD
        Key **keys;
 
        if (options.smartcard_device != NULL &&
            options.num_identity_files < SSH_MAX_IDENTITY_FILES &&
-           (keys = sc_get_keys(options.smartcard_device, NULL)) != NULL ) {
+           (keys = sc_get_keys(options.smartcard_device, NULL)) != NULL) {
                int count = 0;
                for (i = 0; keys[i] != NULL; i++) {
                        count++;
@@ -1251,9 +1299,18 @@ load_public_identity_files(void)
                xfree(keys);
        }
 #endif /* SMARTCARD */
+       if ((pw = getpwuid(original_real_uid)) == NULL)
+               fatal("load_public_identity_files: getpwuid failed");
+       if (gethostname(thishost, sizeof(thishost)) == -1)
+               fatal("load_public_identity_files: gethostname: %s",
+                   strerror(errno));
        for (; i < options.num_identity_files; i++) {
-               filename = tilde_expand_filename(options.identity_files[i],
+               cp = tilde_expand_filename(options.identity_files[i],
                    original_real_uid);
+               filename = percent_expand(cp, "d", pw->pw_dir,
+                   "u", pw->pw_name, "l", thishost, "h", host,
+                   "r", options.user, (char *)NULL);
+               xfree(cp);
                public = key_load_public(filename, NULL);
                debug("identity file %s type %d", filename,
                    public ? public->type : -1);
@@ -1279,14 +1336,14 @@ control_client_sigrelay(int signo)
 static int
 env_permitted(char *env)
 {
-       int i;
+       int i, ret;
        char name[1024], *cp;
 
-       strlcpy(name, env, sizeof(name));
-       if ((cp = strchr(name, '=')) == NULL)
+       if ((cp = strchr(env, '=')) == NULL || cp == env)
                return (0);
-
-       *cp = '\0';
+       ret = snprintf(name, sizeof(name), "%.*s", (int)(cp - env), env);
+       if (ret <= 0 || (size_t)ret >= sizeof(name))
+               fatal("env_permitted: name '%.100s...' too long", env);
 
        for (i = 0; i < options.num_send_env; i++)
                if (match_pattern(name, options.send_env[i]))
@@ -1331,29 +1388,29 @@ control_client(const char *path)
        if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
                fatal("%s socket(): %s", __func__, strerror(errno));
 
-       if (connect(sock, (struct sockaddr*)&addr, addr_len) == -1) {
+       if (connect(sock, (struct sockaddr *)&addr, addr_len) == -1) {
                if (mux_command != SSHMUX_COMMAND_OPEN) {
                        fatal("Control socket connect(%.100s): %s", path,
                            strerror(errno));
                }
                if (errno == ENOENT)
-                       debug("Control socket \"%.100s\" does not exist", path);
+                       debug("Control socket \"%.100s\" does not exist", path);
                else {
-                       error("Control socket connect(%.100s): %s", path,
+                       error("Control socket connect(%.100s): %s", path,
                            strerror(errno));
                }
-               close(sock);
-               return;
-       }
-
-       if (stdin_null_flag) {
-               if ((fd = open(_PATH_DEVNULL, O_RDONLY)) == -1)
-                       fatal("open(/dev/null): %s", strerror(errno));
-               if (dup2(fd, STDIN_FILENO) == -1)
-                       fatal("dup2: %s", strerror(errno));
-               if (fd > STDERR_FILENO)
-                       close(fd);
-       }
+               close(sock);
+               return;
+       }
+
+       if (stdin_null_flag) {
+               if ((fd = open(_PATH_DEVNULL, O_RDONLY)) == -1)
+                       fatal("open(/dev/null): %s", strerror(errno));
+               if (dup2(fd, STDIN_FILENO) == -1)
+                       fatal("dup2: %s", strerror(errno));
+               if (fd > STDERR_FILENO)
+                       close(fd);
+       }
 
        term = getenv("TERM");
 
index 1741c229a09bf69be2415f1668773ff5a04a3a05..353d930415f7ed93c77957ee8c297a33c54e1f4d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ssh1.h,v 1.5 2004/10/20 11:48:53 markus Exp $ */
+/* $OpenBSD: ssh1.h,v 1.6 2006/03/25 22:22:43 djm Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
index 38889bf85b22e49cf21b5e5c96c0d5d762cb60da..20dfda313e8c019d1ac5939da183400890b42b61 100644 (file)
@@ -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.76 2006/01/20 11:21:45 jmc Exp $
+.\" $OpenBSD: ssh_config.5,v 1.97 2006/07/27 08:00:50 jmc Exp $
 .Dd September 25, 1999
 .Dt SSH_CONFIG 5
 .Os
 .It Pa /etc/ssh/ssh_config
 .El
 .Sh DESCRIPTION
-.Nm ssh
+.Xr ssh 1
 obtains configuration data from the following sources in
 the following order:
+.Pp
 .Bl -enum -offset indent -compact
 .It
 command-line options
@@ -84,7 +85,6 @@ The configuration file has the following format:
 Empty lines and lines starting with
 .Ql #
 are comments.
-.Pp
 Otherwise a line is of the format
 .Dq keyword arguments .
 Configuration options may be separated by whitespace or
@@ -93,11 +93,14 @@ optional whitespace and exactly one
 the latter format is useful to avoid the need to quote whitespace
 when specifying configuration options using the
 .Nm ssh ,
-.Nm scp
+.Nm scp ,
 and
 .Nm sftp
 .Fl o
 option.
+Arguments may optionally be enclosed in double quotes
+.Pq \&"
+in order to represent arguments containing spaces.
 .Pp
 The possible
 keywords and their meanings are as follows (note that
@@ -108,25 +111,24 @@ Restricts the following declarations (up to the next
 .Cm Host
 keyword) to be only for those hosts that match one of the patterns
 given after the keyword.
-.Ql \&*
-and
-.Ql \&?
-can be used as wildcards in the
-patterns.
 A single
-.Ql \&*
+.Ql *
 as a pattern can be used to provide global
 defaults for all hosts.
 The host is the
 .Ar hostname
-argument given on the command line (i.e., the name is not converted to
+argument given on the command line (i.e. the name is not converted to
 a canonicalized host name before matching).
+.Pp
+See
+.Sx PATTERNS
+for more information on patterns.
 .It Cm AddressFamily
 Specifies which address family to use when connecting.
 Valid arguments are
 .Dq any ,
 .Dq inet
-(use IPv4 only) or
+(use IPv4 only), or
 .Dq inet6
 (use IPv6 only).
 .It Cm BatchMode
@@ -150,7 +152,7 @@ Note that this option does not work if
 is set to
 .Dq yes .
 .It Cm ChallengeResponseAuthentication
-Specifies whether to use challenge response authentication.
+Specifies whether to use challenge-response authentication.
 The argument to this keyword must be
 .Dq yes
 or
@@ -160,7 +162,8 @@ The default is
 .It Cm CheckHostIP
 If this flag is set to
 .Dq yes ,
-ssh will additionally check the host IP address in the
+.Xr ssh 1
+will additionally check the host IP address in the
 .Pa known_hosts
 file.
 This allows ssh to detect if a host key changed due to DNS spoofing.
@@ -180,7 +183,7 @@ and
 are supported.
 .Ar des
 is only supported in the
-.Nm ssh
+.Xr ssh 1
 client for interoperability with legacy protocol 1 implementations
 that do not support the
 .Ar 3des
@@ -206,18 +209,18 @@ The supported ciphers are
 .Dq 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''
+The default is:
+.Bd -literal -offset 3n
+aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour128,
+arcfour256,arcfour,aes192-cbc,aes256-cbc,aes128-ctr,
+aes192-ctr,aes256-ctr
 .Ed
 .It Cm ClearAllForwardings
-Specifies that all local, remote and dynamic port forwardings
+Specifies that all local, remote, and dynamic port forwardings
 specified in the configuration files or on the command line be
 cleared.
 This option is primarily useful when used from the
-.Nm ssh
+.Xr ssh 1
 command line to clear port forwardings set in
 configuration files, and is automatically set by
 .Xr scp 1
@@ -250,15 +253,15 @@ The argument must be an integer.
 This may be useful in scripts if the connection sometimes fails.
 The default is 1.
 .It Cm ConnectTimeout
-Specifies the timeout (in seconds) used when connecting to the ssh
-server, instead of using the default system TCP timeout.
+Specifies the timeout (in seconds) used when connecting to the
+SSH server, instead of using the default system TCP timeout.
 This value is used only when the target is down or really unreachable,
 not when it refuses the connection.
 .It Cm ControlMaster
 Enables the sharing of multiple sessions over a single network connection.
 When set to
-.Dq yes
-.Nm ssh
+.Dq yes ,
+.Xr ssh 1
 will listen for connections on a control socket specified using the
 .Cm ControlPath
 argument.
@@ -275,8 +278,7 @@ if the control socket does not exist, or is not listening.
 .Pp
 Setting this to
 .Dq ask
-will cause
-.Nm ssh
+will cause ssh
 to listen for control connections, but require confirmation using the
 .Ev SSH_ASKPASS
 program before they are accepted (see
@@ -284,9 +286,8 @@ program before they are accepted (see
 for details).
 If the
 .Cm ControlPath
-can not be opened,
-.Nm ssh
-will continue without connecting to a master instance.
+cannot be opened,
+ssh will continue without connecting to a master instance.
 .Pp
 X11 and
 .Xr ssh-agent 1
@@ -312,16 +313,18 @@ section above or the string
 .Dq none
 to disable connection sharing.
 In the path,
+.Ql %l
+will be substituted by the local host name,
 .Ql %h
 will be substituted by the target host name,
 .Ql %p
-the port and
+the port, and
 .Ql %r
 by the remote login username.
 It is recommended that any
 .Cm ControlPath
 used for opportunistic connection sharing include
-all three of these escape sequences.
+at least %h, %p, and %r.
 This ensures that shared connections are uniquely identified.
 .It Cm DynamicForward
 Specifies that a TCP port on the local machine be forwarded
@@ -352,7 +355,7 @@ empty address or
 indicates that the port should be available from all interfaces.
 .Pp
 Currently the SOCKS4 and SOCKS5 protocols are supported, and
-.Nm ssh
+.Xr ssh 1
 will act as a SOCKS server.
 Multiple forwardings may be specified, and
 additional forwardings can be given on the command line.
@@ -388,6 +391,17 @@ followed by a letter, or
 to disable the escape
 character entirely (making the connection transparent for binary
 data).
+.It Cm ExitOnForwardFailure
+Specifies whether
+.Xr ssh 1
+should terminate the connection if it cannot set up all requested
+dynamic, local, and remote port forwardings.
+The argument must be
+.Dq yes
+or
+.Dq no .
+The default is
+.Dq no .
 .It Cm ForwardAgent
 Specifies whether the connection to the authentication agent (if any)
 will be forwarded to the remote machine.
@@ -427,12 +441,12 @@ if the
 option is also enabled.
 .It Cm ForwardX11Trusted
 If this option is set to
-.Dq yes
-then remote X11 clients will have full access to the original X11 display.
+.Dq yes ,
+remote X11 clients will have full access to the original X11 display.
 .Pp
 If this option is set to
-.Dq no
-then remote X11 clients will be considered untrusted and prevented
+.Dq no ,
+remote X11 clients will be considered untrusted and prevented
 from stealing or tampering with data belonging to trusted X11
 clients.
 Furthermore, the
@@ -449,12 +463,11 @@ the restrictions imposed on untrusted clients.
 Specifies whether remote hosts are allowed to connect to local
 forwarded ports.
 By default,
-.Nm ssh
+.Xr ssh 1
 binds local port forwardings to the loopback address.
 This prevents other remote hosts from connecting to forwarded ports.
 .Cm GatewayPorts
-can be used to specify that
-.Nm ssh
+can be used to specify that ssh
 should bind local port forwardings to the wildcard address,
 thus allowing remote hosts to connect to forwarded ports.
 The argument must be
@@ -495,19 +508,20 @@ This option only applies to protocol version 2 connections using GSSAPI
 key exchange.
 .It Cm HashKnownHosts
 Indicates that
-.Nm ssh
+.Xr ssh 1
 should hash host names and addresses when they are added to
 .Pa ~/.ssh/known_hosts .
 These hashed names may be used normally by
-.Nm ssh
+.Xr ssh 1
 and
-.Nm sshd ,
+.Xr sshd 8 ,
 but they do not reveal identifying information should the file's contents
 be disclosed.
 The default is
 .Dq no .
-Note that hashing of names and addresses will not be retrospectively applied
-to existing known hosts files, but these may be manually hashed using
+Note that existing names and addresses in known hosts files
+will not be converted automatically,
+but may be manually hashed using
 .Xr ssh-keygen 1 .
 .It Cm HostbasedAuthentication
 Specifies whether to try rhosts based authentication with public key
@@ -530,30 +544,29 @@ The default for this option is:
 Specifies an alias that should be used instead of the
 real host name when looking up or saving the host key
 in the host key database files.
-This option is useful for tunneling ssh connections
+This option is useful for tunneling SSH connections
 or for multiple servers running on a single host.
 .It Cm HostName
 Specifies the real host name to log into.
 This can be used to specify nicknames or abbreviations for hosts.
-Default is the name given on the command line.
+The default is the name given on the command line.
 Numeric IP addresses are also permitted (both on the command line and in
 .Cm HostName
 specifications).
 .It Cm IdentitiesOnly
 Specifies that
-.Nm ssh
+.Xr ssh 1
 should only use the authentication identity files configured in the
 .Nm
 files,
-even if the
-.Nm ssh-agent
+even if
+.Xr ssh-agent 1
 offers more identities.
 The argument to this keyword must be
 .Dq yes
 or
 .Dq no .
-This option is intended for situations where
-.Nm ssh-agent
+This option is intended for situations where ssh-agent
 offers many different identities.
 The default is
 .Dq no .
@@ -569,8 +582,21 @@ and
 for protocol version 2.
 Additionally, any identities represented by the authentication agent
 will be used for authentication.
+.Pp
 The file name may use the tilde
-syntax to refer to a user's home directory.
+syntax to refer to a user's home directory or one of the following
+escape characters:
+.Ql %d
+(local user's home directory),
+.Ql %u
+(local user name),
+.Ql %l
+(local host name),
+.Ql %h
+(remote host name) or
+.Ql %r
+(remote user name).
+.Pp
 It is possible to have
 multiple identity files specified in configuration files; all these
 identities will be tried in sequence.
@@ -578,6 +604,13 @@ identities will be tried in sequence.
 Specifies the list of methods to use in keyboard-interactive authentication.
 Multiple method names must be comma-separated.
 The default is to use the server specified list.
+The methods available vary depending on what the server supports.
+For an OpenSSH server,
+it may be zero or more of:
+.Dq bsdauth ,
+.Dq pam ,
+and
+.Dq skey .
 .It Cm LocalCommand
 Specifies a command to execute on the local machine after successfully
 connecting to the server.
@@ -619,9 +652,9 @@ empty address or
 indicates that the port should be available from all interfaces.
 .It Cm LogLevel
 Gives the verbosity level that is used when logging messages from
-.Nm ssh .
+.Xr ssh 1 .
 The possible values are:
-QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, DEBUG1, DEBUG2 and DEBUG3.
+QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, DEBUG1, DEBUG2, and DEBUG3.
 The default is INFO.
 DEBUG and DEBUG1 are equivalent.
 DEBUG2 and DEBUG3 each specify higher levels of verbose output.
@@ -631,7 +664,7 @@ in order of preference.
 The MAC algorithm is used in protocol version 2
 for data integrity protection.
 Multiple algorithms must be comma-separated.
-The default is
+The default is:
 .Dq hmac-md5,hmac-sha1,hmac-ripemd160,hmac-sha1-96,hmac-md5-96 .
 .It Cm NoHostAuthenticationForLocalhost
 This option can be used if the home directory is shared across machines.
@@ -646,7 +679,7 @@ The default is to check the host key for localhost.
 .It Cm NumberOfPasswordPrompts
 Specifies the number of password prompts before giving up.
 The argument to this keyword must be an integer.
-Default is 3.
+The default is 3.
 .It Cm PasswordAuthentication
 Specifies whether to use password authentication.
 The argument to this keyword must be
@@ -670,7 +703,7 @@ The default is
 .Dq no .
 .It Cm Port
 Specifies the port number to connect on the remote host.
-Default is 22.
+The default is 22.
 .It Cm PreferredAuthentications
 Specifies the order in which the client should try protocol 2
 authentication methods.
@@ -679,20 +712,26 @@ This allows a client to prefer one method (e.g.\&
 over another method (e.g.\&
 .Cm password )
 The default for this option is:
-.Dq publickey,gssapi-keyex,external-keyx,gssapi-with-mic,gssapi,password,keyboard-interactive .
+.Do gssapi-keyex ,
+external-keyx,
+gssapi-with-mic,
+hostbased,
+publickey,
+keyboard-interactive,
+password
+.Dc .
 .It Cm Protocol
 Specifies the protocol versions
-.Nm ssh
+.Xr ssh 1
 should support in order of preference.
 The possible values are
-.Dq 1
+.Sq 1
 and
-.Dq 2 .
+.Sq 2 .
 Multiple versions must be comma-separated.
 The default is
 .Dq 2,1 .
-This means that
-.Nm ssh
+This means that ssh
 tries version 2 and falls back to version 1
 if version 2 is not available.
 .It Cm ProxyCommand
@@ -750,9 +789,9 @@ or
 .Sq G
 to indicate Kilobytes, Megabytes, or Gigabytes, respectively.
 The default is between
-.Dq 1G
+.Sq 1G
 and
-.Dq 4G ,
+.Sq 4G ,
 depending on the cipher.
 This option applies to protocol version 2 only.
 .It Cm RemoteForward
@@ -798,7 +837,7 @@ or
 The default is
 .Dq no .
 This option applies to protocol version 1 only and requires
-.Nm ssh
+.Xr ssh 1
 to be setuid root.
 .It Cm RSAAuthentication
 Specifies whether to try RSA authentication.
@@ -816,31 +855,31 @@ Note that this option applies to protocol version 1 only.
 Specifies what variables from the local
 .Xr environ 7
 should be sent to the server.
-Note that environment passing is only supported for protocol 2, the
-server must also support it, and the server must be configured to
+Note that environment passing is only supported for protocol 2.
+The server must also support it, and the server must be configured to
 accept these environment variables.
 Refer to
 .Cm AcceptEnv
 in
 .Xr sshd_config 5
 for how to configure the server.
-Variables are specified by name, which may contain the wildcard characters
-.Ql \&*
-and
-.Ql \&? .
+Variables are specified by name, which may contain wildcard characters.
 Multiple environment variables may be separated by whitespace or spread
 across multiple
 .Cm SendEnv
 directives.
 The default is not to send any environment variables.
+.Pp
+See
+.Sx PATTERNS
+for more information on patterns.
 .It Cm ServerAliveCountMax
 Sets the number of server alive messages (see below) which may be
 sent without
-.Nm ssh
+.Xr ssh 1
 receiving any messages back from the server.
 If this threshold is reached while server alive messages are being sent,
-.Nm ssh
-will disconnect from the server, terminating the session.
+ssh will disconnect from the server, terminating the session.
 It is important to note that the use of server alive messages is very
 different from
 .Cm TCPKeepAlive
@@ -856,14 +895,15 @@ server depend on knowing when a connection has become inactive.
 The default value is 3.
 If, for example,
 .Cm ServerAliveInterval
-(see below) 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.
+is left at the default, if the server becomes unresponsive,
+ssh will disconnect after approximately 45 seconds.
+This option applies to protocol version 2 only.
 .It Cm ServerAliveInterval
 Sets a timeout interval in seconds after which if no data has been received
 from the server,
-.Nm ssh
+.Xr ssh 1
 will send a message through the encrypted
 channel to request a response from the server.
 The default
@@ -872,41 +912,39 @@ 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
-.Nm ssh
+.Xr ssh 1
 should use to communicate with a smartcard used for storing the user's
 private RSA key.
 By default, no device is specified and smartcard support is not activated.
 .It Cm StrictHostKeyChecking
 If this flag is set to
 .Dq yes ,
-.Nm ssh
+.Xr ssh 1
 will never automatically add host keys to the
 .Pa ~/.ssh/known_hosts
 file, and refuses to connect to hosts whose host key has changed.
 This provides maximum protection against trojan horse attacks,
-however, can be annoying when the
+though it can be annoying when the
 .Pa /etc/ssh/ssh_known_hosts
-file is poorly maintained, or connections to new hosts are
+file is poorly maintained or when connections to new hosts are
 frequently made.
 This option forces the user to manually
 add all new hosts.
 If this flag is set to
 .Dq no ,
-.Nm ssh
-will automatically add new host keys to the
+ssh will automatically add new host keys to the
 user known hosts files.
 If this flag is set to
 .Dq ask ,
 new host keys
 will be added to the user known host files only after the user
 has confirmed that is what they really want to do, and
-.Nm ssh
-will refuse to connect to hosts whose host key has changed.
+ssh will refuse to connect to hosts whose host key has changed.
 The host keys of
 known hosts will be verified automatically in all cases.
 The argument must be
 .Dq yes ,
-.Dq no
+.Dq no ,
 or
 .Dq ask .
 The default is
@@ -929,24 +967,44 @@ This is important in scripts, and many users want it too.
 To disable TCP keepalive messages, the value should be set to
 .Dq no .
 .It Cm Tunnel
-Request starting
+Request
 .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 point-to-point
+(layer 3),
 .Dq ethernet
+(layer 2),
 or
 .Dq no .
+Specifying
+.Dq yes
+requests the default tunnel mode, which is
+.Dq point-to-point .
 The default is
 .Dq no .
 .It Cm TunnelDevice
-Force a specified
+Specifies the
 .Xr tun 4
-device on the client.
-Without this option, the next available device will be used.
+devices to open on the client
+.Pq Ar local_tun
+and the server
+.Pq Ar remote_tun .
+.Pp
+The argument must be
+.Sm off
+.Ar local_tun Op : Ar remote_tun .
+.Sm on
+The devices may be specified by numerical ID or the keyword
+.Dq any ,
+which uses the next available tunnel device.
+If
+.Ar remote_tun
+is not specified, it defaults to
+.Dq any .
+The default is
+.Dq any:any .
 .It Cm UsePrivilegedPort
 Specifies whether to use a privileged port for outgoing connections.
 The argument must be
@@ -956,8 +1014,8 @@ or
 The default is
 .Dq no .
 If set to
-.Dq yes
-.Nm ssh
+.Dq yes ,
+.Xr ssh 1
 must be setuid root.
 Note that this option must be set to
 .Dq yes
@@ -990,12 +1048,17 @@ need to confirm new host keys according to the
 option.
 The argument must be
 .Dq yes ,
-.Dq no
+.Dq no ,
 or
 .Dq ask .
 The default is
 .Dq no .
 Note that this option applies to protocol version 2 only.
+.Pp
+See also
+.Sx VERIFYING HOST KEYS
+in
+.Xr ssh 1 .
 .It Cm XAuthLocation
 Specifies the full pathname of the
 .Xr xauth 1
@@ -1003,14 +1066,47 @@ program.
 The default is
 .Pa /usr/X11R6/bin/xauth .
 .El
+.Sh PATTERNS
+A
+.Em pattern
+consists of zero or more non-whitespace characters,
+.Sq *
+(a wildcard that matches zero or more characters),
+or
+.Sq ?\&
+(a wildcard that matches exactly one character).
+For example, to specify a set of declarations for any host in the
+.Dq .co.uk
+set of domains,
+the following pattern could be used:
+.Pp
+.Dl Host *.co.uk
+.Pp
+The following pattern
+would match any host in the 192.168.0.[0-9] network range:
+.Pp
+.Dl Host 192.168.0.?
+.Pp
+A
+.Em pattern-list
+is a comma-separated list of patterns.
+Patterns within pattern-lists may be negated
+by preceding them with an exclamation mark
+.Pq Sq !\& .
+For example,
+to allow a key to be used from anywhere within an organisation
+except from the
+.Dq dialup
+pool,
+the following entry (in authorized_keys) could be used:
+.Pp
+.Dl from=\&"!*.dialup.example.com,*.example.com\&"
 .Sh FILES
 .Bl -tag -width Ds
 .It Pa ~/.ssh/config
 This is the per-user configuration file.
 The format of this file is described above.
-This file is used by the
-.Nm ssh
-client.
+This file is used by the SSH client.
 Because of the potential for abuse, this file must have strict permissions:
 read/write for the user, and not accessible by others.
 .It Pa /etc/ssh/ssh_config
index 975674ccaf99d12568d5773c879ae31f03713a27..e96f02639252569a943fe7decdceb284b28292b4 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: sshconnect.c,v 1.199 2006/08/03 03:34:42 deraadt Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshconnect.c,v 1.171 2005/12/06 22:38:27 reyk Exp $");
 
-#include <openssl/bn.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <netdb.h>
+#ifdef HAVE_PATHS_H
+#include <paths.h>
+#endif
+#include <pwd.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
 
-#include "ssh.h"
 #include "xmalloc.h"
+#include "key.h"
+#include "hostfile.h"
+#include "ssh.h"
 #include "rsa.h"
 #include "buffer.h"
 #include "packet.h"
@@ -32,6 +56,7 @@ RCSID("$OpenBSD: sshconnect.c,v 1.171 2005/12/06 22:38:27 reyk Exp $");
 #include "atomicio.h"
 #include "misc.h"
 #include "dns.h"
+#include "version.h"
 
 char *client_version_string = NULL;
 char *server_version_string = NULL;
@@ -62,7 +87,6 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command)
        int pin[2], pout[2];
        pid_t pid;
        char strport[NI_MAXSERV];
-       size_t len;
 
        /* Convert the port number into a string. */
        snprintf(strport, sizeof strport, "%hu", port);
@@ -74,10 +98,7 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command)
         * Use "exec" to avoid "sh -c" processes on some platforms
         * (e.g. Solaris)
         */
-       len = strlen(proxy_command) + 6;
-       tmp = xmalloc(len);
-       strlcpy(tmp, "exec ", len);
-       strlcat(tmp, proxy_command, len);
+       xasprintf(&tmp, "exec %s", proxy_command);
        command_string = percent_expand(tmp, "h", host,
            "p", strport, (char *)NULL);
        xfree(tmp);
@@ -94,8 +115,7 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command)
                char *argv[10];
 
                /* Child.  Permanently give up superuser privileges. */
-               seteuid(original_real_uid);
-               setuid(original_real_uid);
+               permanently_drop_suid(original_real_uid);
 
                /* Redirect stdin and stdout. */
                close(pin[1]);
@@ -236,7 +256,7 @@ timeout_connect(int sockfd, const struct sockaddr *serv_addr,
        fd_set *fdset;
        struct timeval tv;
        socklen_t optlen;
-       int fdsetsz, optval, rc, result = -1;
+       int optval, rc, result = -1;
 
        if (timeout <= 0)
                return (connect(sockfd, serv_addr, addrlen));
@@ -250,10 +270,8 @@ timeout_connect(int sockfd, const struct sockaddr *serv_addr,
        if (errno != EINPROGRESS)
                return (-1);
 
-       fdsetsz = howmany(sockfd + 1, NFDBITS) * sizeof(fd_mask);
-       fdset = (fd_set *)xmalloc(fdsetsz);
-
-       memset(fdset, 0, fdsetsz);
+       fdset = (fd_set *)xcalloc(howmany(sockfd + 1, NFDBITS),
+           sizeof(fd_mask));
        FD_SET(sockfd, fdset);
        tv.tv_sec = timeout;
        tv.tv_usec = 0;
@@ -336,17 +354,14 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
                fatal("%s: %.100s: %s", __progname, host,
                    gai_strerror(gaierr));
 
-       /*
-        * Try to connect several times.  On some machines, the first time
-        * will sometimes fail.  In general socket code appears to behave
-        * quite magically on many machines.
-                */
-       for (attempt = 0; ;) {
+       for (attempt = 0; attempt < connection_attempts; attempt++) {
                if (attempt > 0)
                        debug("Trying again...");
 
-               /* Loop through addresses for this host, and try each one in
-                  sequence until the connection succeeds. */
+               /*
+                * Loop through addresses for this host, and try each one in
+                * sequence until the connection succeeds.
+                */
                for (ai = aitop; ai; ai = ai->ai_next) {
                        if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
                                continue;
@@ -373,21 +388,13 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
                        } else {
                                debug("connect to address %s port %s: %s",
                                    ntop, strport, strerror(errno));
-                               /*
-                                * Close the failed socket; there appear to
-                                * be some problems when reusing a socket for
-                                * which connect() has already returned an
-                                * error.
-                                */
                                close(sock);
+                               sock = -1;
                        }
                }
-               if (ai)
+               if (sock != -1)
                        break;  /* Successful connection. */
 
-               attempt++;
-               if (attempt >= connection_attempts)
-                       break;
                /* Sleep a moment before retrying. */
                sleep(1);
        }
@@ -395,7 +402,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
        freeaddrinfo(aitop);
 
        /* Return failure if we didn't get a successful connection. */
-       if (attempt >= connection_attempts) {
+       if (sock == -1) {
                error("ssh: connect to host %s port %s: %s",
                    host, strport, strerror(errno));
                return (-1);
@@ -427,10 +434,10 @@ ssh_exchange_identification(void)
        int connection_in = packet_get_connection_in();
        int connection_out = packet_get_connection_out();
        int minor1 = PROTOCOL_MINOR_1;
-       u_int i;
+       u_int i, n;
 
        /* Read other side's version identification. */
-       for (;;) {
+       for (n = 0;;) {
                for (i = 0; i < sizeof(buf) - 1; i++) {
                        size_t len = atomicio(read, connection_in, &buf[i], 1);
 
@@ -447,6 +454,8 @@ ssh_exchange_identification(void)
                                buf[i + 1] = 0;
                                break;
                        }
+                       if (++n > 65536)
+                               fatal("ssh_exchange_identification: No banner received");
                }
                buf[sizeof(buf) - 1] = 0;
                if (strncmp(buf, "SSH-", 4) == 0)
@@ -548,13 +557,17 @@ confirm(const char *prompt)
  * check whether the supplied host key is valid, return -1 if the key
  * is not valid. the user_hostfile will not be updated if 'readonly' is true.
  */
+#define RDRW   0
+#define RDONLY 1
+#define ROQUIET        2
 static int
-check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
-    int readonly, const char *user_hostfile, const char *system_hostfile)
+check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
+    Key *host_key, int readonly, const char *user_hostfile,
+    const char *system_hostfile)
 {
        Key *file_key;
        const char *type = key_type(host_key);
-       char *ip = NULL;
+       char *ip = NULL, *host = NULL;
        char hostline[1000], *hostp, *fp;
        HostStatus host_status;
        HostStatus ip_status;
@@ -605,7 +618,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
                if (getnameinfo(hostaddr, salen, ntop, sizeof(ntop),
                    NULL, 0, NI_NUMERICHOST) != 0)
                        fatal("check_host_key: getnameinfo failed");
-               ip = xstrdup(ntop);
+               ip = put_host_port(ntop, port);
        } else {
                ip = xstrdup("<no hostip for proxy command>");
        }
@@ -613,18 +626,21 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
         * Turn off check_host_ip if the connection is to localhost, via proxy
         * command or if we don't have a hostname to compare with
         */
-       if (options.check_host_ip &&
-           (local || strcmp(host, ip) == 0 || options.proxy_command != NULL))
+       if (options.check_host_ip && (local ||
+           strcmp(hostname, ip) == 0 || options.proxy_command != NULL))
                options.check_host_ip = 0;
 
        /*
-        * Allow the user to record the key under a different name. This is
-        * useful for ssh tunneling over forwarded connections or if you run
-        * multiple sshd's on different ports on the same machine.
+        * Allow the user to record the key under a different name or
+        * differentiate a non-standard port.  This is useful for ssh
+        * tunneling over forwarded connections or if you run multiple
+        * sshd's on different ports on the same machine.
         */
        if (options.host_key_alias != NULL) {
-               host = options.host_key_alias;
+               host = xstrdup(options.host_key_alias);
                debug("using hostkeyalias: %s", host);
+       } else {
+               host = put_host_port(hostname, port);
        }
 
        /*
@@ -693,6 +709,15 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
                }
                break;
        case HOST_NEW:
+               if (options.host_key_alias == NULL && port != 0 &&
+                   port != SSH_DEFAULT_PORT) {
+                       debug("checking without port identifier");
+                       if (check_host_key(hostname, hostaddr, 0, host_key, 2,
+                           user_hostfile, system_hostfile) == 0) {
+                               debug("found matching key w/out port");
+                               break;
+                       }
+               }
                if (readonly)
                        goto fail;
                /* The host is new. */
@@ -772,6 +797,8 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
                            "list of known hosts.", hostp, type);
                break;
        case HOST_CHANGED:
+               if (readonly == ROQUIET)
+                       goto fail;
                if (options.check_host_ip && host_ip_differ) {
                        char *key_msg;
                        if (ip_status == HOST_NEW)
@@ -810,7 +837,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
                /*
                 * If strict host key checking has not been requested, allow
                 * the connection but without MITM-able authentication or
-                * agent forwarding.
+                * forwarding.
                 */
                if (options.password_authentication) {
                        error("Password authentication is disabled to avoid "
@@ -845,6 +872,11 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
                        options.num_local_forwards =
                            options.num_remote_forwards = 0;
                }
+               if (options.tun_open != SSH_TUNMODE_NO) {
+                       error("Tunnel forwarding is disabled to avoid "
+                           "man-in-the-middle attacks.");
+                       options.tun_open = SSH_TUNMODE_NO;
+               }
                /*
                 * XXX Should permit the user to change to use the new id.
                 * This could be done by converting the host key to an
@@ -886,10 +918,12 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
        }
 
        xfree(ip);
+       xfree(host);
        return 0;
 
 fail:
        xfree(ip);
+       xfree(host);
        return -1;
 }
 
@@ -923,12 +957,13 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
        /* return ok if the key can be found in an old keyfile */
        if (stat(options.system_hostfile2, &st) == 0 ||
            stat(options.user_hostfile2, &st) == 0) {
-               if (check_host_key(host, hostaddr, host_key, /*readonly*/ 1,
-                   options.user_hostfile2, options.system_hostfile2) == 0)
+               if (check_host_key(host, hostaddr, options.port, host_key,
+                   RDONLY, options.user_hostfile2,
+                   options.system_hostfile2) == 0)
                        return 0;
        }
-       return check_host_key(host, hostaddr, host_key, /*readonly*/ 0,
-           options.user_hostfile, options.system_hostfile);
+       return check_host_key(host, hostaddr, options.port, host_key,
+           RDRW, options.user_hostfile, options.system_hostfile);
 }
 
 /*
@@ -952,7 +987,7 @@ ssh_login(Sensitive *sensitive, const char *orighost,
        host = xstrdup(orighost);
        for (cp = host; *cp; cp++)
                if (isupper(*cp))
-                       *cp = tolower(*cp);
+                       *cp = (char)tolower(*cp);
 
        /* Exchange protocol version identification strings with the server. */
        ssh_exchange_identification();
@@ -969,6 +1004,7 @@ ssh_login(Sensitive *sensitive, const char *orighost,
                ssh_kex(host, hostaddr);
                ssh_userauth1(local_user, server_user, host, sensitive);
        }
+       xfree(local_user);
 }
 
 void
@@ -982,8 +1018,7 @@ ssh_put_password(char *password)
                return;
        }
        size = roundup(strlen(password) + 1, 32);
-       padded = xmalloc(size);
-       memset(padded, 0, size);
+       padded = xcalloc(1, size);
        strlcpy(padded, password, size);
        packet_put_string(padded, size);
        memset(padded, 0, size);
index 440d7c5bdb07ce0804f266befe7fcc438a6f2e95..90fcb344fc4f62020a132c1eb01a0cb91cc61dca 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: sshconnect1.c,v 1.69 2006/08/03 03:34:42 deraadt Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshconnect1.c,v 1.62 2005/10/30 08:52:18 djm Exp $");
+
+#include <sys/types.h>
+#include <sys/socket.h>
 
 #include <openssl/bn.h>
 #include <openssl/md5.h>
 
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <pwd.h>
+
+#include "xmalloc.h"
 #include "ssh.h"
 #include "ssh1.h"
-#include "xmalloc.h"
 #include "rsa.h"
 #include "buffer.h"
 #include "packet.h"
+#include "key.h"
+#include "cipher.h"
 #include "kex.h"
 #include "uidswap.h"
 #include "log.h"
 #include "readconf.h"
-#include "key.h"
 #include "authfd.h"
 #include "sshconnect.h"
 #include "authfile.h"
 #include "misc.h"
-#include "cipher.h"
 #include "canohost.h"
+#include "hostfile.h"
 #include "auth.h"
 
 /* Session id for the current session. */
@@ -197,7 +208,7 @@ try_rsa_authentication(int idx)
        BIGNUM *challenge;
        Key *public, *private;
        char buf[300], *passphrase, *comment, *authfile;
-       int i, type, quit;
+       int i, perm_ok = 1, type, quit;
 
        public = options.identity_keys[idx];
        authfile = options.identity_files[idx];
@@ -243,15 +254,16 @@ try_rsa_authentication(int idx)
        if (public->flags & KEY_FLAG_EXT)
                private = public;
        else
-               private = key_load_private_type(KEY_RSA1, authfile, "", NULL);
-       if (private == NULL && !options.batch_mode) {
+               private = key_load_private_type(KEY_RSA1, authfile, "", NULL,
+                   &perm_ok);
+       if (private == NULL && !options.batch_mode && perm_ok) {
                snprintf(buf, sizeof(buf),
                    "Enter passphrase for RSA key '%.100s': ", comment);
                for (i = 0; i < options.number_of_password_prompts; i++) {
                        passphrase = read_passphrase(buf, 0);
                        if (strcmp(passphrase, "") != 0) {
                                private = key_load_private_type(KEY_RSA1,
-                                   authfile, passphrase, NULL);
+                                   authfile, passphrase, NULL, NULL);
                                quit = 0;
                        } else {
                                debug2("no passphrase given, try next key");
@@ -268,7 +280,7 @@ try_rsa_authentication(int idx)
        xfree(comment);
 
        if (private == NULL) {
-               if (!options.batch_mode)
+               if (!options.batch_mode && perm_ok)
                        error("Bad passphrase.");
 
                /* Send a dummy response packet to avoid protocol error. */
index c35587ff7aee791309235947e054d2f3b2ce13db..60c31c4ea6e8961a5dab133babd46993a8623af0 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: sshconnect2.c,v 1.162 2006/08/30 00:06:51 dtucker Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshconnect2.c,v 1.143 2005/10/14 02:17:59 stevesk Exp $");
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
 
 #include "openbsd-compat/sys-queue.h"
 
+#include "xmalloc.h"
 #include "ssh.h"
 #include "ssh2.h"
-#include "xmalloc.h"
 #include "buffer.h"
 #include "packet.h"
 #include "compat.h"
-#include "bufaux.h"
 #include "cipher.h"
+#include "key.h"
 #include "kex.h"
 #include "myproposal.h"
 #include "sshconnect.h"
@@ -49,6 +62,7 @@ RCSID("$OpenBSD: sshconnect2.c,v 1.143 2005/10/14 02:17:59 stevesk Exp $");
 #include "canohost.h"
 #include "msg.h"
 #include "pathnames.h"
+#include "uidswap.h"
 
 #ifdef GSSAPI
 #include "ssh-gss.h"
@@ -127,8 +141,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
        if (options.ciphers != NULL) {
                myproposal[PROPOSAL_ENC_ALGS_CTOS] =
                myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
-       } 
-
+       }
        myproposal[PROPOSAL_ENC_ALGS_CTOS] =
            compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]);
        myproposal[PROPOSAL_ENC_ALGS_STOC] =
@@ -172,6 +185,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
        kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client;
        kex->kex[KEX_GSS_GEX_SHA1] = kexgss_client;
 #endif
+       kex->kex[KEX_DH_GEX_SHA256] = kexgex_client;
        kex->client_version_string=client_version_string;
        kex->server_version_string=server_version_string;
        kex->verify_host_key=&verify_host_key_callback;
@@ -443,7 +457,7 @@ input_userauth_banner(int type, u_int32_t seq, void *ctxt)
        debug3("input_userauth_banner");
        msg = packet_get_string(NULL);
        lang = packet_get_string(NULL);
-       if (options.log_level > SYSLOG_LEVEL_QUIET)
+       if (options.log_level >= SYSLOG_LEVEL_INFO)
                fprintf(stderr, "%s", msg);
        xfree(msg);
        xfree(lang);
@@ -585,17 +599,10 @@ userauth_gssapi(Authctxt *authctxt)
 
        /* Check to see if the mechanism is usable before we offer it */
        while (mech < gss_supported->count && !ok) {
-               if (gssctxt)
-                       ssh_gssapi_delete_ctx(&gssctxt);
-               ssh_gssapi_build_ctx(&gssctxt);
-               ssh_gssapi_set_oid(gssctxt, &gss_supported->elements[mech]);
-
                /* My DER encoding requires length<128 */
                if (gss_supported->elements[mech].length < 128 &&
-                   ssh_gssapi_check_mechanism(&gss_supported->elements[mech],
-                                              gss_host) &&
-                   !GSS_ERROR(ssh_gssapi_import_name(gssctxt,
-                                                     gss_host))) {
+                   ssh_gssapi_check_mechanism(&gssctxt, 
+                   &gss_supported->elements[mech], gss_host)) {
                        ok = 1; /* Mechanism works */
                } else {
                        mech++;
@@ -1157,14 +1164,16 @@ load_identity_file(char *filename)
 {
        Key *private;
        char prompt[300], *passphrase;
-       int quit, i;
+       int perm_ok, quit, i;
        struct stat st;
 
        if (stat(filename, &st) < 0) {
                debug3("no such identity: %s", filename);
                return NULL;
        }
-       private = key_load_private_type(KEY_UNSPEC, filename, "", NULL);
+       private = key_load_private_type(KEY_UNSPEC, filename, "", NULL, &perm_ok);
+       if (!perm_ok)
+               return NULL;
        if (private == NULL) {
                if (options.batch_mode)
                        return NULL;
@@ -1173,8 +1182,8 @@ load_identity_file(char *filename)
                for (i = 0; i < options.number_of_password_prompts; i++) {
                        passphrase = read_passphrase(prompt, 0);
                        if (strcmp(passphrase, "") != 0) {
-                               private = key_load_private_type(KEY_UNSPEC, filename,
-                                   passphrase, NULL);
+                               private = key_load_private_type(KEY_UNSPEC,
+                                   filename, passphrase, NULL, NULL);
                                quit = 0;
                        } else {
                                debug2("no passphrase given, try next key");
@@ -1217,8 +1226,7 @@ pubkey_prepare(Authctxt *authctxt)
                if (key && key->type == KEY_RSA1)
                        continue;
                options.identity_keys[i] = NULL;
-               id = xmalloc(sizeof(*id));
-               memset(id, 0, sizeof(*id));
+               id = xcalloc(1, sizeof(*id));
                id->key = key;
                id->filename = xstrdup(options.identity_files[i]);
                TAILQ_INSERT_TAIL(&files, id, next);
@@ -1242,8 +1250,7 @@ pubkey_prepare(Authctxt *authctxt)
                                }
                        }
                        if (!found && !options.identities_only) {
-                               id = xmalloc(sizeof(*id));
-                               memset(id, 0, sizeof(*id));
+                               id = xcalloc(1, sizeof(*id));
                                id->key = key;
                                id->filename = comment;
                                id->ac = ac;
@@ -1439,8 +1446,7 @@ ssh_keysign(Key *key, u_char **sigp, u_int *lenp,
                return -1;
        }
        if (pid == 0) {
-               seteuid(getuid());
-               setuid(getuid());
+               permanently_drop_suid(getuid());
                close(from[0]);
                if (dup2(from[1], STDOUT_FILENO) < 0)
                        fatal("ssh_keysign: dup2: %s", strerror(errno));
@@ -1520,12 +1526,11 @@ userauth_hostbased(Authctxt *authctxt)
        if (p == NULL) {
                error("userauth_hostbased: cannot get local ipaddr/name");
                key_free(private);
+               xfree(blob);
                return 0;
        }
        len = strlen(p) + 2;
-       chost = xmalloc(len);
-       strlcpy(chost, p, len);
-       strlcat(chost, ".", len);
+       xasprintf(&chost, "%s.", p);
        debug2("userauth_hostbased: chost %s", chost);
        xfree(p);
 
@@ -1558,6 +1563,7 @@ userauth_hostbased(Authctxt *authctxt)
                error("key_sign failed");
                xfree(chost);
                xfree(pkalg);
+               xfree(blob);
                return 0;
        }
        packet_start(SSH2_MSG_USERAUTH_REQUEST);
@@ -1573,6 +1579,7 @@ userauth_hostbased(Authctxt *authctxt)
        xfree(signature);
        xfree(chost);
        xfree(pkalg);
+       xfree(blob);
 
        packet_send();
        return 1;
index 51d339b658143e982cce65e93d77e196188ec340..522279ee351d4594db1033ae8746c59035510f46 100644 (file)
@@ -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.215 2006/02/01 09:11:41 jmc Exp $
+.\" $OpenBSD: sshd.8,v 1.234 2006/08/21 08:15:57 dtucker Exp $
 .Dd September 25, 1999
 .Dt SSHD 8
 .Os
@@ -81,7 +81,7 @@ configuration file.
 .Nm
 rereads its configuration file when it receives a hangup signal,
 .Dv SIGHUP ,
-by executing itself with the name and options it was started with, e.g.,
+by executing itself with the name and options it was started with, e.g.\&
 .Pa /usr/sbin/sshd .
 .Pp
 The options are as follows:
@@ -154,7 +154,7 @@ is normally not run
 from inetd because it needs to generate the server key before it can
 respond to the client, and this may take tens of seconds.
 Clients would have to wait too long if the key was regenerated every time.
-However, with small key sizes (e.g., 512) using
+However, with small key sizes (e.g. 512) using
 .Nm
 from inetd may
 be feasible.
@@ -308,17 +308,6 @@ 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
@@ -326,7 +315,7 @@ 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.
+After this, the client either requests a shell or execution of a command.
 The sides then enter session mode.
 In this mode, either side may send
 data at any time, and such data is forwarded to/from the shell or
@@ -381,31 +370,73 @@ The
 .Dq rc
 files are given the X11
 authentication protocol and cookie in standard input.
+See
+.Sx SSHRC ,
+below.
 .It
 Runs user's shell or command.
 .El
+.Sh SSHRC
+If the file
+.Pa ~/.ssh/rc
+exists,
+.Xr sh 1
+runs it after reading the
+environment files but before starting the user's shell or command.
+It must not produce any output on stdout; stderr must be used
+instead.
+If X11 forwarding is in use, it will receive the "proto cookie" pair in
+its standard input (and
+.Ev DISPLAY
+in its environment).
+The script must call
+.Xr xauth 1
+because
+.Nm
+will not run xauth automatically to add X11 cookies.
+.Pp
+The primary purpose of this file is to run any initialization routines
+which may be needed before the user's home directory becomes
+accessible; AFS is a particular example of such an environment.
+.Pp
+This file will probably contain some initialization code followed by
+something similar to:
+.Bd -literal -offset 3n
+if read proto cookie && [ -n "$DISPLAY" ]; then
+       if [ `echo $DISPLAY | cut -c1-10` = 'localhost:' ]; then
+               # X11UseLocalhost=yes
+               echo add unix:`echo $DISPLAY |
+                   cut -c11-` $proto $cookie
+       else
+               # X11UseLocalhost=no
+               echo add $DISPLAY $proto $cookie
+       fi | xauth -q -
+fi
+.Ed
+.Pp
+If this file does not exist,
+.Pa /etc/ssh/sshrc
+is run, and if that
+does not exist either, xauth is used to add the cookie.
 .Sh AUTHORIZED_KEYS FILE FORMAT
-.Pa ~/.ssh/authorized_keys
-is the default file that lists the public keys that are
-permitted for RSA authentication in protocol version 1
-and for public key authentication (PubkeyAuthentication)
-in protocol version 2.
 .Cm AuthorizedKeysFile
-may be used to specify an alternative file.
-.Pp
+specifies the file containing public keys for
+public key authentication;
+if none is specified, the default is
+.Pa ~/.ssh/authorized_keys .
 Each line of the file contains one
 key (empty lines and lines starting with a
 .Ql #
 are ignored as
 comments).
-Each RSA public key consists of the following fields, separated by
-spaces: options, bits, exponent, modulus, comment.
-Each protocol version 2 public key consists of:
-options, keytype, base64 encoded key, comment.
-The options field
-is optional; its presence is determined by whether the line starts
+Protocol 1 public keys consist of the following space-separated fields:
+options, bits, exponent, modulus, comment.
+Protocol 2 public key consist of:
+options, keytype, base64-encoded key, comment.
+The options field is optional;
+its presence is determined by whether the line starts
 with a number or not (the options field never starts with a number).
-The bits, exponent, modulus and comment fields give the RSA key for
+The bits, exponent, modulus, and comment fields give the RSA key for
 protocol version 1; the
 comment field is not used for anything (but may be convenient for the
 user to identify the key).
@@ -420,7 +451,7 @@ Note that lines in this file are usually several hundred bytes long
 keys up to 16 kilobits.
 You don't want to type them in; instead, copy the
 .Pa identity.pub ,
-.Pa id_dsa.pub
+.Pa id_dsa.pub ,
 or the
 .Pa id_rsa.pub
 file and edit it.
@@ -435,26 +466,6 @@ No spaces are permitted, except within double quotes.
 The following option specifications are supported (note
 that option keywords are case-insensitive):
 .Bl -tag -width Ds
-.It Cm from="pattern-list"
-Specifies that in addition to public key authentication, the canonical name
-of the remote host must be present in the comma-separated list of
-patterns
-.Pf ( Ql \&*
-and
-.Ql \&?
-serve as wildcards).
-The list may also contain
-patterns negated by prefixing them with
-.Ql \&! ;
-if the canonical host name matches a negated pattern, the key is not accepted.
-The purpose
-of this option is to optionally increase security: public key authentication
-by itself does not trust the network or name servers or anything (but
-the key); however, if somebody somehow steals the key, the key
-permits an intruder to log in from anywhere in the world.
-This additional option makes using a stolen key more difficult (name
-servers and/or routers would have to be compromised in addition to
-just the key).
 .It Cm command="command"
 Specifies that the command is executed whenever this key is used for
 authentication.
@@ -470,6 +481,9 @@ to restrict certain public keys to perform just a specific operation.
 An example might be a key that permits remote backups but nothing else.
 Note that the client may specify TCP and/or X11
 forwarding unless they are explicitly prohibited.
+The command originally supplied by the client is available in the
+.Ev SSH_ORIGINAL_COMMAND
+environment variable.
 Note that this option applies to shell, command or subsystem execution.
 .It Cm environment="NAME=value"
 Specifies that the string is to be added to the environment when
@@ -484,20 +498,38 @@ option.
 This option is automatically disabled if
 .Cm UseLogin
 is enabled.
+.It Cm from="pattern-list"
+Specifies that in addition to public key authentication, the canonical name
+of the remote host must be present in the comma-separated list of
+patterns.
+The purpose
+of this option is to optionally increase security: public key authentication
+by itself does not trust the network or name servers or anything (but
+the key); however, if somebody somehow steals the key, the key
+permits an intruder to log in from anywhere in the world.
+This additional option makes using a stolen key more difficult (name
+servers and/or routers would have to be compromised in addition to
+just the key).
+.Pp
+See
+.Sx PATTERNS
+in
+.Xr ssh_config 5
+for more information on patterns.
+.It Cm no-agent-forwarding
+Forbids authentication agent forwarding when this key is used for
+authentication.
 .It Cm no-port-forwarding
 Forbids TCP forwarding when this key is used for authentication.
 Any port forward requests by the client will return an error.
-This might be used, e.g., in connection with the
+This might be used, e.g. in connection with the
 .Cm command
 option.
+.It Cm no-pty
+Prevents tty allocation (a request to allocate a pty will fail).
 .It Cm no-X11-forwarding
 Forbids X11 forwarding when this key is used for authentication.
 Any X11 forward requests by the client will return an error.
-.It Cm no-agent-forwarding
-Forbids authentication agent forwarding when this key is used for
-authentication.
-.It Cm no-pty
-Prevents tty allocation (a request to allocate a pty will fail).
 .It Cm permitopen="host:port"
 Limit local
 .Li ``ssh -L''
@@ -517,16 +549,20 @@ 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
 .Pp
-from="*.niksula.hut.fi,!pc.niksula.hut.fi" 1024 35 23...2334 ylo@niksula
-.Pp
-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
+An example authorized_keys file:
+.Bd -literal -offset 3n
+# Comments allowed at start of line
+ssh-rsa AAAAB3Nza...LiPk== user@example.net
+from="*.sales.example.net,!pc.sales.example.net" ssh-rsa
+AAAAB2...19Q== john@example.net
+command="dump /home",no-pty,no-port-forwarding ssh-dss
+AAAAC3...51R== example.net
+permitopen="192.0.2.1:80",permitopen="192.0.2.2:25" ssh-dss
+AAAAB5...21S==
+tunnel="0",command="sh /etc/netstart tun0" ssh-rsa AAAA...==
+jane@example.net
+.Ed
 .Sh SSH_KNOWN_HOSTS FILE FORMAT
 The
 .Pa /etc/ssh/ssh_known_hosts
@@ -535,7 +571,7 @@ and
 files contain host public keys for all known hosts.
 The global file should
 be prepared by the administrator (optional), and the per-user file is
-maintained automatically: whenever the user connects from an unknown host
+maintained automatically: whenever the user connects from an unknown host,
 its key is added to the per-user file.
 .Pp
 Each line in these files contains the following fields: hostnames,
@@ -543,7 +579,7 @@ bits, exponent, modulus, comment.
 The fields are separated by spaces.
 .Pp
 Hostnames is a comma-separated list of patterns
-.Pf ( Ql \&*
+.Pf ( Ql *
 and
 .Ql \&?
 act as
@@ -555,6 +591,13 @@ A pattern may also be preceded by
 to indicate negation: if the host name matches a negated
 pattern, it is not accepted (by that line) even if it matched another
 pattern on the line.
+A hostname or address may optionally be enclosed within
+.Ql \&[
+and
+.Ql \&]
+brackets then followed by
+.Ql \&:
+and a non-standard port number.
 .Pp
 Alternately, hostnames may be stored in a hashed form which hides host names
 and addresses should the file's contents be disclosed.
@@ -565,7 +608,7 @@ Only one hashed hostname may appear on a single line and none of the above
 negation or wildcard operators may be applied.
 .Pp
 Bits, exponent, and modulus are taken directly from the RSA host key; they
-can be obtained, e.g., from
+can be obtained, for example, from
 .Pa /etc/ssh/ssh_host_key.pub .
 The optional comment field continues to the end of the line, and is not used.
 .Pp
@@ -590,88 +633,19 @@ Rather, generate them by a script
 or by taking
 .Pa /etc/ssh/ssh_host_key.pub
 and adding the host names at the front.
-.Ss Examples
-.Bd -literal
-closenet,...,130.233.208.41 1024 37 159...93 closenet.hut.fi
-cvs.openbsd.org,199.185.137.3 ssh-rsa AAAA1234.....=
-.Ed
-.Bd -literal
+.Pp
+An example ssh_known_hosts file:
+.Bd -literal -offset 3n
+# Comments allowed at start of line
+closenet,...,192.0.2.53 1024 37 159...93 closenet.example.net
+cvs.example.net,192.0.2.10 ssh-rsa AAAA1234.....=
 # A hashed hostname
 |1|JfKTdBh7rNbXkVAQCRp4OQoPfmI=|USECr3SWf1JUPsms5AqfD5QfxkM= ssh-rsa
 AAAA1234.....=
 .Ed
 .Sh FILES
-.Bl -tag -width Ds
-.It Pa /etc/ssh/sshd_config
-Contains configuration data for
-.Nm sshd .
-The file format and configuration options are described in
-.Xr sshd_config 5 .
-.It Pa /etc/ssh/ssh_host_key, /etc/ssh/ssh_host_dsa_key, /etc/ssh/ssh_host_rsa_key
-These three files contain the private parts of the host keys.
-These files should only be owned by root, readable only by root, and not
-accessible to others.
-Note that
-.Nm
-does not start if this file is group/world-accessible.
-.It Pa /etc/ssh/ssh_host_key.pub, /etc/ssh/ssh_host_dsa_key.pub, /etc/ssh/ssh_host_rsa_key.pub
-These three files contain the public parts of the host keys.
-These files should be world-readable but writable only by
-root.
-Their contents should match the respective private parts.
-These files are not
-really used for anything; they are provided for the convenience of
-the user so their contents can be copied to known hosts files.
-These files are created using
-.Xr ssh-keygen 1 .
-.It Pa /etc/moduli
-Contains Diffie-Hellman groups used for the "Diffie-Hellman Group Exchange".
-The file format is described in
-.Xr moduli 5 .
-.It Pa /var/empty
-.Xr chroot 2
-directory used by
-.Nm
-during privilege separation in the pre-authentication phase.
-The directory should not contain any files and must be owned by root
-and not group or world-writable.
-.It Pa /var/run/sshd.pid
-Contains the process ID of the
-.Nm
-listening for connections (if there are several daemons running
-concurrently for different ports, this contains the process ID of the one
-started last).
-The content of this file is not sensitive; it can be world-readable.
-.It Pa ~/.ssh/authorized_keys
-Lists the public keys (RSA or DSA) that can be used to log into the user's account.
-This file must be readable by root (which may on some machines imply
-it being world-readable if the user's home directory resides on an NFS
-volume).
-It is recommended that it not be accessible by others.
-The format of this file is described above.
-Users will place the contents of their
-.Pa identity.pub ,
-.Pa id_dsa.pub
-and/or
-.Pa id_rsa.pub
-files into this file, as described in
-.Xr ssh-keygen 1 .
-.It Pa "/etc/ssh/ssh_known_hosts", "~/.ssh/known_hosts"
-These files are consulted when using rhosts with RSA host
-authentication or protocol version 2 hostbased authentication
-to check the public key of the host.
-The key must be listed in one of these files to be accepted.
-The client uses the same files
-to verify that it is connecting to the correct remote host.
-These files should be writable only by root/the owner.
-.Pa /etc/ssh/ssh_known_hosts
-should be world-readable, and
-.Pa ~/.ssh/known_hosts
-can, but need not be, world-readable.
-.It Pa /etc/motd
-See
-.Xr motd 5 .
-.It Pa ~/.hushlogin
+.Bl -tag -width Ds -compact
+.It ~/.hushlogin
 This file is used to suppress printing the last login time and
 .Pa /etc/motd ,
 if
@@ -682,86 +656,49 @@ respectively,
 are enabled.
 It does not suppress printing of the banner specified by
 .Cm Banner .
-.It Pa /etc/nologin
-If this file exists,
+.Pp
+.It ~/.rhosts
+This file is used for host-based authentication (see
+.Xr ssh 1
+for more information).
+On some machines this file may need to be
+world-readable if the user's home directory is on an NFS partition,
+because
 .Nm
-refuses to let anyone except root log in.
-The contents of the file
-are displayed to anyone trying to log in, and non-root connections are
-refused.
-The file should be world-readable.
-.It Pa /etc/hosts.allow, /etc/hosts.deny
-Access controls that should be enforced by tcp-wrappers are defined here.
-Further details are described in
-.Xr hosts_access 5 .
-.It Pa ~/.rhosts
-This file is used during
-.Cm RhostsRSAAuthentication
-and
-.Cm HostbasedAuthentication
-and contains host-username pairs, separated by a space, one per
-line.
-The given user on the corresponding host is permitted to log in
-without a password.
-The same file is used by rlogind and rshd.
-The file must
-be writable only by the user; it is recommended that it not be
+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 is also possible to use netgroups in the file.
-Either host or user
-name may be of the form +@groupname to specify all hosts or all users
-in the group.
-.It Pa ~/.shosts
-For ssh,
-this file is exactly the same as for
-.Pa .rhosts .
-However, this file is
-not used by rlogin and rshd, so using this permits access using SSH only.
-.It Pa /etc/hosts.equiv
-This file is used during
-.Cm RhostsRSAAuthentication
-and
-.Cm HostbasedAuthentication
-authentication.
-In the simplest form, this file contains host names, one per line.
-Users on
-those hosts are permitted to log in without a password, provided they
-have the same user name on both machines.
-The host name may also be
-followed by a user name; such users are permitted to log in as
-.Em any
-user on this machine (except root).
-Additionally, the syntax
-.Dq +@group
-can be used to specify netgroups.
-Negated entries start with
-.Ql \&- .
-.Pp
-If the client host/user is successfully matched in this file, login is
-automatically permitted provided the client and server user names are the
-same.
-Additionally, successful client host key authentication is required.
-This file must be writable only by root; it is recommended
-that it be world-readable.
-.Pp
-.Sy "Warning: It is almost never a good idea to use user names in"
-.Pa hosts.equiv .
-Beware that it really means that the named user(s) can log in as
-.Em anybody ,
-which includes bin, daemon, adm, and other accounts that own critical
-binaries and directories.
-Using a user name practically grants the user root access.
-The only valid use for user names that I can think
-of is in negative entries.
-.Pp
-Note that this warning also applies to rsh/rlogin.
-.It Pa /etc/shosts.equiv
-This is processed exactly as
-.Pa /etc/hosts.equiv .
-However, this file may be useful in environments that want to run both
-rsh/rlogin and ssh.
-.It Pa ~/.ssh/environment
+.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 above.
+The content of the file is not highly sensitive, but the recommended
+permissions are read/write for the user, and not accessible by others.
+.Pp
+If this file, the
+.Pa ~/.ssh
+directory, or the user's home directory are writable
+by other users, then the file could be modified or replaced by unauthorized
+users.
+In this case,
+.Nm
+will not allow it to be used unless the
+.Cm StrictModes
+option has been set to
+.Dq no .
+The recommended permissions can be set by executing
+.Dq chmod go-w ~/ ~/.ssh ~/.ssh/authorized_keys .
+.Pp
+.It ~/.ssh/environment
 This file is read into the environment at login (if it exists).
 It can only contain empty lines, comment lines (that start with
 .Ql # ) ,
@@ -772,55 +709,115 @@ Environment processing is disabled by default and is
 controlled via the
 .Cm PermitUserEnvironment
 option.
-.It Pa ~/.ssh/rc
-If this file exists, it is run with
-.Pa /bin/sh
-after reading the
-environment files but before starting the user's shell or command.
-It must not produce any output on stdout; stderr must be used
-instead.
-If X11 forwarding is in use, it will receive the "proto cookie" pair in
-its standard input (and
-.Ev DISPLAY
-in its environment).
-The script must call
-.Xr xauth 1
-because
+.Pp
+.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.
+The format of this file is described above.
+This file should be writable only by root/the owner and
+can, but need not be, world-readable.
+.Pp
+.It ~/.ssh/rc
+Contains initialization routines to be run before
+the user's home directory becomes accessible.
+This file should be writable only by the user, and need not be
+readable by anyone else.
+.Pp
+.It /etc/hosts.allow
+.It /etc/hosts.deny
+Access controls that should be enforced by tcp-wrappers are defined here.
+Further details are described in
+.Xr hosts_access 5 .
+.Pp
+.It /etc/hosts.equiv
+This file is for host-based authentication (see
+.Xr ssh 1 ) .
+It should only be writable by root.
+.Pp
+.It /etc/moduli
+Contains Diffie-Hellman groups used for the "Diffie-Hellman Group Exchange".
+The file format is described in
+.Xr moduli 5 .
+.Pp
+.It /etc/motd
+See
+.Xr motd 5 .
+.Pp
+.It /etc/nologin
+If this file exists,
 .Nm
-will not run xauth automatically to add X11 cookies.
+refuses to let anyone except root log in.
+The contents of the file
+are displayed to anyone trying to log in, and non-root connections are
+refused.
+The file should be world-readable.
 .Pp
-The primary purpose of this file is to run any initialization routines
-which may be needed before the user's home directory becomes
-accessible; AFS is a particular example of such an environment.
+.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 /etc/ssh/ssh_known_hosts
+Systemwide list of known host keys.
+This file should be prepared by the
+system administrator to contain the public host keys of all machines in the
+organization.
+The format of this file is described above.
+This file should be writable only by root/the owner and
+should be world-readable.
 .Pp
-This file will probably contain some initialization code followed by
-something similar to:
-.Bd -literal
-if read proto cookie && [ -n "$DISPLAY" ]; then
-       if [ `echo $DISPLAY | cut -c1-10` = 'localhost:' ]; then
-               # X11UseLocalhost=yes
-               echo add unix:`echo $DISPLAY |
-                   cut -c11-` $proto $cookie
-       else
-               # X11UseLocalhost=no
-               echo add $DISPLAY $proto $cookie
-       fi | xauth -q -
-fi
-.Ed
+.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.
+These files should only be owned by root, readable only by root, and not
+accessible to others.
+Note that
+.Nm
+does not start if these files are group/world-accessible.
 .Pp
-If this file does not exist,
-.Pa /etc/ssh/sshrc
-is run, and if that
-does not exist either, xauth is used to add the cookie.
+.It /etc/ssh/ssh_host_key.pub
+.It /etc/ssh/ssh_host_dsa_key.pub
+.It /etc/ssh/ssh_host_rsa_key.pub
+These three files contain the public parts of the host keys.
+These files should be world-readable but writable only by
+root.
+Their contents should match the respective private parts.
+These files are not
+really used for anything; they are provided for the convenience of
+the user so their contents can be copied to known hosts files.
+These files are created using
+.Xr ssh-keygen 1 .
 .Pp
-This file should be writable only by the user, and need not be
-readable by anyone else.
-.It Pa /etc/ssh/sshrc
-Like
-.Pa ~/.ssh/rc .
-This can be used to specify
+.It /etc/ssh/sshd_config
+Contains configuration data for
+.Nm sshd .
+The file format and configuration options are described in
+.Xr sshd_config 5 .
+.Pp
+.It /etc/ssh/sshrc
+Similar to
+.Pa ~/.ssh/rc ,
+it can be used to specify
 machine-specific login-time initializations globally.
 This file should be writable only by root, and should be world-readable.
+.Pp
+.It /var/empty
+.Xr chroot 2
+directory used by
+.Nm
+during privilege separation in the pre-authentication phase.
+The directory should not contain any files and must be owned by root
+and not group or world-writable.
+.Pp
+.It /var/run/sshd.pid
+Contains the process ID of the
+.Nm
+listening for connections (if there are several daemons running
+concurrently for different ports, this contains the process ID of the one
+started last).
+The content of this file is not sensitive; it can be world-readable.
 .El
 .Sh SEE ALSO
 .Xr scp 1 ,
@@ -836,26 +833,6 @@ This file should be writable only by root, and should be world-readable.
 .Xr sshd_config 5 ,
 .Xr inetd 8 ,
 .Xr sftp-server 8
-.Rs
-.%A T. Ylonen
-.%A T. Kivinen
-.%A M. Saarinen
-.%A T. Rinne
-.%A S. Lehtinen
-.%T "SSH Protocol Architecture"
-.%N draft-ietf-secsh-architecture-12.txt
-.%D January 2002
-.%O work in progress material
-.Re
-.Rs
-.%A M. Friedl
-.%A N. Provos
-.%A W. A. Simpson
-.%T "Diffie-Hellman Group Exchange for the SSH Transport Layer Protocol"
-.%N draft-ietf-secsh-dh-group-exchange-02.txt
-.%D January 2002
-.%O work in progress material
-.Re
 .Sh AUTHORS
 OpenSSH is a derivative of the original and free
 ssh 1.2.12 release by Tatu Ylonen.
@@ -867,3 +844,14 @@ Markus Friedl contributed the support for SSH
 protocol versions 1.5 and 2.0.
 Niels Provos and Markus Friedl contributed support
 for privilege separation.
+.Sh CAVEATS
+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).
index 7f09723f169dd5bb7ded774bb3f1c7c1cfd828e3..066900d95f57b1124eda9a60f961f81c50e17482 100644 (file)
@@ -1,3 +1,4 @@
+/* $OpenBSD: sshd.c,v 1.347 2006/08/18 09:15:20 markus Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshd.c,v 1.318 2005/12/24 02:27:41 djm Exp $");
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+#include "openbsd-compat/sys-tree.h"
+#include <sys/wait.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <netdb.h>
+#ifdef HAVE_PATHS_H
+#include <paths.h>
+#endif
+#include <grp.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
 
 #include <openssl/dh.h>
 #include <openssl/bn.h>
@@ -53,28 +80,28 @@ RCSID("$OpenBSD: sshd.c,v 1.318 2005/12/24 02:27:41 djm Exp $");
 #include <prot.h>
 #endif
 
+#include "xmalloc.h"
 #include "ssh.h"
 #include "ssh1.h"
 #include "ssh2.h"
-#include "xmalloc.h"
 #include "rsa.h"
 #include "sshpty.h"
 #include "packet.h"
 #include "log.h"
+#include "buffer.h"
 #include "servconf.h"
 #include "uidswap.h"
 #include "compat.h"
-#include "buffer.h"
-#include "bufaux.h"
 #include "cipher.h"
-#include "kex.h"
 #include "key.h"
+#include "kex.h"
 #include "dh.h"
 #include "myproposal.h"
 #include "authfile.h"
 #include "pathnames.h"
 #include "atomicio.h"
 #include "canohost.h"
+#include "hostfile.h"
 #include "auth.h"
 #include "misc.h"
 #include "msg.h"
@@ -83,8 +110,12 @@ RCSID("$OpenBSD: sshd.c,v 1.318 2005/12/24 02:27:41 djm Exp $");
 #include "session.h"
 #include "monitor_mm.h"
 #include "monitor.h"
+#ifdef GSSAPI
+#include "ssh-gss.h"
+#endif
 #include "monitor_wrap.h"
 #include "monitor_fdpass.h"
+#include "version.h"
 
 #ifdef USE_SECURITY_SESSION_API
 #include <Security/AuthSession.h>
@@ -205,15 +236,21 @@ int *startup_pipes = NULL;
 int startup_pipe;              /* in child */
 
 /* variables used for privilege separation */
-int use_privsep;
+int use_privsep = -1;
 struct monitor *pmonitor = NULL;
 
 /* global authentication context */
 Authctxt *the_authctxt = NULL;
 
+/* sshd_config buffer */
+Buffer cfg;
+
 /* message to be displayed after login */
 Buffer loginmsg;
 
+/* Unprivileged user */
+struct passwd *privsep_pw = NULL;
+
 /* Prototypes for various functions defined later in this file. */
 void destroy_sensitive_data(void);
 void demote_sensitive_data(void);
@@ -250,6 +287,8 @@ close_startup_pipes(void)
  * the effect is to reread the configuration file (and to regenerate
  * the server key).
  */
+
+/*ARGSUSED*/
 static void
 sighup_handler(int sig)
 {
@@ -279,6 +318,7 @@ sighup_restart(void)
 /*
  * Generic signal handler for terminating signals in the master daemon.
  */
+/*ARGSUSED*/
 static void
 sigterm_handler(int sig)
 {
@@ -289,6 +329,7 @@ sigterm_handler(int sig)
  * SIGCHLD handler.  This is called whenever a child dies.  This will then
  * reap any zombies left by exited children.
  */
+/*ARGSUSED*/
 static void
 main_sigchld_handler(int sig)
 {
@@ -307,16 +348,15 @@ main_sigchld_handler(int sig)
 /*
  * Signal handler for the alarm after the login grace period has expired.
  */
+/*ARGSUSED*/
 static void
 grace_alarm_handler(int sig)
 {
-       /* XXX no idea how fix this signal handler */
-
        if (use_privsep && pmonitor != NULL && pmonitor->m_pid > 0)
                kill(pmonitor->m_pid, SIGALRM);
 
        /* Log error and exit. */
-       fatal("Timeout before authentication for %s", get_remote_ipaddr());
+       sigdie("Timeout before authentication for %s", get_remote_ipaddr());
 }
 
 /*
@@ -349,6 +389,7 @@ generate_ephemeral_server_key(void)
        arc4random_stir();
 }
 
+/*ARGSUSED*/
 static void
 key_regeneration_alarm(int sig)
 {
@@ -545,7 +586,6 @@ privsep_preauth_child(void)
 {
        u_int32_t rnd[256];
        gid_t gidset[1];
-       struct passwd *pw;
        int i;
 
        /* Enable challenge-response authentication for privilege separation */
@@ -558,12 +598,6 @@ privsep_preauth_child(void)
        /* Demote the private keys to public keys. */
        demote_sensitive_data();
 
-       if ((pw = getpwnam(SSH_PRIVSEP_USER)) == NULL)
-               fatal("Privilege separation user %s does not exist",
-                   SSH_PRIVSEP_USER);
-       memset(pw->pw_passwd, 0, strlen(pw->pw_passwd));
-       endpwent();
-
        /* Change our root directory */
        if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1)
                fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR,
@@ -572,16 +606,16 @@ privsep_preauth_child(void)
                fatal("chdir(\"/\"): %s", strerror(errno));
 
        /* Drop our privileges */
-       debug3("privsep user:group %u:%u", (u_int)pw->pw_uid,
-           (u_int)pw->pw_gid);
+       debug3("privsep user:group %u:%u", (u_int)privsep_pw->pw_uid,
+           (u_int)privsep_pw->pw_gid);
 #if 0
        /* XXX not ready, too heavy after chroot */
-       do_setusercontext(pw);
+       do_setusercontext(privsep_pw);
 #else
-       gidset[0] = pw->pw_gid;
+       gidset[0] = privsep_pw->pw_gid;
        if (setgroups(1, gidset) < 0)
                fatal("setgroups: %.100s", strerror(errno));
-       permanently_set_uid(pw);
+       permanently_set_uid(privsep_pw);
 #endif
 }
 
@@ -870,6 +904,325 @@ recv_rexec_state(int fd, Buffer *conf)
        debug3("%s: done", __func__);
 }
 
+/* Accept a connection from inetd */
+static void
+server_accept_inetd(int *sock_in, int *sock_out)
+{
+       int fd;
+
+       startup_pipe = -1;
+       if (rexeced_flag) {
+               close(REEXEC_CONFIG_PASS_FD);
+               *sock_in = *sock_out = dup(STDIN_FILENO);
+               if (!debug_flag) {
+                       startup_pipe = dup(REEXEC_STARTUP_PIPE_FD);
+                       close(REEXEC_STARTUP_PIPE_FD);
+               }
+       } else {
+               *sock_in = dup(STDIN_FILENO);
+               *sock_out = dup(STDOUT_FILENO);
+       }
+       /*
+        * We intentionally do not close the descriptors 0, 1, and 2
+        * as our code for setting the descriptors won't work if
+        * ttyfd happens to be one of those.
+        */
+       if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
+               dup2(fd, STDIN_FILENO);
+               dup2(fd, STDOUT_FILENO);
+               if (fd > STDOUT_FILENO)
+                       close(fd);
+       }
+       debug("inetd sockets after dupping: %d, %d", *sock_in, *sock_out);
+}
+
+/*
+ * Listen for TCP connections
+ */
+static void
+server_listen(void)
+{
+       int ret, listen_sock, on = 1;
+       struct addrinfo *ai;
+       char ntop[NI_MAXHOST], strport[NI_MAXSERV];
+
+       for (ai = options.listen_addrs; ai; ai = ai->ai_next) {
+               if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
+                       continue;
+               if (num_listen_socks >= MAX_LISTEN_SOCKS)
+                       fatal("Too many listen sockets. "
+                           "Enlarge MAX_LISTEN_SOCKS");
+               if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen,
+                   ntop, sizeof(ntop), strport, sizeof(strport),
+                   NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
+                       error("getnameinfo failed: %.100s",
+                           (ret != EAI_SYSTEM) ? gai_strerror(ret) :
+                           strerror(errno));
+                       continue;
+               }
+               /* Create socket for listening. */
+               listen_sock = socket(ai->ai_family, ai->ai_socktype,
+                   ai->ai_protocol);
+               if (listen_sock < 0) {
+                       /* kernel may not support ipv6 */
+                       verbose("socket: %.100s", strerror(errno));
+                       continue;
+               }
+               if (set_nonblock(listen_sock) == -1) {
+                       close(listen_sock);
+                       continue;
+               }
+               /*
+                * Set socket options.
+                * Allow local port reuse in TIME_WAIT.
+                */
+               if (setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR,
+                   &on, sizeof(on)) == -1)
+                       error("setsockopt SO_REUSEADDR: %s", strerror(errno));
+
+               debug("Bind to port %s on %s.", strport, ntop);
+
+               /* Bind the socket to the desired port. */
+               if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) < 0) {
+                       error("Bind to port %s on %s failed: %.200s.",
+                           strport, ntop, strerror(errno));
+                       close(listen_sock);
+                       continue;
+               }
+               listen_socks[num_listen_socks] = listen_sock;
+               num_listen_socks++;
+
+               /* Start listening on the port. */
+               if (listen(listen_sock, SSH_LISTEN_BACKLOG) < 0)
+                       fatal("listen on [%s]:%s: %.100s",
+                           ntop, strport, strerror(errno));
+               logit("Server listening on %s port %s.", ntop, strport);
+       }
+       freeaddrinfo(options.listen_addrs);
+
+       if (!num_listen_socks)
+               fatal("Cannot bind any address.");
+}
+
+/*
+ * The main TCP accept loop. Note that, for the non-debug case, returns
+ * from this function are in a forked subprocess.
+ */
+static void
+server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
+{
+       fd_set *fdset;
+       int i, j, ret, maxfd;
+       int key_used = 0, startups = 0;
+       int startup_p[2] = { -1 , -1 };
+       struct sockaddr_storage from;
+       socklen_t fromlen;
+       pid_t pid;
+
+       /* setup fd set for accept */
+       fdset = NULL;
+       maxfd = 0;
+       for (i = 0; i < num_listen_socks; i++)
+               if (listen_socks[i] > maxfd)
+                       maxfd = listen_socks[i];
+       /* pipes connected to unauthenticated childs */
+       startup_pipes = xcalloc(options.max_startups, sizeof(int));
+       for (i = 0; i < options.max_startups; i++)
+               startup_pipes[i] = -1;
+
+       /*
+        * Stay listening for connections until the system crashes or
+        * the daemon is killed with a signal.
+        */
+       for (;;) {
+               if (received_sighup)
+                       sighup_restart();
+               if (fdset != NULL)
+                       xfree(fdset);
+               fdset = (fd_set *)xcalloc(howmany(maxfd + 1, NFDBITS),
+                   sizeof(fd_mask));
+
+               for (i = 0; i < num_listen_socks; i++)
+                       FD_SET(listen_socks[i], fdset);
+               for (i = 0; i < options.max_startups; i++)
+                       if (startup_pipes[i] != -1)
+                               FD_SET(startup_pipes[i], fdset);
+
+               /* Wait in select until there is a connection. */
+               ret = select(maxfd+1, fdset, NULL, NULL, NULL);
+               if (ret < 0 && errno != EINTR)
+                       error("select: %.100s", strerror(errno));
+               if (received_sigterm) {
+                       logit("Received signal %d; terminating.",
+                           (int) received_sigterm);
+                       close_listen_socks();
+                       unlink(options.pid_file);
+                       exit(255);
+               }
+               if (key_used && key_do_regen) {
+                       generate_ephemeral_server_key();
+                       key_used = 0;
+                       key_do_regen = 0;
+               }
+               if (ret < 0)
+                       continue;
+
+               for (i = 0; i < options.max_startups; i++)
+                       if (startup_pipes[i] != -1 &&
+                           FD_ISSET(startup_pipes[i], fdset)) {
+                               /*
+                                * the read end of the pipe is ready
+                                * if the child has closed the pipe
+                                * after successful authentication
+                                * or if the child has died
+                                */
+                               close(startup_pipes[i]);
+                               startup_pipes[i] = -1;
+                               startups--;
+                       }
+               for (i = 0; i < num_listen_socks; i++) {
+                       if (!FD_ISSET(listen_socks[i], fdset))
+                               continue;
+                       fromlen = sizeof(from);
+                       *newsock = accept(listen_socks[i],
+                           (struct sockaddr *)&from, &fromlen);
+                       if (*newsock < 0) {
+                               if (errno != EINTR && errno != EWOULDBLOCK)
+                                       error("accept: %.100s", strerror(errno));
+                               continue;
+                       }
+                       if (unset_nonblock(*newsock) == -1) {
+                               close(*newsock);
+                               continue;
+                       }
+                       if (drop_connection(startups) == 1) {
+                               debug("drop connection #%d", startups);
+                               close(*newsock);
+                               continue;
+                       }
+                       if (pipe(startup_p) == -1) {
+                               close(*newsock);
+                               continue;
+                       }
+
+                       if (rexec_flag && socketpair(AF_UNIX,
+                           SOCK_STREAM, 0, config_s) == -1) {
+                               error("reexec socketpair: %s",
+                                   strerror(errno));
+                               close(*newsock);
+                               close(startup_p[0]);
+                               close(startup_p[1]);
+                               continue;
+                       }
+
+                       for (j = 0; j < options.max_startups; j++)
+                               if (startup_pipes[j] == -1) {
+                                       startup_pipes[j] = startup_p[0];
+                                       if (maxfd < startup_p[0])
+                                               maxfd = startup_p[0];
+                                       startups++;
+                                       break;
+                               }
+
+                       /*
+                        * Got connection.  Fork a child to handle it, unless
+                        * we are in debugging mode.
+                        */
+                       if (debug_flag) {
+                               /*
+                                * In debugging mode.  Close the listening
+                                * socket, and start processing the
+                                * connection without forking.
+                                */
+                               debug("Server will not fork when running in debugging mode.");
+                               close_listen_socks();
+                               *sock_in = *newsock;
+                               *sock_out = *newsock;
+                               close(startup_p[0]);
+                               close(startup_p[1]);
+                               startup_pipe = -1;
+                               pid = getpid();
+                               if (rexec_flag) {
+                                       send_rexec_state(config_s[0],
+                                           &cfg);
+                                       close(config_s[0]);
+                               }
+                               break;
+                       }
+
+                       /*
+                        * Normal production daemon.  Fork, and have
+                        * the child process the connection. The
+                        * parent continues listening.
+                        */
+                       platform_pre_fork();
+                       if ((pid = fork()) == 0) {
+                               /*
+                                * Child.  Close the listening and
+                                * max_startup sockets.  Start using
+                                * the accepted socket. Reinitialize
+                                * logging (since our pid has changed).
+                                * We break out of the loop to handle
+                                * the connection.
+                                */
+                               platform_post_fork_child();
+                               startup_pipe = startup_p[1];
+                               close_startup_pipes();
+                               close_listen_socks();
+                               *sock_in = *newsock;
+                               *sock_out = *newsock;
+                               log_init(__progname,
+                                   options.log_level,
+                                   options.log_facility,
+                                   log_stderr);
+                               if (rexec_flag)
+                                       close(config_s[0]);
+                               break;
+                       }
+
+                       /* Parent.  Stay in the loop. */
+                       platform_post_fork_parent(pid);
+                       if (pid < 0)
+                               error("fork: %.100s", strerror(errno));
+                       else
+                               debug("Forked child %ld.", (long)pid);
+
+                       close(startup_p[1]);
+
+                       if (rexec_flag) {
+                               send_rexec_state(config_s[0], &cfg);
+                               close(config_s[0]);
+                               close(config_s[1]);
+                       }
+
+                       /*
+                        * Mark that the key has been used (it
+                        * was "given" to the child).
+                        */
+                       if ((options.protocol & SSH_PROTO_1) &&
+                           key_used == 0) {
+                               /* Schedule server key regeneration alarm. */
+                               signal(SIGALRM, key_regeneration_alarm);
+                               alarm(options.key_regeneration_time);
+                               key_used = 1;
+                       }
+
+                       close(*newsock);
+
+                       /*
+                        * Ensure that our random state differs
+                        * from that of the child
+                        */
+                       arc4random_stir();
+               }
+
+               /* child process check (or debug mode) */
+               if (num_listen_socks < 0)
+                       break;
+       }
+}
+
+
 /*
  * Main program for the daemon.
  */
@@ -878,25 +1231,14 @@ main(int ac, char **av)
 {
        extern char *optarg;
        extern int optind;
-       int opt, j, i, fdsetsz, on = 1;
+       int opt, i, on = 1;
        int sock_in = -1, sock_out = -1, newsock = -1;
-       pid_t pid;
-       socklen_t fromlen;
-       fd_set *fdset;
-       struct sockaddr_storage from;
        const char *remote_ip;
        int remote_port;
-       FILE *f;
-       struct addrinfo *ai;
-       char ntop[NI_MAXHOST], strport[NI_MAXSERV];
        char *line;
-       int listen_sock, maxfd;
-       int startup_p[2] = { -1 , -1 }, config_s[2] = { -1 , -1 };
-       int startups = 0;
+       int config_s[2] = { -1 , -1 };
        Key *key;
        Authctxt *authctxt;
-       int ret, key_used = 0;
-       Buffer cfg;
 
 #ifdef HAVE_SECUREWARE
        (void)set_auth_parameters(ac, av);
@@ -907,7 +1249,7 @@ main(int ac, char **av)
        /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */
        saved_argc = ac;
        rexec_argc = ac;
-       saved_argv = xmalloc(sizeof(*saved_argv) * (ac + 1));
+       saved_argv = xcalloc(ac + 1, sizeof(*saved_argv));
        for (i = 0; i < ac; i++)
                saved_argv[i] = xstrdup(av[i]);
        saved_argv[i] = NULL;
@@ -969,7 +1311,8 @@ main(int ac, char **av)
                        options.log_level = SYSLOG_LEVEL_QUIET;
                        break;
                case 'b':
-                       options.server_key_bits = atoi(optarg);
+                       options.server_key_bits = (int)strtonum(optarg, 256,
+                           32768, NULL);
                        break;
                case 'p':
                        options.ports_from_cmdline = 1;
@@ -1006,7 +1349,7 @@ main(int ac, char **av)
                        test_flag = 1;
                        break;
                case 'u':
-                       utmp_len = atoi(optarg);
+                       utmp_len = (u_int)strtonum(optarg, 0, MAXHOSTNAMELEN+1, NULL);
                        if (utmp_len > MAXHOSTNAMELEN) {
                                fprintf(stderr, "Invalid utmp length.\n");
                                exit(1);
@@ -1015,7 +1358,7 @@ main(int ac, char **av)
                case 'o':
                        line = xstrdup(optarg);
                        if (process_server_config_line(&options, line,
-                           "command-line", 0) != 0)
+                           "command-line", 0, NULL, NULL, NULL, NULL) != 0)
                                exit(1);
                        xfree(line);
                        break;
@@ -1073,11 +1416,8 @@ main(int ac, char **av)
        else
                load_server_config(config_file_name, &cfg);
 
-       parse_server_config(&options,
-           rexeced_flag ? "rexec" : config_file_name, &cfg);
-
-       if (!rexec_flag)
-               buffer_free(&cfg);
+       parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name,
+           &cfg, NULL, NULL, NULL);
 
        seed_rng();
 
@@ -1095,8 +1435,17 @@ main(int ac, char **av)
 
        debug("sshd version %.100s", SSH_RELEASE);
 
+       /* Store privilege separation user for later use */
+       if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL)
+               fatal("Privilege separation user %s does not exist",
+                   SSH_PRIVSEP_USER);
+       memset(privsep_pw->pw_passwd, 0, strlen(privsep_pw->pw_passwd));
+       privsep_pw->pw_passwd = "*";
+       privsep_pw = pwcopy(privsep_pw);
+       endpwent();
+
        /* load private host keys */
-       sensitive_data.host_keys = xmalloc(options.num_host_key_files *
+       sensitive_data.host_keys = xcalloc(options.num_host_key_files,
            sizeof(Key *));
        for (i = 0; i < options.num_host_key_files; i++)
                sensitive_data.host_keys[i] = NULL;
@@ -1165,12 +1514,8 @@ main(int ac, char **av)
        }
 
        if (use_privsep) {
-               struct passwd *pw;
                struct stat st;
 
-               if ((pw = getpwnam(SSH_PRIVSEP_USER)) == NULL)
-                       fatal("Privilege separation user %s does not exist",
-                           SSH_PRIVSEP_USER);
                if ((stat(_PATH_PRIVSEP_CHROOT_DIR, &st) == -1) ||
                    (S_ISDIR(st.st_mode) == 0))
                        fatal("Missing privilege separation directory: %s",
@@ -1202,7 +1547,7 @@ main(int ac, char **av)
                debug("setgroups() failed: %.200s", strerror(errno));
 
        if (rexec_flag) {
-               rexec_argv = xmalloc(sizeof(char *) * (rexec_argc + 2));
+               rexec_argv = xcalloc(rexec_argc + 2, sizeof(char *));
                for (i = 0; i < rexec_argc; i++) {
                        debug("rexec_argv[%d]='%s'", i, saved_argv[i]);
                        rexec_argv[i] = saved_argv[i];
@@ -1250,121 +1595,31 @@ main(int ac, char **av)
        /* ignore SIGPIPE */
        signal(SIGPIPE, SIG_IGN);
 
-       /* Start listening for a socket, unless started from inetd. */
+       /* Get a connection, either from inetd or a listening TCP socket */
        if (inetd_flag) {
-               int fd;
+               server_accept_inetd(&sock_in, &sock_out);
 
-               startup_pipe = -1;
-               if (rexeced_flag) {
-                       close(REEXEC_CONFIG_PASS_FD);
-                       sock_in = sock_out = dup(STDIN_FILENO);
-                       if (!debug_flag) {
-                               startup_pipe = dup(REEXEC_STARTUP_PIPE_FD);
-                               close(REEXEC_STARTUP_PIPE_FD);
-                       }
-               } else {
-                       sock_in = dup(STDIN_FILENO);
-                       sock_out = dup(STDOUT_FILENO);
-               }
-               /*
-                * We intentionally do not close the descriptors 0, 1, and 2
-                * as our code for setting the descriptors won't work if
-                * ttyfd happens to be one of those.
-                */
-               if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
-                       dup2(fd, STDIN_FILENO);
-                       dup2(fd, STDOUT_FILENO);
-                       if (fd > STDOUT_FILENO)
-                               close(fd);
-               }
-               debug("inetd sockets after dupping: %d, %d", sock_in, sock_out);
                if ((options.protocol & SSH_PROTO_1) &&
                    sensitive_data.server_key == NULL)
                        generate_ephemeral_server_key();
        } else {
-               for (ai = options.listen_addrs; ai; ai = ai->ai_next) {
-                       if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
-                               continue;
-                       if (num_listen_socks >= MAX_LISTEN_SOCKS)
-                               fatal("Too many listen sockets. "
-                                   "Enlarge MAX_LISTEN_SOCKS");
-                       if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen,
-                           ntop, sizeof(ntop), strport, sizeof(strport),
-                           NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
-                               error("getnameinfo failed: %.100s",
-                                   (ret != EAI_SYSTEM) ? gai_strerror(ret) :
-                                   strerror(errno));
-                               continue;
-                       }
-                       /* Create socket for listening. */
-                       listen_sock = socket(ai->ai_family, ai->ai_socktype,
-                           ai->ai_protocol);
-                       if (listen_sock < 0) {
-                               /* kernel may not support ipv6 */
-                               verbose("socket: %.100s", strerror(errno));
-                               continue;
-                       }
-                       if (set_nonblock(listen_sock) == -1) {
-                               close(listen_sock);
-                               continue;
-                       }
-                       /*
-                        * Set socket options.
-                        * Allow local port reuse in TIME_WAIT.
-                        */
-                       if (setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR,
-                           &on, sizeof(on)) == -1)
-                               error("setsockopt SO_REUSEADDR: %s", strerror(errno));
-
-                       debug("Bind to port %s on %s.", strport, ntop);
-
-                       /* Bind the socket to the desired port. */
-                       if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) < 0) {
-                               if (!ai->ai_next)
-                                   error("Bind to port %s on %s failed: %.200s.",
-                                           strport, ntop, strerror(errno));
-                               close(listen_sock);
-                               continue;
-                       }
-                       listen_socks[num_listen_socks] = listen_sock;
-                       num_listen_socks++;
-
-                       /* Start listening on the port. */
-                       logit("Server listening on %s port %s.", ntop, strport);
-                       if (listen(listen_sock, SSH_LISTEN_BACKLOG) < 0)
-                               fatal("listen: %.100s", strerror(errno));
-
-               }
-               freeaddrinfo(options.listen_addrs);
-
-               if (!num_listen_socks)
-                       fatal("Cannot bind any address.");
+               server_listen();
 
                if (options.protocol & SSH_PROTO_1)
                        generate_ephemeral_server_key();
 
-               /*
-                * Arrange to restart on SIGHUP.  The handler needs
-                * listen_sock.
-                */
                signal(SIGHUP, sighup_handler);
-
+               signal(SIGCHLD, main_sigchld_handler);
                signal(SIGTERM, sigterm_handler);
                signal(SIGQUIT, sigterm_handler);
 
-               /* Arrange SIGCHLD to be caught. */
-               signal(SIGCHLD, main_sigchld_handler);
-
-               /* Write out the pid file after the sigterm handler is setup */
+               /*
+                * Write out the pid file after the sigterm handler
+                * is setup and the listen sockets are bound
+                */
                if (!debug_flag) {
-                       /*
-                        * Record our pid in /var/run/sshd.pid to make it
-                        * easier to kill the correct sshd.  We don't want to
-                        * do this before the bind above because the bind will
-                        * fail if there already is a daemon, and this will
-                        * overwrite any old pid in the file.
-                        */
-                       f = fopen(options.pid_file, "wb");
+                       FILE *f = fopen(options.pid_file, "w");
+
                        if (f == NULL) {
                                error("Couldn't create pid file \"%s\": %s",
                                    options.pid_file, strerror(errno));
@@ -1374,194 +1629,9 @@ main(int ac, char **av)
                        }
                }
 
-               /* setup fd set for listen */
-               fdset = NULL;
-               maxfd = 0;
-               for (i = 0; i < num_listen_socks; i++)
-                       if (listen_socks[i] > maxfd)
-                               maxfd = listen_socks[i];
-               /* pipes connected to unauthenticated childs */
-               startup_pipes = xmalloc(options.max_startups * sizeof(int));
-               for (i = 0; i < options.max_startups; i++)
-                       startup_pipes[i] = -1;
-
-               /*
-                * Stay listening for connections until the system crashes or
-                * the daemon is killed with a signal.
-                */
-               for (;;) {
-                       if (received_sighup)
-                               sighup_restart();
-                       if (fdset != NULL)
-                               xfree(fdset);
-                       fdsetsz = howmany(maxfd+1, NFDBITS) * sizeof(fd_mask);
-                       fdset = (fd_set *)xmalloc(fdsetsz);
-                       memset(fdset, 0, fdsetsz);
-
-                       for (i = 0; i < num_listen_socks; i++)
-                               FD_SET(listen_socks[i], fdset);
-                       for (i = 0; i < options.max_startups; i++)
-                               if (startup_pipes[i] != -1)
-                                       FD_SET(startup_pipes[i], fdset);
-
-                       /* Wait in select until there is a connection. */
-                       ret = select(maxfd+1, fdset, NULL, NULL, NULL);
-                       if (ret < 0 && errno != EINTR)
-                               error("select: %.100s", strerror(errno));
-                       if (received_sigterm) {
-                               logit("Received signal %d; terminating.",
-                                   (int) received_sigterm);
-                               close_listen_socks();
-                               unlink(options.pid_file);
-                               exit(255);
-                       }
-                       if (key_used && key_do_regen) {
-                               generate_ephemeral_server_key();
-                               key_used = 0;
-                               key_do_regen = 0;
-                       }
-                       if (ret < 0)
-                               continue;
-
-                       for (i = 0; i < options.max_startups; i++)
-                               if (startup_pipes[i] != -1 &&
-                                   FD_ISSET(startup_pipes[i], fdset)) {
-                                       /*
-                                        * the read end of the pipe is ready
-                                        * if the child has closed the pipe
-                                        * after successful authentication
-                                        * or if the child has died
-                                        */
-                                       close(startup_pipes[i]);
-                                       startup_pipes[i] = -1;
-                                       startups--;
-                               }
-                       for (i = 0; i < num_listen_socks; i++) {
-                               if (!FD_ISSET(listen_socks[i], fdset))
-                                       continue;
-                               fromlen = sizeof(from);
-                               newsock = accept(listen_socks[i], (struct sockaddr *)&from,
-                                   &fromlen);
-                               if (newsock < 0) {
-                                       if (errno != EINTR && errno != EWOULDBLOCK)
-                                               error("accept: %.100s", strerror(errno));
-                                       continue;
-                               }
-                               if (unset_nonblock(newsock) == -1) {
-                                       close(newsock);
-                                       continue;
-                               }
-                               if (drop_connection(startups) == 1) {
-                                       debug("drop connection #%d", startups);
-                                       close(newsock);
-                                       continue;
-                               }
-                               if (pipe(startup_p) == -1) {
-                                       close(newsock);
-                                       continue;
-                               }
-
-                               if (rexec_flag && socketpair(AF_UNIX,
-                                   SOCK_STREAM, 0, config_s) == -1) {
-                                       error("reexec socketpair: %s",
-                                           strerror(errno));
-                                       close(newsock);
-                                       close(startup_p[0]);
-                                       close(startup_p[1]);
-                                       continue;
-                               }
-
-                               for (j = 0; j < options.max_startups; j++)
-                                       if (startup_pipes[j] == -1) {
-                                               startup_pipes[j] = startup_p[0];
-                                               if (maxfd < startup_p[0])
-                                                       maxfd = startup_p[0];
-                                               startups++;
-                                               break;
-                                       }
-
-                               /*
-                                * Got connection.  Fork a child to handle it, unless
-                                * we are in debugging mode.
-                                */
-                               if (debug_flag) {
-                                       /*
-                                        * In debugging mode.  Close the listening
-                                        * socket, and start processing the
-                                        * connection without forking.
-                                        */
-                                       debug("Server will not fork when running in debugging mode.");
-                                       close_listen_socks();
-                                       sock_in = newsock;
-                                       sock_out = newsock;
-                                       close(startup_p[0]);
-                                       close(startup_p[1]);
-                                       startup_pipe = -1;
-                                       pid = getpid();
-                                       if (rexec_flag) {
-                                               send_rexec_state(config_s[0],
-                                                   &cfg);
-                                               close(config_s[0]);
-                                       }
-                                       break;
-                               } else {
-                                       /*
-                                        * Normal production daemon.  Fork, and have
-                                        * the child process the connection. The
-                                        * parent continues listening.
-                                        */
-                                       if ((pid = fork()) == 0) {
-                                               /*
-                                                * Child.  Close the listening and max_startup
-                                                * sockets.  Start using the accepted socket.
-                                                * Reinitialize logging (since our pid has
-                                                * changed).  We break out of the loop to handle
-                                                * the connection.
-                                                */
-                                               startup_pipe = startup_p[1];
-                                               close_startup_pipes();
-                                               close_listen_socks();
-                                               sock_in = newsock;
-                                               sock_out = newsock;
-                                               log_init(__progname, options.log_level, options.log_facility, log_stderr);
-                                               if (rexec_flag)
-                                                       close(config_s[0]);
-                                               break;
-                                       }
-                               }
-
-                               /* Parent.  Stay in the loop. */
-                               if (pid < 0)
-                                       error("fork: %.100s", strerror(errno));
-                               else
-                                       debug("Forked child %ld.", (long)pid);
-
-                               close(startup_p[1]);
-
-                               if (rexec_flag) {
-                                       send_rexec_state(config_s[0], &cfg);
-                                       close(config_s[0]);
-                                       close(config_s[1]);
-                               }
-
-                               /* Mark that the key has been used (it was "given" to the child). */
-                               if ((options.protocol & SSH_PROTO_1) &&
-                                   key_used == 0) {
-                                       /* Schedule server key regeneration alarm. */
-                                       signal(SIGALRM, key_regeneration_alarm);
-                                       alarm(options.key_regeneration_time);
-                                       key_used = 1;
-                               }
-
-                               arc4random_stir();
-
-                               /* Close the new socket (the child is now taking care of it). */
-                               close(newsock);
-                       }
-                       /* child process check (or debug mode) */
-                       if (num_listen_socks < 0)
-                               break;
-               }
+               /* Accept a connection and return in a forked child */
+               server_accept_loop(&sock_in, &sock_out,
+                   &newsock, config_s);
        }
 
        /* This is the child processing a new connection. */
@@ -1656,7 +1726,13 @@ main(int ac, char **av)
         * 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);
+       (void) get_canonical_hostname(0);
+       /*
+        * The rest of the code depends on the fact that
+        * get_remote_ipaddr() caches the remote ip, even if
+        * the socket goes away.
+        */
+       remote_ip = get_remote_ipaddr();
 
 #ifdef SSH_AUDIT_EVENTS
        audit_connection_from(remote_ip, remote_port);
@@ -1759,8 +1835,7 @@ main(int ac, char **av)
        packet_set_nonblocking();
 
        /* allocate authentication context */
-       authctxt = xmalloc(sizeof(*authctxt));
-       memset(authctxt, 0, sizeof(*authctxt));
+       authctxt = xcalloc(1, sizeof(*authctxt));
 
        authctxt->loginmsg = &loginmsg;
 
@@ -1799,6 +1874,7 @@ main(int ac, char **av)
         */
        alarm(0);
        signal(SIGALRM, SIG_DFL);
+       authctxt->authenticated = 1;
        if (startup_pipe != -1) {
                close(startup_pipe);
                startup_pipe = -1;
@@ -1851,11 +1927,14 @@ ssh1_session_key(BIGNUM *session_key_int)
 {
        int rsafail = 0;
 
-       if (BN_cmp(sensitive_data.server_key->rsa->n, sensitive_data.ssh1_host_key->rsa->n) > 0) {
+       if (BN_cmp(sensitive_data.server_key->rsa->n,
+           sensitive_data.ssh1_host_key->rsa->n) > 0) {
                /* Server key has bigger modulus. */
                if (BN_num_bits(sensitive_data.server_key->rsa->n) <
-                   BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + SSH_KEY_BITS_RESERVED) {
-                       fatal("do_connection: %s: server_key %d < host_key %d + SSH_KEY_BITS_RESERVED %d",
+                   BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) +
+                   SSH_KEY_BITS_RESERVED) {
+                       fatal("do_connection: %s: "
+                           "server_key %d < host_key %d + SSH_KEY_BITS_RESERVED %d",
                            get_remote_ipaddr(),
                            BN_num_bits(sensitive_data.server_key->rsa->n),
                            BN_num_bits(sensitive_data.ssh1_host_key->rsa->n),
@@ -1870,8 +1949,10 @@ ssh1_session_key(BIGNUM *session_key_int)
        } else {
                /* Host key has bigger modulus (or they are equal). */
                if (BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) <
-                   BN_num_bits(sensitive_data.server_key->rsa->n) + SSH_KEY_BITS_RESERVED) {
-                       fatal("do_connection: %s: host_key %d < server_key %d + SSH_KEY_BITS_RESERVED %d",
+                   BN_num_bits(sensitive_data.server_key->rsa->n) +
+                   SSH_KEY_BITS_RESERVED) {
+                       fatal("do_connection: %s: "
+                           "host_key %d < server_key %d + SSH_KEY_BITS_RESERVED %d",
                            get_remote_ipaddr(),
                            BN_num_bits(sensitive_data.ssh1_host_key->rsa->n),
                            BN_num_bits(sensitive_data.server_key->rsa->n),
@@ -2096,7 +2177,7 @@ do_ssh2_kex(void)
                myproposal[PROPOSAL_COMP_ALGS_CTOS] =
                myproposal[PROPOSAL_COMP_ALGS_STOC] = "none,zlib@openssh.com";
        }
-       
+
        myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types();
 
        /* start key exchange */
@@ -2154,9 +2235,10 @@ do_ssh2_kex(void)
        kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
        kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
 #endif
-       kex->server = 1;
-       kex->client_version_string=client_version_string;
-       kex->server_version_string=server_version_string;
+       kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
+       kex->server = 1;
+       kex->client_version_string=client_version_string;
+       kex->server_version_string=server_version_string;
        kex->load_host_key=&get_hostkey_by_type;
        kex->host_key_index=&get_hostkey_index;
 
index d260303b9453b15b7ceee0f9db9528f8d1a9807b..ee42c715ead4d7faec2814175741cc5f423123eb 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: sshd_config,v 1.73 2005/12/06 22:38:28 reyk Exp $
+#      $OpenBSD: sshd_config,v 1.74 2006/07/19 13:07:10 dtucker Exp $
 
 # This is the sshd server system-wide configuration file.  See
 # sshd_config(5) for more information.
 
 # Set this to 'yes' to enable PAM authentication, account processing, 
 # and session processing. If this is enabled, PAM authentication will 
-# be allowed through the ChallengeResponseAuthentication mechanism. 
-# Depending on your PAM configuration, this may bypass the setting of 
-# PasswordAuthentication, PermitEmptyPasswords, and 
-# "PermitRootLogin without-password". If you just want the PAM account and 
-# session checks to run without PAM authentication, then enable this but set 
-# ChallengeResponseAuthentication=no
+# be allowed through the ChallengeResponseAuthentication and
+# PasswordAuthentication.  Depending on your PAM configuration,
+# PAM authentication via ChallengeResponseAuthentication may bypass
+# the setting of "PermitRootLogin without-password".
+# If you just want the PAM account and session checks to run without
+# PAM authentication, then enable this but set PasswordAuthentication
+# and ChallengeResponseAuthentication to 'no'.
 #UsePAM no
 
 #AllowTcpForwarding yes
 #MaxStartups 10
 #PermitTunnel no
 
-# override default of no subsystems
-Subsystem      sftp    /usr/libexec/sftp-server
-
-# no default banner path
-#Banner /some/path
-
 # the following are HPN related configuration options
 # tcp receive buffer polling. enable in autotuning kernels
 #TcpRcvBufPoll no
@@ -121,4 +116,16 @@ Subsystem  sftp    /usr/libexec/sftp-server
 
 # buffer size for hpn to non-hn connections
 #HPNBufferSize 2048
+# end of HPN options
+
+# no default banner path
+#Banner /some/path
+
+# override default of no subsystems
+Subsystem      sftp    /usr/libexec/sftp-server
 
+# Example of overriding settings on a per-user basis
+#Match User anoncvs
+#      X11Forwarding no
+#      AllowTcpForwarding no
+#      ForceCommand cvs server
index 31e112f4adc241cf7e8fb4b05abda7b12deda94a..2a0636142f7292ccd79a7ade7aa8d45842b44f03 100644 (file)
@@ -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.48 2006/01/02 17:09:49 jmc Exp $
+.\" $OpenBSD: sshd_config.5,v 1.70 2006/08/21 08:14:01 dtucker Exp $
 .Dd September 25, 1999
 .Dt SSHD_CONFIG 5
 .Os
@@ -46,7 +46,7 @@
 .It Pa /etc/ssh/sshd_config
 .El
 .Sh DESCRIPTION
-.Nm sshd
+.Xr sshd 8
 reads configuration data from
 .Pa /etc/ssh/sshd_config
 (or the file specified with
@@ -56,6 +56,9 @@ The file contains keyword-argument pairs, one per line.
 Lines starting with
 .Ql #
 and empty lines are interpreted as comments.
+Arguments may optionally be enclosed in double quotes
+.Pq \&"
+in order to represent arguments containing spaces.
 .Pp
 The possible
 keywords and their meanings are as follows (note that
@@ -72,7 +75,7 @@ in
 for how to configure the client.
 Note that environment passing is only supported for protocol 2.
 Variables are specified by name, which may contain the wildcard characters
-.Ql \&*
+.Ql *
 and
 .Ql \&? .
 Multiple environment variables may be separated by whitespace or spread
@@ -85,11 +88,11 @@ For this reason, care should be taken in the use of this directive.
 The default is not to accept any environment variables.
 .It Cm AddressFamily
 Specifies which address family should be used by
-.Nm sshd .
+.Xr sshd 8 .
 Valid arguments are
 .Dq any ,
 .Dq inet
-(use IPv4 only) or
+(use IPv4 only), or
 .Dq inet6
 (use IPv6 only).
 The default is
@@ -99,13 +102,20 @@ This keyword can be followed by a list of group name patterns, separated
 by spaces.
 If specified, login is allowed only for users whose primary
 group or supplementary group list matches one of the patterns.
-.Ql \&*
-and
-.Ql \&?
-can be used as
-wildcards in the patterns.
 Only group names are valid; a numerical group ID is not recognized.
 By default, login is allowed for all groups.
+The allow/deny directives are processed in the following order:
+.Cm DenyUsers ,
+.Cm AllowUsers ,
+.Cm DenyGroups ,
+and finally
+.Cm AllowGroups .
+.Pp
+See
+.Sx PATTERNS
+in
+.Xr ssh_config 5
+for more information on patterns.
 .It Cm AllowTcpForwarding
 Specifies whether TCP forwarding is permitted.
 The default is
@@ -118,24 +128,31 @@ This keyword can be followed by a list of user name patterns, separated
 by spaces.
 If specified, login is allowed only for user names that
 match one of the patterns.
-.Ql \&*
-and
-.Ql \&?
-can be used as
-wildcards in the patterns.
 Only user names are valid; a numerical user ID is not recognized.
 By default, login is allowed for all users.
 If the pattern takes the form USER@HOST then USER and HOST
 are separately checked, restricting logins to particular
 users from particular hosts.
+The allow/deny directives are processed in the following order:
+.Cm DenyUsers ,
+.Cm AllowUsers ,
+.Cm DenyGroups ,
+and finally
+.Cm AllowGroups .
+.Pp
+See
+.Sx PATTERNS
+in
+.Xr ssh_config 5
+for more information on patterns.
 .It Cm AuthorizedKeysFile
 Specifies the file that contains the public keys that can be used
 for user authentication.
 .Cm AuthorizedKeysFile
 may contain tokens of the form %T which are substituted during connection
-set-up.
+setup.
 The following tokens are defined: %% is replaced by a literal '%',
-%h is replaced by the home directory of the user being authenticated and
+%h is replaced by the home directory of the user being authenticated, and
 %u is replaced by the username of that user.
 After expansion,
 .Cm AuthorizedKeysFile
@@ -151,7 +168,7 @@ authentication is allowed.
 This option is only available for protocol version 2.
 By default, no banner is displayed.
 .It Cm ChallengeResponseAuthentication
-Specifies whether challenge response authentication is allowed.
+Specifies whether challenge-response authentication is allowed.
 All authentication styles from
 .Xr login.conf 5
 are supported.
@@ -174,20 +191,19 @@ The supported ciphers are
 .Dq 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''
+The default is:
+.Bd -literal -offset 3n
+aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour128,
+arcfour256,arcfour,aes192-cbc,aes256-cbc,aes128-ctr,
+aes192-ctr,aes256-ctr
 .Ed
 .It Cm ClientAliveCountMax
 Sets the number of client alive messages (see below) which may be
 sent without
-.Nm sshd
+.Xr sshd 8
 receiving any messages back from the client.
 If this threshold is reached while client alive messages are being sent,
-.Nm sshd
-will disconnect the client, terminating the session.
+sshd will disconnect the client, terminating the session.
 It is important to note that the use of client alive messages is very
 different from
 .Cm TCPKeepAlive
@@ -205,12 +221,13 @@ If
 .Cm ClientAliveInterval
 (see below) is set to 15, and
 .Cm ClientAliveCountMax
-is left at the default, unresponsive ssh clients
+is left at the default, unresponsive SSH clients
 will be disconnected after approximately 45 seconds.
+This option applies to protocol version 2 only.
 .It Cm ClientAliveInterval
 Sets a timeout interval in seconds after which if no data has been received
 from the client,
-.Nm sshd
+.Xr sshd 8
 will send a message through the encrypted
 channel to request a response from the client.
 The default
@@ -231,36 +248,62 @@ This keyword can be followed by a list of group name patterns, separated
 by spaces.
 Login is disallowed for users whose primary group or supplementary
 group list matches one of the patterns.
-.Ql \&*
-and
-.Ql \&?
-can be used as
-wildcards in the patterns.
 Only group names are valid; a numerical group ID is not recognized.
 By default, login is allowed for all groups.
+The allow/deny directives are processed in the following order:
+.Cm DenyUsers ,
+.Cm AllowUsers ,
+.Cm DenyGroups ,
+and finally
+.Cm AllowGroups .
+.Pp
+See
+.Sx PATTERNS
+in
+.Xr ssh_config 5
+for more information on patterns.
 .It Cm DenyUsers
 This keyword can be followed by a list of user name patterns, separated
 by spaces.
 Login is disallowed for user names that match one of the patterns.
-.Ql \&*
-and
-.Ql \&?
-can be used as wildcards in the patterns.
 Only user names are valid; a numerical user ID is not recognized.
 By default, login is allowed for all users.
 If the pattern takes the form USER@HOST then USER and HOST
 are separately checked, restricting logins to particular
 users from particular hosts.
+The allow/deny directives are processed in the following order:
+.Cm DenyUsers ,
+.Cm AllowUsers ,
+.Cm DenyGroups ,
+and finally
+.Cm AllowGroups .
+.Pp
+See
+.Sx PATTERNS
+in
+.Xr ssh_config 5
+for more information on patterns.
+.It Cm ForceCommand
+Forces the execution of the command specified by
+.Cm ForceCommand ,
+ignoring any command supplied by the client.
+The command is invoked by using the user's login shell with the -c option.
+This applies to shell, command, or subsystem execution.
+It is most useful inside a
+.Cm Match
+block.
+The command originally supplied by the client is available in the
+.Ev SSH_ORIGINAL_COMMAND
+environment variable.
 .It Cm GatewayPorts
 Specifies whether remote hosts are allowed to connect to ports
 forwarded for the client.
 By default,
-.Nm sshd
+.Xr sshd 8
 binds remote port forwardings to the loopback address.
 This prevents other remote hosts from connecting to forwarded ports.
 .Cm GatewayPorts
-can be used to specify that
-.Nm sshd
+can be used to specify that sshd
 should allow remote port forwardings to bind to non-loopback addresses, thus
 allowing other hosts to connect.
 The argument may be
@@ -297,12 +340,29 @@ The default is
 .It Cm HostbasedAuthentication
 Specifies whether rhosts or /etc/hosts.equiv authentication together
 with successful public key client host authentication is allowed
-(hostbased authentication).
+(host-based authentication).
 This option is similar to
 .Cm RhostsRSAAuthentication
 and applies to protocol version 2 only.
 The default is
 .Dq no .
+.It Cm HostbasedUsesNameFromPacketOnly
+Specifies whether or not the server will attempt to perform a reverse
+name lookup when matching the name in the
+.Pa ~/.shosts ,
+.Pa ~/.rhosts ,
+and
+.Pa /etc/hosts.equiv
+files during
+.Cm HostbasedAuthentication .
+A setting of
+.Dq yes
+means that
+.Xr sshd 8
+uses the name supplied by the client rather than
+attempting to resolve the name from the TCP connection itself.
+The default is
+.Dq no .
 .It Cm HostKey
 Specifies a file containing a private host key
 used by SSH.
@@ -314,7 +374,7 @@ and
 .Pa /etc/ssh/ssh_host_dsa_key
 for protocol version 2.
 Note that
-.Nm sshd
+.Xr sshd 8
 will refuse to use a file if it is group/world-accessible.
 It is possible to have multiple host key files.
 .Dq rsa1
@@ -341,7 +401,7 @@ The default is
 .Dq yes .
 .It Cm IgnoreUserKnownHosts
 Specifies whether
-.Nm sshd
+.Xr sshd 8
 should ignore the user's
 .Pa ~/.ssh/known_hosts
 during
@@ -356,24 +416,24 @@ Specifies whether the password provided by the user for
 will be validated through the Kerberos KDC.
 To use this option, the server needs a
 Kerberos servtab which allows the verification of the KDC's identity.
-Default is
+The default is
 .Dq no .
 .It Cm KerberosGetAFSToken
 If AFS is active and the user has a Kerberos 5 TGT, attempt to acquire
 an AFS token before accessing the user's home directory.
-Default is
+The default is
 .Dq no .
 .It Cm KerberosOrLocalPasswd
-If set then if password authentication through Kerberos fails then
+If password authentication through Kerberos fails then
 the password will be validated via any additional local mechanism
 such as
 .Pa /etc/passwd .
-Default is
+The default is
 .Dq yes .
 .It Cm KerberosTicketCleanup
 Specifies whether to automatically destroy the user's ticket cache
 file on logout.
-Default is
+The default is
 .Dq yes .
 .It Cm KeyRegenerationInterval
 In protocol version 1, the ephemeral server key is automatically regenerated
@@ -386,7 +446,7 @@ If the value is 0, the key is never regenerated.
 The default is 3600 (seconds).
 .It Cm ListenAddress
 Specifies the local addresses
-.Nm sshd
+.Xr sshd 8
 should listen on.
 The following forms may be used:
 .Pp
@@ -412,8 +472,7 @@ The following forms may be used:
 If
 .Ar port
 is not specified,
-.Nm sshd
-will listen on the address and all prior
+sshd will listen on the address and all prior
 .Cm Port
 options specified.
 The default is to listen on all local addresses.
@@ -422,7 +481,7 @@ Multiple
 options are permitted.
 Additionally, any
 .Cm Port
-options must precede this option for non port qualified addresses.
+options must precede this option for non-port qualified addresses.
 .It Cm LoginGraceTime
 The server disconnects after this time if the user has not
 successfully logged in.
@@ -430,9 +489,9 @@ If the value is 0, there is no time limit.
 The default is 120 seconds.
 .It Cm LogLevel
 Gives the verbosity level that is used when logging messages from
-.Nm sshd .
+.Xr sshd 8 .
 The possible values are:
-QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, DEBUG1, DEBUG2 and DEBUG3.
+QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, DEBUG1, DEBUG2, and DEBUG3.
 The default is INFO.
 DEBUG and DEBUG1 are equivalent.
 DEBUG2 and DEBUG3 each specify higher levels of debugging output.
@@ -442,8 +501,37 @@ Specifies the available MAC (message authentication code) algorithms.
 The MAC algorithm is used in protocol version 2
 for data integrity protection.
 Multiple algorithms must be comma-separated.
-The default is
+The default is:
 .Dq hmac-md5,hmac-sha1,hmac-ripemd160,hmac-sha1-96,hmac-md5-96 .
+.It Cm Match
+Introduces a conditional block.
+If all of the criteria on the
+.Cm Match
+line are satisfied, the keywords on the following lines override those
+set in the global section of the config file, until either another
+.Cm Match
+line or the end of the file.
+The arguments to
+.Cm Match
+are one or more criteria-pattern pairs.
+The available criteria are
+.Cm User ,
+.Cm Group ,
+.Cm Host ,
+and
+.Cm Address .
+Only a subset of keywords may be used on the lines following a
+.Cm Match
+keyword.
+Available keywords are
+.Cm AllowTcpForwarding ,
+.Cm ForceCommand ,
+.Cm GatewayPorts ,
+.Cm PermitOpen ,
+.Cm X11DisplayOffset ,
+.Cm X11Forwarding ,
+and
+.Cm X11UseLocalHost .
 .It Cm MaxAuthTries
 Specifies the maximum number of authentication attempts permitted per
 connection.
@@ -452,8 +540,7 @@ additional failures are logged.
 The default is 6.
 .It Cm MaxStartups
 Specifies the maximum number of concurrent unauthenticated connections to the
-.Nm sshd
-daemon.
+SSH daemon.
 Additional connections will be dropped until authentication succeeds or the
 .Cm LoginGraceTime
 expires for a connection.
@@ -462,8 +549,8 @@ The default is 10.
 Alternatively, random early drop can be enabled by specifying
 the three colon separated values
 .Dq start:rate:full
-(e.g., "10:30:60").
-.Nm sshd
+(e.g. "10:30:60").
+.Xr sshd 8
 will refuse connection attempts with a probability of
 .Dq rate/100
 (30%)
@@ -484,24 +571,51 @@ When password authentication is allowed, it specifies whether the
 server allows login to accounts with empty password strings.
 The default is
 .Dq no .
+.It Cm PermitOpen
+Specifies the destinations to which TCP port forwarding is permitted.
+The forwarding specification must be one of the following forms:
+.Pp
+.Bl -item -offset indent -compact
+.It
+.Cm PermitOpen
+.Sm off
+.Ar host : port
+.Sm on
+.It
+.Cm PermitOpen
+.Sm off
+.Ar IPv4_addr : port
+.Sm on
+.It
+.Cm PermitOpen
+.Sm off
+.Ar \&[ IPv6_addr \&] : port
+.Sm on
+.El
+.Pp
+Multiple forwards may be specified by separating them with whitespace.
+An argument of
+.Dq any
+can be used to remove all restrictions and permit any forwarding requests.
+By default all port forwarding requests are permitted.
 .It Cm PermitRootLogin
 Specifies whether root can log in using
 .Xr ssh 1 .
 The argument must be
 .Dq yes ,
 .Dq without-password ,
-.Dq forced-commands-only
+.Dq forced-commands-only ,
 or
 .Dq no .
 The default is
 .Dq yes .
 .Pp
 If this option is set to
-.Dq without-password
+.Dq without-password ,
 password authentication is disabled for root.
 .Pp
 If this option is set to
-.Dq forced-commands-only
+.Dq forced-commands-only ,
 root login with public key authentication will be allowed,
 but only if the
 .Ar command
@@ -511,7 +625,7 @@ normally not allowed).
 All other authentication methods are disabled for root.
 .Pp
 If this option is set to
-.Dq no
+.Dq no ,
 root is not allowed to log in.
 .It Cm PermitTunnel
 Specifies whether
@@ -519,10 +633,17 @@ Specifies whether
 device forwarding is allowed.
 The argument must be
 .Dq yes ,
-.Dq point-to-point ,
+.Dq point-to-point
+(layer 3),
 .Dq ethernet
-or
+(layer 2), or
 .Dq no .
+Specifying
+.Dq yes
+permits both
+.Dq point-to-point
+and
+.Dq ethernet .
 The default is
 .Dq no .
 .It Cm PermitUserEnvironment
@@ -533,7 +654,7 @@ and
 options in
 .Pa ~/.ssh/authorized_keys
 are processed by
-.Nm sshd .
+.Xr sshd 8 .
 The default is
 .Dq no .
 Enabling environment processing may enable users to bypass access
@@ -541,13 +662,12 @@ restrictions in some configurations using mechanisms such as
 .Ev LD_PRELOAD .
 .It Cm PidFile
 Specifies the file that contains the process ID of the
-.Nm sshd
-daemon.
+SSH daemon.
 The default is
 .Pa /var/run/sshd.pid .
 .It Cm Port
 Specifies the port number that
-.Nm sshd
+.Xr sshd 8
 listens on.
 The default is 22.
 Multiple options of this type are permitted.
@@ -555,14 +675,14 @@ See also
 .Cm ListenAddress .
 .It Cm PrintLastLog
 Specifies whether
-.Nm sshd
+.Xr sshd 8
 should print the date and time of the last user login when a user logs
 in interactively.
 The default is
 .Dq yes .
 .It Cm PrintMotd
 Specifies whether
-.Nm sshd
+.Xr sshd 8
 should print
 .Pa /etc/motd
 when a user logs in interactively.
@@ -573,12 +693,12 @@ The default is
 .Dq yes .
 .It Cm Protocol
 Specifies the protocol versions
-.Nm sshd
+.Xr sshd 8
 supports.
 The possible values are
-.Dq 1
+.Sq 1
 and
-.Dq 2 .
+.Sq 2 .
 Multiple versions must be comma-separated.
 The default is
 .Dq 2,1 .
@@ -610,7 +730,7 @@ Defines the number of bits in the ephemeral protocol version 1 server key.
 The minimum value is 512, and the default is 768.
 .It Cm StrictModes
 Specifies whether
-.Nm sshd
+.Xr sshd 8
 should check file modes and ownership of the
 user's files and home directory before accepting login.
 This is normally desirable because novices sometimes accidentally leave their
@@ -618,9 +738,9 @@ directory or files world-writable.
 The default is
 .Dq yes .
 .It Cm Subsystem
-Configures an external subsystem (e.g., file transfer daemon).
-Arguments should be a subsystem name and a command to execute upon subsystem
-request.
+Configures an external subsystem (e.g. file transfer daemon).
+Arguments should be a subsystem name and a command (with optional arguments)
+to execute upon subsystem request.
 The command
 .Xr sftp-server 8
 implements the
@@ -630,7 +750,7 @@ By default no subsystems are defined.
 Note that this option applies to protocol version 2 only.
 .It Cm SyslogFacility
 Gives the facility code that is used when logging messages from
-.Nm sshd .
+.Xr sshd 8 .
 The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2,
 LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.
 The default is AUTH.
@@ -657,7 +777,7 @@ To disable TCP keepalive messages, the value should be set to
 .Dq no .
 .It Cm UseDNS
 Specifies whether
-.Nm sshd
+.Xr sshd 8
 should look up the remote host name and check that
 the resolved host name for the remote IP address maps back to the
 very same IP address.
@@ -688,7 +808,10 @@ If set to
 .Dq yes
 this will enable PAM authentication using
 .Cm ChallengeResponseAuthentication
-and PAM account and session module processing for all authentication types.
+and
+.Cm PasswordAuthentication
+in addition to PAM account and session module processing for all
+authentication types.
 .Pp
 Because PAM challenge-response authentication usually serves an equivalent
 role to password authentication, you should disable either
@@ -705,7 +828,7 @@ The default is
 .Dq no .
 .It Cm UsePrivilegeSeparation
 Specifies whether
-.Nm sshd
+.Xr sshd 8
 separates privileges by creating an unprivileged child process
 to deal with incoming network traffic.
 After successful authentication, another process will be created that has
@@ -716,11 +839,9 @@ The default is
 .Dq yes .
 .It Cm X11DisplayOffset
 Specifies the first display number available for
-.Nm sshd Ns 's
+.Xr sshd 8 Ns 's
 X11 forwarding.
-This prevents
-.Nm sshd
-from interfering with real X11 servers.
+This prevents sshd from interfering with real X11 servers.
 The default is 10.
 .It Cm X11Forwarding
 Specifies whether X11 forwarding is permitted.
@@ -733,14 +854,14 @@ The default is
 .Pp
 When X11 forwarding is enabled, there may be additional exposure to
 the server and to client displays if the
-.Nm sshd
+.Xr sshd 8
 proxy display is configured to listen on the wildcard address (see
 .Cm X11UseLocalhost
-below), however this is not the default.
+below), though this is not the default.
 Additionally, the authentication spoofing and authentication data
 verification and substitution occur on the client side.
 The security risk of using X11 forwarding is that the client's X11
-display server may be exposed to attack when the ssh client requests
+display server may be exposed to attack when the SSH client requests
 forwarding (see the warnings for
 .Cm ForwardX11
 in
@@ -758,12 +879,11 @@ X11 forwarding is automatically disabled if
 is enabled.
 .It Cm X11UseLocalhost
 Specifies whether
-.Nm sshd
+.Xr sshd 8
 should bind the X11 forwarding server to the loopback address or to
 the wildcard address.
 By default,
-.Nm sshd
-binds the forwarding server to the loopback address and sets the
+sshd binds the forwarding server to the loopback address and sets the
 hostname part of the
 .Ev DISPLAY
 environment variable to
@@ -789,8 +909,8 @@ program.
 The default is
 .Pa /usr/X11R6/bin/xauth .
 .El
-.Ss Time Formats
-.Nm sshd
+.Sh TIME FORMATS
+.Xr sshd 8
 command-line arguments and configuration file options that specify time
 may be expressed using a sequence of the form:
 .Sm off
@@ -803,7 +923,7 @@ is a positive integer value and
 is one of the following:
 .Pp
 .Bl -tag -width Ds -compact -offset indent
-.It Cm <none>
+.It Aq Cm none
 seconds
 .It Cm s | Cm S
 seconds
@@ -834,7 +954,7 @@ Time format examples:
 .Bl -tag -width Ds
 .It Pa /etc/ssh/sshd_config
 Contains configuration data for
-.Nm sshd .
+.Xr sshd 8 .
 This file should be writable by root only, but it is recommended
 (though not necessary) that it be world-readable.
 .El
index 4ae1b415d6d814dd3c9c63348e538d2063e4781c..74e0977506d89d7e9f81417fb134d32ea9578850 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: version.h,v 1.46 2006/02/01 11:27:22 markus Exp $ */
+/* $OpenBSD: version.h,v 1.47 2006/08/30 00:14:37 djm Exp $ */
 
 #ifdef GSI
 #define GSI_VERSION    " GSI"
 #define MGLUE_VERSION  ""
 #endif
 
-#define SSH_VERSION    "OpenSSH_4.3"
+#define SSH_HPN                        "-hpn12"
+#define NCSA_VERSION   " NCSA_GSSAPI_20060928"
 
-#define SSH_PORTABLE   "p2"
-#define SSH_HPN                "-hpn12"
-#define SSH_RELEASE    SSH_VERSION SSH_PORTABLE SSH_HPN \
-                       " NCSA_GSSAPI_20060726" \
-                       GSI_VERSION KRB5_VERSION MGLUE_VERSION
+#define SSH_VERSION    "OpenSSH_4.4"
+
+#define SSH_PORTABLE   "p1"
+#define SSH_RELEASE    SSH_VERSION SSH_PORTABLE \
+            SSH_HPN NCSA_VERSION GSI_VERSION KRB5_VERSION MGLUE_VERSION
This page took 3.334061 seconds and 5 git commands to generate.