]> 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 \
-       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
@@ -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)
 
-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)
@@ -406,7 +406,7 @@ uninstall:
        -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 ]  || \
@@ -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_PLINK="plink"; \
+       TEST_SSH_PUTTYGEN="puttygen"; \
        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_PLINK="$${TEST_SSH_PLINK}" \
+               TEST_SSH_PUTTYGEN="$${TEST_SSH_PUTTYGEN}" \
                EXEEXT="$(EXEEXT)" \
                $@
 
index 62ee40282d7233aca67b8d903a1eb5ee1430e068..575bf8900ee39e9e3cb89061934b659bd87b52d6 100644 (file)
 #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>
index a07f1fe77d86e7290209ffcbf8346bf97b9786a2..ccdb9937e364af74197f31a1a1f62ab0feaabb52 100644 (file)
@@ -598,15 +598,17 @@ static struct pam_conv store_conv = { sshpam_store_conv, NULL };
 void
 sshpam_cleanup(void)
 {
-       debug("PAM: cleanup");
-       if (sshpam_handle == NULL)
+       if (sshpam_handle == NULL || (use_privsep && !mm_is_monitor()))
                return;
+       debug("PAM: cleanup");
        pam_set_item(sshpam_handle, PAM_CONV, (const void *)&null_conv);
        if (sshpam_cred_established) {
+               debug("PAM: deleting credentials");
                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;
        }
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.
  *
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.
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
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.
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.
  *
@@ -32,6 +32,7 @@
 #include <fcntl.h>
 #include <stdarg.h>
 #include <unistd.h>
+#include <string.h>
 
 #include "xmalloc.h"
 #include "key.h"
@@ -106,7 +107,9 @@ userauth_banner(void)
 {
        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)
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.
  *
@@ -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);
-int user_key_allowed(struct passwd *, Key *);
 
 /*
  * 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
@@ -34,6 +34,7 @@
 #include "packet.h"
 #include "log.h"
 #include "canohost.h"
+#include "misc.h"
 
 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,
-                   r == EAI_SYSTEM ? strerror(errno) : gai_strerror(r));
+                   ssh_gai_strerror(r));
                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",
-                   r == EAI_SYSTEM ? strerror(errno) : gai_strerror(r));
+                   ssh_gai_strerror(r));
        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
@@ -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) &&
-                   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;
@@ -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",
-                           gai_strerror(r));
+                           ssh_gai_strerror(r));
                } else {
                        error("channel_setup_fwd_listener: "
-                           "getaddrinfo(%.64s): %s", addr, gai_strerror(r));
+                           "getaddrinfo(%.64s): %s", addr,
+                           ssh_gai_strerror(r));
                }
                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,
-                   gai_strerror(gaierr));
+                   ssh_gai_strerror(gaierr));
                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) {
-                       error("getaddrinfo: %.100s", gai_strerror(gaierr));
+                       error("getaddrinfo: %.100s", ssh_gai_strerror(gaierr));
                        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) {
-               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) {
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
@@ -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 server_alive_timeouts = 0;
 
 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)
 {
-       server_alive_timeouts = 0;
+       keep_alive_timeouts = 0;
        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);
        }
@@ -722,7 +721,7 @@ client_process_control(fd_set *readset)
        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;
 
@@ -870,9 +869,23 @@ client_process_control(fd_set *readset)
        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]);
@@ -944,6 +957,9 @@ process_cmdline(void)
        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);
@@ -1044,6 +1060,10 @@ out:
        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 */
@@ -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,
-           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",
@@ -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,
-           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",
index 2cccf746dc623798f3a4b2a27d598689b35f95fc..bb82bc717b9859f65fcb91ddcabda2fe5a7eb89e 100644 (file)
@@ -90,6 +90,13 @@ AC_C_INLINE
 
 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}'`
@@ -105,6 +112,44 @@ if test "$GCC" = "yes" || test "$GCC" = "egcs"; then
                *) ;;
        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
