]> andersk Git - gssapi-openssh.git/commitdiff
merged OpenSSH 3.9p1 to trunk OPENSSH_4_9P1_GSSAPI_20080401
authorbasney <basney>
Tue, 1 Apr 2008 16:20:38 +0000 (16:20 +0000)
committerbasney <basney>
Tue, 1 Apr 2008 16:20:38 +0000 (16:20 +0000)
50 files changed:
openssh/Makefile.in
openssh/atomicio.c
openssh/auth-pam.c
openssh/auth.c
openssh/auth.h
openssh/auth1.c
openssh/auth2-gss.c
openssh/auth2-none.c
openssh/auth2.c
openssh/canohost.c
openssh/channels.c
openssh/clientloop.c
openssh/configure.ac
openssh/contrib/gnome-ssh-askpass2.c
openssh/defines.h
openssh/key.c
openssh/misc.c
openssh/monitor.c
openssh/monitor_fdpass.c
openssh/monitor_fdpass.h
openssh/monitor_wrap.c
openssh/openbsd-compat/fake-rfc2553.h
openssh/openbsd-compat/getrrsetbyname.c
openssh/openbsd-compat/getrrsetbyname.h
openssh/openbsd-compat/port-aix.c
openssh/openbsd-compat/port-aix.h
openssh/openbsd-compat/sys-queue.h
openssh/openbsd-compat/sys-tree.h
openssh/packet.c
openssh/packet.h
openssh/readconf.c
openssh/readconf.h
openssh/scp.c
openssh/servconf.c
openssh/servconf.h
openssh/serverloop.c
openssh/session.c
openssh/sftp.c
openssh/ssh-agent.c
openssh/ssh-keyscan.c
openssh/ssh.1
openssh/ssh.c
openssh/ssh_config.5
openssh/sshconnect.c
openssh/sshconnect2.c
openssh/sshd.8
openssh/sshd.c
openssh/sshd_config
openssh/sshd_config.5
openssh/version.h

index cac0ba58e0e3c333c0fb16efa4cef71584b3b8a1..781a6835b8529f3c51da2d1f880d013c81858451 100644 (file)
@@ -90,7 +90,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
        kexgsss.o \
        gss-serv-gsi.o \
        loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.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 platform.o
+       audit.o audit-bsm.o platform.o sftp-server.o sftp-common.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
 
 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
@@ -160,8 +160,8 @@ ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o
 ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o
        $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
 
 ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o
        $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
 
-sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o
-       $(LD) -o $@ sftp-server.o sftp-common.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
+sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o sftp-server-main.o
+       $(LD) -o $@ sftp-server.o sftp-common.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
 
 sftp$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-client.o sftp-common.o sftp-glob.o progressmeter.o
        $(LD) -o $@ progressmeter.o sftp.o sftp-client.o sftp-common.o sftp-glob.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(LIBEDIT)
 
 sftp$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-client.o sftp-common.o sftp-glob.o progressmeter.o
        $(LD) -o $@ progressmeter.o sftp.o sftp-client.o sftp-common.o sftp-glob.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(LIBEDIT)
@@ -406,7 +406,7 @@ uninstall:
        -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8
        -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
 
        -rm -f $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8
        -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
 
-tests: $(TARGETS)
+tests interop-tests:   $(TARGETS)
        BUILDDIR=`pwd`; \
        [ -d `pwd`/regress ]  ||  mkdir -p `pwd`/regress; \
        [ -f `pwd`/regress/Makefile ]  || \
        BUILDDIR=`pwd`; \
        [ -d `pwd`/regress ]  ||  mkdir -p `pwd`/regress; \
        [ -f `pwd`/regress/Makefile ]  || \
@@ -420,6 +420,8 @@ tests:      $(TARGETS)
        TEST_SSH_SSHKEYSCAN="$${BUILDDIR}/ssh-keyscan"; \
        TEST_SSH_SFTP="$${BUILDDIR}/sftp"; \
        TEST_SSH_SFTPSERVER="$${BUILDDIR}/sftp-server"; \
        TEST_SSH_SSHKEYSCAN="$${BUILDDIR}/ssh-keyscan"; \
        TEST_SSH_SFTP="$${BUILDDIR}/sftp"; \
        TEST_SSH_SFTPSERVER="$${BUILDDIR}/sftp-server"; \
+       TEST_SSH_PLINK="plink"; \
+       TEST_SSH_PUTTYGEN="puttygen"; \
        cd $(srcdir)/regress || exit $$?; \
        $(MAKE) \
                .OBJDIR="$${BUILDDIR}/regress" \
        cd $(srcdir)/regress || exit $$?; \
        $(MAKE) \
                .OBJDIR="$${BUILDDIR}/regress" \
@@ -436,6 +438,8 @@ tests:      $(TARGETS)
                TEST_SSH_SSHKEYSCAN="$${TEST_SSH_SSHKEYSCAN}" \
                TEST_SSH_SFTP="$${TEST_SSH_SFTP}" \
                TEST_SSH_SFTPSERVER="$${TEST_SSH_SFTPSERVER}" \
                TEST_SSH_SSHKEYSCAN="$${TEST_SSH_SSHKEYSCAN}" \
                TEST_SSH_SFTP="$${TEST_SSH_SFTP}" \
                TEST_SSH_SFTPSERVER="$${TEST_SSH_SFTPSERVER}" \
+               TEST_SSH_PLINK="$${TEST_SSH_PLINK}" \
+               TEST_SSH_PUTTYGEN="$${TEST_SSH_PUTTYGEN}" \
                EXEEXT="$(EXEEXT)" \
                $@
 
                EXEEXT="$(EXEEXT)" \
                $@
 
index 62ee40282d7233aca67b8d903a1eb5ee1430e068..575bf8900ee39e9e3cb89061934b659bd87b52d6 100644 (file)
 #include <errno.h>
 #ifdef HAVE_POLL_H
 #include <poll.h>
 #include <errno.h>
 #ifdef HAVE_POLL_H
 #include <poll.h>
+#else
+# ifdef HAVE_SYS_POLL_H
+#  include <sys/poll.h>
+# endif
 #endif
 #include <string.h>
 #include <unistd.h>
 #endif
 #include <string.h>
 #include <unistd.h>
index a07f1fe77d86e7290209ffcbf8346bf97b9786a2..ccdb9937e364af74197f31a1a1f62ab0feaabb52 100644 (file)
@@ -598,15 +598,17 @@ static struct pam_conv store_conv = { sshpam_store_conv, NULL };
 void
 sshpam_cleanup(void)
 {
 void
 sshpam_cleanup(void)
 {
-       debug("PAM: cleanup");
-       if (sshpam_handle == NULL)
+       if (sshpam_handle == NULL || (use_privsep && !mm_is_monitor()))
                return;
                return;
+       debug("PAM: cleanup");
        pam_set_item(sshpam_handle, PAM_CONV, (const void *)&null_conv);
        if (sshpam_cred_established) {
        pam_set_item(sshpam_handle, PAM_CONV, (const void *)&null_conv);
        if (sshpam_cred_established) {
+               debug("PAM: deleting credentials");
                pam_setcred(sshpam_handle, PAM_DELETE_CRED);
                sshpam_cred_established = 0;
        }
        if (sshpam_session_open) {
                pam_setcred(sshpam_handle, PAM_DELETE_CRED);
                sshpam_cred_established = 0;
        }
        if (sshpam_session_open) {
+               debug("PAM: closing session");
                pam_close_session(sshpam_handle, PAM_SILENT);
                sshpam_session_open = 0;
        }
                pam_close_session(sshpam_handle, PAM_SILENT);
                sshpam_session_open = 0;
        }
index 68e350bc1c0d77321fdf61f26037f758c5d48207..f35600eed1fe302754c3d40e50f83164dd1b1d3a 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth.c,v 1.75 2006/08/03 03:34:41 deraadt Exp $ */
+/* $OpenBSD: auth.c,v 1.78 2007/09/21 08:15:29 djm Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
index 9ba2975dce19139ecc356e6778809c806365f755..5c05408febd1b4cd821684224bdfa012db33a7ae 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth.h,v 1.58 2006/08/18 09:15:20 markus Exp $ */
+/* $OpenBSD: auth.h,v 1.60 2007/09/21 08:15:29 djm Exp $ */
 
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
 
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
index b9d6b1115f4f98d778f80186eacc41ee5cc6ce17..c17cc91335fb7baed4870f17270a15e011b03a45 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth1.c,v 1.70 2006/08/03 03:34:41 deraadt Exp $ */
+/* $OpenBSD: auth1.c,v 1.71 2007/09/21 08:15:29 djm Exp $ */
 /*
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  *                    All rights reserved
 /*
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  *                    All rights reserved
index 44bcbefd9f1cf5ec581054eab0875132b929cdf2..2cf692945ecb2b2500980b144f94bc5bb7b08684 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2-gss.c,v 1.15 2006/08/03 03:34:41 deraadt Exp $ */
+/* $OpenBSD: auth2-gss.c,v 1.16 2007/10/29 00:52:45 dtucker Exp $ */
 
 /*
  * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
 
 /*
  * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
index 952b448248e94cd21d6ce76a6d11db0e0eccee88..28e593e6c9bdc7728a7be4b68689bb3b7def9c08 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2-none.c,v 1.13 2006/08/05 07:52:52 dtucker Exp $ */
+/* $OpenBSD: auth2-none.c,v 1.14 2007/08/23 03:22:16 djm Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
@@ -32,6 +32,7 @@
 #include <fcntl.h>
 #include <stdarg.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <stdarg.h>
 #include <unistd.h>
+#include <string.h>
 
 #include "xmalloc.h"
 #include "key.h"
 
 #include "xmalloc.h"
 #include "key.h"
@@ -106,7 +107,9 @@ userauth_banner(void)
 {
        char *banner = NULL;
 
 {
        char *banner = NULL;
 
-       if (options.banner == NULL || (datafellows & SSH_BUG_BANNER))
+       if (options.banner == NULL ||
+           strcasecmp(options.banner, "none") == 0 ||
+           (datafellows & SSH_BUG_BANNER) != 0)
                return;
 
        if ((banner = PRIVSEP(auth2_read_banner())) == NULL)
                return;
 
        if ((banner = PRIVSEP(auth2_read_banner())) == NULL)
index ff7d639e68a86ca956205e375131090b095415b5..9043b2c91dc566c08ac2e396d0de924daa238789 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2.c,v 1.115 2007/04/14 22:01:58 stevesk Exp $ */
+/* $OpenBSD: auth2.c,v 1.116 2007/09/29 00:25:51 dtucker Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
@@ -97,7 +97,6 @@ static void input_userauth_request(int, u_int32_t, void *);
 /* helper */
 static Authmethod *authmethod_lookup(const char *);
 static char *authmethods_get(void);
 /* helper */
 static Authmethod *authmethod_lookup(const char *);
 static char *authmethods_get(void);
-int user_key_allowed(struct passwd *, Key *);
 
 /*
  * loop until authctxt->success == TRUE
 
 /*
  * loop until authctxt->success == TRUE
index 7e88dc8d189f8ca205110989e68036b9a7ccda47..670f23bf5befc9744e3e0c754b0dbdcc22565578 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: canohost.c,v 1.61 2006/08/03 03:34:41 deraadt Exp $ */
+/* $OpenBSD: canohost.c,v 1.62 2007/12/27 14:22:08 dtucker Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -34,6 +34,7 @@
 #include "packet.h"
 #include "log.h"
 #include "canohost.h"
 #include "packet.h"
 #include "log.h"
 #include "canohost.h"
+#include "misc.h"
 
 static void check_ip_options(int, char *);
 
 
 static void check_ip_options(int, char *);
 
@@ -273,7 +274,7 @@ get_socket_address(int sock, int remote, int flags)
        if ((r = getnameinfo((struct sockaddr *)&addr, addrlen, ntop,
            sizeof(ntop), NULL, 0, flags)) != 0) {
                error("get_socket_address: getnameinfo %d failed: %s", flags,
        if ((r = getnameinfo((struct sockaddr *)&addr, addrlen, ntop,
            sizeof(ntop), NULL, 0, flags)) != 0) {
                error("get_socket_address: getnameinfo %d failed: %s", flags,
-                   r == EAI_SYSTEM ? strerror(errno) : gai_strerror(r));
+                   ssh_gai_strerror(r));
                return NULL;
        }
        return xstrdup(ntop);
                return NULL;
        }
        return xstrdup(ntop);
@@ -374,7 +375,7 @@ get_sock_port(int sock, int local)
        if ((r = getnameinfo((struct sockaddr *)&from, fromlen, NULL, 0,
            strport, sizeof(strport), NI_NUMERICSERV)) != 0)
                fatal("get_sock_port: getnameinfo NI_NUMERICSERV failed: %s",
        if ((r = getnameinfo((struct sockaddr *)&from, fromlen, NULL, 0,
            strport, sizeof(strport), NI_NUMERICSERV)) != 0)
                fatal("get_sock_port: getnameinfo NI_NUMERICSERV failed: %s",
-                   r == EAI_SYSTEM ? strerror(errno) : gai_strerror(r));
+                   ssh_gai_strerror(r));
        return atoi(strport);
 }
 
        return atoi(strport);
 }
 
index 2ef1af902fc7a35c1ee546d0bc706355a43e14a9..87dcb730f177a0130be91402649ace3bf06a42a9 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: channels.c,v 1.270 2007/06/25 08:20:03 dtucker Exp $ */
+/* $OpenBSD: channels.c,v 1.272 2008/01/19 23:02:40 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -2420,7 +2420,7 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
                        wildcard = 1;
        } else if (gateway_ports || is_client) {
                if (((datafellows & SSH_OLD_FORWARD_ADDR) &&
                        wildcard = 1;
        } else if (gateway_ports || is_client) {
                if (((datafellows & SSH_OLD_FORWARD_ADDR) &&
-                   strcmp(listen_addr, "0.0.0.0") == 0) ||
+                   strcmp(listen_addr, "0.0.0.0") == 0 && is_client == 0) ||
                    *listen_addr == '\0' || strcmp(listen_addr, "*") == 0 ||
                    (!is_client && gateway_ports == 1))
                        wildcard = 1;
                    *listen_addr == '\0' || strcmp(listen_addr, "*") == 0 ||
                    (!is_client && gateway_ports == 1))
                        wildcard = 1;
@@ -2444,10 +2444,11 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
                if (addr == NULL) {
                        /* This really shouldn't happen */
                        packet_disconnect("getaddrinfo: fatal error: %s",
                if (addr == NULL) {
                        /* This really shouldn't happen */
                        packet_disconnect("getaddrinfo: fatal error: %s",
-                           gai_strerror(r));
+                           ssh_gai_strerror(r));
                } else {
                        error("channel_setup_fwd_listener: "
                } else {
                        error("channel_setup_fwd_listener: "
-                           "getaddrinfo(%.64s): %s", addr, gai_strerror(r));
+                           "getaddrinfo(%.64s): %s", addr,
+                           ssh_gai_strerror(r));
                }
                return 0;
        }
                }
                return 0;
        }