@@ -223,6 +268,7 @@ AC_CHECK_HEADERS( \
        sys/dir.h \
        sys/mman.h \
        sys/ndir.h \
+       sys/poll.h \
        sys/prctl.h \
        sys/pstat.h \
        sys/select.h \
@@ -343,7 +389,7 @@ int main(void) { exit(0); }
                [],
                [#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]),
            [],
@@ -397,6 +443,7 @@ int main(void) { exit(0); }
        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])
@@ -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])
+       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);],
@@ -428,7 +480,7 @@ int main(void) { exit(0); }
                fi],
                [AC_MSG_RESULT(no)]
        )
-       ;;
+       ;;
 *-*-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(BROKEN_GLOB, 1, [FreeBSD glob does not do what we need])
        ;;
 *-*-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(BROKEN_SHADOW_EXPIRE, 1, [QNX shadow support is broken])
        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_addr)
+               AC_CHECK_FUNCS(getaudit_addr aug_get_machine)
                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"
-       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"
 
@@ -3367,7 +3424,7 @@ int main() { return 0; }
 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.])
@@ -3594,32 +3651,6 @@ else
        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`
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_keep_above(GTK_WINDOW(dialog), 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
 
+#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
@@ -567,11 +571,6 @@ struct winsize {
 # 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__)
@@ -698,9 +697,11 @@ struct winsize {
 # 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
-# define CUSTOM_SYS_AUTH_PASSWD 1
 #endif
 
 /* HP-UX 11.11 */
index 06b15d65c1617a74f33b32881ef587e91889031e..1fce541408a15eb8fc43dcc81d0d65bd36cf6882 100644 (file)
@@ -38,6 +38,7 @@
 #include <sys/types.h>
 
 #include <openssl/evp.h>
+#include <openbsd-compat/openssl-compat.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.
@@ -42,6 +42,7 @@
 
 #include <errno.h>
 #include <fcntl.h>
+#include <netdb.h>
 #ifdef HAVE_PATHS_H
 # include <paths.h>
 #include <pwd.h>
@@ -120,6 +121,14 @@ unset_nonblock(int fd)
        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)
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>
@@ -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);
+
+ out:
        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);
 
@@ -1351,8 +1351,9 @@ mm_answer_pty(int sock, Buffer *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)
@@ -1583,6 +1584,11 @@ mm_answer_term(int sock, Buffer *req)
        /* 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);
@@ -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) 
-               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) {
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.
@@ -40,7 +40,7 @@
 #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))
@@ -49,7 +49,11 @@ mm_send_fd(int sock, int fd)
        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
 
@@ -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_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;
@@ -72,15 +76,21 @@ mm_send_fd(int sock, int fd)
        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));
-       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);
+               return -1;
+       }
+       return 0;
 #else
-       fatal("%s: UsePrivilegeSeparation=yes not supported",
-           __func__);
+       error("%s: file descriptor passing not supported", __func__);
+       return -1;
 #endif
 }
 
@@ -94,7 +104,10 @@ mm_receive_fd(int sock)
        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
 
@@ -107,33 +120,43 @@ mm_receive_fd(int sock)
        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
 
-       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);
+               return -1;
+       }
 
 #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);
-       if (cmsg == NULL)
-               fatal("%s: no message header", __func__);
+       if (cmsg == NULL) {
+               error("%s: no message header", __func__);
+               return -1;
+       }
 #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);
+               return -1;
+       }
 #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
 }
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>
@@ -28,7 +28,7 @@
 #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_ */
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>
@@ -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) {
-               buffer_free(&m);
-               return (NULL);
+               pw = NULL;
+               goto out;
        }
        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);
 
+out:
        /* 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);
 
-       *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);
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)
-#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 */
 
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.
@@ -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,
-           T_SIG);
+           T_RRSIG);
 
        /* 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 &&
-                   rr->type  == T_SIG)
+                   rr->type  == T_RRSIG)
                        rdata = &rrset->rri_sigs[index_sig++];
 
                if (rdata) {
index 39995b63fc0333b9383565d6de4e3720ab04e802..1283f55062e0cc5ebdb323cb68c4b02d125d2be5 100644 (file)
@@ -62,8 +62,8 @@
 #define HFIXEDSZ 12
 #endif
 
-#ifndef T_SIG
-#define T_SIG 24
+#ifndef T_RRSIG
+#define T_RRSIG 46
 #endif
 
 /*
index 0723e98deb456c0fa7547998528f50cddf84ecdf..fd578f2acbade6600dd69d33c8c23600aa70ede3 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *
  * 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
@@ -395,4 +395,47 @@ sshaix_getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
 }
 # 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 */
index eae82a9e0858549faec39a3021f16002e6fb1bb9..147ad0b35aefed289f29671b00f92ea85d10c6f5 100644 (file)
@@ -3,7 +3,7 @@
 /*
  *
  * 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
@@ -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
 
+/*
+ * 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 */
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 $       */
 
 /*
  * 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.
  */
@@ -229,13 +235,14 @@ struct {                                                          \
 #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;                \
-               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;             \
+               _Q_INVALIDATE((elm)->field.sle_next);                   \
        }                                                               \
 } 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;                   \
+       _Q_INVALIDATE((elm)->field.le_prev);                            \
+       _Q_INVALIDATE((elm)->field.le_next);                            \
 } 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);                                \
+       _Q_INVALIDATE((elm)->field.le_prev);                            \
+       _Q_INVALIDATE((elm)->field.le_next);                            \
 } while (0)
 
 /*
@@ -369,8 +380,8 @@ struct {                                                            \
        (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)
 
@@ -465,6 +476,8 @@ struct {                                                            \
        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 {                     \
@@ -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);                               \
+       _Q_INVALIDATE((elm)->field.tqe_prev);                           \
+       _Q_INVALIDATE((elm)->field.tqe_next);                           \
 } while (0)
 
 /*
@@ -575,6 +590,8 @@ struct {                                                            \
        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 {                   \
@@ -588,6 +605,8 @@ struct {                                                            \
                (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_ */
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.
@@ -289,7 +289,7 @@ void name##_SPLAY_MINMAX(struct name *head, int __comp) \
             (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 */                   \
@@ -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_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
@@ -626,7 +626,7 @@ name##_RB_FIND(struct name *head, struct type *elm)                 \
 }                                                                      \
                                                                        \
 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);                             \
@@ -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_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;                                               \
-            (x) = name##_RB_NEXT(head, x))
+            (x) = name##_RB_NEXT(x))
 
 #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
@@ -136,6 +136,8 @@ static int server_side = 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 {
@@ -1197,10 +1199,12 @@ packet_read_poll_seqnr(u_int32_t *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:
+                               debug3("Received SSH2_MSG_IGNORE");
                                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>
@@ -90,6 +90,7 @@ void   tty_make_modes(int, struct termios *);
 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
 
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
@@ -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;
+       LogLevel *log_level_ptr;
        long long orig, val64;
        size_t len;
        Forward fwd;
@@ -551,7 +552,6 @@ parse_yesnoask:
                goto parse_int;
 
        case oRekeyLimit:
-               intptr = &options->rekey_limit;
                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 */
-               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);
-               if (*activep && *intptr == -1)
-                       *intptr = (int)val64;
+               if (*activep && options->rekey_limit == -1)
+                       options->rekey_limit = (u_int32_t)val64;
                break;
 
        case oIdentityFile:
@@ -749,14 +749,14 @@ parse_int:
                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>");
-               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:
@@ -1347,7 +1347,7 @@ parse_forward(Forward *fwd, const char *fwdspec)
 
        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 &&
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>
@@ -109,7 +109,7 @@ typedef struct {
        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;
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).
 #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
 
 extern char *__progname;
 
+#define COPY_BUFLEN    16384
+
 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 *[]);
+size_t scpio(ssize_t (*)(int, void *, size_t), int, void *, size_t, off_t *);
 void usage(void);
 
 int
@@ -441,6 +451,43 @@ main(int argc, char **argv)
        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)
 {
@@ -583,7 +630,6 @@ source(int argc, char **argv)
        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;
@@ -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",
-                           (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;
@@ -645,7 +697,7 @@ syserr:                     run_err("%s: %s", name, strerror(errno));
                (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;
@@ -654,27 +706,25 @@ next:                     if (fd != -1) {
                }
                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) {
-                               result = atomicio(read, fd, bp->buf, amt);
-                               if (result != amt)
+                               if (atomicio(read, fd, bp->buf, amt) != amt)
                                        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();
 
@@ -780,10 +830,10 @@ bwlimit(int amount)
                        thresh /= 2;
                        if (thresh < 2048)
                                thresh = 2048;
-               } else if (bwend.tv_usec < 100) {
+               } else if (bwend.tv_usec < 10000) {
                        thresh *= 2;
-                       if (thresh > 32768)
-                               thresh = 32768;
+                       if (thresh > COPY_BUFLEN * 4)
+                               thresh = COPY_BUFLEN * 4;
                }
 
                TIMEVAL_TO_TIMESPEC(&bwend, &ts);
@@ -974,7 +1024,7 @@ bad:                       run_err("%s: %s", np, strerror(errno));
                        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;
                }
@@ -984,26 +1034,24 @@ bad:                     run_err("%s: %s", np, strerror(errno));
                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 {
-                               j = atomicio(read, remin, cp, amt);
+                               j = scpio(read, remin, cp, amt, &statbytes);
                                if (j == 0) {
-                                       run_err("%s", j ? strerror(errno) :
+                                       run_err("%s", j != EPIPE ?
+                                           strerror(errno) :
                                            "dropped connection");
                                        exit(1);
                                }
                                amt -= j;
                                cp += j;
-                               statbytes += j;
                        } while (amt > 0);
 
-                       if (limit_rate)
-                               bwlimit(sizeof(buf));
-
                        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;
                        }
                }
+               unset_nonblock(remin);
                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
@@ -130,6 +130,7 @@ initialize_server_options(ServerOptions *options)
        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;
@@ -351,12 +352,13 @@ typedef enum {
        sBanner, sUseDNS, sHostbasedAuthentication,
        sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
        sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
-       sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
+       sGssAuthentication, sGssCleanupCreds,
+    sGssStrictAcceptor,
        sGssKeyEx, 
     sGssCredsPath,
        sGsiAllowLimitedProxy,
     sAcceptEnv, sPermitTunnel,
-       sMatch, sPermitOpen, sForceCommand,
+       sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
        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 },
-       { "permitrootlogin", sPermitRootLogin, SSHCFG_GLOBAL },
+       { "permitrootlogin", sPermitRootLogin, SSHCFG_ALL },
        { "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 },
+       { "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
         { "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>",
-                   gai_strerror(gaierr));
+                   ssh_gai_strerror(gaierr));
        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;
+       SyslogFacility *log_facility_ptr;
+       LogLevel *log_level_ptr;
        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);
-               if (*intptr == -1)
+               if (*activep && *intptr == -1)
                        *intptr = value;
                break;
 
@@ -1113,25 +1118,25 @@ parse_flag:
                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>");
-               if (*intptr == -1)
-                       *intptr = (SyslogFacility) value;
+               if (*log_facility_ptr == -1)
+                       *log_facility_ptr = (SyslogFacility) value;
                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>");
-               if (*intptr == -1)
-                       *intptr = (LogLevel) value;
+               if (*log_level_ptr == -1)
+                       *log_level_ptr = (LogLevel) value;
                break;
 
        case sAllowTcpForwarding:
@@ -1282,6 +1287,7 @@ parse_flag:
        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:
@@ -1390,6 +1396,17 @@ parse_flag:
                        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);
@@ -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(permit_root_login);
 
        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);
+       M_CP_STROPT(chroot_directory);
 }
 
 #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>
@@ -36,6 +36,9 @@
 
 #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;
@@ -154,6 +157,8 @@ typedef struct {
        int     permit_tun;
 
        int     num_permitted_opens;
+
+       char   *chroot_directory;
 }       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
@@ -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 client_alive_timeouts = 0;
 
 /*
  * 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 */
-       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);
        }
@@ -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.
         */
-       client_alive_timeouts = 0;
+       keep_alive_timeouts = 0;
 }
 
 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
 #include "sshlogin.h"
 #include "serverloop.h"
 #include "canohost.h"
+#include "misc.h"
 #include "session.h"
 #include "kex.h"
 #include "monitor_wrap.h"
+#include "sftp.h"
 
 #if defined(KRB5) && defined(USE_AFS)
 #include <kafs.h>
@@ -134,9 +136,13 @@ extern Buffer loginmsg;
 const char *original_command = NULL;
 
 /* data */
-#define MAX_SESSIONS 10
+#define MAX_SESSIONS 20
 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
@@ -444,11 +450,6 @@ do_exec_no_pty(Session *s, const char *command)
 
        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;
@@ -579,14 +580,6 @@ do_exec_pty(Session *s, const char *command)
        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;
@@ -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 (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;
+               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);
        }
 
@@ -743,7 +744,6 @@ do_exec(Session *s, const char *command)
                PRIVSEP(audit_run_command(shell));
        }
 #endif
-
        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 (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,
@@ -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;
 
-       /* 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)
@@ -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)
 {
+       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 */
@@ -1470,21 +1534,13 @@ do_setusercontext(struct passwd *pw)
 # 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) {
-                       do_pam_session();
                        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);
                }
@@ -1507,13 +1563,6 @@ do_setusercontext(struct passwd *pw)
                        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.
@@ -1521,21 +1570,39 @@ do_setusercontext(struct passwd *pw)
                 * 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);
-#  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 USE_LIBIAF
+# ifdef USE_LIBIAF
                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
@@ -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.
  */
+#define ARGV_MAX 10
 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;
 
@@ -1812,12 +1880,30 @@ do_child(Session *s, const char *command)
 #endif
        }
 
+       closefrom(STDERR_FILENO + 1);
+
        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 */
@@ -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 (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;
+                       } else {
+                               s->is_subsystem = SUBSYSTEM_EXT;
                        }
                        debug("subsystem: exec() %s", cmd);
-                       s->is_subsystem = 1;
                        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
-               packet_put_char(WCOREDUMP(status));
+               packet_put_char(WCOREDUMP(status)? 1 : 0);
 #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>
  *
@@ -26,6 +26,7 @@
 #include <sys/socket.h>
 #include <sys/wait.h>
 
+#include <ctype.h>
 #include <errno.h>
 
 #ifdef HAVE_PATHS_H
@@ -346,144 +347,78 @@ infer_path(const char *p, char **ifp)
 }
 
 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:
-                       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
-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
@@ -498,17 +433,6 @@ is_dir(char *path)
        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)
 {
@@ -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;
+       struct stat sb;
 
        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);
-       if (glob(src, 0, NULL, &g)) {
+       if (glob(src, GLOB_NOCHECK, NULL, &g)) {
                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++) {
-               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;
@@ -866,15 +797,189 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path,
        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;
-       char *cp2;
+       char *cp2, **argv;
        int base = 0;
        long l;
-       int i, cmdnum;
+       int i, cmdnum, optidx, argc;
 
        /* Skip leading whitespace */
        cp = cp + strspn(cp, WHITESPACE);
@@ -890,17 +995,13 @@ parse_args(const char **cpp, int *pflag, int *lflag, int *iflag,
                cp++;
        }
 
+       if ((argv = makeargv(cp, &argc)) == NULL)
+               return -1;
+
        /* 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;
-               }
        }
        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.");
-               return (-1);
+               return -1;
        }
 
        /* Get arguments and parse flags */
        *lflag = *pflag = *n_arg = 0;
        *path1 = *path2 = NULL;
+       optidx = 1;
        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) */
-               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);
-                       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:
-               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);
-                       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:
@@ -953,59 +1058,57 @@ parse_args(const char **cpp, int *pflag, int *lflag, int *iflag,
        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);
-                       return(-1);
+                       return -1;
                }
+               *path1 = xstrdup(argv[optidx]);
+               /* Only "rm" globs */
+               if (cmdnum != I_RM)
+                       undo_glob_escape(*path1);
                break;
        case I_LS:
-               if (parse_ls_flags(&cp, lflag))
+               if ((optidx = parse_ls_flags(argv, argc, lflag)) == -1)
                        return(-1);
                /* Path is optional */
-               if (get_pathname(&cp, path1))
-                       return(-1);
+               if (argc - optidx > 0)
+                       *path1 = xstrdup(argv[optidx]);
                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:
-               base = 8;
        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;
-               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);
-                       return(-1);
+                       return -1;
                }
-               cp = cp2;
                *n_arg = l;
-               if (cmdnum == I_LUMASK && strchr(WHITESPACE, *cp))
+               if (cmdnum == I_LUMASK)
                        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) */
-               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);
-                       return(-1);
+                       return -1;
                }
+               *path1 = xstrdup(argv[optidx + 1]);
                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
@@ -51,6 +51,7 @@
 
 #include <openssl/evp.h>
 #include <openssl/md5.h>
+#include "openbsd-compat/openssl-compat.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);
+       Identity *id;
        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 (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->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);
-               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,
@@ -1016,7 +1018,7 @@ check_parent_exists(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");
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>.
  *
@@ -410,7 +410,7 @@ tcpconnect(char *host)
        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) {
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.
 .\"
-.\" $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
@@ -506,7 +506,7 @@ This can be specified on a
 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
@@ -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
+.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
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
@@ -72,6 +72,7 @@
 
 #include <openssl/evp.h>
 #include <openssl/err.h>
+#include "openbsd-compat/openssl-compat.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;
-       int dummy;
+       int dummy, timeout_ms;
        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;
+               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);
@@ -510,13 +518,6 @@ main(int ac, char **av)
                                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;
@@ -688,11 +689,15 @@ main(int ac, char **av)
        }
 
        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;
+       }
        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;
+       }
 
        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);
+               xfree(options.control_path);
                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);
 
+       timeout_ms = options.connection_timeout * 1000;
+
        /* 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
@@ -722,6 +731,9 @@ main(int ac, char **av)
            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
@@ -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. */
-       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) {
@@ -1021,6 +1034,11 @@ ssh_session(void)
        /* 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)
@@ -1313,6 +1331,7 @@ static void
 load_public_identity_files(void)
 {
        char *filename, *cp, thishost[NI_MAXHOST];
+       char *pwdir = NULL, *pwname = NULL;
        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");
+       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);
-               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);
@@ -1358,6 +1379,10 @@ load_public_identity_files(void)
                options.identity_files[i] = filename;
                options.identity_keys[i] = public;
        }
+       bzero(pwname, strlen(pwname));
+       xfree(pwname);
+       bzero(pwdir, strlen(pwdir));
+       xfree(pwdir);
 }
 
 static void
@@ -1369,8 +1394,12 @@ control_client_sighandler(int signo)
 static void
 control_client_sigrelay(int signo)
 {
+       int save_errno = errno;
+
        if (control_server_pid > 1)
                kill(control_server_pid, signo);
+
+       errno = save_errno;
 }
 
 static int
@@ -1464,6 +1493,8 @@ control_client(const char *path)
        if (options.forward_agent)
                flags |= SSHMUX_FLAG_AGENT_FWD;
 
+       signal(SIGPIPE, SIG_IGN);
+
        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__);
 
-       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);
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.
 .\"
-.\" $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
@@ -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 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.
@@ -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
-.Pa /bin/sh .
+the user's shell.
 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
-.Pa /bin/sh .
+the user's shell.
 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
@@ -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 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.
  */
@@ -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 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);
@@ -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. */
-               argv[0] = _PATH_BSHELL;
+               argv[0] = shell;
                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,
-                   gai_strerror(gaierr));
+                   ssh_gai_strerror(gaierr));
                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,
-    socklen_t addrlen, int timeout)
+    socklen_t addrlen, int *timeoutp)
 {
        fd_set *fdset;
-       struct timeval tv;
+       struct timeval tv, t_start;
        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);
-               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);
-       tv.tv_sec = timeout;
-       tv.tv_usec = 0;
+       ms_to_timeval(&tv, *timeoutp);
 
        for (;;) {
                rc = select(sockfd + 1, NULL, fdset, NULL, &tv);
@@ -314,6 +340,16 @@ timeout_connect(int sockfd, const struct sockaddr *serv_addr,
        }
 
        xfree(fdset);
+
+ done:
+       if (result == 0 && *timeoutp > 0) {
+               ms_subtract_diff(&t_start, timeoutp);
+               if (*timeoutp <= 0) {
+                       errno = ETIMEDOUT;
+                       result = -1;
+               }
+       }
+
        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,
-    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;
@@ -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)
-               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) {
@@ -384,7 +420,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
                                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;
@@ -411,7 +447,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
        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));
@@ -427,7 +463,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
  * 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;
@@ -435,16 +471,44 @@ ssh_exchange_identification(void)
        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. */
+       remaining = timeout_ms;
        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)
-                               fatal("ssh_exchange_identification: Connection closed by remote host");
+                               fatal("ssh_exchange_identification: "
+                                   "Connection closed by remote host");
                        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;
@@ -455,7 +519,8 @@ ssh_exchange_identification(void)
                                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)
@@ -463,6 +528,7 @@ ssh_exchange_identification(void)
                debug("ssh_exchange_identification: %s", buf);
        }
        server_version_string = xstrdup(buf);
+       xfree(fdset);
 
        /*
         * 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,
-    struct sockaddr *hostaddr, struct passwd *pw)
+    struct sockaddr *hostaddr, struct passwd *pw, int timeout_ms)
 {
        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. */
-       ssh_exchange_identification();
+       ssh_exchange_identification(timeout_ms);
 
        /* 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.
  *
@@ -170,7 +170,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
 #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);
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.
 .\"
-.\" $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
@@ -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).
+.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.
@@ -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
+.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.
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
@@ -75,6 +75,8 @@
 #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 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
@@ -593,11 +595,12 @@ privsep_preauth_child(void)
 {
        u_int32_t rnd[256];
        gid_t gidset[1];
-       int i;
+       u_int i;
 
        /* 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));
@@ -672,6 +675,9 @@ privsep_preauth(Authctxt *authctxt)
 static void
 privsep_postauth(Authctxt *authctxt)
 {
+       u_int32_t rnd[256];
+       u_int i;
+
 #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();
 
+       arc4random_stir();
+       for (i = 0; i < 256; i++)
+               rnd[i] = arc4random();
+       RAND_seed(rnd, sizeof(rnd));
+
        /* 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",
-                           (ret != EAI_SYSTEM) ? gai_strerror(ret) :
-                           strerror(errno));
+                           ssh_gai_strerror(ret));
                        continue;
                }
                /* Create socket for listening. */
@@ -989,6 +999,16 @@ server_listen(void)
                    &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, 
@@ -1384,7 +1404,7 @@ main(int ac, char **av)
        }
        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);
@@ -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);
-
-               if ((options.protocol & SSH_PROTO_1) &&
-                   sensitive_data.server_key == NULL)
-                       generate_ephemeral_server_key();
        } else {
                server_listen();
 
@@ -1760,6 +1776,8 @@ main(int ac, char **av)
        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;
@@ -1854,6 +1872,10 @@ main(int ac, char **av)
        }
 #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 */
@@ -1906,6 +1928,20 @@ main(int ac, char **av)
        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.
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.
@@ -109,9 +109,10 @@ Protocol 2
 #PidFile /var/run/sshd.pid
 #MaxStartups 10
 #PermitTunnel no
+#ChrootDirectory none
 
 # no default banner path
-#Banner /some/path
+#Banner none
 
 # 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.
 .\"
-.\" $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
@@ -159,10 +159,11 @@ directory.
 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.
+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
@@ -172,6 +173,45 @@ All authentication styles from
 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.
@@ -284,7 +324,9 @@ for more information on patterns.
 .It Cm ForceCommand
 Forces the execution of the command specified by
 .Cm ForceCommand ,
-ignoring any command supplied by the client.
+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
@@ -293,6 +335,11 @@ block.
 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.
@@ -562,6 +609,7 @@ Available keywords are
 .Cm KerberosAuthentication ,
 .Cm PasswordAuthentication ,
 .Cm PermitOpen ,
+.Cm PermitRootLogin ,
 .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.
+.Pp
 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
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"
@@ -18,9 +18,9 @@
 #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"
This page took 2.334366 seconds and 5 git commands to generate.