@@ -2776,7 +2777,7 @@ connect_to(const char *host, u_short port)
        snprintf(strport, sizeof strport, "%d", port);
        if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) {
                error("connect_to %.100s: unknown host (%s)", host,
        snprintf(strport, sizeof strport, "%d", port);
        if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) {
                error("connect_to %.100s: unknown host (%s)", host,
-                   gai_strerror(gaierr));
+                   ssh_gai_strerror(gaierr));
                return -1;
        }
        for (ai = aitop; ai; ai = ai->ai_next) {
                return -1;
        }
        for (ai = aitop; ai; ai = ai->ai_next) {
@@ -2919,7 +2920,7 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
                hints.ai_socktype = SOCK_STREAM;
                snprintf(strport, sizeof strport, "%d", port);
                if ((gaierr = getaddrinfo(NULL, strport, &hints, &aitop)) != 0) {
                hints.ai_socktype = SOCK_STREAM;
                snprintf(strport, sizeof strport, "%d", port);
                if ((gaierr = getaddrinfo(NULL, strport, &hints, &aitop)) != 0) {
-                       error("getaddrinfo: %.100s", gai_strerror(gaierr));
+                       error("getaddrinfo: %.100s", ssh_gai_strerror(gaierr));
                        return -1;
                }
                for (ai = aitop; ai; ai = ai->ai_next) {
                        return -1;
                }
                for (ai = aitop; ai; ai = ai->ai_next) {
@@ -3099,7 +3100,8 @@ x11_connect_display(void)
        hints.ai_socktype = SOCK_STREAM;
        snprintf(strport, sizeof strport, "%u", 6000 + display_number);
        if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) {
        hints.ai_socktype = SOCK_STREAM;
        snprintf(strport, sizeof strport, "%u", 6000 + display_number);
        if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) {
-               error("%.100s: unknown host. (%s)", buf, gai_strerror(gaierr));
+               error("%.100s: unknown host. (%s)", buf,
+               ssh_gai_strerror(gaierr));
                return -1;
        }
        for (ai = aitop; ai; ai = ai->ai_next) {
                return -1;
        }
        for (ai = aitop; ai; ai = ai->ai_next) {
index d8016acccac38ec393dc24a57c3ecff8b84ba107..afd68064fab9e160a78bfd5f210d1e0134537bfc 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: clientloop.c,v 1.181 2007/08/15 08:14:46 markus Exp $ */
+/* $OpenBSD: clientloop.c,v 1.188 2008/02/22 20:44:02 dtucker Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -157,7 +157,6 @@ static int connection_in;   /* Connection to server (input). */
 static int connection_out;     /* Connection to server (output). */
 static int need_rekeying;      /* Set to non-zero if rekeying is requested. */
 static int session_closed = 0; /* In SSH2: login session closed. */
 static int connection_out;     /* Connection to server (output). */
 static int need_rekeying;      /* Set to non-zero if rekeying is requested. */
 static int session_closed = 0; /* In SSH2: login session closed. */
-static int server_alive_timeouts = 0;
 
 static void client_init_dispatch(void);
 int    session_ident = -1;
 
 static void client_init_dispatch(void);
 int    session_ident = -1;
@@ -467,14 +466,14 @@ client_check_window_change(void)
 static void
 client_global_request_reply(int type, u_int32_t seq, void *ctxt)
 {
 static void
 client_global_request_reply(int type, u_int32_t seq, void *ctxt)
 {
-       server_alive_timeouts = 0;
+       keep_alive_timeouts = 0;
        client_global_request_reply_fwd(type, seq, ctxt);
 }
 
 static void
 server_alive_check(void)
 {
        client_global_request_reply_fwd(type, seq, ctxt);
 }
 
 static void
 server_alive_check(void)
 {
-       if (++server_alive_timeouts > options.server_alive_count_max) {
+       if (++keep_alive_timeouts > options.server_alive_count_max) {
                logit("Timeout, server not responding.");
                cleanup_exit(255);
        }
                logit("Timeout, server not responding.");
                cleanup_exit(255);
        }
@@ -722,7 +721,7 @@ client_process_control(fd_set *readset)
        struct sockaddr_storage addr;
        struct confirm_ctx *cctx;
        char *cmd;
        struct sockaddr_storage addr;
        struct confirm_ctx *cctx;
        char *cmd;
-       u_int i, len, env_len, command, flags;
+       u_int i, j, len, env_len, command, flags;
        uid_t euid;
        gid_t egid;
 
        uid_t euid;
        gid_t egid;
 
@@ -870,9 +869,23 @@ client_process_control(fd_set *readset)
        xfree(cmd);
 
        /* Gather fds from client */
        xfree(cmd);
 
        /* Gather fds from client */
-       new_fd[0] = mm_receive_fd(client_fd);
-       new_fd[1] = mm_receive_fd(client_fd);
-       new_fd[2] = mm_receive_fd(client_fd);
+       for(i = 0; i < 3; i++) {
+               if ((new_fd[i] = mm_receive_fd(client_fd)) == -1) {
+                       error("%s: failed to receive fd %d from slave",
+                           __func__, i);
+                       for (j = 0; j < i; j++)
+                               close(new_fd[j]);
+                       for (j = 0; j < env_len; j++)
+                               xfree(cctx->env[j]);
+                       if (env_len > 0)
+                               xfree(cctx->env);
+                       xfree(cctx->term);
+                       buffer_free(&cctx->cmd);
+                       close(client_fd);
+                       xfree(cctx);
+                       return;
+               }
+       }
 
        debug2("%s: got fds stdin %d, stdout %d, stderr %d", __func__,
            new_fd[0], new_fd[1], new_fd[2]);
 
        debug2("%s: got fds stdin %d, stdout %d, stderr %d", __func__,
            new_fd[0], new_fd[1], new_fd[2]);
@@ -944,6 +957,9 @@ process_cmdline(void)
        u_short cancel_port;
        Forward fwd;
 
        u_short cancel_port;
        Forward fwd;
 
+       bzero(&fwd, sizeof(fwd));
+       fwd.listen_host = fwd.connect_host = NULL;
+
        leave_raw_mode();
        handler = signal(SIGINT, SIG_IGN);
        cmd = s = read_passphrase("\r\nssh> ", RP_ECHO);
        leave_raw_mode();
        handler = signal(SIGINT, SIG_IGN);
        cmd = s = read_passphrase("\r\nssh> ", RP_ECHO);
@@ -1044,6 +1060,10 @@ out:
        enter_raw_mode();
        if (cmd)
                xfree(cmd);
        enter_raw_mode();
        if (cmd)
                xfree(cmd);
+       if (fwd.listen_host != NULL)
+               xfree(fwd.listen_host);
+       if (fwd.connect_host != NULL)
+               xfree(fwd.connect_host);
 }
 
 /* process the characters one by one */
 }
 
 /* process the characters one by one */
@@ -1725,7 +1745,7 @@ client_request_forwarded_tcpip(const char *request_type, int rchan)
        if (options.hpn_disabled) 
        c = channel_new("forwarded-tcpip",
            SSH_CHANNEL_CONNECTING, sock, sock, -1,
        if (options.hpn_disabled) 
        c = channel_new("forwarded-tcpip",
            SSH_CHANNEL_CONNECTING, sock, sock, -1,
-           CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0,
+           CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0,
            originator_address, 1);
        else
                c = channel_new("forwarded-tcpip",
            originator_address, 1);
        else
                c = channel_new("forwarded-tcpip",
@@ -1796,7 +1816,7 @@ client_request_agent(const char *request_type, int rchan)
        if (options.hpn_disabled) 
        c = channel_new("authentication agent connection",
            SSH_CHANNEL_OPEN, sock, sock, -1,
        if (options.hpn_disabled) 
        c = channel_new("authentication agent connection",
            SSH_CHANNEL_OPEN, sock, sock, -1,
-           CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0,
+           CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0,
            "authentication agent connection", 1);
        else
                c = channel_new("authentication agent connection",
            "authentication agent connection", 1);
        else
                c = channel_new("authentication agent connection",
index 2cccf746dc623798f3a4b2a27d598689b35f95fc..bb82bc717b9859f65fcb91ddcabda2fe5a7eb89e 100644 (file)
@@ -90,6 +90,13 @@ AC_C_INLINE
 
 AC_CHECK_DECL(LLONG_MAX, have_llong_max=1, , [#include <limits.h>])
 
 
 AC_CHECK_DECL(LLONG_MAX, have_llong_max=1, , [#include <limits.h>])
 
+use_stack_protector=1
+AC_ARG_WITH(stackprotect,
+    [  --without-stackprotect  Don't use compiler's stack protection], [
+    if test "x$withval" = "xno"; then
+       use_stack_protector=0
+    fi ])
+
 if test "$GCC" = "yes" || test "$GCC" = "egcs"; then
        CFLAGS="$CFLAGS -Wall -Wpointer-arith -Wuninitialized"
        GCC_VER=`$CC -v 2>&1 | $AWK '/gcc version /{print $3}'`
 if test "$GCC" = "yes" || test "$GCC" = "egcs"; then
        CFLAGS="$CFLAGS -Wall -Wpointer-arith -Wuninitialized"
        GCC_VER=`$CC -v 2>&1 | $AWK '/gcc version /{print $3}'`
@@ -105,6 +112,44 @@ if test "$GCC" = "yes" || test "$GCC" = "egcs"; then
                *) ;;
        esac
 
                *) ;;
        esac
 
+       # -fstack-protector-all doesn't always work for some GCC versions
+       # and/or platforms, so we test if we can.  If it's not supported
+       # on a give platform gcc will emit a warning so we use -Werror.
+       if test "x$use_stack_protector" = "x1"; then
+           for t in -fstack-protector-all -fstack-protector; do
+               AC_MSG_CHECKING(if $CC supports $t)
+               saved_CFLAGS="$CFLAGS"
+               saved_LDFLAGS="$LDFLAGS"
+               CFLAGS="$CFLAGS $t -Werror"
+               LDFLAGS="$LDFLAGS $t -Werror"
+               AC_LINK_IFELSE(
+                       [AC_LANG_SOURCE([
+#include <stdlib.h>
+int main(void){return 0;}
+                        ])],
+                   [ AC_MSG_RESULT(yes)
+                     CFLAGS="$saved_CFLAGS $t"
+                     LDFLAGS="$saved_LDFLAGS $t"
+                     AC_MSG_CHECKING(if $t works)
+                     AC_RUN_IFELSE(
+                       [AC_LANG_SOURCE([
+#include <stdlib.h>
+int main(void){exit(0);}
+                       ])],
+                       [ AC_MSG_RESULT(yes)
+                         break ],
+                       [ AC_MSG_RESULT(no) ],
+                       [ AC_MSG_WARN([cross compiling: cannot test])
+                         break ]
+                     )
+                   ],
+                   [ AC_MSG_RESULT(no) ]
+               )
+               CFLAGS="$saved_CFLAGS"
+               LDFLAGS="$saved_LDFLAGS"
+           done
+       fi
+
        if test -z "$have_llong_max"; then
                # retry LLONG_MAX with -std=gnu99, needed on some Linuxes
                unset ac_cv_have_decl_LLONG_MAX
        if test -z "$have_llong_max"; then
                # retry LLONG_MAX with -std=gnu99, needed on some Linuxes
                unset ac_cv_have_decl_LLONG_MAX
@@ -223,6 +268,7 @@ AC_CHECK_HEADERS( \
        sys/dir.h \
        sys/mman.h \
        sys/ndir.h \
        sys/dir.h \
        sys/mman.h \
        sys/ndir.h \
+       sys/poll.h \
        sys/prctl.h \
        sys/pstat.h \
        sys/select.h \
        sys/prctl.h \
        sys/pstat.h \
        sys/select.h \
@@ -343,7 +389,7 @@ int main(void) { exit(0); }
                [],
                [#include <usersec.h>]
        )
                [],
                [#include <usersec.h>]
        )
-       AC_CHECK_FUNCS(setauthdb)
+       AC_CHECK_FUNCS(getgrset setauthdb)
        AC_CHECK_DECL(F_CLOSEM,
            AC_DEFINE(HAVE_FCNTL_CLOSEM, 1, [Use F_CLOSEM fcntl for closefrom]),
            [],
        AC_CHECK_DECL(F_CLOSEM,
            AC_DEFINE(HAVE_FCNTL_CLOSEM, 1, [Use F_CLOSEM fcntl for closefrom]),
            [],
@@ -397,6 +443,7 @@ int main(void) { exit(0); }
        AC_DEFINE(SETEUID_BREAKS_SETUID)
        AC_DEFINE(BROKEN_SETREUID)
        AC_DEFINE(BROKEN_SETREGID)
        AC_DEFINE(SETEUID_BREAKS_SETUID)
        AC_DEFINE(BROKEN_SETREUID)
        AC_DEFINE(BROKEN_SETREGID)
+       AC_DEFINE(BROKEN_GLOB, 1, [OS X glob does not do what we expect])
        AC_DEFINE_UNQUOTED(BIND_8_COMPAT, 1,
                [Define if your resolver libs need this for getrrsetbyname])
        AC_DEFINE(SSH_TUN_FREEBSD, 1, [Open tunnel devices the FreeBSD way])
        AC_DEFINE_UNQUOTED(BIND_8_COMPAT, 1,
                [Define if your resolver libs need this for getrrsetbyname])
        AC_DEFINE(SSH_TUN_FREEBSD, 1, [Open tunnel devices the FreeBSD way])
@@ -404,6 +451,11 @@ int main(void) { exit(0); }
            [Use tunnel device compatibility to OpenBSD])
        AC_DEFINE(SSH_TUN_PREPEND_AF, 1,
            [Prepend the address family to IP tunnel traffic])
            [Use tunnel device compatibility to OpenBSD])
        AC_DEFINE(SSH_TUN_PREPEND_AF, 1,
            [Prepend the address family to IP tunnel traffic])
+       m4_pattern_allow(AU_IPv)
+       AC_CHECK_DECL(AU_IPv4, [], 
+           AC_DEFINE(AU_IPv4, 0, [System only supports IPv4 audit records])
+           [#include <bsm/audit.h>]
+       )
        AC_MSG_CHECKING(if we have the Security Authorization Session API)
        AC_TRY_COMPILE([#include <Security/AuthSession.h>],
                [SessionCreate(0, 0);],
        AC_MSG_CHECKING(if we have the Security Authorization Session API)
        AC_TRY_COMPILE([#include <Security/AuthSession.h>],
                [SessionCreate(0, 0);],
@@ -428,7 +480,7 @@ int main(void) { exit(0); }
                fi],
                [AC_MSG_RESULT(no)]
        )
                fi],
                [AC_MSG_RESULT(no)]
        )
-       ;;
+       ;;
 *-*-dragonfly*)
        SSHDLIBS="$SSHDLIBS -lcrypt"
        ;;
 *-*-dragonfly*)
        SSHDLIBS="$SSHDLIBS -lcrypt"
        ;;
@@ -565,6 +617,7 @@ mips-sony-bsd|mips-sony-newsos4)
        AC_DEFINE(SSH_TUN_FREEBSD, 1, [Open tunnel devices the FreeBSD way])
        AC_CHECK_HEADER([net/if_tap.h], ,
            AC_DEFINE(SSH_TUN_NO_L2, 1, [No layer 2 tunnel support]))
        AC_DEFINE(SSH_TUN_FREEBSD, 1, [Open tunnel devices the FreeBSD way])
        AC_CHECK_HEADER([net/if_tap.h], ,
            AC_DEFINE(SSH_TUN_NO_L2, 1, [No layer 2 tunnel support]))
+       AC_DEFINE(BROKEN_GLOB, 1, [FreeBSD glob does not do what we need])
        ;;
 *-*-bsdi*)
        AC_DEFINE(SETEUID_BREAKS_SETUID)
        ;;
 *-*-bsdi*)
        AC_DEFINE(SETEUID_BREAKS_SETUID)
@@ -801,6 +854,7 @@ mips-sony-bsd|mips-sony-newsos4)
        AC_DEFINE(MISSING_FD_MASK, 1, [Define on *nto-qnx systems])
        AC_DEFINE(DISABLE_LASTLOG)
        AC_DEFINE(SSHD_ACQUIRES_CTTY)
        AC_DEFINE(MISSING_FD_MASK, 1, [Define on *nto-qnx systems])
        AC_DEFINE(DISABLE_LASTLOG)
        AC_DEFINE(SSHD_ACQUIRES_CTTY)
+       AC_DEFINE(BROKEN_SHADOW_EXPIRE, 1, [QNX shadow support is broken])
        enable_etc_default_login=no     # has incompatible /etc/default/login
        case "$host" in
        *-*-nto-qnx6*)
        enable_etc_default_login=no     # has incompatible /etc/default/login
        case "$host" in
        *-*-nto-qnx6*)
@@ -1378,7 +1432,7 @@ AC_ARG_WITH(audit,
                AC_CHECK_FUNCS(getaudit, [],
                    [AC_MSG_ERROR(BSM enabled and required function not found)])
                # These are optional
                AC_CHECK_FUNCS(getaudit, [],
                    [AC_MSG_ERROR(BSM enabled and required function not found)])
                # These are optional
-               AC_CHECK_FUNCS(getaudit_addr)
+               AC_CHECK_FUNCS(getaudit_addr aug_get_machine)
                AC_DEFINE(USE_BSM_AUDIT, 1, [Use BSM audit module])
                ;;
          debug)
                AC_DEFINE(USE_BSM_AUDIT, 1, [Use BSM audit module])
                ;;
          debug)
@@ -2170,7 +2224,10 @@ AC_CHECK_FUNCS(SHA256_Update EVP_sha256)
 saved_LIBS="$LIBS"
 AC_CHECK_LIB(iaf, ia_openinfo, [
        LIBS="$LIBS -liaf"
 saved_LIBS="$LIBS"
 AC_CHECK_LIB(iaf, ia_openinfo, [
        LIBS="$LIBS -liaf"
-       AC_CHECK_FUNCS(set_id, [SSHDLIBS="$SSHDLIBS -liaf"])
+       AC_CHECK_FUNCS(set_id, [SSHDLIBS="$SSHDLIBS -liaf"
+                               AC_DEFINE(HAVE_LIBIAF, 1,
+                       [Define if system has libiaf that supports set_id])
+                               ])
 ])
 LIBS="$saved_LIBS"
 
 ])
 LIBS="$saved_LIBS"
 
@@ -3367,7 +3424,7 @@ int main() { return 0; }
 SELINUX_MSG="no"
 LIBSELINUX=""
 AC_ARG_WITH(selinux,
 SELINUX_MSG="no"
 LIBSELINUX=""
 AC_ARG_WITH(selinux,
-       [  --with-selinux   Enable SELinux support],
+       [  --with-selinux          Enable SELinux support],
        [ if test "x$withval" != "xno" ; then
                save_LIBS="$LIBS"
                AC_DEFINE(WITH_SELINUX,1,[Define if you want SELinux support.])
        [ if test "x$withval" != "xno" ; then
                save_LIBS="$LIBS"
                AC_DEFINE(WITH_SELINUX,1,[Define if you want SELinux support.])
@@ -3594,32 +3651,6 @@ else
        AC_SUBST(XAUTH_PATH)
 fi
 
        AC_SUBST(XAUTH_PATH)
 fi
 
-AC_CHECK_DECL(_PATH_BSHELL, ,
- AC_DEFINE_UNQUOTED(_PATH_BSHELL, "/bin/sh",
- [Define to your C shell if not defined in paths.h]),
- [ #include <paths.h> ]
-)
-
-AC_CHECK_DECL(_PATH_CSHELL, ,
- AC_DEFINE_UNQUOTED(_PATH_CSHELL, "/bin/csh",
- [Define to your Bourne shell if not defined in paths.h]),
- [ #include <paths.h> ]
-)
-
-AC_CHECK_DECL(_PATH_SHELLS, ,
- AC_DEFINE_UNQUOTED(_PATH_SHELLS, "/etc/shells",
- [Define to your shells file if not defined in paths.h]),
- [ #include <paths.h> ]
-)
-
-# if _PATH_MAILDIR is in paths.h then we won't go hunting for it.
-AC_CHECK_DECL(_PATH_MAILDIR,
- AC_DEFINE(PATH_MAILDIR_IN_PATHS_H, 1,
- [Define if _PATH_MAILDIR is in paths.h]),
- ,
- [ #include <paths.h> ]
-)
-
 # Check for mail directory (last resort if we cannot get it from headers)
 if test ! -z "$MAIL" ; then
        maildir=`dirname $MAIL`
 # Check for mail directory (last resort if we cannot get it from headers)
 if test ! -z "$MAIL" ; then
        maildir=`dirname $MAIL`
index 0ce8daec9b144f653464216ccf6fadec26820ccc..901176dbb17c3c0fb4dc259d83210307e555f632 100644 (file)
@@ -111,6 +111,7 @@ passphrase_dialog(char *message)
 
        gtk_window_set_title(GTK_WINDOW(dialog), "OpenSSH");
        gtk_window_set_position (GTK_WINDOW(dialog), GTK_WIN_POS_CENTER);
 
        gtk_window_set_title(GTK_WINDOW(dialog), "OpenSSH");
        gtk_window_set_position (GTK_WINDOW(dialog), GTK_WIN_POS_CENTER);
+       gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE);
        gtk_label_set_line_wrap(GTK_LABEL((GTK_MESSAGE_DIALOG(dialog))->label),
                                TRUE);
 
        gtk_label_set_line_wrap(GTK_LABEL((GTK_MESSAGE_DIALOG(dialog))->label),
                                TRUE);
 
index 21ed8039a9f210674173d712fb3ac40c27c19a29..03b0d13d3e721a48dabe7db16821e9a47773bc4a 100644 (file)
@@ -544,6 +544,10 @@ struct winsize {
 # undef HAVE_UPDWTMPX
 #endif
 
 # undef HAVE_UPDWTMPX
 #endif
 
+#if defined(BROKEN_SHADOW_EXPIRE) && defined(HAS_SHADOW_EXPIRE)
+# undef HAS_SHADOW_EXPIRE
+#endif
+
 #if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) && \
     defined(SYSLOG_R_SAFE_IN_SIGHAND)
 # define DO_LOG_SAFE_IN_SIGHAND
 #if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) && \
     defined(SYSLOG_R_SAFE_IN_SIGHAND)
 # define DO_LOG_SAFE_IN_SIGHAND
@@ -567,11 +571,6 @@ struct winsize {
 # define CUSTOM_SSH_AUDIT_EVENTS
 #endif
 
 # define CUSTOM_SSH_AUDIT_EVENTS
 #endif
 
-/* OPENSSL_free() is Free() in versions before OpenSSL 0.9.6 */
-#if !defined(OPENSSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x0090600f)
-# define OPENSSL_free(x) Free(x)
-#endif
-
 #if !defined(HAVE___func__) && defined(HAVE___FUNCTION__)
 #  define __func__ __FUNCTION__
 #elif !defined(HAVE___func__)
 #if !defined(HAVE___func__) && defined(HAVE___FUNCTION__)
 #  define __func__ __FUNCTION__
 #elif !defined(HAVE___func__)
@@ -698,9 +697,11 @@ struct winsize {
 # define CUSTOM_SYS_AUTH_PASSWD 1
 #endif
 
 # define CUSTOM_SYS_AUTH_PASSWD 1
 #endif
 
+#if defined(HAVE_LIBIAF) && defined(HAVE_SET_ID)
+# define CUSTOM_SYS_AUTH_PASSWD 1
+#endif
 #if defined(HAVE_LIBIAF) && defined(HAVE_SET_ID) && !defined(BROKEN_LIBIAF)
 # define USE_LIBIAF
 #if defined(HAVE_LIBIAF) && defined(HAVE_SET_ID) && !defined(BROKEN_LIBIAF)
 # define USE_LIBIAF
-# define CUSTOM_SYS_AUTH_PASSWD 1
 #endif
 
 /* HP-UX 11.11 */
 #endif
 
 /* HP-UX 11.11 */
index 06b15d65c1617a74f33b32881ef587e91889031e..1fce541408a15eb8fc43dcc81d0d65bd36cf6882 100644 (file)
@@ -38,6 +38,7 @@
 #include <sys/types.h>
 
 #include <openssl/evp.h>
 #include <sys/types.h>
 
 #include <openssl/evp.h>
+#include <openbsd-compat/openssl-compat.h>
 
 #include <stdarg.h>
 #include <stdio.h>
 
 #include <stdarg.h>
 #include <stdio.h>
index 1cb71f8767c46c7dbb58c1530c368c197c5fefe7..3018bb144be7f1e5e85b3f86ea7aacadffbe31e0 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: misc.c,v 1.65 2006/11/23 01:35:11 ray Exp $ */
+/* $OpenBSD: misc.c,v 1.67 2008/01/01 08:47:04 dtucker Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  * Copyright (c) 2005,2006 Damien Miller.  All rights reserved.
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  * Copyright (c) 2005,2006 Damien Miller.  All rights reserved.
@@ -42,6 +42,7 @@
 
 #include <errno.h>
 #include <fcntl.h>
 
 #include <errno.h>
 #include <fcntl.h>
+#include <netdb.h>
 #ifdef HAVE_PATHS_H
 # include <paths.h>
 #include <pwd.h>
 #ifdef HAVE_PATHS_H
 # include <paths.h>
 #include <pwd.h>
@@ -120,6 +121,14 @@ unset_nonblock(int fd)
        return (0);
 }
 
        return (0);
 }
 
+const char *
+ssh_gai_strerror(int gaierr)
+{
+       if (gaierr == EAI_SYSTEM)
+               return strerror(errno);
+       return gai_strerror(gaierr);
+}
+
 /* disable nagle on socket */
 void
 set_nodelay(int fd)
 /* disable nagle on socket */
 void
 set_nodelay(int fd)
index 92eeeb6a543c36ad675e950dac615bd670e14d1c..823d8f840a76359f4316064cd5a6b890d1f11de5 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor.c,v 1.91 2007/05/17 20:52:13 djm Exp $ */
+/* $OpenBSD: monitor.c,v 1.94 2007/10/29 04:08:08 dtucker Exp $ */
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
  * Copyright 2002 Markus Friedl <markus@openbsd.org>
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
  * Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -680,11 +680,11 @@ mm_answer_pwnamallow(int sock, Buffer *m)
 #endif
        buffer_put_cstring(m, pwent->pw_dir);
        buffer_put_cstring(m, pwent->pw_shell);
 #endif
        buffer_put_cstring(m, pwent->pw_dir);
        buffer_put_cstring(m, pwent->pw_shell);
+
+ out:
        buffer_put_string(m, &options, sizeof(options));
        if (options.banner != NULL)
                buffer_put_cstring(m, options.banner);
        buffer_put_string(m, &options, sizeof(options));
        if (options.banner != NULL)
                buffer_put_cstring(m, options.banner);
-
- out:
        debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed);
        mm_request_send(sock, MONITOR_ANS_PWNAM, m);
 
        debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed);
        mm_request_send(sock, MONITOR_ANS_PWNAM, m);
 
@@ -1351,8 +1351,9 @@ mm_answer_pty(int sock, Buffer *m)
 
        mm_request_send(sock, MONITOR_ANS_PTY, m);
 
 
        mm_request_send(sock, MONITOR_ANS_PTY, m);
 
-       mm_send_fd(sock, s->ptyfd);
-       mm_send_fd(sock, s->ttyfd);
+       if (mm_send_fd(sock, s->ptyfd) == -1 ||
+           mm_send_fd(sock, s->ttyfd) == -1)
+               fatal("%s: send fds failed", __func__);
 
        /* make sure nothing uses fd 0 */
        if ((fd0 = open(_PATH_DEVNULL, O_RDONLY)) < 0)
 
        /* make sure nothing uses fd 0 */
        if ((fd0 = open(_PATH_DEVNULL, O_RDONLY)) < 0)
@@ -1583,6 +1584,11 @@ mm_answer_term(int sock, Buffer *req)
        /* The child is terminating */
        session_destroy_all(&mm_session_close);
 
        /* The child is terminating */
        session_destroy_all(&mm_session_close);
 
+#ifdef USE_PAM
+       if (options.use_pam)
+               sshpam_cleanup();
+#endif
+
        while (waitpid(pmonitor->m_pid, &status, 0) == -1)
                if (errno != EINTR)
                        exit(1);
        while (waitpid(pmonitor->m_pid, &status, 0) == -1)
                if (errno != EINTR)
                        exit(1);
@@ -2011,7 +2017,7 @@ mm_answer_gss_sign(int socket, Buffer *m)
        data.value = buffer_get_string(m, &len);
        data.length = len;
        if (data.length != 20) 
        data.value = buffer_get_string(m, &len);
        data.length = len;
        if (data.length != 20) 
-               fatal("%s: data length incorrect: %d", __func__, data.length);
+               fatal("%s: data length incorrect: %d", __func__, (int)data.length);
 
        /* Save the session ID on the first time around */
        if (session_id2_len == 0) {
 
        /* Save the session ID on the first time around */
        if (session_id2_len == 0) {
index 9f8e9cd550fe0764ee8bafdf23e0aca2e1cadcec..cab538bc900300262cebacde9a2122ab95ce3059 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor_fdpass.c,v 1.12 2006/08/03 03:34:42 deraadt Exp $ */
+/* $OpenBSD: monitor_fdpass.c,v 1.17 2008/03/24 16:11:07 deraadt Exp $ */
 /*
  * Copyright 2001 Niels Provos <provos@citi.umich.edu>
  * All rights reserved.
 /*
  * Copyright 2001 Niels Provos <provos@citi.umich.edu>
  * All rights reserved.
@@ -40,7 +40,7 @@
 #include "log.h"
 #include "monitor_fdpass.h"
 
 #include "log.h"
 #include "monitor_fdpass.h"
 
-void
+int
 mm_send_fd(int sock, int fd)
 {
 #if defined(HAVE_SENDMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR))
 mm_send_fd(int sock, int fd)
 {
 #if defined(HAVE_SENDMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR))
@@ -49,7 +49,11 @@ mm_send_fd(int sock, int fd)
        char ch = '\0';
        ssize_t n;
 #ifndef HAVE_ACCRIGHTS_IN_MSGHDR
        char ch = '\0';
        ssize_t n;
 #ifndef HAVE_ACCRIGHTS_IN_MSGHDR
-       char tmp[CMSG_SPACE(sizeof(int))];
+       union {
+               struct cmsghdr hdr;
+               char tmp[CMSG_SPACE(sizeof(int))];
+               char buf[CMSG_SPACE(sizeof(int))];
+       } cmsgbuf;
        struct cmsghdr *cmsg;
 #endif
 
        struct cmsghdr *cmsg;
 #endif
 
@@ -58,8 +62,8 @@ mm_send_fd(int sock, int fd)
        msg.msg_accrights = (caddr_t)&fd;
        msg.msg_accrightslen = sizeof(fd);
 #else
        msg.msg_accrights = (caddr_t)&fd;
        msg.msg_accrightslen = sizeof(fd);
 #else
-       msg.msg_control = (caddr_t)tmp;
-       msg.msg_controllen = CMSG_LEN(sizeof(int));
+       msg.msg_control = (caddr_t)&cmsgbuf.buf;
+       msg.msg_controllen = sizeof(cmsgbuf.buf);
        cmsg = CMSG_FIRSTHDR(&msg);
        cmsg->cmsg_len = CMSG_LEN(sizeof(int));
        cmsg->cmsg_level = SOL_SOCKET;
        cmsg = CMSG_FIRSTHDR(&msg);
        cmsg->cmsg_len = CMSG_LEN(sizeof(int));
        cmsg->cmsg_level = SOL_SOCKET;
@@ -72,15 +76,21 @@ mm_send_fd(int sock, int fd)
        msg.msg_iov = &vec;
        msg.msg_iovlen = 1;
 
        msg.msg_iov = &vec;
        msg.msg_iovlen = 1;
 
-       if ((n = sendmsg(sock, &msg, 0)) == -1)
-               fatal("%s: sendmsg(%d): %s", __func__, fd,
+       if ((n = sendmsg(sock, &msg, 0)) == -1) {
+               error("%s: sendmsg(%d): %s", __func__, fd,
                    strerror(errno));
                    strerror(errno));
-       if (n != 1)
-               fatal("%s: sendmsg: expected sent 1 got %ld",
+               return -1;
+       }
+
+       if (n != 1) {
+               error("%s: sendmsg: expected sent 1 got %ld",
                    __func__, (long)n);
                    __func__, (long)n);
+               return -1;
+       }
+       return 0;
 #else
 #else
-       fatal("%s: UsePrivilegeSeparation=yes not supported",
-           __func__);
+       error("%s: file descriptor passing not supported", __func__);
+       return -1;
 #endif
 }
 
 #endif
 }
 
@@ -94,7 +104,10 @@ mm_receive_fd(int sock)
        char ch;
        int fd;
 #ifndef HAVE_ACCRIGHTS_IN_MSGHDR
        char ch;
        int fd;
 #ifndef HAVE_ACCRIGHTS_IN_MSGHDR
-       char tmp[CMSG_SPACE(sizeof(int))];
+       union {
+               struct cmsghdr hdr;
+               char buf[CMSG_SPACE(sizeof(int))];
+       } cmsgbuf;
        struct cmsghdr *cmsg;
 #endif
 
        struct cmsghdr *cmsg;
 #endif
 
@@ -107,33 +120,43 @@ mm_receive_fd(int sock)
        msg.msg_accrights = (caddr_t)&fd;
        msg.msg_accrightslen = sizeof(fd);
 #else
        msg.msg_accrights = (caddr_t)&fd;
        msg.msg_accrightslen = sizeof(fd);
 #else
-       msg.msg_control = tmp;
-       msg.msg_controllen = sizeof(tmp);
+       msg.msg_control = &cmsgbuf.buf;
+       msg.msg_controllen = sizeof(cmsgbuf.buf);
 #endif
 
 #endif
 
-       if ((n = recvmsg(sock, &msg, 0)) == -1)
-               fatal("%s: recvmsg: %s", __func__, strerror(errno));
-       if (n != 1)
-               fatal("%s: recvmsg: expected received 1 got %ld",
+       if ((n = recvmsg(sock, &msg, 0)) == -1) {
+               error("%s: recvmsg: %s", __func__, strerror(errno));
+               return -1;
+       }
+       if (n != 1) {
+               error("%s: recvmsg: expected received 1 got %ld",
                    __func__, (long)n);
                    __func__, (long)n);
+               return -1;
+       }
 
 #ifdef HAVE_ACCRIGHTS_IN_MSGHDR
 
 #ifdef HAVE_ACCRIGHTS_IN_MSGHDR
-       if (msg.msg_accrightslen != sizeof(fd))
-               fatal("%s: no fd", __func__);
+       if (msg.msg_accrightslen != sizeof(fd)) {
+               error("%s: no fd", __func__);
+               return -1;
+       }
 #else
        cmsg = CMSG_FIRSTHDR(&msg);
 #else
        cmsg = CMSG_FIRSTHDR(&msg);
-       if (cmsg == NULL)
-               fatal("%s: no message header", __func__);
+       if (cmsg == NULL) {
+               error("%s: no message header", __func__);
+               return -1;
+       }
 #ifndef BROKEN_CMSG_TYPE
 #ifndef BROKEN_CMSG_TYPE
-       if (cmsg->cmsg_type != SCM_RIGHTS)
-               fatal("%s: expected type %d got %d", __func__,
+       if (cmsg->cmsg_type != SCM_RIGHTS) {
+               error("%s: expected type %d got %d", __func__,
                    SCM_RIGHTS, cmsg->cmsg_type);
                    SCM_RIGHTS, cmsg->cmsg_type);
+               return -1;
+       }
 #endif
        fd = (*(int *)CMSG_DATA(cmsg));
 #endif
        return fd;
 #else
 #endif
        fd = (*(int *)CMSG_DATA(cmsg));
 #endif
        return fd;
 #else
-       fatal("%s: UsePrivilegeSeparation=yes not supported",
-           __func__);
+       error("%s: file descriptor passing not supported", __func__);
+       return -1;
 #endif
 }
 #endif
 }
index 12c67ec2d1f22d349ba978a75fbf184591eb79e1..a4b1f6358969d41fc32a62362b72b2fc8fa48357 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor_fdpass.h,v 1.3 2006/03/25 22:22:43 djm Exp $ */
+/* $OpenBSD: monitor_fdpass.h,v 1.4 2007/09/04 03:21:03 djm Exp $ */
 
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
 
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
@@ -28,7 +28,7 @@
 #ifndef _MM_FDPASS_H_
 #define _MM_FDPASS_H_
 
 #ifndef _MM_FDPASS_H_
 #define _MM_FDPASS_H_
 
-void mm_send_fd(int, int);
+int mm_send_fd(int, int);
 int mm_receive_fd(int);
 
 #endif /* _MM_FDPASS_H_ */
 int mm_receive_fd(int);
 
 #endif /* _MM_FDPASS_H_ */
index 97715e4516a63c5d6b5b34c7cdebd0f1e882131a..c16f789a73348465c722ac8bba4f556f829f2fc9 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor_wrap.c,v 1.57 2007/06/07 19:37:34 pvalchev Exp $ */
+/* $OpenBSD: monitor_wrap.c,v 1.60 2007/10/29 04:08:08 dtucker Exp $ */
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
  * Copyright 2002 Markus Friedl <markus@openbsd.org>
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
  * Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -222,8 +222,8 @@ mm_getpwnamallow(const char *username)
        mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PWNAM, &m);
 
        if (buffer_get_char(&m) == 0) {
        mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PWNAM, &m);
 
        if (buffer_get_char(&m) == 0) {
-               buffer_free(&m);
-               return (NULL);
+               pw = NULL;
+               goto out;
        }
        pw = buffer_get_string(&m, &len);
        if (len != sizeof(struct passwd))
        }
        pw = buffer_get_string(&m, &len);
        if (len != sizeof(struct passwd))
@@ -237,6 +237,7 @@ mm_getpwnamallow(const char *username)
        pw->pw_dir = buffer_get_string(&m, NULL);
        pw->pw_shell = buffer_get_string(&m, NULL);
 
        pw->pw_dir = buffer_get_string(&m, NULL);
        pw->pw_shell = buffer_get_string(&m, NULL);
 
+out:
        /* copy options block as a Match directive may have changed some */
        newopts = buffer_get_string(&m, &len);
        if (len != sizeof(*newopts))
        /* copy options block as a Match directive may have changed some */
        newopts = buffer_get_string(&m, &len);
        if (len != sizeof(*newopts))
@@ -688,8 +689,9 @@ mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen)
        buffer_append(&loginmsg, msg, strlen(msg));
        xfree(msg);
 
        buffer_append(&loginmsg, msg, strlen(msg));
        xfree(msg);
 
-       *ptyfd = mm_receive_fd(pmonitor->m_recvfd);
-       *ttyfd = mm_receive_fd(pmonitor->m_recvfd);
+       if ((*ptyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1 ||
+           (*ttyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1)
+               fatal("%s: receive fds failed", __func__);
 
        /* Success */
        return (1);
 
        /* Success */
        return (1);
index 8431a42f802c6c1fcb9bff4d9c99d79458ef59d3..60212b4044f2d26c7abeab12ae2f342fb8137dad 100644 (file)
@@ -152,7 +152,7 @@ int getaddrinfo(const char *, const char *,
 #endif /* !HAVE_GETADDRINFO */
 
 #if !defined(HAVE_GAI_STRERROR) && !defined(HAVE_CONST_GAI_STRERROR_PROTO)
 #endif /* !HAVE_GETADDRINFO */
 
 #if !defined(HAVE_GAI_STRERROR) && !defined(HAVE_CONST_GAI_STRERROR_PROTO)
-#define gai_strerror(a)                (ssh_gai_strerror(a))
+#define gai_strerror(a)                (_ssh_compat_gai_strerror(a))
 char *gai_strerror(int);
 #endif /* !HAVE_GAI_STRERROR */
 
 char *gai_strerror(int);
 #endif /* !HAVE_GAI_STRERROR */
 
index 80af3f5425287724d3439fc12242a1e6fd613862..785b2256911ceb84d2cc77f38bd6a9e131f62ad8 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: getrrsetbyname.c,v 1.10 2005/03/30 02:58:28 tedu Exp $ */
+/* $OpenBSD: getrrsetbyname.c,v 1.11 2007/10/11 18:36:41 jakob Exp $ */
 
 /*
  * Copyright (c) 2001 Jakob Schlyter. All rights reserved.
 
 /*
  * Copyright (c) 2001 Jakob Schlyter. All rights reserved.
@@ -288,7 +288,7 @@ getrrsetbyname(const char *hostname, unsigned int rdclass,
        rrset->rri_nrdatas = count_dns_rr(response->answer, rrset->rri_rdclass,
            rrset->rri_rdtype);
        rrset->rri_nsigs = count_dns_rr(response->answer, rrset->rri_rdclass,
        rrset->rri_nrdatas = count_dns_rr(response->answer, rrset->rri_rdclass,
            rrset->rri_rdtype);
        rrset->rri_nsigs = count_dns_rr(response->answer, rrset->rri_rdclass,
-           T_SIG);
+           T_RRSIG);
 
        /* allocate memory for answers */
        rrset->rri_rdatas = calloc(rrset->rri_nrdatas,
 
        /* allocate memory for answers */
        rrset->rri_rdatas = calloc(rrset->rri_nrdatas,
@@ -318,7 +318,7 @@ getrrsetbyname(const char *hostname, unsigned int rdclass,
                        rdata = &rrset->rri_rdatas[index_ans++];
 
                if (rr->class == rrset->rri_rdclass &&
                        rdata = &rrset->rri_rdatas[index_ans++];
 
                if (rr->class == rrset->rri_rdclass &&
-                   rr->type  == T_SIG)
+                   rr->type  == T_RRSIG)
                        rdata = &rrset->rri_sigs[index_sig++];
 
                if (rdata) {
                        rdata = &rrset->rri_sigs[index_sig++];
 
                if (rdata) {
index 39995b63fc0333b9383565d6de4e3720ab04e802..1283f55062e0cc5ebdb323cb68c4b02d125d2be5 100644 (file)
@@ -62,8 +62,8 @@
 #define HFIXEDSZ 12
 #endif
 
 #define HFIXEDSZ 12
 #endif
 
-#ifndef T_SIG
-#define T_SIG 24
+#ifndef T_RRSIG
+#define T_RRSIG 46
 #endif
 
 /*
 #endif
 
 /*
index 0723e98deb456c0fa7547998528f50cddf84ecdf..fd578f2acbade6600dd69d33c8c23600aa70ede3 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *
  * Copyright (c) 2001 Gert Doering.  All rights reserved.
 /*
  *
  * Copyright (c) 2001 Gert Doering.  All rights reserved.
- * Copyright (c) 2003,2004,2005 Darren Tucker.  All rights reserved.
+ * Copyright (c) 2003,2004,2005,2006 Darren Tucker.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -395,4 +395,47 @@ sshaix_getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
 }
 # endif /* AIX_GETNAMEINFO_HACK */
 
 }
 # endif /* AIX_GETNAMEINFO_HACK */
 
+# if defined(USE_GETGRSET)
+#  include <stdlib.h>
+int
+getgrouplist(const char *user, gid_t pgid, gid_t *groups, int *grpcnt)
+{
+       char *cp, *grplist, *grp;
+       gid_t gid;
+       int ret = 0, ngroups = 0, maxgroups;
+       long l;
+
+       maxgroups = *grpcnt;
+
+       if ((cp = grplist = getgrset(user)) == NULL)
+               return -1;
+
+       /* handle zero-length case */
+       if (maxgroups <= 0) {
+               *grpcnt = 0;
+               return -1;
+       }
+
+       /* copy primary group */
+       groups[ngroups++] = pgid;
+
+       /* copy each entry from getgrset into group list */
+       while ((grp = strsep(&grplist, ",")) != NULL) {
+               l = strtol(grp, NULL, 10);
+               if (ngroups >= maxgroups || l == LONG_MIN || l == LONG_MAX) {
+                       ret = -1;
+                       goto out;
+               }
+               gid = (gid_t)l;
+               if (gid == pgid)
+                       continue;       /* we have already added primary gid */
+               groups[ngroups++] = gid;
+       }
+out:
+       free(cp);
+       *grpcnt = ngroups;
+       return ret;
+}
+# endif        /* USE_GETGRSET */
+
 #endif /* _AIX */
 #endif /* _AIX */
index eae82a9e0858549faec39a3021f16002e6fb1bb9..147ad0b35aefed289f29671b00f92ea85d10c6f5 100644 (file)
@@ -3,7 +3,7 @@
 /*
  *
  * Copyright (c) 2001 Gert Doering.  All rights reserved.
 /*
  *
  * Copyright (c) 2001 Gert Doering.  All rights reserved.
- * Copyright (c) 2004, 2005 Darren Tucker.  All rights reserved.
+ * Copyright (c) 2004,2005,2006 Darren Tucker.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -103,4 +103,14 @@ int sshaix_getnameinfo(const struct sockaddr *, size_t, char *, size_t,
 # define getnameinfo(a,b,c,d,e,f,g) (sshaix_getnameinfo(a,b,c,d,e,f,g))
 #endif
 
 # define getnameinfo(a,b,c,d,e,f,g) (sshaix_getnameinfo(a,b,c,d,e,f,g))
 #endif
 
+/*
+ * We use getgrset in preference to multiple getgrent calls for efficiency
+ * plus it supports NIS and LDAP groups.
+ */
+#if !defined(HAVE_GETGROUPLIST) && defined(HAVE_GETGRSET)
+# define HAVE_GETGROUPLIST
+# define USE_GETGRSET
+int getgrouplist(const char *, gid_t, gid_t *, int *);
+#endif
+
 #endif /* _AIX */
 #endif /* _AIX */
index 402343324f97877fe1114bb925d9d381e14dc896..5cf0587bd1c2e511a609c0f913df52b32307f4b2 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: queue.h,v 1.25 2004/04/08 16:08:21 henning Exp $      */
+/*     $OpenBSD: queue.h,v 1.32 2007/04/30 18:42:34 pedro Exp $        */
 /*     $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $       */
 
 /*
 /*     $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $       */
 
 /*
  * For details on the use of these macros, see the queue(3) manual page.
  */
 
  * For details on the use of these macros, see the queue(3) manual page.
  */
 
+#if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC))
+#define _Q_INVALIDATE(a) (a) = ((void *)-1)
+#else
+#define _Q_INVALIDATE(a)
+#endif
+
 /*
  * Singly-linked List definitions.
  */
 /*
  * Singly-linked List definitions.
  */
@@ -229,13 +235,14 @@ struct {                                                          \
 #define SLIST_REMOVE(head, elm, type, field) do {                      \
        if ((head)->slh_first == (elm)) {                               \
                SLIST_REMOVE_HEAD((head), field);                       \
 #define SLIST_REMOVE(head, elm, type, field) do {                      \
        if ((head)->slh_first == (elm)) {                               \
                SLIST_REMOVE_HEAD((head), field);                       \
-       }                                                               \
-       else {                                                          \
+       } else {                                                        \
                struct type *curelm = (head)->slh_first;                \
                struct type *curelm = (head)->slh_first;                \
-               while( curelm->field.sle_next != (elm) )                \
+                                                                       \
+               while (curelm->field.sle_next != (elm))                 \
                        curelm = curelm->field.sle_next;                \
                curelm->field.sle_next =                                \
                    curelm->field.sle_next->field.sle_next;             \
                        curelm = curelm->field.sle_next;                \
                curelm->field.sle_next =                                \
                    curelm->field.sle_next->field.sle_next;             \
+               _Q_INVALIDATE((elm)->field.sle_next);                   \
        }                                                               \
 } while (0)
 
        }                                                               \
 } while (0)
 
@@ -303,6 +310,8 @@ struct {                                                            \
                (elm)->field.le_next->field.le_prev =                   \
                    (elm)->field.le_prev;                               \
        *(elm)->field.le_prev = (elm)->field.le_next;                   \
                (elm)->field.le_next->field.le_prev =                   \
                    (elm)->field.le_prev;                               \
        *(elm)->field.le_prev = (elm)->field.le_next;                   \
+       _Q_INVALIDATE((elm)->field.le_prev);                            \
+       _Q_INVALIDATE((elm)->field.le_next);                            \
 } while (0)
 
 #define LIST_REPLACE(elm, elm2, field) do {                            \
 } while (0)
 
 #define LIST_REPLACE(elm, elm2, field) do {                            \
@@ -311,6 +320,8 @@ struct {                                                            \
                    &(elm2)->field.le_next;                             \
        (elm2)->field.le_prev = (elm)->field.le_prev;                   \
        *(elm2)->field.le_prev = (elm2);                                \
                    &(elm2)->field.le_next;                             \
        (elm2)->field.le_prev = (elm)->field.le_prev;                   \
        *(elm2)->field.le_prev = (elm2);                                \
+       _Q_INVALIDATE((elm)->field.le_prev);                            \
+       _Q_INVALIDATE((elm)->field.le_next);                            \
 } while (0)
 
 /*
 } while (0)
 
 /*
@@ -369,8 +380,8 @@ struct {                                                            \
        (listelm)->field.sqe_next = (elm);                              \
 } while (0)
 
        (listelm)->field.sqe_next = (elm);                              \
 } while (0)
 
-#define SIMPLEQ_REMOVE_HEAD(head, elm, field) do {                     \
-       if (((head)->sqh_first = (elm)->field.sqe_next) == NULL)        \
+#define SIMPLEQ_REMOVE_HEAD(head, field) do {                  \
+       if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
                (head)->sqh_last = &(head)->sqh_first;                  \
 } while (0)
 
                (head)->sqh_last = &(head)->sqh_first;                  \
 } while (0)
 
@@ -465,6 +476,8 @@ struct {                                                            \
        else                                                            \
                (head)->tqh_last = (elm)->field.tqe_prev;               \
        *(elm)->field.tqe_prev = (elm)->field.tqe_next;                 \
        else                                                            \
                (head)->tqh_last = (elm)->field.tqe_prev;               \
        *(elm)->field.tqe_prev = (elm)->field.tqe_next;                 \
+       _Q_INVALIDATE((elm)->field.tqe_prev);                           \
+       _Q_INVALIDATE((elm)->field.tqe_next);                           \
 } while (0)
 
 #define TAILQ_REPLACE(head, elm, elm2, field) do {                     \
 } while (0)
 
 #define TAILQ_REPLACE(head, elm, elm2, field) do {                     \
@@ -475,6 +488,8 @@ struct {                                                            \
                (head)->tqh_last = &(elm2)->field.tqe_next;             \
        (elm2)->field.tqe_prev = (elm)->field.tqe_prev;                 \
        *(elm2)->field.tqe_prev = (elm2);                               \
                (head)->tqh_last = &(elm2)->field.tqe_next;             \
        (elm2)->field.tqe_prev = (elm)->field.tqe_prev;                 \
        *(elm2)->field.tqe_prev = (elm2);                               \
+       _Q_INVALIDATE((elm)->field.tqe_prev);                           \
+       _Q_INVALIDATE((elm)->field.tqe_next);                           \
 } while (0)
 
 /*
 } while (0)
 
 /*
@@ -575,6 +590,8 @@ struct {                                                            \
        else                                                            \
                (elm)->field.cqe_prev->field.cqe_next =                 \
                    (elm)->field.cqe_next;                              \
        else                                                            \
                (elm)->field.cqe_prev->field.cqe_next =                 \
                    (elm)->field.cqe_next;                              \
+       _Q_INVALIDATE((elm)->field.cqe_prev);                           \
+       _Q_INVALIDATE((elm)->field.cqe_next);                           \
 } while (0)
 
 #define CIRCLEQ_REPLACE(head, elm, elm2, field) do {                   \
 } while (0)
 
 #define CIRCLEQ_REPLACE(head, elm, elm2, field) do {                   \
@@ -588,6 +605,8 @@ struct {                                                            \
                (head).cqh_first = (elm2);                              \
        else                                                            \
                (elm2)->field.cqe_prev->field.cqe_next = (elm2);        \
                (head).cqh_first = (elm2);                              \
        else                                                            \
                (elm2)->field.cqe_prev->field.cqe_next = (elm2);        \
+       _Q_INVALIDATE((elm)->field.cqe_prev);                           \
+       _Q_INVALIDATE((elm)->field.cqe_next);                           \
 } while (0)
 
 #endif /* !_FAKE_QUEUE_H_ */
 } while (0)
 
 #endif /* !_FAKE_QUEUE_H_ */
index c80b90b21e42112d808b8bfb3e6595320a274ba7..d4949b5e769ff714d099ad10e705b39176a5bdd3 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: tree.h,v 1.7 2002/10/17 21:51:54 art Exp $    */
+/*     $OpenBSD: tree.h,v 1.10 2007/10/29 23:49:41 djm Exp $   */
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
  * All rights reserved.
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
  * All rights reserved.
@@ -289,7 +289,7 @@ void name##_SPLAY_MINMAX(struct name *head, int __comp) \
             (x) != NULL;                                               \
             (x) = SPLAY_NEXT(name, head, x))
 
             (x) != NULL;                                               \
             (x) = SPLAY_NEXT(name, head, x))
 
-/* Macros that define a red-back tree */
+/* Macros that define a red-black tree */
 #define RB_HEAD(name, type)                                            \
 struct name {                                                          \
        struct type *rbh_root; /* root of the tree */                   \
 #define RB_HEAD(name, type)                                            \
 struct name {                                                          \
        struct type *rbh_root; /* root of the tree */                   \
@@ -381,9 +381,9 @@ void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\
 struct type *name##_RB_REMOVE(struct name *, struct type *);           \
 struct type *name##_RB_INSERT(struct name *, struct type *);           \
 struct type *name##_RB_FIND(struct name *, struct type *);             \
 struct type *name##_RB_REMOVE(struct name *, struct type *);           \
 struct type *name##_RB_INSERT(struct name *, struct type *);           \
 struct type *name##_RB_FIND(struct name *, struct type *);             \
-struct type *name##_RB_NEXT(struct name *, struct type *);             \
-struct type *name##_RB_MINMAX(struct name *, int);                     \
-                                                                       \
+struct type *name##_RB_NEXT(struct type *);                            \
+struct type *name##_RB_MINMAX(struct name *, int);                     
+
 
 /* Main rb operation.
  * Moves node close to the key of elm to top
 
 /* Main rb operation.
  * Moves node close to the key of elm to top
@@ -626,7 +626,7 @@ name##_RB_FIND(struct name *head, struct type *elm)                 \
 }                                                                      \
                                                                        \
 struct type *                                                          \
 }                                                                      \
                                                                        \
 struct type *                                                          \
-name##_RB_NEXT(struct name *head, struct type *elm)                    \
+name##_RB_NEXT(struct type *elm)                                       \
 {                                                                      \
        if (RB_RIGHT(elm, field)) {                                     \
                elm = RB_RIGHT(elm, field);                             \
 {                                                                      \
        if (RB_RIGHT(elm, field)) {                                     \
                elm = RB_RIGHT(elm, field);                             \
@@ -667,13 +667,13 @@ name##_RB_MINMAX(struct name *head, int val)                              \
 #define RB_INSERT(name, x, y)  name##_RB_INSERT(x, y)
 #define RB_REMOVE(name, x, y)  name##_RB_REMOVE(x, y)
 #define RB_FIND(name, x, y)    name##_RB_FIND(x, y)
 #define RB_INSERT(name, x, y)  name##_RB_INSERT(x, y)
 #define RB_REMOVE(name, x, y)  name##_RB_REMOVE(x, y)
 #define RB_FIND(name, x, y)    name##_RB_FIND(x, y)
-#define RB_NEXT(name, x, y)    name##_RB_NEXT(x, y)
+#define RB_NEXT(name, x, y)    name##_RB_NEXT(y)
 #define RB_MIN(name, x)                name##_RB_MINMAX(x, RB_NEGINF)
 #define RB_MAX(name, x)                name##_RB_MINMAX(x, RB_INF)
 
 #define RB_FOREACH(x, name, head)                                      \
        for ((x) = RB_MIN(name, head);                                  \
             (x) != NULL;                                               \
 #define RB_MIN(name, x)                name##_RB_MINMAX(x, RB_NEGINF)
 #define RB_MAX(name, x)                name##_RB_MINMAX(x, RB_INF)
 
 #define RB_FOREACH(x, name, head)                                      \
        for ((x) = RB_MIN(name, head);                                  \
             (x) != NULL;                                               \
-            (x) = name##_RB_NEXT(head, x))
+            (x) = name##_RB_NEXT(x))
 
 #endif /* _SYS_TREE_H_ */
 
 #endif /* _SYS_TREE_H_ */
index cab44bcd79420e1444128c1bf0de38aa7888a754..62ef30f9067f434e228d7235ab9b87c5466d5a35 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: packet.c,v 1.148 2007/06/07 19:37:34 pvalchev Exp $ */
+/* $OpenBSD: packet.c,v 1.151 2008/02/22 20:44:02 dtucker Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -136,6 +136,8 @@ static int server_side = 0;
 /* Set to true if we are authenticated. */
 static int after_authentication = 0;
 
 /* Set to true if we are authenticated. */
 static int after_authentication = 0;
 
+int keep_alive_timeouts = 0;
+
 /* Session key information for Encryption and MAC */
 Newkeys *newkeys[MODE_MAX];
 static struct packet_state {
 /* Session key information for Encryption and MAC */
 Newkeys *newkeys[MODE_MAX];
 static struct packet_state {
@@ -1197,10 +1199,12 @@ packet_read_poll_seqnr(u_int32_t *seqnr_p)
        for (;;) {
                if (compat20) {
                        type = packet_read_poll2(seqnr_p);
        for (;;) {
                if (compat20) {
                        type = packet_read_poll2(seqnr_p);
+                       keep_alive_timeouts = 0;
                        if (type)
                                DBG(debug("received packet type %d", type));
                        switch (type) {
                        case SSH2_MSG_IGNORE:
                        if (type)
                                DBG(debug("received packet type %d", type));
                        switch (type) {
                        case SSH2_MSG_IGNORE:
+                               debug3("Received SSH2_MSG_IGNORE");
                                break;
                        case SSH2_MSG_DEBUG:
                                packet_get_char();
                                break;
                        case SSH2_MSG_DEBUG:
                                packet_get_char();
index caf8c46f58083fc86f2bf3c4cd290cecfaeee191..f5dda7f39bf84753232bb526744ebfa6951313fd 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: packet.h,v 1.45 2006/03/25 22:22:43 djm Exp $ */
+/* $OpenBSD: packet.h,v 1.46 2008/02/22 20:44:02 dtucker Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -90,6 +90,7 @@ void   tty_make_modes(int, struct termios *);
 void    tty_parse_modes(int, int *);
 
 extern u_int max_packet_size;
 void    tty_parse_modes(int, int *);
 
 extern u_int max_packet_size;
+extern int keep_alive_timeouts;
 int     packet_set_maxsize(u_int);
 #define  packet_get_maxsize() max_packet_size
 
 int     packet_set_maxsize(u_int);
 #define  packet_get_maxsize() max_packet_size
 
index 6896dab129703f111dc359e8d032c6c3fb37d4ef..dce06dcc6a99cd218265218af56598b27b08f5cc 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.c,v 1.162 2007/03/20 03:56:12 tedu Exp $ */
+/* $OpenBSD: readconf.c,v 1.165 2008/01/19 23:09:49 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -340,6 +340,7 @@ process_config_line(Options *options, const char *host,
 {
        char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256];
        int opcode, *intptr, value, value2, scale;
 {
        char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256];
        int opcode, *intptr, value, value2, scale;
+       LogLevel *log_level_ptr;
        long long orig, val64;
        size_t len;
        Forward fwd;
        long long orig, val64;
        size_t len;
        Forward fwd;
@@ -551,7 +552,6 @@ parse_yesnoask:
                goto parse_int;
 
        case oRekeyLimit:
                goto parse_int;
 
        case oRekeyLimit:
-               intptr = &options->rekey_limit;
                arg = strdelim(&s);
                if (!arg || *arg == '\0')
                        fatal("%.200s line %d: Missing argument.", filename, linenum);
                arg = strdelim(&s);
                if (!arg || *arg == '\0')
                        fatal("%.200s line %d: Missing argument.", filename, linenum);
@@ -579,14 +579,14 @@ parse_yesnoask:
                }
                val64 *= scale;
                /* detect integer wrap and too-large limits */
                }
                val64 *= scale;
                /* detect integer wrap and too-large limits */
-               if ((val64 / scale) != orig || val64 > INT_MAX)
+               if ((val64 / scale) != orig || val64 > UINT_MAX)
                        fatal("%.200s line %d: RekeyLimit too large",
                            filename, linenum);
                if (val64 < 16)
                        fatal("%.200s line %d: RekeyLimit too small",
                            filename, linenum);
                        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 = (int)val64;
+               if (*activep && options->rekey_limit == -1)
+                       options->rekey_limit = (u_int32_t)val64;
                break;
 
        case oIdentityFile:
                break;
 
        case oIdentityFile:
@@ -749,14 +749,14 @@ parse_int:
                break;
 
        case oLogLevel:
                break;
 
        case oLogLevel:
-               intptr = (int *) &options->log_level;
+               log_level_ptr = &options->log_level;
                arg = strdelim(&s);
                value = log_level_number(arg);
                if (value == SYSLOG_LEVEL_NOT_SET)
                        fatal("%.200s line %d: unsupported log level '%s'",
                            filename, linenum, arg ? arg : "<NONE>");
                arg = strdelim(&s);
                value = log_level_number(arg);
                if (value == SYSLOG_LEVEL_NOT_SET)
                        fatal("%.200s line %d: unsupported log level '%s'",
                            filename, linenum, arg ? arg : "<NONE>");
-               if (*activep && (LogLevel) *intptr == SYSLOG_LEVEL_NOT_SET)
-                       *intptr = (LogLevel) value;
+               if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
+                       *log_level_ptr = (LogLevel) value;
                break;
 
        case oLocalForward:
                break;
 
        case oLocalForward:
@@ -1347,7 +1347,7 @@ parse_forward(Forward *fwd, const char *fwdspec)
 
        xfree(p);
 
 
        xfree(p);
 
-       if (fwd->listen_port == 0 && fwd->connect_port == 0)
+       if (fwd->listen_port == 0 || fwd->connect_port == 0)
                goto fail_free;
 
        if (fwd->connect_host != NULL &&
                goto fail_free;
 
        if (fwd->connect_host != NULL &&
index 98622732bddc871f65bd8ba0571a569c527db92d..6f757ca5bcc087b9de5788651c56eb83c5454f47 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.h,v 1.71 2006/08/03 03:34:42 deraadt Exp $ */
+/* $OpenBSD: readconf.h,v 1.72 2008/01/19 23:09:49 djm Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -109,7 +109,7 @@ typedef struct {
        int     clear_forwardings;
 
        int     enable_ssh_keysign;
        int     clear_forwardings;
 
        int     enable_ssh_keysign;
-       int     rekey_limit;
+       int64_t rekey_limit;
        int     none_switch;    /* Use none cipher */
        int     none_enabled;   /* Allow none to be used */
        int     no_host_authentication_for_localhost;
        int     none_switch;    /* Use none cipher */
        int     none_enabled;   /* Allow none to be used */
        int     no_host_authentication_for_localhost;
index 1c17f22c854e4a135d8fb6e1ebc7dabc3821c527..ffd381d3724b7f37cee36cfd0ef5aab46422a7b1 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: scp.c,v 1.160 2007/08/06 19:16:06 sobrado Exp $ */
+/* $OpenBSD: scp.c,v 1.162 2008/01/01 09:06:39 dtucker Exp $ */
 /*
  * scp - secure remote copy.  This is basically patched BSD rcp which
  * uses ssh to do the data transfer (instead of using rcmd).
 /*
  * scp - secure remote copy.  This is basically patched BSD rcp which
  * uses ssh to do the data transfer (instead of using rcmd).
 #ifdef HAVE_SYS_STAT_H
 # include <sys/stat.h>
 #endif
 #ifdef HAVE_SYS_STAT_H
 # include <sys/stat.h>
 #endif
+#ifdef HAVE_POLL_H
+#include <poll.h>
+#else
+# ifdef HAVE_SYS_POLL_H
+#  include <sys/poll.h>
+# endif
+#endif
 #ifdef HAVE_SYS_TIME_H
 # include <sys/time.h>
 #endif
 #ifdef HAVE_SYS_TIME_H
 # include <sys/time.h>
 #endif
 
 extern char *__progname;
 
 
 extern char *__progname;
 
+#define COPY_BUFLEN    16384
+
 int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout);
 
 void bwlimit(int);
 int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout);
 
 void bwlimit(int);
@@ -282,6 +291,7 @@ void sink(int, char *[]);
 void source(int, char *[]);
 void tolocal(int, char *[]);
 void toremote(char *, int, char *[]);
 void source(int, char *[]);
 void tolocal(int, char *[]);
 void toremote(char *, int, char *[]);
+size_t scpio(ssize_t (*)(int, void *, size_t), int, void *, size_t, off_t *);
 void usage(void);
 
 int
 void usage(void);
 
 int
@@ -441,6 +451,43 @@ main(int argc, char **argv)
        exit(errs != 0);
 }
 
        exit(errs != 0);
 }
 
+/*
+ * atomicio-like wrapper that also applies bandwidth limits and updates
+ * the progressmeter counter.
+ */
+size_t
+scpio(ssize_t (*f)(int, void *, size_t), int fd, void *_p, size_t l, off_t *c)
+{
+       u_char *p = (u_char *)_p;
+       size_t offset;
+       ssize_t r;
+       struct pollfd pfd;
+
+       pfd.fd = fd;
+       pfd.events = f == read ? POLLIN : POLLOUT;
+       for (offset = 0; offset < l;) {
+               r = f(fd, p + offset, l - offset);
+               if (r == 0) {
+                       errno = EPIPE;
+                       return offset;
+               }
+               if (r < 0) {
+                       if (errno == EINTR)
+                               continue;
+                       if (errno == EAGAIN) {
+                               (void)poll(&pfd, 1, -1); /* Ignore errors */
+                               continue;
+                       }
+                       return offset;
+               }
+               offset += (size_t)r;
+               *c += (off_t)r;
+               if (limit_rate)
+                       bwlimit(r);
+       }
+       return offset;
+}
+
 void
 toremote(char *targ, int argc, char **argv)
 {
 void
 toremote(char *targ, int argc, char **argv)
 {
@@ -583,7 +630,6 @@ source(int argc, char **argv)
        static BUF buffer;
        BUF *bp;
        off_t i, amt, statbytes;
        static BUF buffer;
        BUF *bp;
        off_t i, amt, statbytes;
-       size_t result;
        int fd = -1, haderr, indx;
        char *last, *name, buf[16384], encname[MAXPATHLEN];
        int len;
        int fd = -1, haderr, indx;
        char *last, *name, buf[16384], encname[MAXPATHLEN];
        int len;
@@ -629,8 +675,14 @@ syserr:                    run_err("%s: %s", name, strerror(errno));
                         * versions expecting microseconds.
                         */
                        (void) snprintf(buf, sizeof buf, "T%lu 0 %lu 0\n",
                         * versions expecting microseconds.
                         */
                        (void) snprintf(buf, sizeof buf, "T%lu 0 %lu 0\n",
-                           (u_long) stb.st_mtime,
-                           (u_long) stb.st_atime);
+                           (u_long) (stb.st_mtime < 0 ? 0 : stb.st_mtime),
+                           (u_long) (stb.st_atime < 0 ? 0 : stb.st_atime));
+                       if (verbose_mode) {
+                               fprintf(stderr, "File mtime %ld atime %ld\n",
+                                   (long)stb.st_mtime, (long)stb.st_atime);
+                               fprintf(stderr, "Sending file timestamps: %s",
+                                   buf);
+                       }
                        (void) atomicio(vwrite, remout, buf, strlen(buf));
                        if (response() < 0)
                                goto next;
                        (void) atomicio(vwrite, remout, buf, strlen(buf));
                        if (response() < 0)
                                goto next;
@@ -645,7 +697,7 @@ syserr:                     run_err("%s: %s", name, strerror(errno));
                (void) atomicio(vwrite, remout, buf, strlen(buf));
                if (response() < 0)
                        goto next;
                (void) atomicio(vwrite, remout, buf, strlen(buf));
                if (response() < 0)
                        goto next;
-               if ((bp = allocbuf(&buffer, fd, sizeof(buf))) == NULL) {
+               if ((bp = allocbuf(&buffer, fd, COPY_BUFLEN)) == NULL) {
 next:                  if (fd != -1) {
                                (void) close(fd);
                                fd = -1;
 next:                  if (fd != -1) {
                                (void) close(fd);
                                fd = -1;
@@ -654,27 +706,25 @@ next:                     if (fd != -1) {
                }
                if (showprogress)
                        start_progress_meter(curfile, stb.st_size, &statbytes);
                }
                if (showprogress)
                        start_progress_meter(curfile, stb.st_size, &statbytes);
-               /* Keep writing after an error so that we stay sync'd up. */
+               set_nonblock(remout);
                for (haderr = i = 0; i < stb.st_size; i += bp->cnt) {
                        amt = bp->cnt;
                        if (i + amt > stb.st_size)
                                amt = stb.st_size - i;
                        if (!haderr) {
                for (haderr = i = 0; i < stb.st_size; i += bp->cnt) {
                        amt = bp->cnt;
                        if (i + amt > stb.st_size)
                                amt = stb.st_size - i;
                        if (!haderr) {
-                               result = atomicio(read, fd, bp->buf, amt);
-                               if (result != amt)
+                               if (atomicio(read, fd, bp->buf, amt) != amt)
                                        haderr = errno;
                        }
                                        haderr = errno;
                        }
-                       if (haderr)
-                               (void) atomicio(vwrite, remout, bp->buf, amt);
-                       else {
-                               result = atomicio(vwrite, remout, bp->buf, amt);
-                               if (result != amt)
-                                       haderr = errno;
-                               statbytes += result;
+                       /* Keep writing after error to retain sync */
+                       if (haderr) {
+                               (void)atomicio(vwrite, remout, bp->buf, amt);
+                               continue;
                        }
                        }
-                       if (limit_rate)
-                               bwlimit(amt);
+                       if (scpio(vwrite, remout, bp->buf, amt,
+                           &statbytes) != amt)
+                               haderr = errno;
                }
                }
+               unset_nonblock(remout);
                if (showprogress)
                        stop_progress_meter();
 
                if (showprogress)
                        stop_progress_meter();
 
@@ -780,10 +830,10 @@ bwlimit(int amount)
                        thresh /= 2;
                        if (thresh < 2048)
                                thresh = 2048;
                        thresh /= 2;
                        if (thresh < 2048)
                                thresh = 2048;
-               } else if (bwend.tv_usec < 100) {
+               } else if (bwend.tv_usec < 10000) {
                        thresh *= 2;
                        thresh *= 2;
-                       if (thresh > 32768)
-                               thresh = 32768;
+                       if (thresh > COPY_BUFLEN * 4)
+                               thresh = COPY_BUFLEN * 4;
                }
 
                TIMEVAL_TO_TIMESPEC(&bwend, &ts);
                }
 
                TIMEVAL_TO_TIMESPEC(&bwend, &ts);
@@ -974,7 +1024,7 @@ bad:                       run_err("%s: %s", np, strerror(errno));
                        continue;
                }
                (void) atomicio(vwrite, remout, "", 1);
                        continue;
                }
                (void) atomicio(vwrite, remout, "", 1);
-               if ((bp = allocbuf(&buffer, ofd, sizeof(buf))) == NULL) {
+               if ((bp = allocbuf(&buffer, ofd, COPY_BUFLEN)) == NULL) {
                        (void) close(ofd);
                        continue;
                }
                        (void) close(ofd);
                        continue;
                }
@@ -984,26 +1034,24 @@ bad:                     run_err("%s: %s", np, strerror(errno));
                statbytes = 0;
                if (showprogress)
                        start_progress_meter(curfile, size, &statbytes);
                statbytes = 0;
                if (showprogress)
                        start_progress_meter(curfile, size, &statbytes);
-               for (count = i = 0; i < size; i += sizeof(buf)) {
-                       amt = sizeof(buf);
+               set_nonblock(remin);
+               for (count = i = 0; i < size; i += bp->cnt) {
+                       amt = bp->cnt;
                        if (i + amt > size)
                                amt = size - i;
                        count += amt;
                        do {
                        if (i + amt > size)
                                amt = size - i;
                        count += amt;
                        do {
-                               j = atomicio(read, remin, cp, amt);
+                               j = scpio(read, remin, cp, amt, &statbytes);
                                if (j == 0) {
                                if (j == 0) {
-                                       run_err("%s", j ? strerror(errno) :
+                                       run_err("%s", j != EPIPE ?
+                                           strerror(errno) :
                                            "dropped connection");
                                        exit(1);
                                }
                                amt -= j;
                                cp += j;
                                            "dropped connection");
                                        exit(1);
                                }
                                amt -= j;
                                cp += j;
-                               statbytes += j;
                        } while (amt > 0);
 
                        } while (amt > 0);
 
-                       if (limit_rate)
-                               bwlimit(sizeof(buf));
-
                        if (count == bp->cnt) {
                                /* Keep reading so we stay sync'd up. */
                                if (wrerr == NO) {
                        if (count == bp->cnt) {
                                /* Keep reading so we stay sync'd up. */
                                if (wrerr == NO) {
@@ -1017,6 +1065,7 @@ bad:                      run_err("%s: %s", np, strerror(errno));
                                cp = bp->buf;
                        }
                }
                                cp = bp->buf;
                        }
                }
+               unset_nonblock(remin);
                if (showprogress)
                        stop_progress_meter();
                if (count != 0 && wrerr == NO &&
                if (showprogress)
                        stop_progress_meter();
                if (count != 0 && wrerr == NO &&
index 34faed963ad931089ddc55d2371e77ed09ed5eda..54ab140faf61fee789b9411432e7c42a1c1015a6 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: servconf.c,v 1.172 2007/04/23 10:15:39 dtucker Exp $ */
+/* $OpenBSD: servconf.c,v 1.177 2008/02/10 10:54:28 djm Exp $ */
 /*
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  *                    All rights reserved
 /*
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  *                    All rights reserved
@@ -130,6 +130,7 @@ initialize_server_options(ServerOptions *options)
        options->permit_tun = -1;
        options->num_permitted_opens = -1;
        options->adm_forced_command = NULL;
        options->permit_tun = -1;
        options->num_permitted_opens = -1;
        options->adm_forced_command = NULL;
+       options->chroot_directory = NULL;
         options->none_enabled = -1;
         options->tcp_rcv_buf_poll = -1;
         options->hpn_disabled = -1;
         options->none_enabled = -1;
         options->tcp_rcv_buf_poll = -1;
         options->hpn_disabled = -1;
@@ -351,12 +352,13 @@ typedef enum {
        sBanner, sUseDNS, sHostbasedAuthentication,
        sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
        sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
        sBanner, sUseDNS, sHostbasedAuthentication,
        sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
        sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
-       sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
+       sGssAuthentication, sGssCleanupCreds,
+    sGssStrictAcceptor,
        sGssKeyEx, 
     sGssCredsPath,
        sGsiAllowLimitedProxy,
     sAcceptEnv, sPermitTunnel,
        sGssKeyEx, 
     sGssCredsPath,
        sGsiAllowLimitedProxy,
     sAcceptEnv, sPermitTunnel,
-       sMatch, sPermitOpen, sForceCommand,
+       sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
        sUsePrivilegeSeparation, sNoneEnabled, sTcpRcvBufPoll, 
         sHPNDisabled, sHPNBufferSize,
        sDeprecated, sUnsupported
        sUsePrivilegeSeparation, sNoneEnabled, sTcpRcvBufPoll, 
         sHPNDisabled, sHPNBufferSize,
        sDeprecated, sUnsupported
@@ -387,7 +389,7 @@ static struct {
        { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
        { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
        { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
        { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
        { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
        { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
-       { "permitrootlogin", sPermitRootLogin, SSHCFG_GLOBAL },
+       { "permitrootlogin", sPermitRootLogin, SSHCFG_ALL },
        { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
        { "loglevel", sLogLevel, SSHCFG_GLOBAL },
        { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
        { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
        { "loglevel", sLogLevel, SSHCFG_GLOBAL },
        { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
@@ -486,6 +488,7 @@ static struct {
        { "match", sMatch, SSHCFG_ALL },
        { "permitopen", sPermitOpen, SSHCFG_ALL },
        { "forcecommand", sForceCommand, SSHCFG_ALL },
        { "match", sMatch, SSHCFG_ALL },
        { "permitopen", sPermitOpen, SSHCFG_ALL },
        { "forcecommand", sForceCommand, SSHCFG_ALL },
+       { "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
         { "noneenabled", sNoneEnabled },
         { "hpndisabled", sHPNDisabled },
         { "hpnbuffersize", sHPNBufferSize },
         { "noneenabled", sNoneEnabled },
         { "hpndisabled", sHPNDisabled },
         { "hpnbuffersize", sHPNBufferSize },
@@ -546,7 +549,7 @@ add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
        if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
                fatal("bad addr or host: %s (%s)",
                    addr ? addr : "<NULL>",
        if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
                fatal("bad addr or host: %s (%s)",
                    addr ? addr : "<NULL>",
-                   gai_strerror(gaierr));
+                   ssh_gai_strerror(gaierr));
        for (ai = aitop; ai->ai_next; ai = ai->ai_next)
                ;
        ai->ai_next = options->listen_addrs;
        for (ai = aitop; ai->ai_next; ai = ai->ai_next)
                ;
        ai->ai_next = options->listen_addrs;
@@ -709,6 +712,8 @@ process_server_config_line(ServerOptions *options, char *line,
 {
        char *cp, **charptr, *arg, *p;
        int cmdline = 0, *intptr, value, n;
 {
        char *cp, **charptr, *arg, *p;
        int cmdline = 0, *intptr, value, n;
+       SyslogFacility *log_facility_ptr;
+       LogLevel *log_level_ptr;
        ServerOpCodes opcode;
        u_short port;
        u_int i, flags = 0;
        ServerOpCodes opcode;
        u_short port;
        u_int i, flags = 0;
@@ -892,7 +897,7 @@ parse_filename:
                        fatal("%s line %d: Bad yes/"
                            "without-password/forced-commands-only/no "
                            "argument: %s", filename, linenum, arg);
                        fatal("%s line %d: Bad yes/"
                            "without-password/forced-commands-only/no "
                            "argument: %s", filename, linenum, arg);
-               if (*intptr == -1)
+               if (*activep && *intptr == -1)
                        *intptr = value;
                break;
 
                        *intptr = value;
                break;
 
@@ -1113,25 +1118,25 @@ parse_flag:
                goto parse_flag;
 
        case sLogFacility:
                goto parse_flag;
 
        case sLogFacility:
-               intptr = (int *) &options->log_facility;
+               log_facility_ptr = &options->log_facility;
                arg = strdelim(&cp);
                value = log_facility_number(arg);
                if (value == SYSLOG_FACILITY_NOT_SET)
                        fatal("%.200s line %d: unsupported log facility '%s'",
                            filename, linenum, arg ? arg : "<NONE>");
                arg = strdelim(&cp);
                value = log_facility_number(arg);
                if (value == SYSLOG_FACILITY_NOT_SET)
                        fatal("%.200s line %d: unsupported log facility '%s'",
                            filename, linenum, arg ? arg : "<NONE>");
-               if (*intptr == -1)
-                       *intptr = (SyslogFacility) value;
+               if (*log_facility_ptr == -1)
+                       *log_facility_ptr = (SyslogFacility) value;
                break;
 
        case sLogLevel:
                break;
 
        case sLogLevel:
-               intptr = (int *) &options->log_level;
+               log_level_ptr = &options->log_level;
                arg = strdelim(&cp);
                value = log_level_number(arg);
                if (value == SYSLOG_LEVEL_NOT_SET)
                        fatal("%.200s line %d: unsupported log level '%s'",
                            filename, linenum, arg ? arg : "<NONE>");
                arg = strdelim(&cp);
                value = log_level_number(arg);
                if (value == SYSLOG_LEVEL_NOT_SET)
                        fatal("%.200s line %d: unsupported log level '%s'",
                            filename, linenum, arg ? arg : "<NONE>");
-               if (*intptr == -1)
-                       *intptr = (LogLevel) value;
+               if (*log_level_ptr == -1)
+                       *log_level_ptr = (LogLevel) value;
                break;
 
        case sAllowTcpForwarding:
                break;
 
        case sAllowTcpForwarding:
@@ -1282,6 +1287,7 @@ parse_flag:
        case sBanner:
                charptr = &options->banner;
                goto parse_filename;
        case sBanner:
                charptr = &options->banner;
                goto parse_filename;
+
        /*
         * These options can contain %X options expanded at
         * connect time, so that you can specify paths like:
        /*
         * These options can contain %X options expanded at
         * connect time, so that you can specify paths like:
@@ -1390,6 +1396,17 @@ parse_flag:
                        options->adm_forced_command = xstrdup(cp + len);
                return 0;
 
                        options->adm_forced_command = xstrdup(cp + len);
                return 0;
 
+       case sChrootDirectory:
+               charptr = &options->chroot_directory;
+
+               arg = strdelim(&cp);
+               if (!arg || *arg == '\0')
+                       fatal("%s line %d: missing file name.",
+                           filename, linenum);
+               if (*activep && *charptr == NULL)
+                       *charptr = xstrdup(arg);
+               break;
+
        case sDeprecated:
                logit("%s line %d: Deprecated option %s",
                    filename, linenum, arg);
        case sDeprecated:
                logit("%s line %d: Deprecated option %s",
                    filename, linenum, arg);
@@ -1486,6 +1503,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
        M_CP_INTOPT(kerberos_authentication);
        M_CP_INTOPT(hostbased_authentication);
        M_CP_INTOPT(kbd_interactive_authentication);
        M_CP_INTOPT(kerberos_authentication);
        M_CP_INTOPT(hostbased_authentication);
        M_CP_INTOPT(kbd_interactive_authentication);
+       M_CP_INTOPT(permit_root_login);
 
        M_CP_INTOPT(allow_tcp_forwarding);
        M_CP_INTOPT(gateway_ports);
 
        M_CP_INTOPT(allow_tcp_forwarding);
        M_CP_INTOPT(gateway_ports);
@@ -1497,6 +1515,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
        if (preauth)
                return;
        M_CP_STROPT(adm_forced_command);
        if (preauth)
                return;
        M_CP_STROPT(adm_forced_command);
+       M_CP_STROPT(chroot_directory);
 }
 
 #undef M_CP_INTOPT
 }
 
 #undef M_CP_INTOPT
index 72ea2364dea6f8125596289fbc04001670d6f826..26dfd2e0c9028958e71317540233afcb80319d83 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: servconf.h,v 1.80 2007/02/19 10:45:58 dtucker Exp $ */
+/* $OpenBSD: servconf.h,v 1.82 2008/02/13 22:38:17 djm Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -36,6 +36,9 @@
 
 #define DEFAULT_AUTH_FAIL_MAX  6       /* Default for MaxAuthTries */
 
 
 #define DEFAULT_AUTH_FAIL_MAX  6       /* Default for MaxAuthTries */
 
+/* Magic name for internal sftp-server */
+#define INTERNAL_SFTP_NAME     "internal-sftp"
+
 typedef struct {
        u_int num_ports;
        u_int ports_from_cmdline;
 typedef struct {
        u_int num_ports;
        u_int ports_from_cmdline;
@@ -154,6 +157,8 @@ typedef struct {
        int     permit_tun;
 
        int     num_permitted_opens;
        int     permit_tun;
 
        int     num_permitted_opens;
+
+       char   *chroot_directory;
 }       ServerOptions;
 
 void    initialize_server_options(ServerOptions *);
 }       ServerOptions;
 
 void    initialize_server_options(ServerOptions *);
index e66e0a98d47f183ae9a65624b9cda0a169b77959..1331dd8e96088b03340191263e79ab05971e4d95 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: serverloop.c,v 1.145 2006/10/11 12:38:03 markus Exp $ */
+/* $OpenBSD: serverloop.c,v 1.148 2008/02/22 20:44:02 dtucker Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -104,7 +104,6 @@ static int connection_in;   /* Connection to client (input). */
 static int connection_out;     /* Connection to client (output). */
 static int connection_closed = 0;      /* Connection to client closed. */
 static u_int buffer_high;      /* "Soft" max buffer size. */
 static int connection_out;     /* Connection to client (output). */
 static int connection_closed = 0;      /* Connection to client closed. */
 static u_int buffer_high;      /* "Soft" max buffer size. */
-static int client_alive_timeouts = 0;
 
 /*
  * This SIGCHLD kludge is used to detect when the child exits.  The server
 
 /*
  * This SIGCHLD kludge is used to detect when the child exits.  The server
@@ -262,7 +261,7 @@ client_alive_check(void)
        int channel_id;
 
        /* timeout, check to see how many we have had */
        int channel_id;
 
        /* timeout, check to see how many we have had */
-       if (++client_alive_timeouts > options.client_alive_count_max) {
+       if (++keep_alive_timeouts > options.client_alive_count_max) {
                logit("Timeout, client not responding.");
                cleanup_exit(255);
        }
                logit("Timeout, client not responding.");
                cleanup_exit(255);
        }
@@ -910,7 +909,7 @@ server_input_keep_alive(int type, u_int32_t seq, void *ctxt)
         * even if this was generated by something other than
         * the bogus CHANNEL_REQUEST we send for keepalives.
         */
         * even if this was generated by something other than
         * the bogus CHANNEL_REQUEST we send for keepalives.
         */
-       client_alive_timeouts = 0;
+       keep_alive_timeouts = 0;
 }
 
 static void
 }
 
 static void
index 36b67180c3a3b2627158f4a37a82f06c70d80a57..ef308cdecbd258ec20d647d40234be6e47e7a92d 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: session.c,v 1.221 2007/01/21 01:41:54 stevesk Exp $ */
+/* $OpenBSD: session.c,v 1.233 2008/03/26 21:28:14 djm Exp $ */
 /*
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  *                    All rights reserved
 /*
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  *                    All rights reserved
 #include "sshlogin.h"
 #include "serverloop.h"
 #include "canohost.h"
 #include "sshlogin.h"
 #include "serverloop.h"
 #include "canohost.h"
+#include "misc.h"
 #include "session.h"
 #include "kex.h"
 #include "monitor_wrap.h"
 #include "session.h"
 #include "kex.h"
 #include "monitor_wrap.h"
+#include "sftp.h"
 
 #if defined(KRB5) && defined(USE_AFS)
 #include <kafs.h>
 
 #if defined(KRB5) && defined(USE_AFS)
 #include <kafs.h>
@@ -134,9 +136,13 @@ extern Buffer loginmsg;
 const char *original_command = NULL;
 
 /* data */
 const char *original_command = NULL;
 
 /* data */
-#define MAX_SESSIONS 10
+#define MAX_SESSIONS 20
 Session        sessions[MAX_SESSIONS];
 
 Session        sessions[MAX_SESSIONS];
 
+#define SUBSYSTEM_NONE         0
+#define SUBSYSTEM_EXT          1
+#define SUBSYSTEM_INT_SFTP     2
+
 #ifdef HAVE_LOGIN_CAP
 login_cap_t *lc;
 #endif
 #ifdef HAVE_LOGIN_CAP
 login_cap_t *lc;
 #endif
@@ -444,11 +450,6 @@ do_exec_no_pty(Session *s, const char *command)
 
        session_proctitle(s);
 
 
        session_proctitle(s);
 
-#if defined(USE_PAM)
-       if (options.use_pam && !use_privsep)
-               do_pam_setcred(1);
-#endif /* USE_PAM */
-
        /* Fork the child. */
        if ((pid = fork()) == 0) {
                is_child = 1;
        /* Fork the child. */
        if ((pid = fork()) == 0) {
                is_child = 1;
@@ -579,14 +580,6 @@ do_exec_pty(Session *s, const char *command)
        ptyfd = s->ptyfd;
        ttyfd = s->ttyfd;
 
        ptyfd = s->ptyfd;
        ttyfd = s->ttyfd;
 
-#if defined(USE_PAM)
-       if (options.use_pam) {
-               do_pam_set_tty(s->tty);
-               if (!use_privsep)
-                       do_pam_setcred(1);
-       }
-#endif
-
        /* Fork the child. */
        if ((pid = fork()) == 0) {
                is_child = 1;
        /* Fork the child. */
        if ((pid = fork()) == 0) {
                is_child = 1;
@@ -705,10 +698,18 @@ do_exec(Session *s, const char *command)
        if (options.adm_forced_command) {
                original_command = command;
                command = options.adm_forced_command;
        if (options.adm_forced_command) {
                original_command = command;
                command = options.adm_forced_command;
+               if (strcmp(INTERNAL_SFTP_NAME, command) == 0)
+                       s->is_subsystem = SUBSYSTEM_INT_SFTP;
+               else if (s->is_subsystem)
+                       s->is_subsystem = SUBSYSTEM_EXT;
                debug("Forced command (config) '%.900s'", command);
        } else if (forced_command) {
                original_command = command;
                command = forced_command;
                debug("Forced command (config) '%.900s'", command);
        } else if (forced_command) {
                original_command = command;
                command = forced_command;
+               if (strcmp(INTERNAL_SFTP_NAME, command) == 0)
+                       s->is_subsystem = SUBSYSTEM_INT_SFTP;
+               else if (s->is_subsystem)
+                       s->is_subsystem = SUBSYSTEM_EXT;
                debug("Forced command (key option) '%.900s'", command);
        }
 
                debug("Forced command (key option) '%.900s'", command);
        }
 
@@ -743,7 +744,6 @@ do_exec(Session *s, const char *command)
                PRIVSEP(audit_run_command(shell));
        }
 #endif
                PRIVSEP(audit_run_command(shell));
        }
 #endif
-
        if (s->ttyfd != -1)
                do_exec_pty(s, command);
        else
        if (s->ttyfd != -1)
                do_exec_pty(s, command);
        else
@@ -939,8 +939,9 @@ read_environment_file(char ***env, u_int *envsize,
                        ;
                if (!*cp || *cp == '#' || *cp == '\n')
                        continue;
                        ;
                if (!*cp || *cp == '#' || *cp == '\n')
                        continue;
-               if (strchr(cp, '\n'))
-                       *strchr(cp, '\n') = '\0';
+
+               cp[strcspn(cp, "\n")] = '\0';
+
                value = strchr(cp, '=');
                if (value == NULL) {
                        fprintf(stderr, "Bad line %u in %.100s\n", lineno,
                value = strchr(cp, '=');
                if (value == NULL) {
                        fprintf(stderr, "Bad line %u in %.100s\n", lineno,
@@ -1371,8 +1372,9 @@ do_rc_files(Session *s, const char *shell)
        do_xauth =
            s->display != NULL && s->auth_proto != NULL && s->auth_data != NULL;
 
        do_xauth =
            s->display != NULL && s->auth_proto != NULL && s->auth_data != NULL;
 
-       /* ignore _PATH_SSH_USER_RC for subsystems */
-       if (!s->is_subsystem && (stat(_PATH_SSH_USER_RC, &st) >= 0)) {
+       /* ignore _PATH_SSH_USER_RC for subsystems and admin forced commands */
+       if (!s->is_subsystem && options.adm_forced_command == NULL &&
+           !no_user_rc &&  (stat(_PATH_SSH_USER_RC, &st) >= 0)) {
                snprintf(cmd, sizeof cmd, "%s -c '%s %s'",
                    shell, _PATH_BSHELL, _PATH_SSH_USER_RC);
                if (debug_flag)
                snprintf(cmd, sizeof cmd, "%s -c '%s %s'",
                    shell, _PATH_BSHELL, _PATH_SSH_USER_RC);
                if (debug_flag)
@@ -1453,10 +1455,72 @@ do_nologin(struct passwd *pw)
        }
 }
 
        }
 }
 
+/*
+ * Chroot into a directory after checking it for safety: all path components
+ * must be root-owned directories with strict permissions.
+ */
+static void
+safely_chroot(const char *path, uid_t uid)
+{
+       const char *cp;
+       char component[MAXPATHLEN];
+       struct stat st;
+
+       if (*path != '/')
+               fatal("chroot path does not begin at root");
+       if (strlen(path) >= sizeof(component))
+               fatal("chroot path too long");
+
+       /*
+        * Descend the path, checking that each component is a
+        * root-owned directory with strict permissions.
+        */
+       for (cp = path; cp != NULL;) {
+               if ((cp = strchr(cp, '/')) == NULL)
+                       strlcpy(component, path, sizeof(component));
+               else {
+                       cp++;
+                       memcpy(component, path, cp - path);
+                       component[cp - path] = '\0';
+               }
+       
+               debug3("%s: checking '%s'", __func__, component);
+
+               if (stat(component, &st) != 0)
+                       fatal("%s: stat(\"%s\"): %s", __func__,
+                           component, strerror(errno));
+               if (st.st_uid != 0 || (st.st_mode & 022) != 0)
+                       fatal("bad ownership or modes for chroot "
+                           "directory %s\"%s\"", 
+                           cp == NULL ? "" : "component ", component);
+               if (!S_ISDIR(st.st_mode))
+                       fatal("chroot path %s\"%s\" is not a directory",
+                           cp == NULL ? "" : "component ", component);
+
+       }
+
+       if (chdir(path) == -1)
+               fatal("Unable to chdir to chroot path \"%s\": "
+                   "%s", path, strerror(errno));
+       if (chroot(path) == -1)
+               fatal("chroot(\"%s\"): %s", path, strerror(errno));
+       if (chdir("/") == -1)
+               fatal("%s: chdir(/) after chroot: %s",
+                   __func__, strerror(errno));
+       verbose("Changed root directory to \"%s\"", path);
+}
+
 /* Set login name, uid, gid, and groups. */
 void
 do_setusercontext(struct passwd *pw)
 {
 /* Set login name, uid, gid, and groups. */
 void
 do_setusercontext(struct passwd *pw)
 {
+       char *chroot_path, *tmp;
+
+#ifdef WITH_SELINUX
+       /* Cache selinux status for later use */
+       (void)ssh_selinux_enabled();
+#endif
+
 #ifndef HAVE_CYGWIN
        if (getuid() == 0 || geteuid() == 0)
 #endif /* HAVE_CYGWIN */
 #ifndef HAVE_CYGWIN
        if (getuid() == 0 || geteuid() == 0)
 #endif /* HAVE_CYGWIN */
@@ -1470,21 +1534,13 @@ do_setusercontext(struct passwd *pw)
 # ifdef __bsdi__
                setpgid(0, 0);
 # endif
 # ifdef __bsdi__
                setpgid(0, 0);
 # endif
-#ifdef GSSAPI
-               if (options.gss_authentication) {
-                       temporarily_use_uid(pw);
-                       ssh_gssapi_storecreds();
-                       restore_uid();
-               }
-#endif
 # ifdef USE_PAM
                if (options.use_pam) {
 # ifdef USE_PAM
                if (options.use_pam) {
-                       do_pam_session();
                        do_pam_setcred(use_privsep);
                }
 # endif /* USE_PAM */
                if (setusercontext(lc, pw, pw->pw_uid,
                        do_pam_setcred(use_privsep);
                }
 # endif /* USE_PAM */
                if (setusercontext(lc, pw, pw->pw_uid,
-                   (LOGIN_SETALL & ~LOGIN_SETPATH)) < 0) {
+                   (LOGIN_SETALL & ~(LOGIN_SETPATH|LOGIN_SETUSER))) < 0) {
                        perror("unable to set user context");
                        exit(1);
                }
                        perror("unable to set user context");
                        exit(1);
                }
@@ -1507,13 +1563,6 @@ do_setusercontext(struct passwd *pw)
                        exit(1);
                }
                endgrent();
                        exit(1);
                }
                endgrent();
-#ifdef GSSAPI
-               if (options.gss_authentication) {
-                       temporarily_use_uid(pw);
-                       ssh_gssapi_storecreds();
-                       restore_uid();
-               }
-#endif
 # ifdef USE_PAM
                /*
                 * PAM credentials may take the form of supplementary groups.
 # ifdef USE_PAM
                /*
                 * PAM credentials may take the form of supplementary groups.
@@ -1521,21 +1570,39 @@ do_setusercontext(struct passwd *pw)
                 * Reestablish them here.
                 */
                if (options.use_pam) {
                 * Reestablish them here.
                 */
                if (options.use_pam) {
-                       do_pam_session();
                        do_pam_setcred(use_privsep);
                }
 # endif /* USE_PAM */
 # if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY)
                irix_setusercontext(pw);
                        do_pam_setcred(use_privsep);
                }
 # endif /* USE_PAM */
 # if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY)
                irix_setusercontext(pw);
-#  endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */
+# endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */
 # ifdef _AIX
                aix_usrinfo(pw);
 # endif /* _AIX */
 # ifdef _AIX
                aix_usrinfo(pw);
 # endif /* _AIX */
-#ifdef USE_LIBIAF
+# ifdef USE_LIBIAF
                if (set_id(pw->pw_name) != 0) {
                        exit(1);
                }
                if (set_id(pw->pw_name) != 0) {
                        exit(1);
                }
-#endif /* USE_LIBIAF */
+# endif /* USE_LIBIAF */
+#endif
+
+               if (options.chroot_directory != NULL &&
+                   strcasecmp(options.chroot_directory, "none") != 0) {
+                        tmp = tilde_expand_filename(options.chroot_directory,
+                           pw->pw_uid);
+                       chroot_path = percent_expand(tmp, "h", pw->pw_dir,
+                           "u", pw->pw_name, (char *)NULL);
+                       safely_chroot(chroot_path, pw->pw_uid);
+                       free(tmp);
+                       free(chroot_path);
+               }
+
+#ifdef HAVE_LOGIN_CAP
+               if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETUSER) < 0) {
+                       perror("unable to set user context (setuser)");
+                       exit(1);
+               }
+#else
                /* Permanently switch to the desired uid. */
                permanently_set_uid(pw);
 #endif
                /* Permanently switch to the desired uid. */
                permanently_set_uid(pw);
 #endif
@@ -1634,12 +1701,13 @@ child_close_fds(void)
  * environment, closing extra file descriptors, setting the user and group
  * ids, and executing the command or shell.
  */
  * environment, closing extra file descriptors, setting the user and group
  * ids, and executing the command or shell.
  */
+#define ARGV_MAX 10
 void
 do_child(Session *s, const char *command)
 {
        extern char **environ;
        char **env;
 void
 do_child(Session *s, const char *command)
 {
        extern char **environ;
        char **env;
-       char *argv[10];
+       char *argv[ARGV_MAX];
        const char *shell, *shell0, *hostname = NULL;
        struct passwd *pw = s->pw;
 
        const char *shell, *shell0, *hostname = NULL;
        struct passwd *pw = s->pw;
 
@@ -1812,12 +1880,30 @@ do_child(Session *s, const char *command)
 #endif
        }
 
 #endif
        }
 
+       closefrom(STDERR_FILENO + 1);
+
        if (!options.use_login)
                do_rc_files(s, shell);
 
        /* restore SIGPIPE for child */
        signal(SIGPIPE, SIG_DFL);
 
        if (!options.use_login)
                do_rc_files(s, shell);
 
        /* restore SIGPIPE for child */
        signal(SIGPIPE, SIG_DFL);
 
+       if (s->is_subsystem == SUBSYSTEM_INT_SFTP) {
+               extern int optind, optreset;
+               int i;
+               char *p, *args;
+
+               setproctitle("%s@internal-sftp-server", s->pw->pw_name);
+               args = strdup(command ? command : "sftp-server");
+               for (i = 0, (p = strtok(args, " ")); p; (p = strtok(NULL, " ")))
+                       if (i < ARGV_MAX - 1)
+                               argv[i++] = p;
+               argv[i] = NULL;
+               optind = optreset = 1;
+               __progname = argv[0];
+               exit(sftp_server_main(i, argv, s->pw));
+       }
+
        if (options.use_login) {
                launch_login(pw, hostname);
                /* NEVERREACHED */
        if (options.use_login) {
                launch_login(pw, hostname);
                /* NEVERREACHED */
@@ -2090,13 +2176,16 @@ session_subsystem_req(Session *s)
                if (strcmp(subsys, options.subsystem_name[i]) == 0) {
                        prog = options.subsystem_command[i];
                        cmd = options.subsystem_args[i];
                if (strcmp(subsys, options.subsystem_name[i]) == 0) {
                        prog = options.subsystem_command[i];
                        cmd = options.subsystem_args[i];
-                       if (stat(prog, &st) < 0) {
+                       if (!strcmp(INTERNAL_SFTP_NAME, prog)) {
+                               s->is_subsystem = SUBSYSTEM_INT_SFTP;
+                       } else if (stat(prog, &st) < 0) {
                                error("subsystem: cannot stat %s: %s", prog,
                                    strerror(errno));
                                break;
                                error("subsystem: cannot stat %s: %s", prog,
                                    strerror(errno));
                                break;
+                       } else {
+                               s->is_subsystem = SUBSYSTEM_EXT;
                        }
                        debug("subsystem: exec() %s", cmd);
                        }
                        debug("subsystem: exec() %s", cmd);
-                       s->is_subsystem = 1;
                        do_exec(s, cmd);
                        success = 1;
                        break;
                        do_exec(s, cmd);
                        success = 1;
                        break;
@@ -2427,7 +2516,7 @@ session_exit_message(Session *s, int status)
                channel_request_start(s->chanid, "exit-signal", 0);
                packet_put_cstring(sig2name(WTERMSIG(status)));
 #ifdef WCOREDUMP
                channel_request_start(s->chanid, "exit-signal", 0);
                packet_put_cstring(sig2name(WTERMSIG(status)));
 #ifdef WCOREDUMP
-               packet_put_char(WCOREDUMP(status));
+               packet_put_char(WCOREDUMP(status)? 1 : 0);
 #else /* WCOREDUMP */
                packet_put_char(0);
 #endif /* WCOREDUMP */
 #else /* WCOREDUMP */
                packet_put_char(0);
 #endif /* WCOREDUMP */
index f0d5dd557e94a42b7060ce8c1a4cd158a150643d..861c3db05031c20f239b578705b958671707ecbe 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp.c,v 1.96 2007/01/03 04:09:15 stevesk Exp $ */
+/* $OpenBSD: sftp.c,v 1.99 2008/01/20 00:38:30 djm Exp $ */
 /*
  * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
  *
 /*
  * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
  *
@@ -26,6 +26,7 @@
 #include <sys/socket.h>
 #include <sys/wait.h>
 
 #include <sys/socket.h>
 #include <sys/wait.h>
 
+#include <ctype.h>
 #include <errno.h>
 
 #ifdef HAVE_PATHS_H
 #include <errno.h>
 
 #ifdef HAVE_PATHS_H
@@ -346,144 +347,78 @@ infer_path(const char *p, char **ifp)
 }
 
 static int
 }
 
 static int
-parse_getput_flags(const char **cpp, int *pflag)
+parse_getput_flags(const char *cmd, char **argv, int argc, int *pflag)
 {
 {
-       const char *cp = *cpp;
+       extern int optind, optreset, opterr;
+       int ch;
 
 
-       /* Check for flags */
-       if (cp[0] == '-' && cp[1] && strchr(WHITESPACE, cp[2])) {
-               switch (cp[1]) {
+       optind = optreset = 1;
+       opterr = 0;
+
+       *pflag = 0;
+       while ((ch = getopt(argc, argv, "Pp")) != -1) {
+               switch (ch) {
                case 'p':
                case 'P':
                        *pflag = 1;
                        break;
                default:
                case 'p':
                case 'P':
                        *pflag = 1;
                        break;
                default:
-                       error("Invalid flag -%c", cp[1]);
-                       return(-1);
+                       error("%s: Invalid flag -%c", cmd, ch);
+                       return -1;
                }
                }
-               cp += 2;
-               *cpp = cp + strspn(cp, WHITESPACE);
        }
 
        }
 
-       return(0);
+       return optind;
 }
 
 static int
 }
 
 static int
-parse_ls_flags(const char **cpp, int *lflag)
+parse_ls_flags(char **argv, int argc, int *lflag)
 {
 {
-       const char *cp = *cpp;
+       extern int optind, optreset, opterr;
+       int ch;
 
 
-       /* Defaults */
-       *lflag = LS_NAME_SORT;
+       optind = optreset = 1;
+       opterr = 0;
 
 
-       /* Check for flags */
-       if (cp++[0] == '-') {
-               for (; strchr(WHITESPACE, *cp) == NULL; cp++) {
-                       switch (*cp) {
-                       case 'l':
-                               *lflag &= ~VIEW_FLAGS;
-                               *lflag |= LS_LONG_VIEW;
-                               break;
-                       case '1':
-                               *lflag &= ~VIEW_FLAGS;
-                               *lflag |= LS_SHORT_VIEW;
-                               break;
-                       case 'n':
-                               *lflag &= ~VIEW_FLAGS;
-                               *lflag |= LS_NUMERIC_VIEW|LS_LONG_VIEW;
-                               break;
-                       case 'S':
-                               *lflag &= ~SORT_FLAGS;
-                               *lflag |= LS_SIZE_SORT;
-                               break;
-                       case 't':
-                               *lflag &= ~SORT_FLAGS;
-                               *lflag |= LS_TIME_SORT;
-                               break;
-                       case 'r':
-                               *lflag |= LS_REVERSE_SORT;
-                               break;
-                       case 'f':
-                               *lflag &= ~SORT_FLAGS;
-                               break;
-                       case 'a':
-                               *lflag |= LS_SHOW_ALL;
-                               break;
-                       default:
-                               error("Invalid flag -%c", *cp);
-                               return(-1);
-                       }
-               }
-               *cpp = cp + strspn(cp, WHITESPACE);
-       }
-
-       return(0);
-}
-
-static int
-get_pathname(const char **cpp, char **path)
-{
-       const char *cp = *cpp, *end;
-       char quot;
-       u_int i, j;
-
-       cp += strspn(cp, WHITESPACE);
-       if (!*cp) {
-               *cpp = cp;
-               *path = NULL;
-               return (0);
-       }
-
-       *path = xmalloc(strlen(cp) + 1);
-
-       /* Check for quoted filenames */
-       if (*cp == '\"' || *cp == '\'') {
-               quot = *cp++;
-
-               /* Search for terminating quote, unescape some chars */
-               for (i = j = 0; i <= strlen(cp); i++) {
-                       if (cp[i] == quot) {    /* Found quote */
-                               i++;
-                               (*path)[j] = '\0';
-                               break;
-                       }
-                       if (cp[i] == '\0') {    /* End of string */
-                               error("Unterminated quote");
-                               goto fail;
-                       }
-                       if (cp[i] == '\\') {    /* Escaped characters */
-                               i++;
-                               if (cp[i] != '\'' && cp[i] != '\"' &&
-                                   cp[i] != '\\') {
-                                       error("Bad escaped character '\\%c'",
-                                           cp[i]);
-                                       goto fail;
-                               }
-                       }
-                       (*path)[j++] = cp[i];
-               }
-
-               if (j == 0) {
-                       error("Empty quotes");
-                       goto fail;
+       *lflag = LS_NAME_SORT;
+       while ((ch = getopt(argc, argv, "1Saflnrt")) != -1) {
+               switch (ch) {
+               case '1':
+                       *lflag &= ~VIEW_FLAGS;
+                       *lflag |= LS_SHORT_VIEW;
+                       break;
+               case 'S':
+                       *lflag &= ~SORT_FLAGS;
+                       *lflag |= LS_SIZE_SORT;
+                       break;
+               case 'a':
+                       *lflag |= LS_SHOW_ALL;
+                       break;
+               case 'f':
+                       *lflag &= ~SORT_FLAGS;
+                       break;
+               case 'l':
+                       *lflag &= ~VIEW_FLAGS;
+                       *lflag |= LS_LONG_VIEW;
+                       break;
+               case 'n':
+                       *lflag &= ~VIEW_FLAGS;
+                       *lflag |= LS_NUMERIC_VIEW|LS_LONG_VIEW;
+                       break;
+               case 'r':
+                       *lflag |= LS_REVERSE_SORT;
+                       break;
+               case 't':
+                       *lflag &= ~SORT_FLAGS;
+                       *lflag |= LS_TIME_SORT;
+                       break;
+               default:
+                       error("ls: Invalid flag -%c", ch);
+                       return -1;
                }
                }
-               *cpp = cp + i + strspn(cp + i, WHITESPACE);
-       } else {
-               /* Read to end of filename */
-               end = strpbrk(cp, WHITESPACE);
-               if (end == NULL)
-                       end = strchr(cp, '\0');
-               *cpp = end + strspn(end, WHITESPACE);
-
-               memcpy(*path, cp, end - cp);
-               (*path)[end - cp] = '\0';
        }
        }
-       return (0);
 
 
- fail:
-       xfree(*path);
-       *path = NULL;
-       return (-1);
+       return optind;
 }
 
 static int
 }
 
 static int
@@ -498,17 +433,6 @@ is_dir(char *path)
        return(S_ISDIR(sb.st_mode));
 }
 
        return(S_ISDIR(sb.st_mode));
 }
 
-static int
-is_reg(char *path)
-{
-       struct stat sb;
-
-       if (stat(path, &sb) == -1)
-               fatal("stat %s: %s", path, strerror(errno));
-
-       return(S_ISREG(sb.st_mode));
-}
-
 static int
 remote_is_dir(struct sftp_conn *conn, char *path)
 {
 static int
 remote_is_dir(struct sftp_conn *conn, char *path)
 {
@@ -597,6 +521,7 @@ process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag)
        glob_t g;
        int err = 0;
        int i;
        glob_t g;
        int err = 0;
        int i;
+       struct stat sb;
 
        if (dst) {
                tmp_dst = xstrdup(dst);
 
        if (dst) {
                tmp_dst = xstrdup(dst);
@@ -605,7 +530,7 @@ process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag)
 
        memset(&g, 0, sizeof(g));
        debug3("Looking up %s", src);
 
        memset(&g, 0, sizeof(g));
        debug3("Looking up %s", src);
-       if (glob(src, 0, NULL, &g)) {
+       if (glob(src, GLOB_NOCHECK, NULL, &g)) {
                error("File \"%s\" not found.", src);
                err = -1;
                goto out;
                error("File \"%s\" not found.", src);
                err = -1;
                goto out;
@@ -620,7 +545,13 @@ process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag)
        }
 
        for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
        }
 
        for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
-               if (!is_reg(g.gl_pathv[i])) {
+               if (stat(g.gl_pathv[i], &sb) == -1) {
+                       err = -1;
+                       error("stat %s: %s", g.gl_pathv[i], strerror(errno));
+                       continue;
+               }
+
+               if (!S_ISREG(sb.st_mode)) {
                        error("skipping non-regular file %s",
                            g.gl_pathv[i]);
                        continue;
                        error("skipping non-regular file %s",
                            g.gl_pathv[i]);
                        continue;
@@ -866,15 +797,189 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path,
        return (0);
 }
 
        return (0);
 }
 
+/*
+ * Undo escaping of glob sequences in place. Used to undo extra escaping
+ * applied in makeargv() when the string is destined for a function that
+ * does not glob it.
+ */
+static void
+undo_glob_escape(char *s)
+{
+       size_t i, j;
+
+       for (i = j = 0;;) {
+               if (s[i] == '\0') {
+                       s[j] = '\0';
+                       return;
+               }
+               if (s[i] != '\\') {
+                       s[j++] = s[i++];
+                       continue;
+               }
+               /* s[i] == '\\' */
+               ++i;
+               switch (s[i]) {
+               case '?':
+               case '[':
+               case '*':
+               case '\\':
+                       s[j++] = s[i++];
+                       break;
+               case '\0':
+                       s[j++] = '\\';
+                       s[j] = '\0';
+                       return;
+               default:
+                       s[j++] = '\\';
+                       s[j++] = s[i++];
+                       break;
+               }
+       }
+}
+
+/*
+ * Split a string into an argument vector using sh(1)-style quoting,
+ * comment and escaping rules, but with some tweaks to handle glob(3)
+ * wildcards.
+ * Returns NULL on error or a NULL-terminated array of arguments.
+ */
+#define MAXARGS        128
+#define MAXARGLEN      8192
+static char **
+makeargv(const char *arg, int *argcp)
+{
+       int argc, quot;
+       size_t i, j;
+       static char argvs[MAXARGLEN];
+       static char *argv[MAXARGS + 1];
+       enum { MA_START, MA_SQUOTE, MA_DQUOTE, MA_UNQUOTED } state, q;
+
+       *argcp = argc = 0;
+       if (strlen(arg) > sizeof(argvs) - 1) {
+ args_too_longs:
+               error("string too long");
+               return NULL;
+       }
+       state = MA_START;
+       i = j = 0;
+       for (;;) {
+               if (isspace(arg[i])) {
+                       if (state == MA_UNQUOTED) {
+                               /* Terminate current argument */
+                               argvs[j++] = '\0';
+                               argc++;
+                               state = MA_START;
+                       } else if (state != MA_START)
+                               argvs[j++] = arg[i];
+               } else if (arg[i] == '"' || arg[i] == '\'') {
+                       q = arg[i] == '"' ? MA_DQUOTE : MA_SQUOTE;
+                       if (state == MA_START) {
+                               argv[argc] = argvs + j;
+                               state = q;
+                       } else if (state == MA_UNQUOTED) 
+                               state = q;
+                       else if (state == q)
+                               state = MA_UNQUOTED;
+                       else
+                               argvs[j++] = arg[i];
+               } else if (arg[i] == '\\') {
+                       if (state == MA_SQUOTE || state == MA_DQUOTE) {
+                               quot = state == MA_SQUOTE ? '\'' : '"';
+                               /* Unescape quote we are in */
+                               /* XXX support \n and friends? */
+                               if (arg[i + 1] == quot) {
+                                       i++;
+                                       argvs[j++] = arg[i];
+                               } else if (arg[i + 1] == '?' ||
+                                   arg[i + 1] == '[' || arg[i + 1] == '*') {
+                                       /*
+                                        * Special case for sftp: append
+                                        * double-escaped glob sequence -
+                                        * glob will undo one level of
+                                        * escaping. NB. string can grow here.
+                                        */
+                                       if (j >= sizeof(argvs) - 5)
+                                               goto args_too_longs;
+                                       argvs[j++] = '\\';
+                                       argvs[j++] = arg[i++];
+                                       argvs[j++] = '\\';
+                                       argvs[j++] = arg[i];
+                               } else {
+                                       argvs[j++] = arg[i++];
+                                       argvs[j++] = arg[i];
+                               }
+                       } else {
+                               if (state == MA_START) {
+                                       argv[argc] = argvs + j;
+                                       state = MA_UNQUOTED;
+                               }
+                               if (arg[i + 1] == '?' || arg[i + 1] == '[' ||
+                                   arg[i + 1] == '*' || arg[i + 1] == '\\') {
+                                       /*
+                                        * Special case for sftp: append
+                                        * escaped glob sequence -
+                                        * glob will undo one level of
+                                        * escaping.
+                                        */
+                                       argvs[j++] = arg[i++];
+                                       argvs[j++] = arg[i];
+                               } else {
+                                       /* Unescape everything */
+                                       /* XXX support \n and friends? */
+                                       i++;
+                                       argvs[j++] = arg[i];
+                               }
+                       }
+               } else if (arg[i] == '#') {
+                       if (state == MA_SQUOTE || state == MA_DQUOTE)
+                               argvs[j++] = arg[i];
+                       else
+                               goto string_done;
+               } else if (arg[i] == '\0') {
+                       if (state == MA_SQUOTE || state == MA_DQUOTE) {
+                               error("Unterminated quoted argument");
+                               return NULL;
+                       }
+ string_done:
+                       if (state == MA_UNQUOTED) {
+                               argvs[j++] = '\0';
+                               argc++;
+                       }
+                       break;
+               } else {
+                       if (state == MA_START) {
+                               argv[argc] = argvs + j;
+                               state = MA_UNQUOTED;
+                       }
+                       if ((state == MA_SQUOTE || state == MA_DQUOTE) &&
+                           (arg[i] == '?' || arg[i] == '[' || arg[i] == '*')) {
+                               /*
+                                * Special case for sftp: escape quoted
+                                * glob(3) wildcards. NB. string can grow
+                                * here.
+                                */
+                               if (j >= sizeof(argvs) - 3)
+                                       goto args_too_longs;
+                               argvs[j++] = '\\';
+                               argvs[j++] = arg[i];
+                       } else
+                               argvs[j++] = arg[i];
+               }
+               i++;
+       }
+       *argcp = argc;
+       return argv;
+}
+
 static int
 parse_args(const char **cpp, int *pflag, int *lflag, int *iflag,
     unsigned long *n_arg, char **path1, char **path2)
 {
        const char *cmd, *cp = *cpp;
 static int
 parse_args(const char **cpp, int *pflag, int *lflag, int *iflag,
     unsigned long *n_arg, char **path1, char **path2)
 {
        const char *cmd, *cp = *cpp;
-       char *cp2;
+       char *cp2, **argv;
        int base = 0;
        long l;
        int base = 0;
        long l;
-       int i, cmdnum;
+       int i, cmdnum, optidx, argc;
 
        /* Skip leading whitespace */
        cp = cp + strspn(cp, WHITESPACE);
 
        /* Skip leading whitespace */
        cp = cp + strspn(cp, WHITESPACE);
@@ -890,17 +995,13 @@ parse_args(const char **cpp, int *pflag, int *lflag, int *iflag,
                cp++;
        }
 
                cp++;
        }
 
+       if ((argv = makeargv(cp, &argc)) == NULL)
+               return -1;
+
        /* Figure out which command we have */
        /* Figure out which command we have */
-       for (i = 0; cmds[i].c; i++) {
-               int cmdlen = strlen(cmds[i].c);
-
-               /* Check for command followed by whitespace */
-               if (!strncasecmp(cp, cmds[i].c, cmdlen) &&
-                   strchr(WHITESPACE, cp[cmdlen])) {
-                       cp += cmdlen;
-                       cp = cp + strspn(cp, WHITESPACE);
+       for (i = 0; cmds[i].c != NULL; i++) {
+               if (strcasecmp(cmds[i].c, argv[0]) == 0)
                        break;
                        break;
-               }
        }
        cmdnum = cmds[i].n;
        cmd = cmds[i].c;
        }
        cmdnum = cmds[i].n;
        cmd = cmds[i].c;
@@ -911,40 +1012,44 @@ parse_args(const char **cpp, int *pflag, int *lflag, int *iflag,
                cmdnum = I_SHELL;
        } else if (cmdnum == -1) {
                error("Invalid command.");
                cmdnum = I_SHELL;
        } else if (cmdnum == -1) {
                error("Invalid command.");
-               return (-1);
+               return -1;
        }
 
        /* Get arguments and parse flags */
        *lflag = *pflag = *n_arg = 0;
        *path1 = *path2 = NULL;
        }
 
        /* Get arguments and parse flags */
        *lflag = *pflag = *n_arg = 0;
        *path1 = *path2 = NULL;
+       optidx = 1;
        switch (cmdnum) {
        case I_GET:
        case I_PUT:
        switch (cmdnum) {
        case I_GET:
        case I_PUT:
-               if (parse_getput_flags(&cp, pflag))
-                       return(-1);
+               if ((optidx = parse_getput_flags(cmd, argv, argc, pflag)) == -1)
+                       return -1;
                /* Get first pathname (mandatory) */
                /* Get first pathname (mandatory) */
-               if (get_pathname(&cp, path1))
-                       return(-1);
-               if (*path1 == NULL) {
+               if (argc - optidx < 1) {
                        error("You must specify at least one path after a "
                            "%s command.", cmd);
                        error("You must specify at least one path after a "
                            "%s command.", cmd);
-                       return(-1);
+                       return -1;
+               }
+               *path1 = xstrdup(argv[optidx]);
+               /* Get second pathname (optional) */
+               if (argc - optidx > 1) {
+                       *path2 = xstrdup(argv[optidx + 1]);
+                       /* Destination is not globbed */
+                       undo_glob_escape(*path2);
                }
                }
-               /* Try to get second pathname (optional) */
-               if (get_pathname(&cp, path2))
-                       return(-1);
                break;
        case I_RENAME:
        case I_SYMLINK:
                break;
        case I_RENAME:
        case I_SYMLINK:
-               if (get_pathname(&cp, path1))
-                       return(-1);
-               if (get_pathname(&cp, path2))
-                       return(-1);
-               if (!*path1 || !*path2) {
+               if (argc - optidx < 2) {
                        error("You must specify two paths after a %s "
                            "command.", cmd);
                        error("You must specify two paths after a %s "
                            "command.", cmd);
-                       return(-1);
+                       return -1;
                }
                }
+               *path1 = xstrdup(argv[optidx]);
+               *path2 = xstrdup(argv[optidx + 1]);
+               /* Paths are not globbed */
+               undo_glob_escape(*path1);
+               undo_glob_escape(*path2);
                break;
        case I_RM:
        case I_MKDIR:
                break;
        case I_RM:
        case I_MKDIR:
@@ -953,59 +1058,57 @@ parse_args(const char **cpp, int *pflag, int *lflag, int *iflag,
        case I_LCHDIR:
        case I_LMKDIR:
                /* Get pathname (mandatory) */
        case I_LCHDIR:
        case I_LMKDIR:
                /* Get pathname (mandatory) */
-               if (get_pathname(&cp, path1))
-                       return(-1);
-               if (*path1 == NULL) {
+               if (argc - optidx < 1) {
                        error("You must specify a path after a %s command.",
                            cmd);
                        error("You must specify a path after a %s command.",
                            cmd);
-                       return(-1);
+                       return -1;
                }
                }
+               *path1 = xstrdup(argv[optidx]);
+               /* Only "rm" globs */
+               if (cmdnum != I_RM)
+                       undo_glob_escape(*path1);
                break;
        case I_LS:
                break;
        case I_LS:
-               if (parse_ls_flags(&cp, lflag))
+               if ((optidx = parse_ls_flags(argv, argc, lflag)) == -1)
                        return(-1);
                /* Path is optional */
                        return(-1);
                /* Path is optional */
-               if (get_pathname(&cp, path1))
-                       return(-1);
+               if (argc - optidx > 0)
+                       *path1 = xstrdup(argv[optidx]);
                break;
        case I_LLS:
                break;
        case I_LLS:
+               /* Skip ls command and following whitespace */
+               cp = cp + strlen(cmd) + strspn(cp, WHITESPACE);
        case I_SHELL:
                /* Uses the rest of the line */
                break;
        case I_LUMASK:
        case I_SHELL:
                /* Uses the rest of the line */
                break;
        case I_LUMASK:
-               base = 8;
        case I_CHMOD:
                base = 8;
        case I_CHOWN:
        case I_CHGRP:
                /* Get numeric arg (mandatory) */
        case I_CHMOD:
                base = 8;
        case I_CHOWN:
        case I_CHGRP:
                /* Get numeric arg (mandatory) */
+               if (argc - optidx < 1)
+                       goto need_num_arg;
                errno = 0;
                errno = 0;
-               l = strtol(cp, &cp2, base);
-               if (cp2 == cp || ((l == LONG_MIN || l == LONG_MAX) &&
-                   errno == ERANGE) || l < 0) {
+               l = strtol(argv[optidx], &cp2, base);
+               if (cp2 == argv[optidx] || *cp2 != '\0' ||
+                   ((l == LONG_MIN || l == LONG_MAX) && errno == ERANGE) ||
+                   l < 0) {
+ need_num_arg:
                        error("You must supply a numeric argument "
                            "to the %s command.", cmd);
                        error("You must supply a numeric argument "
                            "to the %s command.", cmd);
-                       return(-1);
+                       return -1;
                }
                }
-               cp = cp2;
                *n_arg = l;
                *n_arg = l;
-               if (cmdnum == I_LUMASK && strchr(WHITESPACE, *cp))
+               if (cmdnum == I_LUMASK)
                        break;
                        break;
-               if (cmdnum == I_LUMASK || !strchr(WHITESPACE, *cp)) {
-                       error("You must supply a numeric argument "
-                           "to the %s command.", cmd);
-                       return(-1);
-               }
-               cp += strspn(cp, WHITESPACE);
-
                /* Get pathname (mandatory) */
                /* Get pathname (mandatory) */
-               if (get_pathname(&cp, path1))
-                       return(-1);
-               if (*path1 == NULL) {
+               if (argc - optidx < 2) {
                        error("You must specify a path after a %s command.",
                            cmd);
                        error("You must specify a path after a %s command.",
                            cmd);
-                       return(-1);
+                       return -1;
                }
                }
+               *path1 = xstrdup(argv[optidx + 1]);
                break;
        case I_QUIT:
        case I_PWD:
                break;
        case I_QUIT:
        case I_PWD:
index c3d5e5a757d9409a4e6289c8c43841ab44f2c6da..6f8727b33066b5279c1705c992a8bb1a008712a3 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-agent.c,v 1.155 2007/03/19 12:16:42 dtucker Exp $ */
+/* $OpenBSD: ssh-agent.c,v 1.157 2007/09/25 23:48:57 canacar Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -51,6 +51,7 @@
 
 #include <openssl/evp.h>
 #include <openssl/md5.h>
 
 #include <openssl/evp.h>
 #include <openssl/md5.h>
+#include "openbsd-compat/openssl-compat.h"
 
 #include <errno.h>
 #include <fcntl.h>
 
 #include <errno.h>
 #include <fcntl.h>
@@ -457,6 +458,7 @@ static void
 process_add_identity(SocketEntry *e, int version)
 {
        Idtab *tab = idtab_lookup(version);
 process_add_identity(SocketEntry *e, int version)
 {
        Idtab *tab = idtab_lookup(version);
+       Identity *id;
        int type, success = 0, death = 0, confirm = 0;
        char *type_name, *comment;
        Key *k = NULL;
        int type, success = 0, death = 0, confirm = 0;
        char *type_name, *comment;
        Key *k = NULL;
@@ -539,19 +541,19 @@ process_add_identity(SocketEntry *e, int version)
        }
        if (lifetime && !death)
                death = time(NULL) + lifetime;
        }
        if (lifetime && !death)
                death = time(NULL) + lifetime;
-       if (lookup_identity(k, version) == NULL) {
-               Identity *id = xmalloc(sizeof(Identity));
+       if ((id = lookup_identity(k, version)) == NULL) {
+               id = xmalloc(sizeof(Identity));
                id->key = k;
                id->key = k;
-               id->comment = comment;
-               id->death = death;
-               id->confirm = confirm;
                TAILQ_INSERT_TAIL(&tab->idlist, id, next);
                /* Increment the number of identities. */
                tab->nentries++;
        } else {
                key_free(k);
                TAILQ_INSERT_TAIL(&tab->idlist, id, next);
                /* Increment the number of identities. */
                tab->nentries++;
        } else {
                key_free(k);
-               xfree(comment);
+               xfree(id->comment);
        }
        }
+       id->comment = comment;
+       id->death = death;
+       id->confirm = confirm;
 send:
        buffer_put_int(&e->output, 1);
        buffer_put_char(&e->output,
 send:
        buffer_put_int(&e->output, 1);
        buffer_put_char(&e->output,
@@ -1016,7 +1018,7 @@ check_parent_exists(void)
 static void
 usage(void)
 {
 static void
 usage(void)
 {
-       fprintf(stderr, "Usage: %s [options] [command [args ...]]\n",
+       fprintf(stderr, "usage: %s [options] [command [arg ...]]\n",
            __progname);
        fprintf(stderr, "Options:\n");
        fprintf(stderr, "  -c          Generate C-shell commands on stdout.\n");
            __progname);
        fprintf(stderr, "Options:\n");
        fprintf(stderr, "  -c          Generate C-shell commands on stdout.\n");
index b19864007bf5c28225b2534c3b13d5ede5f9cc94..43ebfee552e618d523b136a61940e7588f9ed2c0 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-keyscan.c,v 1.74 2006/10/06 02:29:19 djm Exp $ */
+/* $OpenBSD: ssh-keyscan.c,v 1.75 2007/12/27 14:22:08 dtucker Exp $ */
 /*
  * Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
  *
 /*
  * Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
  *
@@ -410,7 +410,7 @@ tcpconnect(char *host)
        hints.ai_family = IPv4or6;
        hints.ai_socktype = SOCK_STREAM;
        if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0)
        hints.ai_family = IPv4or6;
        hints.ai_socktype = SOCK_STREAM;
        if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0)
-               fatal("getaddrinfo %s: %s", host, gai_strerror(gaierr));
+               fatal("getaddrinfo %s: %s", host, ssh_gai_strerror(gaierr));
        for (ai = aitop; ai; ai = ai->ai_next) {
                s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
                if (s < 0) {
        for (ai = aitop; ai; ai = ai->ai_next) {
                s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
                if (s < 0) {
index 1bf6b5e1c7af9592393935242cd0901213d88caa..d62df903263c5ffdf0ac1a3a17431180d0d38481 100644 (file)
@@ -34,8 +34,8 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
 .\" (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.270 2007/06/12 13:43:55 jmc Exp $
-.Dd $Mdocdate: June 12 2007 $
+.\" $OpenBSD: ssh.1,v 1.273 2008/02/11 07:58:28 jmc Exp $
+.Dd $Mdocdate: March 26 2008 $
 .Dt SSH 1
 .Os
 .Sh NAME
 .Dt SSH 1
 .Os
 .Sh NAME
@@ -506,7 +506,7 @@ This can be specified on a
 per-host basis in the configuration file.
 .It Fl q
 Quiet mode.
 per-host basis in the configuration file.
 .It Fl q
 Quiet mode.
-Causes all warning and diagnostic messages to be suppressed.
+Causes most warning and diagnostic messages to be suppressed.
 .It Fl R Xo
 .Sm off
 .Oo Ar bind_address : Oc
 .It Fl R Xo
 .Sm off
 .Oo Ar bind_address : Oc
@@ -1245,6 +1245,13 @@ This file is used in exactly the same way as
 but allows host-based authentication without permitting login with
 rlogin/rsh.
 .Pp
 but allows host-based authentication without permitting login with
 rlogin/rsh.
 .Pp
+.It ~/.ssh/
+This directory is the default location for all user-specific configuration
+and authentication information.
+There is no general requirement to keep the entire contents of this directory
+secret, but the recommended permissions are read/write/execute for the user,
+and not accessible by others.
+.Pp
 .It ~/.ssh/authorized_keys
 Lists the public keys (RSA/DSA) that can be used for logging in as this user.
 The format of this file is described in the
 .It ~/.ssh/authorized_keys
 Lists the public keys (RSA/DSA) that can be used for logging in as this user.
 The format of this file is described in the
index 296c8a1b2c5930c06753246e54ae523f2f6fd995..7a7adc00ebc8425c81561e7e80100df20a1f1e27 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh.c,v 1.301 2007/08/07 07:32:53 djm Exp $ */
+/* $OpenBSD: ssh.c,v 1.309 2008/01/19 20:51:26 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -72,6 +72,7 @@
 
 #include <openssl/evp.h>
 #include <openssl/err.h>
 
 #include <openssl/evp.h>
 #include <openssl/err.h>
+#include "openbsd-compat/openssl-compat.h"
 
 #include "xmalloc.h"
 #include "ssh.h"
 
 #include "xmalloc.h"
 #include "ssh.h"
@@ -210,7 +211,7 @@ main(int ac, char **av)
        char *p, *cp, *line, buf[256];
        struct stat st;
        struct passwd *pw;
        char *p, *cp, *line, buf[256];
        struct stat st;
        struct passwd *pw;
-       int dummy;
+       int dummy, timeout_ms;
        extern int optind, optreset;
        extern char *optarg;
        struct servent *sp;
        extern int optind, optreset;
        extern char *optarg;
        struct servent *sp;
@@ -502,6 +503,13 @@ main(int ac, char **av)
                        no_shell_flag = 1;
                        no_tty_flag = 1;
                        break;
                        no_shell_flag = 1;
                        no_tty_flag = 1;
                        break;
+               case 'T':
+                       no_tty_flag = 1;
+                       /* ensure that the user doesn't try to backdoor a */
+                       /* null cipher switch on an interactive session */
+                       /* so explicitly disable it no matter what */
+                       options.none_switch=0;
+                       break;
                case 'o':
                        dummy = 1;
                        line = xstrdup(optarg);
                case 'o':
                        dummy = 1;
                        line = xstrdup(optarg);
@@ -510,13 +518,6 @@ main(int ac, char **av)
                                exit(255);
                        xfree(line);
                        break;
                                exit(255);
                        xfree(line);
                        break;
-               case 'T':
-                       no_tty_flag = 1;
-                       /* ensure that the user doesn't try to backdoor a */
-                       /* null cipher switch on an interactive session */
-                       /* so explicitly disable it no matter what */
-                       options.none_switch=0;
-                       break;
                case 's':
                        subsystem_flag = 1;
                        break;
                case 's':
                        subsystem_flag = 1;
                        break;
@@ -688,11 +689,15 @@ main(int ac, char **av)
        }
 
        if (options.proxy_command != NULL &&
        }
 
        if (options.proxy_command != NULL &&
-           strcmp(options.proxy_command, "none") == 0)
+           strcmp(options.proxy_command, "none") == 0) {
+               xfree(options.proxy_command);
                options.proxy_command = NULL;
                options.proxy_command = NULL;
+       }
        if (options.control_path != NULL &&
        if (options.control_path != NULL &&
-           strcmp(options.control_path, "none") == 0)
+           strcmp(options.control_path, "none") == 0) {
+               xfree(options.control_path);
                options.control_path = NULL;
                options.control_path = NULL;
+       }
 
        if (options.control_path != NULL) {
                char thishost[NI_MAXHOST];
 
        if (options.control_path != NULL) {
                char thishost[NI_MAXHOST];
@@ -702,6 +707,7 @@ main(int ac, char **av)
                snprintf(buf, sizeof(buf), "%d", options.port);
                cp = tilde_expand_filename(options.control_path,
                    original_real_uid);
                snprintf(buf, sizeof(buf), "%d", options.port);
                cp = tilde_expand_filename(options.control_path,
                    original_real_uid);
+               xfree(options.control_path);
                options.control_path = percent_expand(cp, "p", buf, "h", host,
                    "r", options.user, "l", thishost, (char *)NULL);
                xfree(cp);
                options.control_path = percent_expand(cp, "p", buf, "h", host,
                    "r", options.user, "l", thishost, (char *)NULL);
                xfree(cp);
@@ -711,9 +717,12 @@ main(int ac, char **av)
        if (options.control_path != NULL)
                control_client(options.control_path);
 
        if (options.control_path != NULL)
                control_client(options.control_path);
 
+       timeout_ms = options.connection_timeout * 1000;
+
        /* Open a connection to the remote host. */
        if (ssh_connect(host, &hostaddr, options.port,
        /* Open a connection to the remote host. */
        if (ssh_connect(host, &hostaddr, options.port,
-           options.address_family, options.connection_attempts,
+           options.address_family, options.connection_attempts, &timeout_ms,
+           options.tcp_keep_alive, 
 #ifdef HAVE_CYGWIN
            options.use_privileged_port,
 #else
 #ifdef HAVE_CYGWIN
            options.use_privileged_port,
 #else
@@ -722,6 +731,9 @@ main(int ac, char **av)
            options.proxy_command) != 0)
                exit(255);
 
            options.proxy_command) != 0)
                exit(255);
 
+       if (timeout_ms > 0)
+               debug3("timeout: %d ms remain after connect", timeout_ms);
+
        /*
         * If we successfully made the connection, load the host private key
         * in case we will need it later for combined rsa-rhosts
        /*
         * If we successfully made the connection, load the host private key
         * in case we will need it later for combined rsa-rhosts
@@ -797,7 +809,8 @@ main(int ac, char **av)
        signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */
 
        /* Log into the remote system.  This never returns if the login fails. */
        signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */
 
        /* Log into the remote system.  This never returns if the login fails. */
-       ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr, pw);
+       ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr,
+           pw, timeout_ms);
 
        /* We no longer need the private host keys.  Clear them now. */
        if (sensitive_data.nkeys != 0) {
 
        /* We no longer need the private host keys.  Clear them now. */
        if (sensitive_data.nkeys != 0) {
@@ -1021,6 +1034,11 @@ ssh_session(void)
        /* Initiate port forwardings. */
        ssh_init_forwarding();
 
        /* Initiate port forwardings. */
        ssh_init_forwarding();
 
+       /* Execute a local command */
+       if (options.local_command != NULL &&
+           options.permit_local_command)
+               ssh_local_cmd(options.local_command);
+
        /* If requested, let ssh continue in the background. */
        if (fork_after_authentication_flag)
                if (daemon(1, 1) < 0)
        /* If requested, let ssh continue in the background. */
        if (fork_after_authentication_flag)
                if (daemon(1, 1) < 0)
@@ -1313,6 +1331,7 @@ static void
 load_public_identity_files(void)
 {
        char *filename, *cp, thishost[NI_MAXHOST];
 load_public_identity_files(void)
 {
        char *filename, *cp, thishost[NI_MAXHOST];
+       char *pwdir = NULL, *pwname = NULL;
        int i = 0;
        Key *public;
        struct passwd *pw;
        int i = 0;
        Key *public;
        struct passwd *pw;
@@ -1341,14 +1360,16 @@ load_public_identity_files(void)
 #endif /* SMARTCARD */
        if ((pw = getpwuid(original_real_uid)) == NULL)
                fatal("load_public_identity_files: getpwuid failed");
 #endif /* SMARTCARD */
        if ((pw = getpwuid(original_real_uid)) == NULL)
                fatal("load_public_identity_files: getpwuid failed");
+       pwname = xstrdup(pw->pw_name);
+       pwdir = xstrdup(pw->pw_dir);
        if (gethostname(thishost, sizeof(thishost)) == -1)
                fatal("load_public_identity_files: gethostname: %s",
                    strerror(errno));
        for (; i < options.num_identity_files; i++) {
                cp = tilde_expand_filename(options.identity_files[i],
                    original_real_uid);
        if (gethostname(thishost, sizeof(thishost)) == -1)
                fatal("load_public_identity_files: gethostname: %s",
                    strerror(errno));
        for (; i < options.num_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,
+               filename = percent_expand(cp, "d", pwdir,
+                   "u", pwname, "l", thishost, "h", host,
                    "r", options.user, (char *)NULL);
                xfree(cp);
                public = key_load_public(filename, NULL);
                    "r", options.user, (char *)NULL);
                xfree(cp);
                public = key_load_public(filename, NULL);
@@ -1358,6 +1379,10 @@ load_public_identity_files(void)
                options.identity_files[i] = filename;
                options.identity_keys[i] = public;
        }
                options.identity_files[i] = filename;
                options.identity_keys[i] = public;
        }
+       bzero(pwname, strlen(pwname));
+       xfree(pwname);
+       bzero(pwdir, strlen(pwdir));
+       xfree(pwdir);
 }
 
 static void
 }
 
 static void
@@ -1369,8 +1394,12 @@ control_client_sighandler(int signo)
 static void
 control_client_sigrelay(int signo)
 {
 static void
 control_client_sigrelay(int signo)
 {
+       int save_errno = errno;
+
        if (control_server_pid > 1)
                kill(control_server_pid, signo);
        if (control_server_pid > 1)
                kill(control_server_pid, signo);
+
+       errno = save_errno;
 }
 
 static int
 }
 
 static int
@@ -1464,6 +1493,8 @@ control_client(const char *path)
        if (options.forward_agent)
                flags |= SSHMUX_FLAG_AGENT_FWD;
 
        if (options.forward_agent)
                flags |= SSHMUX_FLAG_AGENT_FWD;
 
+       signal(SIGPIPE, SIG_IGN);
+
        buffer_init(&m);
 
        /* Send our command to server */
        buffer_init(&m);
 
        /* Send our command to server */
@@ -1525,9 +1556,10 @@ control_client(const char *path)
        if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1)
                fatal("%s: msg_send", __func__);
 
        if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1)
                fatal("%s: msg_send", __func__);
 
-       mm_send_fd(sock, STDIN_FILENO);
-       mm_send_fd(sock, STDOUT_FILENO);
-       mm_send_fd(sock, STDERR_FILENO);
+       if (mm_send_fd(sock, STDIN_FILENO) == -1 ||
+           mm_send_fd(sock, STDOUT_FILENO) == -1 ||
+           mm_send_fd(sock, STDERR_FILENO) == -1)
+               fatal("%s: send fds failed", __func__);
 
        /* Wait for reply, so master has a chance to gather ttymodes */
        buffer_clear(&m);
 
        /* Wait for reply, so master has a chance to gather ttymodes */
        buffer_clear(&m);
index 34d815e421e49f1b5e71780916cc12e0c477f535..b4c865f0ba95791f5aa91e8f3bb0a30f6d3c9c88 100644 (file)
@@ -34,8 +34,8 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
 .\" (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.102 2007/08/15 12:13:41 stevesk Exp $
-.Dd $Mdocdate: August 15 2007 $
+.\" $OpenBSD: ssh_config.5,v 1.105 2007/10/29 07:48:19 jmc Exp $
+.Dd $Mdocdate: December 2 2007 $
 .Dt SSH_CONFIG 5
 .Os
 .Sh NAME
 .Dt SSH_CONFIG 5
 .Os
 .Sh NAME
@@ -599,6 +599,14 @@ escape characters:
 It is possible to have
 multiple identity files specified in configuration files; all these
 identities will be tried in sequence.
 It is possible to have
 multiple identity files specified in configuration files; all these
 identities will be tried in sequence.
+.It Cm KbdInteractiveAuthentication
+Specifies whether to use keyboard-interactive authentication.
+The argument to this keyword must be
+.Dq yes
+or
+.Dq no .
+The default is
+.Dq yes .
 .It Cm KbdInteractiveDevices
 Specifies the list of methods to use in keyboard-interactive authentication.
 Multiple method names must be comma-separated.
 .It Cm KbdInteractiveDevices
 Specifies the list of methods to use in keyboard-interactive authentication.
 Multiple method names must be comma-separated.
@@ -614,7 +622,7 @@ and
 Specifies a command to execute on the local machine after successfully
 connecting to the server.
 The command string extends to the end of the line, and is executed with
 Specifies a command to execute on the local machine after successfully
 connecting to the server.
 The command string extends to the end of the line, and is executed with
-.Pa /bin/sh .
+the user's shell.
 This directive is ignored unless
 .Cm PermitLocalCommand
 has been enabled.
 This directive is ignored unless
 .Cm PermitLocalCommand
 has been enabled.
@@ -740,7 +748,7 @@ if version 2 is not available.
 Specifies the command to use to connect to the server.
 The command
 string extends to the end of the line, and is executed with
 Specifies the command to use to connect to the server.
 The command
 string extends to the end of the line, and is executed with
-.Pa /bin/sh .
+the user's shell.
 In the command string,
 .Ql %h
 will be substituted by the host name to
 In the command string,
 .Ql %h
 will be substituted by the host name to
index 17c4360b8d0fe999869d8c1539eb1b5857e0e46d..26884f5b8434d16f2ca34a96bc25ad217cb407ff 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect.c,v 1.200 2006/10/10 10:12:45 markus Exp $ */
+/* $OpenBSD: sshconnect.c,v 1.203 2007/12/27 14:22:08 dtucker Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -77,6 +77,23 @@ extern pid_t proxy_command_pid;
 static int show_other_keys(const char *, Key *);
 static void warn_changed_key(Key *);
 
 static int show_other_keys(const char *, Key *);
 static void warn_changed_key(Key *);
 
+static void
+ms_subtract_diff(struct timeval *start, int *ms)
+{
+       struct timeval diff, finish;
+
+       gettimeofday(&finish, NULL);
+       timersub(&finish, start, &diff);        
+       *ms -= (diff.tv_sec * 1000) + (diff.tv_usec / 1000);
+}
+
+static void
+ms_to_timeval(struct timeval *tv, int ms)
+{
+       tv->tv_sec = ms / 1000;
+       tv->tv_usec = (ms % 1000) * 1000;
+}
+
 /*
  * Connect to the given ssh server using a proxy command.
  */
 /*
  * Connect to the given ssh server using a proxy command.
  */
@@ -86,7 +103,10 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command)
        char *command_string, *tmp;
        int pin[2], pout[2];
        pid_t pid;
        char *command_string, *tmp;
        int pin[2], pout[2];
        pid_t pid;
-       char strport[NI_MAXSERV];
+       char *shell, strport[NI_MAXSERV];
+
+       if ((shell = getenv("SHELL")) == NULL)
+               shell = _PATH_BSHELL;
 
        /* Convert the port number into a string. */
        snprintf(strport, sizeof strport, "%hu", port);
 
        /* Convert the port number into a string. */
        snprintf(strport, sizeof strport, "%hu", port);
@@ -132,7 +152,7 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command)
 
                /* Stderr is left as it is so that error messages get
                   printed on the user's terminal. */
 
                /* Stderr is left as it is so that error messages get
                   printed on the user's terminal. */
-               argv[0] = _PATH_BSHELL;
+               argv[0] = shell;
                argv[1] = "-c";
                argv[2] = command_string;
                argv[3] = NULL;
                argv[1] = "-c";
                argv[2] = command_string;
                argv[3] = NULL;
@@ -236,7 +256,7 @@ ssh_create_socket(int privileged, struct addrinfo *ai)
        gaierr = getaddrinfo(options.bind_address, "0", &hints, &res);
        if (gaierr) {
                error("getaddrinfo: %s: %s", options.bind_address,
        gaierr = getaddrinfo(options.bind_address, "0", &hints, &res);
        if (gaierr) {
                error("getaddrinfo: %s: %s", options.bind_address,
-                   gai_strerror(gaierr));
+                   ssh_gai_strerror(gaierr));
                close(sock);
                return -1;
        }
                close(sock);
                return -1;
        }
@@ -252,30 +272,36 @@ ssh_create_socket(int privileged, struct addrinfo *ai)
 
 static int
 timeout_connect(int sockfd, const struct sockaddr *serv_addr,
 
 static int
 timeout_connect(int sockfd, const struct sockaddr *serv_addr,
-    socklen_t addrlen, int timeout)
+    socklen_t addrlen, int *timeoutp)
 {
        fd_set *fdset;
 {
        fd_set *fdset;
-       struct timeval tv;
+       struct timeval tv, t_start;
        socklen_t optlen;
        int optval, rc, result = -1;
 
        socklen_t optlen;
        int optval, rc, result = -1;
 
-       if (timeout <= 0)
-               return (connect(sockfd, serv_addr, addrlen));
+       gettimeofday(&t_start, NULL);
+
+       if (*timeoutp <= 0) {
+               result = connect(sockfd, serv_addr, addrlen);
+               goto done;
+       }
 
        set_nonblock(sockfd);
        rc = connect(sockfd, serv_addr, addrlen);
        if (rc == 0) {
                unset_nonblock(sockfd);
 
        set_nonblock(sockfd);
        rc = connect(sockfd, serv_addr, addrlen);
        if (rc == 0) {
                unset_nonblock(sockfd);
-               return (0);
+               result = 0;
+               goto done;
+       }
+       if (errno != EINPROGRESS) {
+               result = -1;
+               goto done;
        }
        }
-       if (errno != EINPROGRESS)
-               return (-1);
 
        fdset = (fd_set *)xcalloc(howmany(sockfd + 1, NFDBITS),
            sizeof(fd_mask));
        FD_SET(sockfd, fdset);
 
        fdset = (fd_set *)xcalloc(howmany(sockfd + 1, NFDBITS),
            sizeof(fd_mask));
        FD_SET(sockfd, fdset);
-       tv.tv_sec = timeout;
-       tv.tv_usec = 0;
+       ms_to_timeval(&tv, *timeoutp);
 
        for (;;) {
                rc = select(sockfd + 1, NULL, fdset, NULL, &tv);
 
        for (;;) {
                rc = select(sockfd + 1, NULL, fdset, NULL, &tv);
@@ -314,6 +340,16 @@ timeout_connect(int sockfd, const struct sockaddr *serv_addr,
        }
 
        xfree(fdset);
        }
 
        xfree(fdset);
+
+ done:
+       if (result == 0 && *timeoutp > 0) {
+               ms_subtract_diff(&t_start, timeoutp);
+               if (*timeoutp <= 0) {
+                       errno = ETIMEDOUT;
+                       result = -1;
+               }
+       }
+
        return (result);
 }
 
        return (result);
 }
 
@@ -330,8 +366,8 @@ timeout_connect(int sockfd, const struct sockaddr *serv_addr,
  */
 int
 ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
  */
 int
 ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
-    u_short port, int family, int connection_attempts,
-    int needpriv, const char *proxy_command)
+    u_short port, int family, int connection_attempts, int *timeout_ms,
+    int want_keepalive, int needpriv, const char *proxy_command)
 {
        int gaierr;
        int on = 1;
 {
        int gaierr;
        int on = 1;
@@ -352,8 +388,8 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
        hints.ai_socktype = SOCK_STREAM;
        snprintf(strport, sizeof strport, "%u", port);
        if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0)
        hints.ai_socktype = SOCK_STREAM;
        snprintf(strport, sizeof strport, "%u", port);
        if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0)
-               fatal("%s: %.100s: %s", __progname, host,
-                   gai_strerror(gaierr));
+               fatal("%s: Could not resolve hostname %.100s: %s", __progname,
+                   host, ssh_gai_strerror(gaierr));
 
        for (attempt = 0; attempt < connection_attempts; attempt++) {
                if (attempt > 0) {
 
        for (attempt = 0; attempt < connection_attempts; attempt++) {
                if (attempt > 0) {
@@ -384,7 +420,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
                                continue;
 
                        if (timeout_connect(sock, ai->ai_addr, ai->ai_addrlen,
                                continue;
 
                        if (timeout_connect(sock, ai->ai_addr, ai->ai_addrlen,
-                           options.connection_timeout) >= 0) {
+                           timeout_ms) >= 0) {
                                /* Successful connection. */
                                memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen);
                                break;
                                /* Successful connection. */
                                memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen);
                                break;
@@ -411,7 +447,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
        debug("Connection established.");
 
        /* Set SO_KEEPALIVE if requested. */
        debug("Connection established.");
 
        /* Set SO_KEEPALIVE if requested. */
-       if (options.tcp_keep_alive &&
+       if (want_keepalive &&
            setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on,
            sizeof(on)) < 0)
                error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
            setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on,
            sizeof(on)) < 0)
                error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
@@ -427,7 +463,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
  * identification string.
  */
 static void
  * identification string.
  */
 static void
-ssh_exchange_identification(void)
+ssh_exchange_identification(int timeout_ms)
 {
        char buf[256], remote_version[256];     /* must be same size! */
        int remote_major, remote_minor, mismatch;
 {
        char buf[256], remote_version[256];     /* must be same size! */
        int remote_major, remote_minor, mismatch;
@@ -435,16 +471,44 @@ ssh_exchange_identification(void)
        int connection_out = packet_get_connection_out();
        int minor1 = PROTOCOL_MINOR_1;
        u_int i, n;
        int connection_out = packet_get_connection_out();
        int minor1 = PROTOCOL_MINOR_1;
        u_int i, n;
+       size_t len;
+       int fdsetsz, remaining, rc;
+       struct timeval t_start, t_remaining;
+       fd_set *fdset;
+
+       fdsetsz = howmany(connection_in + 1, NFDBITS) * sizeof(fd_mask);
+       fdset = xcalloc(1, fdsetsz);
 
        /* Read other side's version identification. */
 
        /* Read other side's version identification. */
+       remaining = timeout_ms;
        for (n = 0;;) {
                for (i = 0; i < sizeof(buf) - 1; i++) {
        for (n = 0;;) {
                for (i = 0; i < sizeof(buf) - 1; i++) {
-                       size_t len = atomicio(read, connection_in, &buf[i], 1);
+                       if (timeout_ms > 0) {
+                               gettimeofday(&t_start, NULL);
+                               ms_to_timeval(&t_remaining, remaining);
+                               FD_SET(connection_in, fdset);
+                               rc = select(connection_in + 1, fdset, NULL,
+                                   fdset, &t_remaining);
+                               ms_subtract_diff(&t_start, &remaining);
+                               if (rc == 0 || remaining <= 0)
+                                       fatal("Connection timed out during "
+                                           "banner exchange");
+                               if (rc == -1) {
+                                       if (errno == EINTR)
+                                               continue;
+                                       fatal("ssh_exchange_identification: "
+                                           "select: %s", strerror(errno));
+                               }
+                       }
+
+                       len = atomicio(read, connection_in, &buf[i], 1);
 
                        if (len != 1 && errno == EPIPE)
 
                        if (len != 1 && errno == EPIPE)
-                               fatal("ssh_exchange_identification: Connection closed by remote host");
+                               fatal("ssh_exchange_identification: "
+                                   "Connection closed by remote host");
                        else if (len != 1)
                        else if (len != 1)
-                               fatal("ssh_exchange_identification: read: %.100s", strerror(errno));
+                               fatal("ssh_exchange_identification: "
+                                   "read: %.100s", strerror(errno));
                        if (buf[i] == '\r') {
                                buf[i] = '\n';
                                buf[i + 1] = 0;
                        if (buf[i] == '\r') {
                                buf[i] = '\n';
                                buf[i + 1] = 0;
@@ -455,7 +519,8 @@ ssh_exchange_identification(void)
                                break;
                        }
                        if (++n > 65536)
                                break;
                        }
                        if (++n > 65536)
-                               fatal("ssh_exchange_identification: No banner received");
+                               fatal("ssh_exchange_identification: "
+                                   "No banner received");
                }
                buf[sizeof(buf) - 1] = 0;
                if (strncmp(buf, "SSH-", 4) == 0)
                }
                buf[sizeof(buf) - 1] = 0;
                if (strncmp(buf, "SSH-", 4) == 0)
@@ -463,6 +528,7 @@ ssh_exchange_identification(void)
                debug("ssh_exchange_identification: %s", buf);
        }
        server_version_string = xstrdup(buf);
                debug("ssh_exchange_identification: %s", buf);
        }
        server_version_string = xstrdup(buf);
+       xfree(fdset);
 
        /*
         * Check that the versions match.  In future this might accept
 
        /*
         * Check that the versions match.  In future this might accept
@@ -975,7 +1041,7 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
  */
 void
 ssh_login(Sensitive *sensitive, const char *orighost,
  */
 void
 ssh_login(Sensitive *sensitive, const char *orighost,
-    struct sockaddr *hostaddr, struct passwd *pw)
+    struct sockaddr *hostaddr, struct passwd *pw, int timeout_ms)
 {
        char *host, *cp;
        char *server_user, *local_user;
 {
        char *host, *cp;
        char *server_user, *local_user;
@@ -990,7 +1056,7 @@ ssh_login(Sensitive *sensitive, const char *orighost,
                        *cp = (char)tolower(*cp);
 
        /* Exchange protocol version identification strings with the server. */
                        *cp = (char)tolower(*cp);
 
        /* Exchange protocol version identification strings with the server. */
-       ssh_exchange_identification();
+       ssh_exchange_identification(timeout_ms);
 
        /* Put the connection into non-blocking mode. */
        packet_set_nonblocking();
 
        /* Put the connection into non-blocking mode. */
        packet_set_nonblocking();
index 42aadb15971e34e3adc6a2d0dcbe6a3de45f7f4d..203e69cbca0b058627a34a32d60e2f5e64886eba 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect2.c,v 1.164 2007/05/17 23:53:41 jolan Exp $ */
+/* $OpenBSD: sshconnect2.c,v 1.165 2008/01/19 23:09:49 djm Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
@@ -170,7 +170,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
 #endif
 
        if (options.rekey_limit)
 #endif
 
        if (options.rekey_limit)
-               packet_set_rekey_limit(options.rekey_limit);
+               packet_set_rekey_limit((u_int32_t)options.rekey_limit);
 
        /* start key exchange */
        kex = kex_setup(myproposal);
 
        /* start key exchange */
        kex = kex_setup(myproposal);
index 12c2cefec6b7e4d6c9db7b38ca0a1c0185a8433d..3bdc05aa20b8dc14a8d0aad638eedc1faba3ca84 100644 (file)
@@ -34,8 +34,8 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
 .\" (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.237 2007/06/07 19:37:34 pvalchev Exp $
-.Dd $Mdocdate: August 16 2007 $
+.\" $OpenBSD: sshd.8,v 1.240 2008/03/26 21:28:14 djm Exp $
+.Dd $Mdocdate: March 27 2008 $
 .Dt SSHD 8
 .Os
 .Sh NAME
 .Dt SSHD 8
 .Os
 .Sh NAME
@@ -531,6 +531,9 @@ This might be used, e.g. in connection with the
 option.
 .It Cm no-pty
 Prevents tty allocation (a request to allocate a pty will fail).
 option.
 .It Cm no-pty
 Prevents tty allocation (a request to allocate a pty will fail).
+.It Cm no-user-rc
+Disables execution of 
+.Pa ~/.ssh/rc .
 .It Cm no-X11-forwarding
 Forbids X11 forwarding when this key is used for authentication.
 Any X11 forward requests by the client will return an error.
 .It Cm no-X11-forwarding
 Forbids X11 forwarding when this key is used for authentication.
 Any X11 forward requests by the client will return an error.
@@ -682,6 +685,13 @@ This file is used in exactly the same way as
 but allows host-based authentication without permitting login with
 rlogin/rsh.
 .Pp
 but allows host-based authentication without permitting login with
 rlogin/rsh.
 .Pp
+.It ~/.ssh/
+This directory is the default location for all user-specific configuration
+and authentication information.
+There is no general requirement to keep the entire contents of this directory
+secret, but the recommended permissions are read/write/execute for the user,
+and not accessible by others.
+.Pp
 .It ~/.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.
 .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.
index 0a3a549f2cc16f2d5891da856219659fc71b1198..f5fd963abe3a45c41825a36513664b54228d3de3 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshd.c,v 1.351 2007/05/22 10:18:52 djm Exp $ */
+/* $OpenBSD: sshd.c,v 1.355 2008/02/14 13:10:31 mbalmer Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -75,6 +75,8 @@
 #include <openssl/bn.h>
 #include <openssl/md5.h>
 #include <openssl/rand.h>
 #include <openssl/bn.h>
 #include <openssl/md5.h>
 #include <openssl/rand.h>
+#include "openbsd-compat/openssl-compat.h"
+
 #ifdef HAVE_SECUREWARE
 #include <sys/security.h>
 #include <prot.h>
 #ifdef HAVE_SECUREWARE
 #include <sys/security.h>
 #include <prot.h>
 #ifdef LIBWRAP
 #include <tcpd.h>
 #include <syslog.h>
 #ifdef LIBWRAP
 #include <tcpd.h>
 #include <syslog.h>
-int allow_severity = LOG_INFO;
-int deny_severity = LOG_WARNING;
+int allow_severity;
+int deny_severity;
 #endif /* LIBWRAP */
 
 #ifndef O_NOCTTY
 #endif /* LIBWRAP */
 
 #ifndef O_NOCTTY
@@ -593,11 +595,12 @@ privsep_preauth_child(void)
 {
        u_int32_t rnd[256];
        gid_t gidset[1];
 {
        u_int32_t rnd[256];
        gid_t gidset[1];
-       int i;
+       u_int i;
 
        /* Enable challenge-response authentication for privilege separation */
        privsep_challenge_enable();
 
 
        /* Enable challenge-response authentication for privilege separation */
        privsep_challenge_enable();
 
+       arc4random_stir();
        for (i = 0; i < 256; i++)
                rnd[i] = arc4random();
        RAND_seed(rnd, sizeof(rnd));
        for (i = 0; i < 256; i++)
                rnd[i] = arc4random();
        RAND_seed(rnd, sizeof(rnd));
@@ -672,6 +675,9 @@ privsep_preauth(Authctxt *authctxt)
 static void
 privsep_postauth(Authctxt *authctxt)
 {
 static void
 privsep_postauth(Authctxt *authctxt)
 {
+       u_int32_t rnd[256];
+       u_int i;
+
 #ifdef DISABLE_FD_PASSING
        if (1) {
 #else
 #ifdef DISABLE_FD_PASSING
        if (1) {
 #else
@@ -703,6 +709,11 @@ privsep_postauth(Authctxt *authctxt)
        /* Demote the private keys to public keys. */
        demote_sensitive_data();
 
        /* Demote the private keys to public keys. */
        demote_sensitive_data();
 
+       arc4random_stir();
+       for (i = 0; i < 256; i++)
+               rnd[i] = arc4random();
+       RAND_seed(rnd, sizeof(rnd));
+
        /* Drop privileges */
        do_setusercontext(authctxt->pw);
 
        /* Drop privileges */
        do_setusercontext(authctxt->pw);
 
@@ -965,8 +976,7 @@ server_listen(void)
                    ntop, sizeof(ntop), strport, sizeof(strport),
                    NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
                        error("getnameinfo failed: %.100s",
                    ntop, sizeof(ntop), strport, sizeof(strport),
                    NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
                        error("getnameinfo failed: %.100s",
-                           (ret != EAI_SYSTEM) ? gai_strerror(ret) :
-                           strerror(errno));
+                           ssh_gai_strerror(ret));
                        continue;
                }
                /* Create socket for listening. */
                        continue;
                }
                /* Create socket for listening. */
@@ -989,6 +999,16 @@ server_listen(void)
                    &on, sizeof(on)) == -1)
                        error("setsockopt SO_REUSEADDR: %s", strerror(errno));
 
                    &on, sizeof(on)) == -1)
                        error("setsockopt SO_REUSEADDR: %s", strerror(errno));
 
+#ifdef IPV6_V6ONLY
+               /* Only communicate in IPv6 over AF_INET6 sockets. */
+               if (ai->ai_family == AF_INET6) {
+                       if (setsockopt(listen_sock, IPPROTO_IPV6, IPV6_V6ONLY,
+                           &on, sizeof(on)) == -1)
+                               error("setsockopt IPV6_V6ONLY: %s",
+                                   strerror(errno));
+               }
+#endif
+
                debug("Bind to port %s on %s.", strport, ntop);
 
                getsockopt(listen_sock, SOL_SOCKET, SO_RCVBUF, 
                debug("Bind to port %s on %s.", strport, ntop);
 
                getsockopt(listen_sock, SOL_SOCKET, SO_RCVBUF, 
@@ -1384,7 +1404,7 @@ main(int ac, char **av)
        }
        if (rexeced_flag || inetd_flag)
                rexec_flag = 0;
        }
        if (rexeced_flag || inetd_flag)
                rexec_flag = 0;
-       if (rexec_flag && (av[0] == NULL || *av[0] != '/'))
+       if (!test_flag && (rexec_flag && (av[0] == NULL || *av[0] != '/')))
                fatal("sshd re-exec requires execution with an absolute path");
        if (rexeced_flag)
                closefrom(REEXEC_MIN_FREE_FD);
                fatal("sshd re-exec requires execution with an absolute path");
        if (rexeced_flag)
                closefrom(REEXEC_MIN_FREE_FD);
@@ -1620,10 +1640,6 @@ main(int ac, char **av)
        /* Get a connection, either from inetd or a listening TCP socket */
        if (inetd_flag) {
                server_accept_inetd(&sock_in, &sock_out);
        /* Get a connection, either from inetd or a listening TCP socket */
        if (inetd_flag) {
                server_accept_inetd(&sock_in, &sock_out);
-
-               if ((options.protocol & SSH_PROTO_1) &&
-                   sensitive_data.server_key == NULL)
-                       generate_ephemeral_server_key();
        } else {
                server_listen();
 
        } else {
                server_listen();
 
@@ -1760,6 +1776,8 @@ main(int ac, char **av)
        audit_connection_from(remote_ip, remote_port);
 #endif
 #ifdef LIBWRAP
        audit_connection_from(remote_ip, remote_port);
 #endif
 #ifdef LIBWRAP
+       allow_severity = options.log_facility|LOG_INFO;
+       deny_severity = options.log_facility|LOG_WARNING;
        /* Check whether logins are denied from this host. */
        if (packet_connection_is_on_socket()) {
                struct request_info req;
        /* Check whether logins are denied from this host. */
        if (packet_connection_is_on_socket()) {
                struct request_info req;
@@ -1854,6 +1872,10 @@ main(int ac, char **av)
        }
 #endif /* AFS || AFS_KRB5 */
 
        }
 #endif /* AFS || AFS_KRB5 */
 
+       /* In inetd mode, generate ephemeral key only for proto 1 connections */
+       if (!compat20 && inetd_flag && sensitive_data.server_key == NULL)
+               generate_ephemeral_server_key();
+
        packet_set_nonblocking();
 
        /* allocate authentication context */
        packet_set_nonblocking();
 
        /* allocate authentication context */
@@ -1906,6 +1928,20 @@ main(int ac, char **av)
        audit_event(SSH_AUTH_SUCCESS);
 #endif
 
        audit_event(SSH_AUTH_SUCCESS);
 #endif
 
+#ifdef GSSAPI
+       if (options.gss_authentication) {
+               temporarily_use_uid(authctxt->pw);
+               ssh_gssapi_storecreds();
+               restore_uid();
+       }
+#endif
+#ifdef USE_PAM
+       if (options.use_pam) {
+               do_pam_setcred(1);
+               do_pam_session();
+       }
+#endif
+
        /*
         * In privilege separation, we fork another child and prepare
         * file descriptor passing.
        /*
         * In privilege separation, we fork another child and prepare
         * file descriptor passing.
index 845e81b5c593cbacd754b1ccb76f584fa143f229..6b584e570eb971051d4dd81d0796e154c4453846 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: sshd_config,v 1.75 2007/03/19 01:01:29 djm Exp $
+#      $OpenBSD: sshd_config,v 1.77 2008/02/08 23:24:07 djm Exp $
 
 # This is the sshd server system-wide configuration file.  See
 # sshd_config(5) for more information.
 
 # This is the sshd server system-wide configuration file.  See
 # sshd_config(5) for more information.
@@ -109,9 +109,10 @@ Protocol 2
 #PidFile /var/run/sshd.pid
 #MaxStartups 10
 #PermitTunnel no
 #PidFile /var/run/sshd.pid
 #MaxStartups 10
 #PermitTunnel no
+#ChrootDirectory none
 
 # no default banner path
 
 # no default banner path
-#Banner /some/path
+#Banner none
 
 # override default of no subsystems
 Subsystem      sftp    /usr/libexec/sftp-server
 
 # override default of no subsystems
 Subsystem      sftp    /usr/libexec/sftp-server
index 15af4a817480f9a02c0e4f14d5487c896ae0b93d..e07eb3b1e3dd03b7a4b131fc0b33214509554464 100644 (file)
@@ -34,8 +34,8 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
 .\" (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.77 2007/06/08 07:48:09 jmc Exp $
-.Dd $Mdocdate: June 11 2007 $
+.\" $OpenBSD: sshd_config.5,v 1.84 2008/03/25 11:58:02 djm Exp $
+.Dd $Mdocdate: March 27 2008 $
 .Dt SSHD_CONFIG 5
 .Os
 .Sh NAME
 .Dt SSHD_CONFIG 5
 .Os
 .Sh NAME
@@ -159,10 +159,11 @@ directory.
 The default is
 .Dq .ssh/authorized_keys .
 .It Cm Banner
 The default is
 .Dq .ssh/authorized_keys .
 .It Cm Banner
-In some jurisdictions, sending a warning message before authentication
-may be relevant for getting legal protection.
 The contents of the specified file are sent to the remote user before
 authentication is allowed.
 The contents of the specified file are sent to the remote user before
 authentication is allowed.
+If the argument is
+.Dq none
+then no banner is displayed.
 This option is only available for protocol version 2.
 By default, no banner is displayed.
 .It Cm ChallengeResponseAuthentication
 This option is only available for protocol version 2.
 By default, no banner is displayed.
 .It Cm ChallengeResponseAuthentication
@@ -172,6 +173,45 @@ All authentication styles from
 are supported.
 The default is
 .Dq yes .
 are supported.
 The default is
 .Dq yes .
+.It Cm ChrootDirectory
+Specifies a path to
+.Xr chroot 2
+to after authentication.
+This path, and all its components, must be root-owned directories that are
+not writable by any other user or group.
+.Pp
+The path may contain the following tokens that are expanded at runtime once
+the connecting user has been authenticated: %% is replaced by a literal '%',
+%h is replaced by the home directory of the user being authenticated, and
+%u is replaced by the username of that user.
+.Pp
+The
+.Cm ChrootDirectory
+must contain the necessary files and directories to support the
+users' session.
+For an interactive session this requires at least a shell, typically
+.Xr sh 1 ,
+and basic
+.Pa /dev
+nodes such as
+.Xr null 4 ,
+.Xr zero 4 ,
+.Xr stdin 4 ,
+.Xr stdout 4 ,
+.Xr stderr 4 ,
+.Xr arandom 4
+and
+.Xr tty 4
+devices.
+For file transfer sessions using
+.Dq sftp ,
+no additional configuration of the environment is necessary if the
+in-process sftp server is used (see
+.Cm Subsystem
+for details).
+.Pp
+The default is not to
+.Xr chroot 2 .
 .It Cm Ciphers
 Specifies the ciphers allowed for protocol version 2.
 Multiple ciphers must be comma-separated.
 .It Cm Ciphers
 Specifies the ciphers allowed for protocol version 2.
 Multiple ciphers must be comma-separated.
@@ -284,7 +324,9 @@ for more information on patterns.
 .It Cm ForceCommand
 Forces the execution of the command specified by
 .Cm ForceCommand ,
 .It Cm ForceCommand
 Forces the execution of the command specified by
 .Cm ForceCommand ,
-ignoring any command supplied by the client.
+ignoring any command supplied by the client and
+.Pa ~/.ssh/rc
+if present.
 The command is invoked by using the user's login shell with the -c option.
 This applies to shell, command, or subsystem execution.
 It is most useful inside a
 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
@@ -293,6 +335,11 @@ block.
 The command originally supplied by the client is available in the
 .Ev SSH_ORIGINAL_COMMAND
 environment variable.
 The command originally supplied by the client is available in the
 .Ev SSH_ORIGINAL_COMMAND
 environment variable.
+Specifying a command of
+.Dq internal-sftp
+will force the use of an in-process sftp server that requires no support
+files when used with
+.Cm ChrootDirectory .
 .It Cm GatewayPorts
 Specifies whether remote hosts are allowed to connect to ports
 forwarded for the client.
 .It Cm GatewayPorts
 Specifies whether remote hosts are allowed to connect to ports
 forwarded for the client.
@@ -562,6 +609,7 @@ Available keywords are
 .Cm KerberosAuthentication ,
 .Cm PasswordAuthentication ,
 .Cm PermitOpen ,
 .Cm KerberosAuthentication ,
 .Cm PasswordAuthentication ,
 .Cm PermitOpen ,
+.Cm PermitRootLogin ,
 .Cm RhostsRSAAuthentication ,
 .Cm RSAAuthentication ,
 .Cm X11DisplayOffset ,
 .Cm RhostsRSAAuthentication ,
 .Cm RSAAuthentication ,
 .Cm X11DisplayOffset ,
@@ -777,11 +825,22 @@ The default is
 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.
 Configures an external subsystem (e.g. file transfer daemon).
 Arguments should be a subsystem name and a command (with optional arguments)
 to execute upon subsystem request.
+.Pp
 The command
 .Xr sftp-server 8
 implements the
 .Dq sftp
 file transfer subsystem.
 The command
 .Xr sftp-server 8
 implements the
 .Dq sftp
 file transfer subsystem.
+.Pp
+Alternately the name
+.Dq internal-sftp
+implements an in-process
+.Dq sftp
+server.
+This may simplify configurations using
+.Cm ChrootDirectory
+to force a different filesystem root on clients.
+.Pp
 By default no subsystems are defined.
 Note that this option applies to protocol version 2 only.
 .It Cm SyslogFacility
 By default no subsystems are defined.
 Note that this option applies to protocol version 2 only.
 .It Cm SyslogFacility
index df822813d6606262d4e54ceafd05092dbc345b5e..a8021b99707f996f720c69775b6ab6d466ca2ed3 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: version.h,v 1.50 2007/08/15 08:16:49 markus Exp $ */
+/* $OpenBSD: version.h,v 1.52 2008/03/27 00:16:49 djm Exp $ */
 
 #ifdef GSI
 #define GSI_VERSION    " GSI"
 
 #ifdef GSI
 #define GSI_VERSION    " GSI"
@@ -18,9 +18,9 @@
 #define MGLUE_VERSION  ""
 #endif
 
 #define MGLUE_VERSION  ""
 #endif
 
-#define NCSA_VERSION   " NCSA_GSSAPI_20080313"
+#define NCSA_VERSION   " NCSA_GSSAPI_20080401"
 
 
-#define SSH_VERSION    "OpenSSH_4.7"
+#define SSH_VERSION    "OpenSSH_4.9"
 
 #define SSH_PORTABLE   "p1"
 #define SSH_HPN         "-hpn13v1"
 
 #define SSH_PORTABLE   "p1"
 #define SSH_HPN         "-hpn13v1"
This page took 0.343005 seconds and 5 git commands to generate.