]> andersk Git - gssapi-openssh.git/commitdiff
merged OpenSSH 5.3p1 to trunk OPENSSH_5_3P1_GSSAPI_20091001
authorbasney <basney>
Thu, 1 Oct 2009 21:24:13 +0000 (21:24 +0000)
committerbasney <basney>
Thu, 1 Oct 2009 21:24:13 +0000 (21:24 +0000)
47 files changed:
openssh/Makefile.in
openssh/README.platform
openssh/auth-pam.c
openssh/auth1.c
openssh/auth2-kbdint.c
openssh/auth2-none.c
openssh/auth2-passwd.c
openssh/auth2-pubkey.c
openssh/auth2.c
openssh/canohost.c
openssh/canohost.h
openssh/channels.c
openssh/clientloop.c
openssh/configure.ac
openssh/contrib/aix/buildbff.sh
openssh/defines.h
openssh/gss-genr.c
openssh/includes.h
openssh/kex.c
openssh/kex.h
openssh/kexdhs.c
openssh/kexgexs.c
openssh/monitor.c
openssh/monitor_mm.c
openssh/monitor_wrap.c
openssh/monitor_wrap.h
openssh/openbsd-compat/getrrsetbyname.c
openssh/openbsd-compat/port-aix.c
openssh/openbsd-compat/port-aix.h
openssh/packet.c
openssh/packet.h
openssh/readconf.c
openssh/readconf.h
openssh/roaming_common.c
openssh/schnorr.c
openssh/servconf.c
openssh/serverloop.c
openssh/session.c
openssh/ssh-agent.c
openssh/ssh.1
openssh/ssh.c
openssh/sshconnect.c
openssh/sshconnect2.c
openssh/sshd.8
openssh/sshd.c
openssh/sshd_config.5
openssh/version.h

index 9a5f9b360ece083d33ed868c0dc23c809c068cc0..28aeee6515407faba842bd39d0c47fed010bc6df 100644 (file)
@@ -76,7 +76,8 @@ LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \
        kexgssc.o
 
 SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
        kexgssc.o
 
 SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
-       sshconnect.o sshconnect1.o sshconnect2.o mux.o
+       sshconnect.o sshconnect1.o sshconnect2.o mux.o \
+       roaming_common.o
 
 SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
        sshpty.o sshlogin.o servconf.o serverloop.o \
 
 SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
        sshpty.o sshlogin.o servconf.o serverloop.o \
@@ -89,7 +90,8 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
        auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o\
        gss-serv-gsi.o \
        loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \
        auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o\
        gss-serv-gsi.o \
        loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \
-       audit.o audit-bsm.o platform.o sftp-server.o sftp-common.o
+       audit.o audit-bsm.o platform.o sftp-server.o sftp-common.o \
+       roaming_common.o
 
 MANPAGES       = moduli.5.out 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    = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-rand-helper.8 ssh-keysign.8 sshd_config.5 ssh_config.5
 
 MANPAGES       = moduli.5.out 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    = moduli.5 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
@@ -154,11 +156,11 @@ ssh-agent$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-agent.o
 ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o
        $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
 
 ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o
        $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
 
-ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o
-       $(LD) -o $@ ssh-keysign.o readconf.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
+ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o roaming_dummy.o
+       $(LD) -o $@ ssh-keysign.o readconf.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
 
 
-ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o
-       $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
+ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o
+       $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(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-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)
@@ -243,7 +245,7 @@ check-config:
        -$(DESTDIR)$(sbindir)/sshd -t -f $(DESTDIR)$(sysconfdir)/sshd_config
 
 scard-install:
        -$(DESTDIR)$(sbindir)/sshd -t -f $(DESTDIR)$(sysconfdir)/sshd_config
 
 scard-install:
-       (cd scard && $(MAKE) DESTDIR=$(DESTDIR) install)
+       (cd scard && env DESTDIR=$(DESTDIR) $(MAKE) DESTDIR=$(DESTDIR) install)
 
 install-files: scard-install
        $(srcdir)/mkinstalldirs $(DESTDIR)$(bindir)
 
 install-files: scard-install
        $(srcdir)/mkinstalldirs $(DESTDIR)$(bindir)
index c54dbf45001ae3a35193bbdf1d558de240193ea0..b2cfa7c4d4925ab18f7aedc140c154b29a1eb2e0 100644 (file)
@@ -56,6 +56,18 @@ using a third party driver. More information is available at:
        http://www-user.rhrk.uni-kl.de/~nissler/tuntap/
 
 
        http://www-user.rhrk.uni-kl.de/~nissler/tuntap/
 
 
+Linux
+-----
+
+Some Linux distributions (including Red Hat/Fedora/CentOS) include
+headers and library links in the -devel RPMs rather than the main
+binary RPMs. If you get an error about headers, or complaining about a
+missing prerequisite then you may need to install the equivalent
+development packages.  On Redhat based distros these may be openssl-devel,
+zlib-devel and pam-devel, on Debian based distros these may be
+libssl-dev, libz-dev and libpam-dev.
+
+
 Solaris
 -------
 If you enable BSM auditing on Solaris, you need to update audit_event(4)
 Solaris
 -------
 If you enable BSM auditing on Solaris, you need to update audit_event(4)
index 582c463a1fa596680052990e83f4db8180c233bc..90ec372c05309cebdf1a84f97797b4eaa1da0254 100644 (file)
@@ -660,16 +660,16 @@ sshpam_cleanup(void)
                return;
        debug("PAM: cleanup");
        pam_set_item(sshpam_handle, PAM_CONV, (const void *)&null_conv);
                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;
        }
        if (sshpam_session_open) {
                debug("PAM: closing session");
                pam_close_session(sshpam_handle, PAM_SILENT);
                sshpam_session_open = 0;
        }
+       if (sshpam_cred_established) {
+               debug("PAM: deleting credentials");
+               pam_setcred(sshpam_handle, PAM_DELETE_CRED);
+               sshpam_cred_established = 0;
+       }
        sshpam_authenticated = 0;
        pam_end(sshpam_handle, sshpam_err);
        sshpam_handle = NULL;
        sshpam_authenticated = 0;
        pam_end(sshpam_handle, sshpam_err);
        sshpam_handle = NULL;
index b8a25587232781b79eba9e024388c3bafe5ac879..1801661fdda8b72236de420f22eb8cd957a4314a 100644 (file)
@@ -318,15 +318,7 @@ do_authloop(Authctxt *authctxt)
                }
 #endif /* _UNICOS */
 
                }
 #endif /* _UNICOS */
 
-#ifdef HAVE_CYGWIN
-               if (authenticated &&
-                   !check_nt_auth(type == SSH_CMSG_AUTH_PASSWORD,
-                   authctxt->pw)) {
-                       packet_disconnect("Authentication rejected for uid %d.",
-                           authctxt->pw == NULL ? -1 : authctxt->pw->pw_uid);
-                       authenticated = 0;
-               }
-#else
+#ifndef HAVE_CYGWIN
                /* Special handling for root */
                if (authenticated && authctxt->pw->pw_uid == 0 &&
                    !auth_root_allowed(meth->name)) {
                /* Special handling for root */
                if (authenticated && authctxt->pw->pw_uid == 0 &&
                    !auth_root_allowed(meth->name)) {
index a4fc9e6f73f23ea236cda775bedf755f84562d06..fae67da6e3375c5e9108ed04d39faa8fa4832975 100644 (file)
@@ -58,10 +58,6 @@ userauth_kbdint(Authctxt *authctxt)
 
        xfree(devs);
        xfree(lang);
 
        xfree(devs);
        xfree(lang);
-#ifdef HAVE_CYGWIN
-       if (check_nt_auth(0, authctxt->pw) == 0)
-               authenticated = 0;
-#endif
        return authenticated;
 }
 
        return authenticated;
 }
 
index 10accfe552dfb0657c5eeca5676d18097e0c07af..08f2f935fe9840dd9cd9d3bd468ecdc2e1e11435 100644 (file)
@@ -61,10 +61,6 @@ userauth_none(Authctxt *authctxt)
 {
        none_enabled = 0;
        packet_check_eom();
 {
        none_enabled = 0;
        packet_check_eom();
-#ifdef HAVE_CYGWIN
-       if (check_nt_auth(1, authctxt->pw) == 0)
-               return (0);
-#endif
        if (options.password_authentication)
                return (PRIVSEP(auth_password(authctxt, "")));
        return (0);
        if (options.password_authentication)
                return (PRIVSEP(auth_password(authctxt, "")));
        return (0);
index 421c5c25d018ab64c45b9b12a770af8a5d8925b8..5f1f3635f7a076a98084843e8b097380b79df765 100644 (file)
@@ -68,10 +68,6 @@ userauth_passwd(Authctxt *authctxt)
                logit("password change not supported");
        else if (PRIVSEP(auth_password(authctxt, password)) == 1)
                authenticated = 1;
                logit("password change not supported");
        else if (PRIVSEP(auth_password(authctxt, password)) == 1)
                authenticated = 1;
-#ifdef HAVE_CYGWIN
-       if (check_nt_auth(1, authctxt->pw) == 0)
-               authenticated = 0;
-#endif
        memset(password, 0, len);
        xfree(password);
        return authenticated;
        memset(password, 0, len);
        xfree(password);
        return authenticated;
index b1e38e5f586d25c59847b1ea5ed6f311a0129b35..2886f1275f025f17e2424c8252bd2c201bf28f73 100644 (file)
@@ -170,10 +170,6 @@ done:
                key_free(key);
        xfree(pkalg);
        xfree(pkblob);
                key_free(key);
        xfree(pkalg);
        xfree(pkblob);
-#ifdef HAVE_CYGWIN
-       if (check_nt_auth(0, authctxt->pw) == 0)
-               authenticated = 0;
-#endif
        return authenticated;
 }
 
        return authenticated;
 }
 
index 1cd3e10364ee7df583ae46718936e226999d6112..25166b4f47404e743c00b236a40d6f555e2d0a81 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2.c,v 1.120 2008/11/04 08:22:12 djm Exp $ */
+/* $OpenBSD: auth2.c,v 1.121 2009/06/22 05:39:28 dtucker Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
@@ -35,8 +35,8 @@
 #include <string.h>
 #include <unistd.h>
 
 #include <string.h>
 #include <unistd.h>
 
-#include "xmalloc.h"
 #include "atomicio.h"
 #include "atomicio.h"
+#include "xmalloc.h"
 #include "ssh2.h"
 #include "packet.h"
 #include "log.h"
 #include "ssh2.h"
 #include "packet.h"
 #include "log.h"
index d154ab80d444fd32f4d210545fbfdc7ec813ec2d..5ef7625b4888a91359be2e912e09e3514f86bfb5 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: canohost.c,v 1.64 2009/02/12 03:00:56 djm Exp $ */
+/* $OpenBSD: canohost.c,v 1.65 2009/05/27 06:31:25 andreas Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -37,6 +37,8 @@
 #include "misc.h"
 
 static void check_ip_options(int, char *);
 #include "misc.h"
 
 static void check_ip_options(int, char *);
+static char *canonical_host_ip = NULL;
+static int cached_port = -1;
 
 /*
  * Return the canonical name of the host at the other end of the socket. The
 
 /*
  * Return the canonical name of the host at the other end of the socket. The
@@ -306,6 +308,16 @@ get_local_name(int sock)
        return get_socket_address(sock, 0, NI_NAMEREQD);
 }
 
        return get_socket_address(sock, 0, NI_NAMEREQD);
 }
 
+void
+clear_cached_addr(void)
+{
+       if (canonical_host_ip != NULL) {
+               xfree(canonical_host_ip);
+               canonical_host_ip = NULL;
+       }
+       cached_port = -1;
+}
+
 /*
  * Returns the IP-address of the remote host as a string.  The returned
  * string must not be freed.
 /*
  * Returns the IP-address of the remote host as a string.  The returned
  * string must not be freed.
@@ -314,8 +326,6 @@ get_local_name(int sock)
 const char *
 get_remote_ipaddr(void)
 {
 const char *
 get_remote_ipaddr(void)
 {
-       static char *canonical_host_ip = NULL;
-
        /* Check whether we have cached the ipaddr. */
        if (canonical_host_ip == NULL) {
                if (packet_connection_is_on_socket()) {
        /* Check whether we have cached the ipaddr. */
        if (canonical_host_ip == NULL) {
                if (packet_connection_is_on_socket()) {
@@ -404,13 +414,11 @@ get_peer_port(int sock)
 int
 get_remote_port(void)
 {
 int
 get_remote_port(void)
 {
-       static int port = -1;
-
        /* Cache to avoid getpeername() on a dead connection */
        /* Cache to avoid getpeername() on a dead connection */
-       if (port == -1)
-               port = get_port(0);
+       if (cached_port == -1)
+               cached_port = get_port(0);
 
 
-       return port;
+       return cached_port;
 }
 
 int
 }
 
 int
index 690ee8029a178e57c4f7be1c5ed7ff28d556c0a0..5285069c641634e2a616ffff485fe2359f009f57 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: canohost.h,v 1.10 2009/02/12 03:00:56 djm Exp $ */
+/* $OpenBSD: canohost.h,v 1.11 2009/05/27 06:31:25 andreas Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -24,7 +24,7 @@ char          *get_local_name(int);
 int             get_remote_port(void);
 int             get_local_port(void);
 int             get_sock_port(int, int);
 int             get_remote_port(void);
 int             get_local_port(void);
 int             get_sock_port(int, int);
-
+void            clear_cached_addr(void);
 
 void            resolve_localhost(char **host);
 
 
 void            resolve_localhost(char **host);
 
index 79c7696cebec97bf6590a5525cb063291e2246e6..1fbbfffae58e0f19b314bf9b8646255a9beb6db6 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: channels.c,v 1.295 2009/02/12 03:00:56 djm Exp $ */
+/* $OpenBSD: channels.c,v 1.296 2009/05/25 06:48:00 andreas Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -1682,6 +1682,7 @@ channel_handle_wfd(Channel *c, fd_set *readset, fd_set *writeset)
                        }
                        return -1;
                }
                        }
                        return -1;
                }
+#ifndef BROKEN_TCGETATTR_ICANON
                if (compat20 && c->isatty && dlen >= 1 && buf[0] != '\r') {
                        if (tcgetattr(c->wfd, &tio) == 0 &&
                            !(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) {
                if (compat20 && c->isatty && dlen >= 1 && buf[0] != '\r') {
                        if (tcgetattr(c->wfd, &tio) == 0 &&
                            !(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) {
@@ -1695,6 +1696,7 @@ channel_handle_wfd(Channel *c, fd_set *readset, fd_set *writeset)
                                packet_send();
                        }
                }
                                packet_send();
                        }
                }
+#endif
                buffer_consume(&c->output, len);
                if (compat20 && len > 0) {
                        c->local_consumed += len;
                buffer_consume(&c->output, len);
                if (compat20 && len > 0) {
                        c->local_consumed += len;
@@ -2469,7 +2471,7 @@ channel_input_status_confirm(int type, u_int32_t seq, void *ctxt)
        int id;
 
        /* Reset keepalive timeout */
        int id;
 
        /* Reset keepalive timeout */
-       keep_alive_timeouts = 0;
+       packet_set_alive_timeouts(0);
 
        id = packet_get_int();
        packet_check_eom();
 
        id = packet_get_int();
        packet_check_eom();
index afd91c1eaaac5385d1d481868651e5abfea8139c..2ea7b51819ace4accb50c7d0e0459ed10bd7156c 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: clientloop.c,v 1.209 2009/02/12 03:00:56 djm Exp $ */
+/* $OpenBSD: clientloop.c,v 1.213 2009/07/05 19:28:33 stevesk Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
 #include "misc.h"
 #include "match.h"
 #include "msg.h"
 #include "misc.h"
 #include "match.h"
 #include "msg.h"
+#include "roaming.h"
 
 #ifdef GSSAPI
 #include "ssh-gss.h"
 
 #ifdef GSSAPI
 #include "ssh-gss.h"
@@ -495,13 +496,13 @@ client_global_request_reply(int type, u_int32_t seq, void *ctxt)
                xfree(gc);
        }
 
                xfree(gc);
        }
 
-       keep_alive_timeouts = 0;
+       packet_set_alive_timeouts(0);
 }
 
 static void
 server_alive_check(void)
 {
 }
 
 static void
 server_alive_check(void)
 {
-       if (++keep_alive_timeouts > options.server_alive_count_max) {
+       if (packet_inc_alive_timeouts() > options.server_alive_count_max) {
                logit("Timeout, server not responding.");
                cleanup_exit(255);
        }
                logit("Timeout, server not responding.");
                cleanup_exit(255);
        }
@@ -638,8 +639,8 @@ client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr)
 static void
 client_process_net_input(fd_set *readset)
 {
 static void
 client_process_net_input(fd_set *readset)
 {
-       int len;
-       char buf[8192];
+       int len, cont = 0;
+       char buf[SSH_IOBUFSZ];
 
        /*
         * Read input from the server, and add any such data to the buffer of
 
        /*
         * Read input from the server, and add any such data to the buffer of
@@ -647,8 +648,8 @@ client_process_net_input(fd_set *readset)
         */
        if (FD_ISSET(connection_in, readset)) {
                /* Read as much as possible. */
         */
        if (FD_ISSET(connection_in, readset)) {
                /* Read as much as possible. */
-               len = read(connection_in, buf, sizeof(buf));
-               if (len == 0) {
+               len = roaming_read(connection_in, buf, sizeof(buf), &cont);
+               if (len == 0 && cont == 0) {
                        /*
                         * Received EOF.  The remote host has closed the
                         * connection.
                        /*
                         * Received EOF.  The remote host has closed the
                         * connection.
@@ -1132,7 +1133,7 @@ static void
 client_process_input(fd_set *readset)
 {
        int len;
 client_process_input(fd_set *readset)
 {
        int len;
-       char buf[8192];
+       char buf[SSH_IOBUFSZ];
 
        /* Read input from stdin. */
        if (FD_ISSET(fileno(stdin), readset)) {
 
        /* Read input from stdin. */
        if (FD_ISSET(fileno(stdin), readset)) {
@@ -1489,6 +1490,14 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
        /* Stop watching for window change. */
        signal(SIGWINCH, SIG_DFL);
 
        /* Stop watching for window change. */
        signal(SIGWINCH, SIG_DFL);
 
+       if (compat20) {
+               packet_start(SSH2_MSG_DISCONNECT);
+               packet_put_int(SSH2_DISCONNECT_BY_APPLICATION);
+               packet_put_cstring("disconnected by user");
+               packet_send();
+               packet_write_wait();
+       }
+
        channel_free_all();
 
        if (have_pty)
        channel_free_all();
 
        if (have_pty)
index afc39b4814d8f307179399a38abe9a54d544feec..af183e54660605201fa7586cd65584a548c2e741 100644 (file)
@@ -388,7 +388,6 @@ AC_CHECK_HEADERS( \
        sys/cdefs.h \
        sys/dir.h \
        sys/mman.h \
        sys/cdefs.h \
        sys/dir.h \
        sys/mman.h \
-       sys/mount.h \
        sys/ndir.h \
        sys/poll.h \
        sys/prctl.h \
        sys/ndir.h \
        sys/poll.h \
        sys/prctl.h \
@@ -435,6 +434,11 @@ AC_CHECK_HEADERS(login_cap.h, [], [], [
 #include <sys/types.h>
 ])
 
 #include <sys/types.h>
 ])
 
+# older BSDs need sys/param.h before sys/mount.h
+AC_CHECK_HEADERS(sys/mount.h, [], [], [
+#include <sys/param.h>
+])
+
 # Messages for features tested for in target-specific section
 SIA_MSG="no"
 SPC_MSG="no"
 # Messages for features tested for in target-specific section
 SIA_MSG="no"
 SPC_MSG="no"
@@ -543,8 +547,6 @@ int main(void) { exit(0); }
        AC_DEFINE(USE_PIPES, 1, [Use PIPES instead of a socketpair()])
        AC_DEFINE(DISABLE_SHADOW, 1,
                [Define if you want to disable shadow passwords])
        AC_DEFINE(USE_PIPES, 1, [Use PIPES instead of a socketpair()])
        AC_DEFINE(DISABLE_SHADOW, 1,
                [Define if you want to disable shadow passwords])
-       AC_DEFINE(IP_TOS_IS_BROKEN, 1,
-               [Define if your system choked on IP TOS setting])
        AC_DEFINE(NO_X11_UNIX_SOCKETS, 1,
                [Define if X11 doesn't support AF_UNIX sockets on that system])
        AC_DEFINE(NO_IPPORT_RESERVED_CONCEPT, 1,
        AC_DEFINE(NO_X11_UNIX_SOCKETS, 1,
                [Define if X11 doesn't support AF_UNIX sockets on that system])
        AC_DEFINE(NO_IPPORT_RESERVED_CONCEPT, 1,
@@ -553,9 +555,11 @@ int main(void) { exit(0); }
        AC_DEFINE(DISABLE_FD_PASSING, 1,
                [Define if your platform needs to skip post auth
                file descriptor passing])
        AC_DEFINE(DISABLE_FD_PASSING, 1,
                [Define if your platform needs to skip post auth
                file descriptor passing])
+       AC_DEFINE(SSH_IOBUFSZ, 65536, [Windows is sensitive to read buffer size])
        ;;
 *-*-dgux*)
        ;;
 *-*-dgux*)
-       AC_DEFINE(IP_TOS_IS_BROKEN)
+       AC_DEFINE(IP_TOS_IS_BROKEN, 1,
+               [Define if your system choked on IP TOS setting])
        AC_DEFINE(SETEUID_BREAKS_SETUID)
        AC_DEFINE(BROKEN_SETREUID)
        AC_DEFINE(BROKEN_SETREGID)
        AC_DEFINE(SETEUID_BREAKS_SETUID)
        AC_DEFINE(BROKEN_SETREUID)
        AC_DEFINE(BROKEN_SETREGID)
@@ -793,6 +797,7 @@ mips-sony-bsd|mips-sony-newsos4)
                after setsid()])
        AC_DEFINE(PASSWD_NEEDS_USERNAME, 1, [must supply username to passwd
                in case the name is longer than 8 chars])
                after setsid()])
        AC_DEFINE(PASSWD_NEEDS_USERNAME, 1, [must supply username to passwd
                in case the name is longer than 8 chars])
+       AC_DEFINE(BROKEN_TCGETATTR_ICANON, 1, [tcgetattr with ICANON may hang])
        external_path_file=/etc/default/login
        # hardwire lastlog location (can't detect it on some versions)
        conf_lastlog_location="/var/adm/lastlog"
        external_path_file=/etc/default/login
        # hardwire lastlog location (can't detect it on some versions)
        conf_lastlog_location="/var/adm/lastlog"
@@ -1104,6 +1109,7 @@ AC_ARG_WITH(zlib,
        fi ]
 )
 
        fi ]
 )
 
+AC_CHECK_HEADER([zlib.h], ,AC_MSG_ERROR([*** zlib.h missing - please install first or check config.log ***]))
 AC_CHECK_LIB(z, deflate, ,
        [
                saved_CPPFLAGS="$CPPFLAGS"
 AC_CHECK_LIB(z, deflate, ,
        [
                saved_CPPFLAGS="$CPPFLAGS"
@@ -1124,7 +1130,6 @@ AC_CHECK_LIB(z, deflate, ,
                )
        ]
 )
                )
        ]
 )
-AC_CHECK_HEADER([zlib.h], ,AC_MSG_ERROR([*** zlib.h missing - please install first or check config.log ***]))
 
 AC_ARG_WITH(zlib-version-check,
        [  --without-zlib-version-check Disable zlib version check],
 
 AC_ARG_WITH(zlib-version-check,
        [  --without-zlib-version-check Disable zlib version check],
@@ -2019,6 +2024,8 @@ AC_TRY_LINK_FUNC(RAND_add, AC_DEFINE(HAVE_OPENSSL, 1,
                        LDFLAGS="-L/usr/local/ssl/lib ${saved_LDFLAGS}"
                fi
                CPPFLAGS="-I/usr/local/ssl/include ${saved_CPPFLAGS}"
                        LDFLAGS="-L/usr/local/ssl/lib ${saved_LDFLAGS}"
                fi
                CPPFLAGS="-I/usr/local/ssl/include ${saved_CPPFLAGS}"
+               AC_CHECK_HEADER([openssl/opensslv.h], ,
+                   AC_MSG_ERROR([*** OpenSSL headers missing - please install first or check config.log ***]))
                AC_TRY_LINK_FUNC(RAND_add, AC_DEFINE(HAVE_OPENSSL),
                        [
                                AC_MSG_ERROR([*** Can't find recent OpenSSL libcrypto (see config.log for details) ***])
                AC_TRY_LINK_FUNC(RAND_add, AC_DEFINE(HAVE_OPENSSL),
                        [
                                AC_MSG_ERROR([*** Can't find recent OpenSSL libcrypto (see config.log for details) ***])
@@ -2203,6 +2210,23 @@ int main(void) { exit(EVP_aes_192_cbc() == NULL || EVP_aes_256_cbc() == NULL);}
        ]
 )
 
        ]
 )
 
+AC_MSG_CHECKING([if EVP_DigestUpdate returns an int])
+AC_LINK_IFELSE(
+       [AC_LANG_SOURCE([[
+#include <string.h>
+#include <openssl/evp.h>
+int main(void) { if(EVP_DigestUpdate(NULL, NULL,0)) exit(0); }
+       ]])],
+       [
+               AC_MSG_RESULT(yes)
+       ],
+       [
+               AC_MSG_RESULT(no)
+               AC_DEFINE(OPENSSL_EVP_DIGESTUPDATE_VOID, 1,
+                   [Define if EVP_DigestUpdate returns void])
+       ]
+)
+
 # Some systems want crypt() from libcrypt, *not* the version in OpenSSL,
 # because the system crypt() is more featureful.
 if test "x$check_for_libcrypt_before" = "x1"; then
 # Some systems want crypt() from libcrypt, *not* the version in OpenSSL,
 # because the system crypt() is more featureful.
 if test "x$check_for_libcrypt_before" = "x1"; then
@@ -2821,7 +2845,7 @@ AC_CHECK_TYPES([fsblkcnt_t, fsfilcnt_t],,,[
 #endif
 ])
 
 #endif
 ])
 
-AC_CHECK_TYPES(in_addr_t,,,
+AC_CHECK_TYPES([in_addr_t, in_port_t],,,
 [#include <sys/types.h>
 #include <netinet/in.h>])
 
 [#include <sys/types.h>
 #include <netinet/in.h>])
 
@@ -3191,15 +3215,41 @@ if test "x$ac_cv_have_accrights_in_msghdr" = "xyes" ; then
                file descriptor passing])
 fi
 
                file descriptor passing])
 fi
 
-AC_MSG_CHECKING(if f_fsid has val members)
+AC_MSG_CHECKING(if struct statvfs.f_fsid is integral type)
 AC_TRY_COMPILE([
 #include <sys/types.h>
 AC_TRY_COMPILE([
 #include <sys/types.h>
+#include <sys/stat.h>
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_MOUNT_H
+#include <sys/mount.h>
+#endif
+#ifdef HAVE_SYS_STATVFS_H
+#include <sys/statvfs.h>
+#endif
+], [struct statvfs s; s.f_fsid = 0;],
+[ AC_MSG_RESULT(yes) ],
+[ AC_MSG_RESULT(no)
+
+       AC_MSG_CHECKING(if fsid_t has member val)
+       AC_TRY_COMPILE([
+#include <sys/types.h>
 #include <sys/statvfs.h>],
 #include <sys/statvfs.h>],
-[struct fsid_t t; t.val[0] = 0;],
+       [fsid_t t; t.val[0] = 0;],
        [ AC_MSG_RESULT(yes)
        [ AC_MSG_RESULT(yes)
-         AC_DEFINE(FSID_HAS_VAL, 1, f_fsid has members) ],
-       [ AC_MSG_RESULT(no) ]
-)
+         AC_DEFINE(FSID_HAS_VAL, 1, fsid_t has member val) ],
+       [ AC_MSG_RESULT(no) ])
+
+       AC_MSG_CHECKING(if f_fsid has member __val)
+       AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <sys/statvfs.h>],
+       [fsid_t t; t.__val[0] = 0;],
+       [ AC_MSG_RESULT(yes)
+         AC_DEFINE(FSID_HAS___VAL, 1, fsid_t has member __val) ],
+       [ AC_MSG_RESULT(no) ])
+])
 
 AC_CACHE_CHECK([for msg_control field in struct msghdr],
                ac_cv_have_control_in_msghdr, [
 
 AC_CACHE_CHECK([for msg_control field in struct msghdr],
                ac_cv_have_control_in_msghdr, [
@@ -3401,12 +3451,30 @@ AC_SEARCH_LIBS(getrrsetbyname, resolv,
                AC_SEARCH_LIBS(res_query, resolv)
                AC_SEARCH_LIBS(dn_expand, resolv)
                AC_MSG_CHECKING(if res_query will link)
                AC_SEARCH_LIBS(res_query, resolv)
                AC_SEARCH_LIBS(dn_expand, resolv)
                AC_MSG_CHECKING(if res_query will link)
-               AC_TRY_LINK_FUNC(res_query, AC_MSG_RESULT(yes),
+               AC_LINK_IFELSE([
+#include "confdefs.h"
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <netdb.h>
+#include <resolv.h>
+int main()
+{
+       res_query (0, 0, 0, 0, 0);
+       return 0;
+}
+                  ],
+                   AC_MSG_RESULT(yes),
                   [AC_MSG_RESULT(no)
                    saved_LIBS="$LIBS"
                    LIBS="$LIBS -lresolv"
                    AC_MSG_CHECKING(for res_query in -lresolv)
                    AC_LINK_IFELSE([
                   [AC_MSG_RESULT(no)
                    saved_LIBS="$LIBS"
                    LIBS="$LIBS -lresolv"
                    AC_MSG_CHECKING(for res_query in -lresolv)
                    AC_LINK_IFELSE([
+#include "confdefs.h"
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <netdb.h>
 #include <resolv.h>
 int main()
 {
 #include <resolv.h>
 int main()
 {
@@ -3414,8 +3482,7 @@ int main()
        return 0;
 }
                        ],
        return 0;
 }
                        ],
-                       [LIBS="$LIBS -lresolv"
-                        AC_MSG_RESULT(yes)],
+                       [AC_MSG_RESULT(yes)],
                        [LIBS="$saved_LIBS"
                         AC_MSG_RESULT(no)])
                    ])
                        [LIBS="$saved_LIBS"
                         AC_MSG_RESULT(no)])
                    ])
@@ -3530,10 +3597,10 @@ AC_ARG_WITH(kerberos5,
                AC_DEFINE(KRB5, 1, [Define if you want Kerberos 5 support])
                KRB5_MSG="yes"
 
                AC_DEFINE(KRB5, 1, [Define if you want Kerberos 5 support])
                KRB5_MSG="yes"
 
-               AC_MSG_CHECKING(for krb5-config)
-               if test -x  $KRB5ROOT/bin/krb5-config ; then
-                       KRB5CONF=$KRB5ROOT/bin/krb5-config
-                       AC_MSG_RESULT($KRB5CONF)
+               AC_PATH_PROG([KRB5CONF],[krb5-config],
+                            [$KRB5ROOT/bin/krb5-config],
+                            [$KRB5ROOT/bin:$PATH])
+               if test -x $KRB5CONF ; then
 
                        AC_MSG_CHECKING(for gssapi support)
                        if $KRB5CONF | grep gssapi >/dev/null ; then
 
                        AC_MSG_CHECKING(for gssapi support)
                        if $KRB5CONF | grep gssapi >/dev/null ; then
@@ -3559,7 +3626,6 @@ AC_ARG_WITH(kerberos5,
                                         AC_MSG_RESULT(no)
                        )
                else
                                         AC_MSG_RESULT(no)
                        )
                else
-                       AC_MSG_RESULT(no)
                        CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include"
                        LDFLAGS="$LDFLAGS -L${KRB5ROOT}/lib"
                        AC_MSG_CHECKING(whether we are using Heimdal)
                        CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include"
                        LDFLAGS="$LDFLAGS -L${KRB5ROOT}/lib"
                        AC_MSG_CHECKING(whether we are using Heimdal)
index 6b283a1ff72d6a486581a61b4bd6fd7ce3a4f465..d3d0be7b608c769bda7ebeb999ffa67565afe84a 100755 (executable)
@@ -151,11 +151,18 @@ fi
 
 
 # Rename config files; postinstall script will copy them if necessary
 
 
 # Rename config files; postinstall script will copy them if necessary
-for cfgfile in ssh_config sshd_config ssh_prng_cmds
+for cfgfile in ssh_config sshd_config
 do
        mv $FAKE_ROOT/$sysconfdir/$cfgfile $FAKE_ROOT/$sysconfdir/$cfgfile.default
 done
 
 do
        mv $FAKE_ROOT/$sysconfdir/$cfgfile $FAKE_ROOT/$sysconfdir/$cfgfile.default
 done
 
+# AIX 5.3 and newer have /dev/random and don't create ssh_prng_cmds
+if [ -f $FAKE_ROOT/$sysconfdir/ssh_prng_cmds ]
+then
+       mv FAKE_ROOT/$sysconfdir/ssh_prng_cmds \
+               $FAKE_ROOT/$sysconfdir/ssh_prng_cmds.default
+fi
+
 #
 # Generate lpp control files.
 #      working dir is $FAKE_ROOT but files are generated in dir above
 #
 # Generate lpp control files.
 #      working dir is $FAKE_ROOT but files are generated in dir above
index 748759785b2384d38234071135b025b04c99922d..2ee6c87c2e81a40d01e414d4dcf1f94a2db22599 100644 (file)
@@ -300,6 +300,9 @@ struct      sockaddr_un {
 #ifndef HAVE_IN_ADDR_T
 typedef u_int32_t      in_addr_t;
 #endif
 #ifndef HAVE_IN_ADDR_T
 typedef u_int32_t      in_addr_t;
 #endif
+#ifndef HAVE_IN_PORT_T
+typedef u_int16_t      in_port_t;
+#endif
 
 #if defined(BROKEN_SYS_TERMIO_H) && !defined(_STRUCT_WINSIZE)
 #define _STRUCT_WINSIZE
 
 #if defined(BROKEN_SYS_TERMIO_H) && !defined(_STRUCT_WINSIZE)
 #define _STRUCT_WINSIZE
@@ -595,6 +598,10 @@ struct winsize {
 #define FSID_TO_ULONG(f) \
        ((((u_int64_t)(f).val[0] & 0xffffffffUL) << 32) | \
            ((f).val[1] & 0xffffffffUL))
 #define FSID_TO_ULONG(f) \
        ((((u_int64_t)(f).val[0] & 0xffffffffUL) << 32) | \
            ((f).val[1] & 0xffffffffUL))
+#elif defined(FSID_HAS___VAL)
+#define FSID_TO_ULONG(f) \
+       ((((u_int64_t)(f).__val[0] & 0xffffffffUL) << 32) | \
+           ((f).__val[1] & 0xffffffffUL))
 #else
 # define FSID_TO_ULONG(f) ((f))
 #endif
 #else
 # define FSID_TO_ULONG(f) ((f))
 #endif
@@ -746,4 +753,8 @@ struct winsize {
 #define INET6_ADDRSTRLEN 46
 #endif
 
 #define INET6_ADDRSTRLEN 46
 #endif
 
+#ifndef SSH_IOBUFSZ
+# define SSH_IOBUFSZ 8192
+#endif
+
 #endif /* _DEFINES_H */
 #endif /* _DEFINES_H */
index 81b85ba43dcdf3760d417bf7f2df5d7770983ec9..dff09212e6ec066a3ab435fc49cbadc2fc413562 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: gss-genr.c,v 1.19 2007/06/12 11:56:15 dtucker Exp $ */
+/* $OpenBSD: gss-genr.c,v 1.20 2009/06/22 05:39:28 dtucker Exp $ */
 
 /*
  * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.
 
 /*
  * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.
index f1b47f666d038b69aa98721b4d455b6094a48210..6bb98780729c8c7e1d1e3ae2b2077a58711e5d6a 100644 (file)
@@ -31,7 +31,8 @@
 #endif
 #if defined(HAVE_GLOB_H) && defined(GLOB_HAS_ALTDIRFUNC) && \
     defined(GLOB_HAS_GL_MATCHC) && \
 #endif
 #if defined(HAVE_GLOB_H) && defined(GLOB_HAS_ALTDIRFUNC) && \
     defined(GLOB_HAS_GL_MATCHC) && \
-    defined(HAVE_DECL_GLOB_NOMATCH) &&  HAVE_DECL_GLOB_NOMATCH != 0
+    defined(HAVE_DECL_GLOB_NOMATCH) &&  HAVE_DECL_GLOB_NOMATCH != 0 && \
+    !defined(BROKEN_GLOB)
 # include <glob.h>
 #endif
 #ifdef HAVE_ENDIAN_H
 # include <glob.h>
 #endif
 #ifdef HAVE_ENDIAN_H
index 38db004c4dc4f0a570adf76c8379c00e36d2a087..71ccfe2858c8edc0d221e20b939e940ba982a4c6 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: kex.c,v 1.80 2008/09/06 12:24:13 djm Exp $ */
+/* $OpenBSD: kex.c,v 1.81 2009/05/27 06:34:36 andreas Exp $ */
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
  *
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
  *
@@ -54,8 +54,6 @@
 #include "ssh-gss.h"
 #endif
 
 #include "ssh-gss.h"
 #endif
 
-#define KEX_COOKIE_LEN 16
-
 #if OPENSSL_VERSION_NUMBER >= 0x00907000L
 # if defined(HAVE_EVP_SHA256)
 # define evp_ssh_sha256 EVP_sha256
 #if OPENSSL_VERSION_NUMBER >= 0x00907000L
 # if defined(HAVE_EVP_SHA256)
 # define evp_ssh_sha256 EVP_sha256
index 6100df8d86b2fe8918044d7a72d6793c6f54536c..eab992ddadcf264e2864c0fddb3439eb79a42ea8 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: kex.h,v 1.46 2007/06/07 19:37:34 pvalchev Exp $ */
+/* $OpenBSD: kex.h,v 1.47 2009/05/27 06:34:36 andreas Exp $ */
 
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
 
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
@@ -30,6 +30,8 @@
 #include <openssl/evp.h>
 #include <openssl/hmac.h>
 
 #include <openssl/evp.h>
 #include <openssl/hmac.h>
 
+#define KEX_COOKIE_LEN 16
+
 #define        KEX_DH1                 "diffie-hellman-group1-sha1"
 #define        KEX_DH14                "diffie-hellman-group14-sha1"
 #define        KEX_DHGEX_SHA1          "diffie-hellman-group-exchange-sha1"
 #define        KEX_DH1                 "diffie-hellman-group1-sha1"
 #define        KEX_DH14                "diffie-hellman-group14-sha1"
 #define        KEX_DHGEX_SHA1          "diffie-hellman-group-exchange-sha1"
index 861708818451f04ce0b54d89f3ed585368819370..a6719f6722f6474334d04604c6e4f97d1c36279e 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexdhs.c,v 1.9 2006/11/06 21:25:28 markus Exp $ */
+/* $OpenBSD: kexdhs.c,v 1.10 2009/06/21 07:37:15 dtucker Exp $ */
 /*
  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
  *
 /*
  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
  *
@@ -137,7 +137,9 @@ kexdh_server(Kex *kex)
        }
 
        /* sign H */
        }
 
        /* sign H */
-       PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, hashlen));
+       if (PRIVSEP(key_sign(server_host_key, &signature, &slen, hash,
+           hashlen)) < 0)
+               fatal("kexdh_server: key_sign failed");
 
        /* destroy_sensitive_data(); */
 
 
        /* destroy_sensitive_data(); */
 
index 76a0f8ca7164d5e0259a49e90e6b29e061ec7381..8515568b36edda5d4d8be638bb031d5f1039ddcb 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: kexgexs.c,v 1.11 2009/01/01 21:17:36 djm Exp $ */
+/* $OpenBSD: kexgexs.c,v 1.12 2009/06/21 07:37:15 dtucker Exp $ */
 /*
  * Copyright (c) 2000 Niels Provos.  All rights reserved.
  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
 /*
  * Copyright (c) 2000 Niels Provos.  All rights reserved.
  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
@@ -179,7 +179,9 @@ kexgex_server(Kex *kex)
        }
 
        /* sign H */
        }
 
        /* sign H */
-       PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, hashlen));
+       if (PRIVSEP(key_sign(server_host_key, &signature, &slen, hash,
+           hashlen)) < 0)
+               fatal("kexgex_server: key_sign failed");
 
        /* destroy_sensitive_data(); */
 
 
        /* destroy_sensitive_data(); */
 
index 3a39cef4a10944243fa6508752a0abaa87775d08..5f3b801580246adfec7e1604450195e9b33c8632 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor.c,v 1.101 2009/02/12 03:26:22 djm Exp $ */
+/* $OpenBSD: monitor.c,v 1.104 2009/06/12 20:43:22 andreas Exp $ */
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
  * Copyright 2002 Markus Friedl <markus@openbsd.org>
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
  * Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -88,6 +88,7 @@
 #include "compat.h"
 #include "ssh2.h"
 #include "jpake.h"
 #include "compat.h"
 #include "ssh2.h"
 #include "jpake.h"
+#include "roaming.h"
 
 #ifdef GSSAPI
 static Gssctxt *gsscontext = NULL;
 
 #ifdef GSSAPI
 static Gssctxt *gsscontext = NULL;
@@ -100,7 +101,6 @@ extern Newkeys *current_keys[];
 extern z_stream incoming_stream;
 extern z_stream outgoing_stream;
 extern u_char session_id[];
 extern z_stream incoming_stream;
 extern z_stream outgoing_stream;
 extern u_char session_id[];
-extern Buffer input, output;
 extern Buffer auth_debug;
 extern int auth_debug_init;
 extern Buffer loginmsg;
 extern Buffer auth_debug;
 extern int auth_debug_init;
 extern Buffer loginmsg;
@@ -126,6 +126,8 @@ struct {
        u_int ilen;
        u_char *output;
        u_int olen;
        u_int ilen;
        u_char *output;
        u_int olen;
+       u_int64_t sent_bytes;
+       u_int64_t recv_bytes;
 } child_state;
 
 /* Functions on the monitor that answer unprivileged requests */
 } child_state;
 
 /* Functions on the monitor that answer unprivileged requests */
@@ -1714,15 +1716,20 @@ monitor_apply_keystate(struct monitor *pmonitor)
 
        /* Network I/O buffers */
        /* XXX inefficient for large buffers, need: buffer_init_from_string */
 
        /* Network I/O buffers */
        /* XXX inefficient for large buffers, need: buffer_init_from_string */
-       buffer_clear(&input);
-       buffer_append(&input, child_state.input, child_state.ilen);
+       buffer_clear(packet_get_input());
+       buffer_append(packet_get_input(), child_state.input, child_state.ilen);
        memset(child_state.input, 0, child_state.ilen);
        xfree(child_state.input);
 
        memset(child_state.input, 0, child_state.ilen);
        xfree(child_state.input);
 
-       buffer_clear(&output);
-       buffer_append(&output, child_state.output, child_state.olen);
+       buffer_clear(packet_get_output());
+       buffer_append(packet_get_output(), child_state.output,
+                     child_state.olen);
        memset(child_state.output, 0, child_state.olen);
        xfree(child_state.output);
        memset(child_state.output, 0, child_state.olen);
        xfree(child_state.output);
+
+       /* Roaming */
+       if (compat20)
+               roam_set_bytes(child_state.sent_bytes, child_state.recv_bytes);
 }
 
 static Kex *
 }
 
 static Kex *
@@ -1845,6 +1852,12 @@ mm_get_keystate(struct monitor *pmonitor)
        child_state.input = buffer_get_string(&m, &child_state.ilen);
        child_state.output = buffer_get_string(&m, &child_state.olen);
 
        child_state.input = buffer_get_string(&m, &child_state.ilen);
        child_state.output = buffer_get_string(&m, &child_state.olen);
 
+       /* Roaming */
+       if (compat20) {
+               child_state.sent_bytes = buffer_get_int64(&m);
+               child_state.recv_bytes = buffer_get_int64(&m);
+       }
+
        buffer_free(&m);
 }
 
        buffer_free(&m);
 }
 
index dab747532a0df2d82d9c30ad1abbeb0522b5ad2b..faf9f3dcb4f6e9eadd14732c5d77e36c37a6fd18 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor_mm.c,v 1.15 2006/08/03 03:34:42 deraadt Exp $ */
+/* $OpenBSD: monitor_mm.c,v 1.16 2009/06/22 05:39:28 dtucker Exp $ */
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
  * All rights reserved.
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
  * All rights reserved.
index a2bc3a6b348740b1198125a5ab8df29532815601..9017cc43359fe5dad6247499d62c2bac69bac4a4 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor_wrap.c,v 1.64 2008/11/04 08:22:13 djm Exp $ */
+/* $OpenBSD: monitor_wrap.c,v 1.68 2009/06/22 05:39:28 dtucker Exp $ */
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
  * Copyright 2002 Markus Friedl <markus@openbsd.org>
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
  * Copyright 2002 Markus Friedl <markus@openbsd.org>
 #include "atomicio.h"
 #include "monitor_fdpass.h"
 #include "misc.h"
 #include "atomicio.h"
 #include "monitor_fdpass.h"
 #include "misc.h"
+#include "schnorr.h"
 #include "jpake.h"
 
 #include "channels.h"
 #include "session.h"
 #include "servconf.h"
 #include "jpake.h"
 
 #include "channels.h"
 #include "session.h"
 #include "servconf.h"
+#include "roaming.h"
 
 /* Imports */
 extern int compat20;
 
 /* Imports */
 extern int compat20;
-extern Newkeys *newkeys[];
 extern z_stream incoming_stream;
 extern z_stream outgoing_stream;
 extern struct monitor *pmonitor;
 extern z_stream incoming_stream;
 extern z_stream outgoing_stream;
 extern struct monitor *pmonitor;
-extern Buffer input, output;
 extern Buffer loginmsg;
 extern ServerOptions options;
 
 extern Buffer loginmsg;
 extern ServerOptions options;
 
@@ -508,7 +508,7 @@ mm_newkeys_to_blob(int mode, u_char **blobp, u_int *lenp)
        Enc *enc;
        Mac *mac;
        Comp *comp;
        Enc *enc;
        Mac *mac;
        Comp *comp;
-       Newkeys *newkey = newkeys[mode];
+       Newkeys *newkey = (Newkeys *)packet_get_newkeys(mode);
 
        debug3("%s: converting %p", __func__, newkey);
 
 
        debug3("%s: converting %p", __func__, newkey);
 
@@ -570,7 +570,7 @@ mm_send_kex(Buffer *m, Kex *kex)
 void
 mm_send_keystate(struct monitor *monitor)
 {
 void
 mm_send_keystate(struct monitor *monitor)
 {
-       Buffer m;
+       Buffer m, *input, *output;
        u_char *blob, *p;
        u_int bloblen, plen;
        u_int32_t seqnr, packets;
        u_char *blob, *p;
        u_int bloblen, plen;
        u_int32_t seqnr, packets;
@@ -608,7 +608,8 @@ mm_send_keystate(struct monitor *monitor)
        }
 
        debug3("%s: Sending new keys: %p %p",
        }
 
        debug3("%s: Sending new keys: %p %p",
-           __func__, newkeys[MODE_OUT], newkeys[MODE_IN]);
+           __func__, packet_get_newkeys(MODE_OUT),
+           packet_get_newkeys(MODE_IN));
 
        /* Keys from Kex */
        if (!mm_newkeys_to_blob(MODE_OUT, &blob, &bloblen))
 
        /* Keys from Kex */
        if (!mm_newkeys_to_blob(MODE_OUT, &blob, &bloblen))
@@ -655,8 +656,16 @@ mm_send_keystate(struct monitor *monitor)
        buffer_put_string(&m, &incoming_stream, sizeof(incoming_stream));
 
        /* Network I/O buffers */
        buffer_put_string(&m, &incoming_stream, sizeof(incoming_stream));
 
        /* Network I/O buffers */
-       buffer_put_string(&m, buffer_ptr(&input), buffer_len(&input));
-       buffer_put_string(&m, buffer_ptr(&output), buffer_len(&output));
+       input = (Buffer *)packet_get_input();
+       output = (Buffer *)packet_get_output();
+       buffer_put_string(&m, buffer_ptr(input), buffer_len(input));
+       buffer_put_string(&m, buffer_ptr(output), buffer_len(output));
+
+       /* Roaming */
+       if (compat20) {
+               buffer_put_int64(&m, get_sent_bytes());
+               buffer_put_int64(&m, get_recv_bytes());
+       }
 
        mm_request_send(monitor->m_recvfd, MONITOR_REQ_KEYEXPORT, &m);
        debug3("%s: Finished sending state", __func__);
 
        mm_request_send(monitor->m_recvfd, MONITOR_REQ_KEYEXPORT, &m);
        debug3("%s: Finished sending state", __func__);
@@ -1404,7 +1413,7 @@ mm_auth2_jpake_get_pwdata(Authctxt *authctxt, BIGNUM **s,
 }
 
 void
 }
 
 void
-mm_jpake_step1(struct jpake_group *grp,
+mm_jpake_step1(struct modp_group *grp,
     u_char **id, u_int *id_len,
     BIGNUM **priv1, BIGNUM **priv2, BIGNUM **g_priv1, BIGNUM **g_priv2,
     u_char **priv1_proof, u_int *priv1_proof_len,
     u_char **id, u_int *id_len,
     BIGNUM **priv1, BIGNUM **priv2, BIGNUM **g_priv1, BIGNUM **g_priv2,
     u_char **priv1_proof, u_int *priv1_proof_len,
@@ -1439,7 +1448,7 @@ mm_jpake_step1(struct jpake_group *grp,
 }
 
 void
 }
 
 void
-mm_jpake_step2(struct jpake_group *grp, BIGNUM *s,
+mm_jpake_step2(struct modp_group *grp, BIGNUM *s,
     BIGNUM *mypub1, BIGNUM *theirpub1, BIGNUM *theirpub2, BIGNUM *mypriv2,
     const u_char *theirid, u_int theirid_len,
     const u_char *myid, u_int myid_len,
     BIGNUM *mypub1, BIGNUM *theirpub1, BIGNUM *theirpub2, BIGNUM *mypriv2,
     const u_char *theirid, u_int theirid_len,
     const u_char *myid, u_int myid_len,
@@ -1479,7 +1488,7 @@ mm_jpake_step2(struct jpake_group *grp, BIGNUM *s,
 }
 
 void
 }
 
 void
-mm_jpake_key_confirm(struct jpake_group *grp, BIGNUM *s, BIGNUM *step2_val,
+mm_jpake_key_confirm(struct modp_group *grp, BIGNUM *s, BIGNUM *step2_val,
     BIGNUM *mypriv2, BIGNUM *mypub1, BIGNUM *mypub2,
     BIGNUM *theirpub1, BIGNUM *theirpub2,
     const u_char *my_id, u_int my_id_len,
     BIGNUM *mypriv2, BIGNUM *mypub1, BIGNUM *mypub2,
     BIGNUM *theirpub1, BIGNUM *theirpub2,
     const u_char *my_id, u_int my_id_len,
index e4a3d485810f827511453ffac5cae870fbbe2759..a52de618c331fcc3920103d484e87749ed46ab50 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor_wrap.h,v 1.21 2008/11/04 08:22:13 djm Exp $ */
+/* $OpenBSD: monitor_wrap.h,v 1.22 2009/03/05 07:18:19 djm Exp $ */
 
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
 
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
@@ -108,17 +108,17 @@ int mm_skey_query(void *, char **, char **, u_int *, char ***, u_int **);
 int mm_skey_respond(void *, u_int, char **);
 
 /* jpake */
 int mm_skey_respond(void *, u_int, char **);
 
 /* jpake */
-struct jpake_group;
+struct modp_group;
 void mm_auth2_jpake_get_pwdata(struct Authctxt *, BIGNUM **, char **, char **);
 void mm_auth2_jpake_get_pwdata(struct Authctxt *, BIGNUM **, char **, char **);
-void mm_jpake_step1(struct jpake_group *, u_char **, u_int *,
+void mm_jpake_step1(struct modp_group *, u_char **, u_int *,
     BIGNUM **, BIGNUM **, BIGNUM **, BIGNUM **,
     u_char **, u_int *, u_char **, u_int *);
     BIGNUM **, BIGNUM **, BIGNUM **, BIGNUM **,
     u_char **, u_int *, u_char **, u_int *);
-void mm_jpake_step2(struct jpake_group *, BIGNUM *,
+void mm_jpake_step2(struct modp_group *, BIGNUM *,
     BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *,
     const u_char *, u_int, const u_char *, u_int,
     const u_char *, u_int, const u_char *, u_int,
     BIGNUM **, u_char **, u_int *);
     BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *,
     const u_char *, u_int, const u_char *, u_int,
     const u_char *, u_int, const u_char *, u_int,
     BIGNUM **, u_char **, u_int *);
-void mm_jpake_key_confirm(struct jpake_group *, BIGNUM *, BIGNUM *,
+void mm_jpake_key_confirm(struct modp_group *, BIGNUM *, BIGNUM *,
     BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *,
     const u_char *, u_int, const u_char *, u_int,
     const u_char *, u_int, const u_char *, u_int,
     BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *,
     const u_char *, u_int, const u_char *, u_int,
     const u_char *, u_int, const u_char *, u_int,
index 785b2256911ceb84d2cc77f38bd6a9e131f62ad8..98876673d0027c8c624e141657a4fbbb6677953c 100644 (file)
@@ -143,7 +143,7 @@ u_int32_t _getlong(register const u_char *);
 
 /* ************** */
 
 
 /* ************** */
 
-#define ANSWER_BUFFER_SIZE 1024*64
+#define ANSWER_BUFFER_SIZE 0xffff
 
 struct dns_query {
        char                    *name;
 
 struct dns_query {
        char                    *name;
index fd578f2acbade6600dd69d33c8c23600aa70ede3..ebf62d316b3688bd8ca6ff954e1f57daef32bc55 100644 (file)
@@ -58,6 +58,8 @@
 
 #include "port-aix.h"
 
 
 #include "port-aix.h"
 
+static char *lastlogin_msg = NULL;
+
 # ifdef HAVE_SETAUTHDB
 static char old_registry[REGISTRY_SIZE] = "";
 # endif
 # ifdef HAVE_SETAUTHDB
 static char old_registry[REGISTRY_SIZE] = "";
 # endif
@@ -277,23 +279,30 @@ sys_auth_record_login(const char *user, const char *host, const char *ttynm,
     Buffer *loginmsg)
 {
        char *msg = NULL;
     Buffer *loginmsg)
 {
        char *msg = NULL;
-       static int msg_done = 0;
        int success = 0;
 
        aix_setauthdb(user);
        if (loginsuccess((char *)user, (char *)host, (char *)ttynm, &msg) == 0) {
                success = 1;
        int success = 0;
 
        aix_setauthdb(user);
        if (loginsuccess((char *)user, (char *)host, (char *)ttynm, &msg) == 0) {
                success = 1;
-               if (msg != NULL && loginmsg != NULL && !msg_done) {
+               if (msg != NULL) {
                        debug("AIX/loginsuccess: msg %s", msg);
                        debug("AIX/loginsuccess: msg %s", msg);
-                       buffer_append(loginmsg, msg, strlen(msg));
-                       xfree(msg);
-                       msg_done = 1;
+                       if (lastlogin_msg == NULL)
+                               lastlogin_msg = msg;
                }
        }
        aix_restoreauthdb();
        return (success);
 }
 
                }
        }
        aix_restoreauthdb();
        return (success);
 }
 
+char *
+sys_auth_get_lastlogin_msg(const char *user, uid_t uid)
+{
+       char *msg = lastlogin_msg;
+
+       lastlogin_msg = NULL;
+       return msg;
+}
+
 #  ifdef CUSTOM_FAILED_LOGIN
 /*
  * record_failed_login: generic "login failed" interface function
 #  ifdef CUSTOM_FAILED_LOGIN
 /*
  * record_failed_login: generic "login failed" interface function
index 147ad0b35aefed289f29671b00f92ea85d10c6f5..8bacc5d8487352071b85e563fb12c35077439dec 100644 (file)
@@ -71,6 +71,11 @@ int passwdexpired(char *, char **);
 # include <sys/timers.h>
 #endif
 
 # include <sys/timers.h>
 #endif
 
+/* for setpcred and friends */
+#ifdef HAVE_USERSEC_H
+# include <usersec.h>
+#endif
+
 /*
  * According to the setauthdb man page, AIX password registries must be 15
  * chars or less plus terminating NUL.
 /*
  * According to the setauthdb man page, AIX password registries must be 15
  * chars or less plus terminating NUL.
@@ -87,6 +92,8 @@ void aix_usrinfo(struct passwd *);
 int sys_auth_allowed_user(struct passwd *, Buffer *);
 # define CUSTOM_SYS_AUTH_RECORD_LOGIN 1
 int sys_auth_record_login(const char *, const char *, const char *, Buffer *);
 int sys_auth_allowed_user(struct passwd *, Buffer *);
 # define CUSTOM_SYS_AUTH_RECORD_LOGIN 1
 int sys_auth_record_login(const char *, const char *, const char *, Buffer *);
+# define CUSTOM_SYS_AUTH_GET_LASTLOGIN_MSG
+char *sys_auth_get_lastlogin_msg(const char *, uid_t);
 # define CUSTOM_FAILED_LOGIN 1
 #endif
 
 # define CUSTOM_FAILED_LOGIN 1
 #endif
 
index 7b77e2986f97f19ad2cc4889ece0803c3e2884a5..06c19f54f121e7e3935c94d233af7f915cd4fdee 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: packet.c,v 1.160 2009/02/13 11:50:21 markus Exp $ */
+/* $OpenBSD: packet.c,v 1.166 2009/06/27 09:29:06 andreas Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -77,6 +77,7 @@
 #include "canohost.h"
 #include "misc.h"
 #include "ssh.h"
 #include "canohost.h"
 #include "misc.h"
 #include "ssh.h"
+#include "roaming.h"
 
 #ifdef PACKET_DEBUG
 #define DBG(x) x
 
 #ifdef PACKET_DEBUG
 #define DBG(x) x
 
 #define PACKET_MAX_SIZE (256 * 1024)
 
 
 #define PACKET_MAX_SIZE (256 * 1024)
 
-/*
- * This variable contains the file descriptors used for communicating with
- * the other side.  connection_in is used for reading; connection_out for
- * writing.  These can be the same descriptor, in which case it is assumed to
- * be a socket.
- */
-static int connection_in = -1;
-static int connection_out = -1;
+struct packet_state {
+       u_int32_t seqnr;
+       u_int32_t packets;
+       u_int64_t blocks;
+       u_int64_t bytes;
+};
 
 
-/* Protocol flags for the remote side. */
-static u_int remote_protocol_flags = 0;
+struct packet {
+       TAILQ_ENTRY(packet) next;
+       u_char type;
+       Buffer payload;
+};
 
 
-/* Encryption context for receiving data.  This is only used for decryption. */
-static CipherContext receive_context;
+struct session_state {
+       /*
+        * This variable contains the file descriptors used for
+        * communicating with the other side.  connection_in is used for
+        * reading; connection_out for writing.  These can be the same
+        * descriptor, in which case it is assumed to be a socket.
+        */
+       int connection_in;
+       int connection_out;
 
 
-/* Encryption context for sending data.  This is only used for encryption. */
-static CipherContext send_context;
+       /* Protocol flags for the remote side. */
+       u_int remote_protocol_flags;
 
 
-/* Buffer for raw input data from the socket. */
-Buffer input;
+       /* Encryption context for receiving data.  Only used for decryption. */
+       CipherContext receive_context;
 
 
-/* Buffer for raw output data going to the socket. */
-Buffer output;
+       /* Encryption context for sending data.  Only used for encryption. */
+       CipherContext send_context;
 
 
-/* Buffer for the partial outgoing packet being constructed. */
-static Buffer outgoing_packet;
+       /* Buffer for raw input data from the socket. */
+       Buffer input;
 
 
-/* Buffer for the incoming packet currently being processed. */
-static Buffer incoming_packet;
+       /* Buffer for raw output data going to the socket. */
+       Buffer output;
 
 
-/* Scratch buffer for packet compression/decompression. */
-static Buffer compression_buffer;
-static int compression_buffer_ready = 0;
+       /* Buffer for the partial outgoing packet being constructed. */
+       Buffer outgoing_packet;
 
 
-/* Flag indicating whether packet compression/decompression is enabled. */
-static int packet_compression = 0;
+       /* Buffer for the incoming packet currently being processed. */
+       Buffer incoming_packet;
 
 
-/* default maximum packet size */
-u_int max_packet_size = 32768;
+       /* Scratch buffer for packet compression/decompression. */
+       Buffer compression_buffer;
+       int compression_buffer_ready;
 
 
-/* Flag indicating whether this module has been initialized. */
-static int initialized = 0;
+       /*
+        * Flag indicating whether packet compression/decompression is
+        * enabled.
+        */
+       int packet_compression;
 
 
-/* Set to true if the connection is interactive. */
-static int interactive_mode = 0;
+       /* default maximum packet size */
+       u_int max_packet_size;
 
 
-/* Set to true if we are the server side. */
-static int server_side = 0;
+       /* Flag indicating whether this module has been initialized. */
+       int initialized;
 
 
-/* Set to true if we are authenticated. */
-static int after_authentication = 0;
+       /* Set to true if the connection is interactive. */
+       int interactive_mode;
 
 
-int keep_alive_timeouts = 0;
+       /* Set to true if we are the server side. */
+       int server_side;
 
 
-/* Set to the maximum time that we will wait to send or receive a packet */
-static int packet_timeout_ms = -1;
+       /* Set to true if we are authenticated. */
+       int after_authentication;
 
 
-/* Session key information for Encryption and MAC */
-Newkeys *newkeys[MODE_MAX];
-static struct packet_state {
-       u_int32_t seqnr;
-       u_int32_t packets;
-       u_int64_t blocks;
-       u_int64_t bytes;
-} p_read, p_send;
+       int keep_alive_timeouts;
 
 
-static u_int64_t max_blocks_in, max_blocks_out;
-static u_int32_t rekey_limit;
+       /* The maximum time that we will wait to send or receive a packet */
+       int packet_timeout_ms;
 
 
-/* Session key for protocol v1 */
-static u_char ssh1_key[SSH_SESSION_KEY_LENGTH];
-static u_int ssh1_keylen;
+       /* Session key information for Encryption and MAC */
+       Newkeys *newkeys[MODE_MAX];
+       struct packet_state p_read, p_send;
 
 
-/* roundup current message to extra_pad bytes */
-static u_char extra_pad = 0;
+       u_int64_t max_blocks_in, max_blocks_out;
+       u_int32_t rekey_limit;
 
 
-/* XXX discard incoming data after MAC error */
-static u_int packet_discard = 0;
-static Mac *packet_discard_mac = NULL;
+       /* Session key for protocol v1 */
+       u_char ssh1_key[SSH_SESSION_KEY_LENGTH];
+       u_int ssh1_keylen;
 
 
-struct packet {
-       TAILQ_ENTRY(packet) next;
-       u_char type;
-       Buffer payload;
+       /* roundup current message to extra_pad bytes */
+       u_char extra_pad;
+
+       /* XXX discard incoming data after MAC error */
+       u_int packet_discard;
+       Mac *packet_discard_mac;
+
+       /* Used in packet_read_poll2() */
+       u_int packlen;
+
+       /* Used in packet_send2 */
+       int rekeying;
+
+       /* Used in packet_set_interactive */
+       int set_interactive_called;
+
+       /* Used in packet_set_maxsize */
+       int set_maxsize_called;
+
+       TAILQ_HEAD(, packet) outgoing;
 };
 };
-TAILQ_HEAD(, packet) outgoing;
+
+static struct session_state *active_state, *backup_state;
+
+static struct session_state *
+alloc_session_state(void)
+{
+    struct session_state *s = xcalloc(1, sizeof(*s));
+
+    s->connection_in = -1;
+    s->connection_out = -1;
+    s->max_packet_size = 32768;
+    s->packet_timeout_ms = -1;
+    return s;
+}
 
 /*
  * Sets the descriptors used for communication.  Disables encryption until
 
 /*
  * Sets the descriptors used for communication.  Disables encryption until
@@ -184,21 +219,23 @@ packet_set_connection(int fd_in, int fd_out)
 
        if (none == NULL)
                fatal("packet_set_connection: cannot load cipher 'none'");
 
        if (none == NULL)
                fatal("packet_set_connection: cannot load cipher 'none'");
-       connection_in = fd_in;
-       connection_out = fd_out;
-       cipher_init(&send_context, none, (const u_char *)"",
+       if (active_state == NULL)
+               active_state = alloc_session_state();
+       active_state->connection_in = fd_in;
+       active_state->connection_out = fd_out;
+       cipher_init(&active_state->send_context, none, (const u_char *)"",
            0, NULL, 0, CIPHER_ENCRYPT);
            0, NULL, 0, CIPHER_ENCRYPT);
-       cipher_init(&receive_context, none, (const u_char *)"",
+       cipher_init(&active_state->receive_context, none, (const u_char *)"",
            0, NULL, 0, CIPHER_DECRYPT);
            0, NULL, 0, CIPHER_DECRYPT);
-       newkeys[MODE_IN] = newkeys[MODE_OUT] = NULL;
-       if (!initialized) {
-               initialized = 1;
-               buffer_init(&input);
-               buffer_init(&output);
-               buffer_init(&outgoing_packet);
-               buffer_init(&incoming_packet);
-               TAILQ_INIT(&outgoing);
-               p_send.packets = p_read.packets = 0;
+       active_state->newkeys[MODE_IN] = active_state->newkeys[MODE_OUT] = NULL;
+       if (!active_state->initialized) {
+               active_state->initialized = 1;
+               buffer_init(&active_state->input);
+               buffer_init(&active_state->output);
+               buffer_init(&active_state->outgoing_packet);
+               buffer_init(&active_state->incoming_packet);
+               TAILQ_INIT(&active_state->outgoing);
+               active_state->p_send.packets = active_state->p_read.packets = 0;
        }
 }
 
        }
 }
 
@@ -206,27 +243,29 @@ void
 packet_set_timeout(int timeout, int count)
 {
        if (timeout == 0 || count == 0) {
 packet_set_timeout(int timeout, int count)
 {
        if (timeout == 0 || count == 0) {
-               packet_timeout_ms = -1;
+               active_state->packet_timeout_ms = -1;
                return;
        }
        if ((INT_MAX / 1000) / count < timeout)
                return;
        }
        if ((INT_MAX / 1000) / count < timeout)
-               packet_timeout_ms = INT_MAX;
+               active_state->packet_timeout_ms = INT_MAX;
        else
        else
-               packet_timeout_ms = timeout * count * 1000;
+               active_state->packet_timeout_ms = timeout * count * 1000;
 }
 
 static void
 packet_stop_discard(void)
 {
 }
 
 static void
 packet_stop_discard(void)
 {
-       if (packet_discard_mac) {
+       if (active_state->packet_discard_mac) {
                char buf[1024];
                
                memset(buf, 'a', sizeof(buf));
                char buf[1024];
                
                memset(buf, 'a', sizeof(buf));
-               while (buffer_len(&incoming_packet) < PACKET_MAX_SIZE)
-                       buffer_append(&incoming_packet, buf, sizeof(buf));
-               (void) mac_compute(packet_discard_mac,
-                   p_read.seqnr,
-                   buffer_ptr(&incoming_packet),
+               while (buffer_len(&active_state->incoming_packet) <
+                   PACKET_MAX_SIZE)
+                       buffer_append(&active_state->incoming_packet, buf,
+                           sizeof(buf));
+               (void) mac_compute(active_state->packet_discard_mac,
+                   active_state->p_read.seqnr,
+                   buffer_ptr(&active_state->incoming_packet),
                    PACKET_MAX_SIZE);
        }
        logit("Finished discarding for %.200s", get_remote_ipaddr());
                    PACKET_MAX_SIZE);
        }
        logit("Finished discarding for %.200s", get_remote_ipaddr());
@@ -239,10 +278,11 @@ packet_start_discard(Enc *enc, Mac *mac, u_int packet_length, u_int discard)
        if (enc == NULL || !cipher_is_cbc(enc->cipher))
                packet_disconnect("Packet corrupt");
        if (packet_length != PACKET_MAX_SIZE && mac && mac->enabled)
        if (enc == NULL || !cipher_is_cbc(enc->cipher))
                packet_disconnect("Packet corrupt");
        if (packet_length != PACKET_MAX_SIZE && mac && mac->enabled)
-               packet_discard_mac = mac;
-       if (buffer_len(&input) >= discard)
+               active_state->packet_discard_mac = mac;
+       if (buffer_len(&active_state->input) >= discard)
                packet_stop_discard();
                packet_stop_discard();
-       packet_discard = discard - buffer_len(&input);
+       active_state->packet_discard = discard -
+           buffer_len(&active_state->input);
 }
 
 /* Returns 1 if remote host is connected via socket, 0 if not. */
 }
 
 /* Returns 1 if remote host is connected via socket, 0 if not. */
@@ -254,15 +294,17 @@ packet_connection_is_on_socket(void)
        socklen_t fromlen, tolen;
 
        /* filedescriptors in and out are the same, so it's a socket */
        socklen_t fromlen, tolen;
 
        /* filedescriptors in and out are the same, so it's a socket */
-       if (connection_in == connection_out)
+       if (active_state->connection_in == active_state->connection_out)
                return 1;
        fromlen = sizeof(from);
        memset(&from, 0, sizeof(from));
                return 1;
        fromlen = sizeof(from);
        memset(&from, 0, sizeof(from));
-       if (getpeername(connection_in, (struct sockaddr *)&from, &fromlen) < 0)
+       if (getpeername(active_state->connection_in, (struct sockaddr *)&from,
+           &fromlen) < 0)
                return 0;
        tolen = sizeof(to);
        memset(&to, 0, sizeof(to));
                return 0;
        tolen = sizeof(to);
        memset(&to, 0, sizeof(to));
-       if (getpeername(connection_out, (struct sockaddr *)&to, &tolen) < 0)
+       if (getpeername(active_state->connection_out, (struct sockaddr *)&to,
+           &tolen) < 0)
                return 0;
        if (fromlen != tolen || memcmp(&from, &to, fromlen) != 0)
                return 0;
                return 0;
        if (fromlen != tolen || memcmp(&from, &to, fromlen) != 0)
                return 0;
@@ -283,9 +325,9 @@ packet_get_keyiv(int mode, u_char *iv, u_int len)
        CipherContext *cc;
 
        if (mode == MODE_OUT)
        CipherContext *cc;
 
        if (mode == MODE_OUT)
-               cc = &send_context;
+               cc = &active_state->send_context;
        else
        else
-               cc = &receive_context;
+               cc = &active_state->receive_context;
 
        cipher_get_keyiv(cc, iv, len);
 }
 
        cipher_get_keyiv(cc, iv, len);
 }
@@ -296,9 +338,9 @@ packet_get_keycontext(int mode, u_char *dat)
        CipherContext *cc;
 
        if (mode == MODE_OUT)
        CipherContext *cc;
 
        if (mode == MODE_OUT)
-               cc = &send_context;
+               cc = &active_state->send_context;
        else
        else
-               cc = &receive_context;
+               cc = &active_state->receive_context;
 
        return (cipher_get_keycontext(cc, dat));
 }
 
        return (cipher_get_keycontext(cc, dat));
 }
@@ -309,9 +351,9 @@ packet_set_keycontext(int mode, u_char *dat)
        CipherContext *cc;
 
        if (mode == MODE_OUT)
        CipherContext *cc;
 
        if (mode == MODE_OUT)
-               cc = &send_context;
+               cc = &active_state->send_context;
        else
        else
-               cc = &receive_context;
+               cc = &active_state->receive_context;
 
        cipher_set_keycontext(cc, dat);
 }
 
        cipher_set_keycontext(cc, dat);
 }
@@ -322,9 +364,9 @@ packet_get_keyiv_len(int mode)
        CipherContext *cc;
 
        if (mode == MODE_OUT)
        CipherContext *cc;
 
        if (mode == MODE_OUT)
-               cc = &send_context;
+               cc = &active_state->send_context;
        else
        else
-               cc = &receive_context;
+               cc = &active_state->receive_context;
 
        return (cipher_get_keyiv_len(cc));
 }
 
        return (cipher_get_keyiv_len(cc));
 }
@@ -335,9 +377,9 @@ packet_set_iv(int mode, u_char *dat)
        CipherContext *cc;
 
        if (mode == MODE_OUT)
        CipherContext *cc;
 
        if (mode == MODE_OUT)
-               cc = &send_context;
+               cc = &active_state->send_context;
        else
        else
-               cc = &receive_context;
+               cc = &active_state->receive_context;
 
        cipher_set_keyiv(cc, dat);
 }
 
        cipher_set_keyiv(cc, dat);
 }
@@ -345,7 +387,7 @@ packet_set_iv(int mode, u_char *dat)
 int
 packet_get_ssh1_cipher(void)
 {
 int
 packet_get_ssh1_cipher(void)
 {
-       return (cipher_get_number(receive_context.cipher));
+       return (cipher_get_number(active_state->receive_context.cipher));
 }
 
 void
 }
 
 void
@@ -354,7 +396,8 @@ packet_get_state(int mode, u_int32_t *seqnr, u_int64_t *blocks, u_int32_t *packe
 {
        struct packet_state *state;
 
 {
        struct packet_state *state;
 
-       state = (mode == MODE_IN) ? &p_read : &p_send;
+       state = (mode == MODE_IN) ?
+           &active_state->p_read : &active_state->p_send;
        if (seqnr)
                *seqnr = state->seqnr;
        if (blocks)
        if (seqnr)
                *seqnr = state->seqnr;
        if (blocks)
@@ -371,7 +414,8 @@ packet_set_state(int mode, u_int32_t seqnr, u_int64_t blocks, u_int32_t packets,
 {
        struct packet_state *state;
 
 {
        struct packet_state *state;
 
-       state = (mode == MODE_IN) ? &p_read : &p_send;
+       state = (mode == MODE_IN) ?
+           &active_state->p_read : &active_state->p_send;
        state->seqnr = seqnr;
        state->blocks = blocks;
        state->packets = packets;
        state->seqnr = seqnr;
        state->blocks = blocks;
        state->packets = packets;
@@ -387,7 +431,8 @@ packet_connection_is_ipv4(void)
        socklen_t tolen = sizeof(to);
 
        memset(&to, 0, sizeof(to));
        socklen_t tolen = sizeof(to);
 
        memset(&to, 0, sizeof(to));
-       if (getsockname(connection_out, (struct sockaddr *)&to, &tolen) < 0)
+       if (getsockname(active_state->connection_out, (struct sockaddr *)&to,
+           &tolen) < 0)
                return 0;
        if (to.ss_family == AF_INET)
                return 1;
                return 0;
        if (to.ss_family == AF_INET)
                return 1;
@@ -405,10 +450,10 @@ void
 packet_set_nonblocking(void)
 {
        /* Set the socket into non-blocking mode. */
 packet_set_nonblocking(void)
 {
        /* Set the socket into non-blocking mode. */
-       set_nonblock(connection_in);
+       set_nonblock(active_state->connection_in);
 
 
-       if (connection_out != connection_in)
-               set_nonblock(connection_out);
+       if (active_state->connection_out != active_state->connection_in)
+               set_nonblock(active_state->connection_out);
 }
 
 /* Returns the socket used for reading. */
 }
 
 /* Returns the socket used for reading. */
@@ -416,7 +461,7 @@ packet_set_nonblocking(void)
 int
 packet_get_connection_in(void)
 {
 int
 packet_get_connection_in(void)
 {
-       return connection_in;
+       return active_state->connection_in;
 }
 
 /* Returns the descriptor used for writing. */
 }
 
 /* Returns the descriptor used for writing. */
@@ -424,7 +469,7 @@ packet_get_connection_in(void)
 int
 packet_get_connection_out(void)
 {
 int
 packet_get_connection_out(void)
 {
-       return connection_out;
+       return active_state->connection_out;
 }
 
 /* Closes the connection and clears and frees internal data structures. */
 }
 
 /* Closes the connection and clears and frees internal data structures. */
@@ -432,26 +477,26 @@ packet_get_connection_out(void)
 void
 packet_close(void)
 {
 void
 packet_close(void)
 {
-       if (!initialized)
+       if (!active_state->initialized)
                return;
                return;
-       initialized = 0;
-       if (connection_in == connection_out) {
-               shutdown(connection_out, SHUT_RDWR);
-               close(connection_out);
+       active_state->initialized = 0;
+       if (active_state->connection_in == active_state->connection_out) {
+               shutdown(active_state->connection_out, SHUT_RDWR);
+               close(active_state->connection_out);
        } else {
        } else {
-               close(connection_in);
-               close(connection_out);
+               close(active_state->connection_in);
+               close(active_state->connection_out);
        }
        }
-       buffer_free(&input);
-       buffer_free(&output);
-       buffer_free(&outgoing_packet);
-       buffer_free(&incoming_packet);
-       if (compression_buffer_ready) {
-               buffer_free(&compression_buffer);
+       buffer_free(&active_state->input);
+       buffer_free(&active_state->output);
+       buffer_free(&active_state->outgoing_packet);
+       buffer_free(&active_state->incoming_packet);
+       if (active_state->compression_buffer_ready) {
+               buffer_free(&active_state->compression_buffer);
                buffer_compress_uninit();
        }
                buffer_compress_uninit();
        }
-       cipher_cleanup(&send_context);
-       cipher_cleanup(&receive_context);
+       cipher_cleanup(&active_state->send_context);
+       cipher_cleanup(&active_state->receive_context);
 }
 
 /* Sets remote side protocol flags. */
 }
 
 /* Sets remote side protocol flags. */
@@ -459,7 +504,7 @@ packet_close(void)
 void
 packet_set_protocol_flags(u_int protocol_flags)
 {
 void
 packet_set_protocol_flags(u_int protocol_flags)
 {
-       remote_protocol_flags = protocol_flags;
+       active_state->remote_protocol_flags = protocol_flags;
 }
 
 /* Returns the remote protocol flags set earlier by the above function. */
 }
 
 /* Returns the remote protocol flags set earlier by the above function. */
@@ -467,7 +512,7 @@ packet_set_protocol_flags(u_int protocol_flags)
 u_int
 packet_get_protocol_flags(void)
 {
 u_int
 packet_get_protocol_flags(void)
 {
-       return remote_protocol_flags;
+       return active_state->remote_protocol_flags;
 }
 
 /*
 }
 
 /*
@@ -478,18 +523,18 @@ packet_get_protocol_flags(void)
 static void
 packet_init_compression(void)
 {
 static void
 packet_init_compression(void)
 {
-       if (compression_buffer_ready == 1)
+       if (active_state->compression_buffer_ready == 1)
                return;
                return;
-       compression_buffer_ready = 1;
-       buffer_init(&compression_buffer);
+       active_state->compression_buffer_ready = 1;
+       buffer_init(&active_state->compression_buffer);
 }
 
 void
 packet_start_compression(int level)
 {
 }
 
 void
 packet_start_compression(int level)
 {
-       if (packet_compression && !compat20)
+       if (active_state->packet_compression && !compat20)
                fatal("Compression already enabled.");
                fatal("Compression already enabled.");
-       packet_compression = 1;
+       active_state->packet_compression = 1;
        packet_init_compression();
        buffer_compress_init_send(level);
        buffer_compress_init_recv();
        packet_init_compression();
        buffer_compress_init_send(level);
        buffer_compress_init_recv();
@@ -513,19 +558,21 @@ packet_set_encryption_key(const u_char *key, u_int keylen,
                fatal("packet_set_encryption_key: keylen too small: %d", keylen);
        if (keylen > SSH_SESSION_KEY_LENGTH)
                fatal("packet_set_encryption_key: keylen too big: %d", keylen);
                fatal("packet_set_encryption_key: keylen too small: %d", keylen);
        if (keylen > SSH_SESSION_KEY_LENGTH)
                fatal("packet_set_encryption_key: keylen too big: %d", keylen);
-       memcpy(ssh1_key, key, keylen);
-       ssh1_keylen = keylen;
-       cipher_init(&send_context, cipher, key, keylen, NULL, 0, CIPHER_ENCRYPT);
-       cipher_init(&receive_context, cipher, key, keylen, NULL, 0, CIPHER_DECRYPT);
+       memcpy(active_state->ssh1_key, key, keylen);
+       active_state->ssh1_keylen = keylen;
+       cipher_init(&active_state->send_context, cipher, key, keylen, NULL,
+           0, CIPHER_ENCRYPT);
+       cipher_init(&active_state->receive_context, cipher, key, keylen, NULL,
+           0, CIPHER_DECRYPT);
 }
 
 u_int
 packet_get_encryption_key(u_char *key)
 {
        if (key == NULL)
 }
 
 u_int
 packet_get_encryption_key(u_char *key)
 {
        if (key == NULL)
-               return (ssh1_keylen);
-       memcpy(key, ssh1_key, ssh1_keylen);
-       return (ssh1_keylen);
+               return (active_state->ssh1_keylen);
+       memcpy(key, active_state->ssh1_key, active_state->ssh1_keylen);
+       return (active_state->ssh1_keylen);
 }
 
 /* Start constructing a packet to send. */
 }
 
 /* Start constructing a packet to send. */
@@ -539,8 +586,8 @@ packet_start(u_char type)
        len = compat20 ? 6 : 9;
        memset(buf, 0, len - 1);
        buf[len - 1] = type;
        len = compat20 ? 6 : 9;
        memset(buf, 0, len - 1);
        buf[len - 1] = type;
-       buffer_clear(&outgoing_packet);
-       buffer_append(&outgoing_packet, buf, len);
+       buffer_clear(&active_state->outgoing_packet);
+       buffer_append(&active_state->outgoing_packet, buf, len);
 }
 
 /* Append payload. */
 }
 
 /* Append payload. */
@@ -549,43 +596,49 @@ packet_put_char(int value)
 {
        char ch = value;
 
 {
        char ch = value;
 
-       buffer_append(&outgoing_packet, &ch, 1);
+       buffer_append(&active_state->outgoing_packet, &ch, 1);
 }
 
 void
 packet_put_int(u_int value)
 {
 }
 
 void
 packet_put_int(u_int value)
 {
-       buffer_put_int(&outgoing_packet, value);
+       buffer_put_int(&active_state->outgoing_packet, value);
+}
+
+void
+packet_put_int64(u_int64_t value)
+{
+       buffer_put_int64(&active_state->outgoing_packet, value);
 }
 
 void
 packet_put_string(const void *buf, u_int len)
 {
 }
 
 void
 packet_put_string(const void *buf, u_int len)
 {
-       buffer_put_string(&outgoing_packet, buf, len);
+       buffer_put_string(&active_state->outgoing_packet, buf, len);
 }
 
 void
 packet_put_cstring(const char *str)
 {
 }
 
 void
 packet_put_cstring(const char *str)
 {
-       buffer_put_cstring(&outgoing_packet, str);
+       buffer_put_cstring(&active_state->outgoing_packet, str);
 }
 
 void
 packet_put_raw(const void *buf, u_int len)
 {
 }
 
 void
 packet_put_raw(const void *buf, u_int len)
 {
-       buffer_append(&outgoing_packet, buf, len);
+       buffer_append(&active_state->outgoing_packet, buf, len);
 }
 
 void
 packet_put_bignum(BIGNUM * value)
 {
 }
 
 void
 packet_put_bignum(BIGNUM * value)
 {
-       buffer_put_bignum(&outgoing_packet, value);
+       buffer_put_bignum(&active_state->outgoing_packet, value);
 }
 
 void
 packet_put_bignum2(BIGNUM * value)
 {
 }
 
 void
 packet_put_bignum2(BIGNUM * value)
 {
-       buffer_put_bignum2(&outgoing_packet, value);
+       buffer_put_bignum2(&active_state->outgoing_packet, value);
 }
 
 /*
 }
 
 /*
@@ -605,24 +658,27 @@ packet_send1(void)
         * If using packet compression, compress the payload of the outgoing
         * packet.
         */
         * If using packet compression, compress the payload of the outgoing
         * packet.
         */
-       if (packet_compression) {
-               buffer_clear(&compression_buffer);
+       if (active_state->packet_compression) {
+               buffer_clear(&active_state->compression_buffer);
                /* Skip padding. */
                /* Skip padding. */
-               buffer_consume(&outgoing_packet, 8);
+               buffer_consume(&active_state->outgoing_packet, 8);
                /* padding */
                /* padding */
-               buffer_append(&compression_buffer, "\0\0\0\0\0\0\0\0", 8);
-               buffer_compress(&outgoing_packet, &compression_buffer);
-               buffer_clear(&outgoing_packet);
-               buffer_append(&outgoing_packet, buffer_ptr(&compression_buffer),
-                   buffer_len(&compression_buffer));
+               buffer_append(&active_state->compression_buffer,
+                   "\0\0\0\0\0\0\0\0", 8);
+               buffer_compress(&active_state->outgoing_packet,
+                   &active_state->compression_buffer);
+               buffer_clear(&active_state->outgoing_packet);
+               buffer_append(&active_state->outgoing_packet,
+                   buffer_ptr(&active_state->compression_buffer),
+                   buffer_len(&active_state->compression_buffer));
        }
        /* Compute packet length without padding (add checksum, remove padding). */
        }
        /* Compute packet length without padding (add checksum, remove padding). */
-       len = buffer_len(&outgoing_packet) + 4 - 8;
+       len = buffer_len(&active_state->outgoing_packet) + 4 - 8;
 
        /* Insert padding. Initialized to zero in packet_start1() */
        padding = 8 - len % 8;
 
        /* Insert padding. Initialized to zero in packet_start1() */
        padding = 8 - len % 8;
-       if (!send_context.plaintext) {
-               cp = buffer_ptr(&outgoing_packet);
+       if (!active_state->send_context.plaintext) {
+               cp = buffer_ptr(&active_state->outgoing_packet);
                for (i = 0; i < padding; i++) {
                        if (i % 4 == 0)
                                rnd = arc4random();
                for (i = 0; i < padding; i++) {
                        if (i % 4 == 0)
                                rnd = arc4random();
@@ -630,33 +686,36 @@ packet_send1(void)
                        rnd >>= 8;
                }
        }
                        rnd >>= 8;
                }
        }
-       buffer_consume(&outgoing_packet, 8 - padding);
+       buffer_consume(&active_state->outgoing_packet, 8 - padding);
 
        /* Add check bytes. */
 
        /* Add check bytes. */
-       checksum = ssh_crc32(buffer_ptr(&outgoing_packet),
-           buffer_len(&outgoing_packet));
+       checksum = ssh_crc32(buffer_ptr(&active_state->outgoing_packet),
+           buffer_len(&active_state->outgoing_packet));
        put_u32(buf, checksum);
        put_u32(buf, checksum);
-       buffer_append(&outgoing_packet, buf, 4);
+       buffer_append(&active_state->outgoing_packet, buf, 4);
 
 #ifdef PACKET_DEBUG
        fprintf(stderr, "packet_send plain: ");
 
 #ifdef PACKET_DEBUG
        fprintf(stderr, "packet_send plain: ");
-       buffer_dump(&outgoing_packet);
+       buffer_dump(&active_state->outgoing_packet);
 #endif
 
        /* Append to output. */
        put_u32(buf, len);
 #endif
 
        /* Append to output. */
        put_u32(buf, len);
-       buffer_append(&output, buf, 4);
-       cp = buffer_append_space(&output, buffer_len(&outgoing_packet));
-       cipher_crypt(&send_context, cp, buffer_ptr(&outgoing_packet),
-           buffer_len(&outgoing_packet));
+       buffer_append(&active_state->output, buf, 4);
+       cp = buffer_append_space(&active_state->output,
+           buffer_len(&active_state->outgoing_packet));
+       cipher_crypt(&active_state->send_context, cp,
+           buffer_ptr(&active_state->outgoing_packet),
+           buffer_len(&active_state->outgoing_packet));
 
 #ifdef PACKET_DEBUG
        fprintf(stderr, "encrypted: ");
 
 #ifdef PACKET_DEBUG
        fprintf(stderr, "encrypted: ");
-       buffer_dump(&output);
+       buffer_dump(&active_state->output);
 #endif
 #endif
-       p_send.packets++;
-       p_send.bytes += len + buffer_len(&outgoing_packet);
-       buffer_clear(&outgoing_packet);
+       active_state->p_send.packets++;
+       active_state->p_send.bytes += len +
+           buffer_len(&active_state->outgoing_packet);
+       buffer_clear(&active_state->outgoing_packet);
 
        /*
         * Note that the packet is now only buffered in output.  It won't be
 
        /*
         * Note that the packet is now only buffered in output.  It won't be
@@ -678,22 +737,22 @@ set_newkeys(int mode)
        debug2("set_newkeys: mode %d", mode);
 
        if (mode == MODE_OUT) {
        debug2("set_newkeys: mode %d", mode);
 
        if (mode == MODE_OUT) {
-               cc = &send_context;
+               cc = &active_state->send_context;
                crypt_type = CIPHER_ENCRYPT;
                crypt_type = CIPHER_ENCRYPT;
-               p_send.packets = p_send.blocks = 0;
-               max_blocks = &max_blocks_out;
+               active_state->p_send.packets = active_state->p_send.blocks = 0;
+               max_blocks = &active_state->max_blocks_out;
        } else {
        } else {
-               cc = &receive_context;
+               cc = &active_state->receive_context;
                crypt_type = CIPHER_DECRYPT;
                crypt_type = CIPHER_DECRYPT;
-               p_read.packets = p_read.blocks = 0;
-               max_blocks = &max_blocks_in;
+               active_state->p_read.packets = active_state->p_read.blocks = 0;
+               max_blocks = &active_state->max_blocks_in;
        }
        }
-       if (newkeys[mode] != NULL) {
+       if (active_state->newkeys[mode] != NULL) {
                debug("set_newkeys: rekeying");
                cipher_cleanup(cc);
                debug("set_newkeys: rekeying");
                cipher_cleanup(cc);
-               enc  = &newkeys[mode]->enc;
-               mac  = &newkeys[mode]->mac;
-               comp = &newkeys[mode]->comp;
+               enc  = &active_state->newkeys[mode]->enc;
+               mac  = &active_state->newkeys[mode]->mac;
+               comp = &active_state->newkeys[mode]->comp;
                mac_clear(mac);
                xfree(enc->name);
                xfree(enc->iv);
                mac_clear(mac);
                xfree(enc->name);
                xfree(enc->iv);
@@ -701,14 +760,14 @@ set_newkeys(int mode)
                xfree(mac->name);
                xfree(mac->key);
                xfree(comp->name);
                xfree(mac->name);
                xfree(mac->key);
                xfree(comp->name);
-               xfree(newkeys[mode]);
+               xfree(active_state->newkeys[mode]);
        }
        }
-       newkeys[mode] = kex_get_newkeys(mode);
-       if (newkeys[mode] == NULL)
+       active_state->newkeys[mode] = kex_get_newkeys(mode);
+       if (active_state->newkeys[mode] == NULL)
                fatal("newkeys: no keys for mode %d", mode);
                fatal("newkeys: no keys for mode %d", mode);
-       enc  = &newkeys[mode]->enc;
-       mac  = &newkeys[mode]->mac;
-       comp = &newkeys[mode]->comp;
+       enc  = &active_state->newkeys[mode]->enc;
+       mac  = &active_state->newkeys[mode]->mac;
+       comp = &active_state->newkeys[mode]->comp;
        if (mac_init(mac) == 0)
                mac->enabled = 1;
        DBG(debug("cipher_init_context: %d", mode));
        if (mac_init(mac) == 0)
                mac->enabled = 1;
        DBG(debug("cipher_init_context: %d", mode));
@@ -719,8 +778,8 @@ set_newkeys(int mode)
           memset(enc->key, 0, enc->key_len);
           memset(mac->key, 0, mac->key_len); */
        if ((comp->type == COMP_ZLIB ||
           memset(enc->key, 0, enc->key_len);
           memset(mac->key, 0, mac->key_len); */
        if ((comp->type == COMP_ZLIB ||
-           (comp->type == COMP_DELAYED && after_authentication)) &&
-           comp->enabled == 0) {
+           (comp->type == COMP_DELAYED &&
+            active_state->after_authentication)) && comp->enabled == 0) {
                packet_init_compression();
                if (mode == MODE_OUT)
                        buffer_compress_init_send(6);
                packet_init_compression();
                if (mode == MODE_OUT)
                        buffer_compress_init_send(6);
@@ -736,8 +795,9 @@ set_newkeys(int mode)
                *max_blocks = (u_int64_t)1 << (enc->block_size*2);
        else
                *max_blocks = ((u_int64_t)1 << 30) / enc->block_size;
                *max_blocks = (u_int64_t)1 << (enc->block_size*2);
        else
                *max_blocks = ((u_int64_t)1 << 30) / enc->block_size;
-       if (rekey_limit)
-               *max_blocks = MIN(*max_blocks, rekey_limit / enc->block_size);
+       if (active_state->rekey_limit)
+               *max_blocks = MIN(*max_blocks,
+                   active_state->rekey_limit / enc->block_size);
 }
 
 /*
 }
 
 /*
@@ -755,12 +815,12 @@ packet_enable_delayed_compress(void)
         * Remember that we are past the authentication step, so rekeying
         * with COMP_DELAYED will turn on compression immediately.
         */
         * Remember that we are past the authentication step, so rekeying
         * with COMP_DELAYED will turn on compression immediately.
         */
-       after_authentication = 1;
+       active_state->after_authentication = 1;
        for (mode = 0; mode < MODE_MAX; mode++) {
                /* protocol error: USERAUTH_SUCCESS received before NEWKEYS */
        for (mode = 0; mode < MODE_MAX; mode++) {
                /* protocol error: USERAUTH_SUCCESS received before NEWKEYS */
-               if (newkeys[mode] == NULL)
+               if (active_state->newkeys[mode] == NULL)
                        continue;
                        continue;
-               comp = &newkeys[mode]->comp;
+               comp = &active_state->newkeys[mode]->comp;
                if (comp && !comp->enabled && comp->type == COMP_DELAYED) {
                        packet_init_compression();
                        if (mode == MODE_OUT)
                if (comp && !comp->enabled && comp->type == COMP_DELAYED) {
                        packet_init_compression();
                        if (mode == MODE_OUT)
@@ -788,37 +848,39 @@ packet_send2_wrapped(void)
        Comp *comp = NULL;
        int block_size;
 
        Comp *comp = NULL;
        int block_size;
 
-       if (newkeys[MODE_OUT] != NULL) {
-               enc  = &newkeys[MODE_OUT]->enc;
-               mac  = &newkeys[MODE_OUT]->mac;
-               comp = &newkeys[MODE_OUT]->comp;
+       if (active_state->newkeys[MODE_OUT] != NULL) {
+               enc  = &active_state->newkeys[MODE_OUT]->enc;
+               mac  = &active_state->newkeys[MODE_OUT]->mac;
+               comp = &active_state->newkeys[MODE_OUT]->comp;
        }
        block_size = enc ? enc->block_size : 8;
 
        }
        block_size = enc ? enc->block_size : 8;
 
-       cp = buffer_ptr(&outgoing_packet);
+       cp = buffer_ptr(&active_state->outgoing_packet);
        type = cp[5];
 
 #ifdef PACKET_DEBUG
        fprintf(stderr, "plain:     ");
        type = cp[5];
 
 #ifdef PACKET_DEBUG
        fprintf(stderr, "plain:     ");
-       buffer_dump(&outgoing_packet);
+       buffer_dump(&active_state->outgoing_packet);
 #endif
 
        if (comp && comp->enabled) {
 #endif
 
        if (comp && comp->enabled) {
-               len = buffer_len(&outgoing_packet);
+               len = buffer_len(&active_state->outgoing_packet);
                /* skip header, compress only payload */
                /* skip header, compress only payload */
-               buffer_consume(&outgoing_packet, 5);
-               buffer_clear(&compression_buffer);
-               buffer_compress(&outgoing_packet, &compression_buffer);
-               buffer_clear(&outgoing_packet);
-               buffer_append(&outgoing_packet, "\0\0\0\0\0", 5);
-               buffer_append(&outgoing_packet, buffer_ptr(&compression_buffer),
-                   buffer_len(&compression_buffer));
+               buffer_consume(&active_state->outgoing_packet, 5);
+               buffer_clear(&active_state->compression_buffer);
+               buffer_compress(&active_state->outgoing_packet,
+                   &active_state->compression_buffer);
+               buffer_clear(&active_state->outgoing_packet);
+               buffer_append(&active_state->outgoing_packet, "\0\0\0\0\0", 5);
+               buffer_append(&active_state->outgoing_packet,
+                   buffer_ptr(&active_state->compression_buffer),
+                   buffer_len(&active_state->compression_buffer));
                DBG(debug("compression: raw %d compressed %d", len,
                DBG(debug("compression: raw %d compressed %d", len,
-                   buffer_len(&outgoing_packet)));
+                   buffer_len(&active_state->outgoing_packet)));
        }
 
        /* sizeof (packet_len + pad_len + payload) */
        }
 
        /* sizeof (packet_len + pad_len + payload) */
-       len = buffer_len(&outgoing_packet);
+       len = buffer_len(&active_state->outgoing_packet);
 
        /*
         * calc size of padding, alloc space, get random data,
 
        /*
         * calc size of padding, alloc space, get random data,
@@ -827,17 +889,19 @@ packet_send2_wrapped(void)
        padlen = block_size - (len % block_size);
        if (padlen < 4)
                padlen += block_size;
        padlen = block_size - (len % block_size);
        if (padlen < 4)
                padlen += block_size;
-       if (extra_pad) {
+       if (active_state->extra_pad) {
                /* will wrap if extra_pad+padlen > 255 */
                /* will wrap if extra_pad+padlen > 255 */
-               extra_pad  = roundup(extra_pad, block_size);
-               pad = extra_pad - ((len + padlen) % extra_pad);
+               active_state->extra_pad =
+                   roundup(active_state->extra_pad, block_size);
+               pad = active_state->extra_pad -
+                   ((len + padlen) % active_state->extra_pad);
                debug3("packet_send2: adding %d (len %d padlen %d extra_pad %d)",
                debug3("packet_send2: adding %d (len %d padlen %d extra_pad %d)",
-                   pad, len, padlen, extra_pad);
+                   pad, len, padlen, active_state->extra_pad);
                padlen += pad;
                padlen += pad;
-               extra_pad = 0;
+               active_state->extra_pad = 0;
        }
        }
-       cp = buffer_append_space(&outgoing_packet, padlen);
-       if (enc && !send_context.plaintext) {
+       cp = buffer_append_space(&active_state->outgoing_packet, padlen);
+       if (enc && !active_state->send_context.plaintext) {
                /* random padding */
                for (i = 0; i < padlen; i++) {
                        if (i % 4 == 0)
                /* random padding */
                for (i = 0; i < padlen; i++) {
                        if (i % 4 == 0)
@@ -850,43 +914,45 @@ packet_send2_wrapped(void)
                memset(cp, 0, padlen);
        }
        /* packet_length includes payload, padding and padding length field */
                memset(cp, 0, padlen);
        }
        /* packet_length includes payload, padding and padding length field */
-       packet_length = buffer_len(&outgoing_packet) - 4;
-       cp = buffer_ptr(&outgoing_packet);
+       packet_length = buffer_len(&active_state->outgoing_packet) - 4;
+       cp = buffer_ptr(&active_state->outgoing_packet);
        put_u32(cp, packet_length);
        cp[4] = padlen;
        DBG(debug("send: len %d (includes padlen %d)", packet_length+4, padlen));
 
        /* compute MAC over seqnr and packet(length fields, payload, padding) */
        if (mac && mac->enabled) {
        put_u32(cp, packet_length);
        cp[4] = padlen;
        DBG(debug("send: len %d (includes padlen %d)", packet_length+4, padlen));
 
        /* compute MAC over seqnr and packet(length fields, payload, padding) */
        if (mac && mac->enabled) {
-               macbuf = mac_compute(mac, p_send.seqnr,
-                   buffer_ptr(&outgoing_packet),
-                   buffer_len(&outgoing_packet));
-               DBG(debug("done calc MAC out #%d", p_send.seqnr));
+               macbuf = mac_compute(mac, active_state->p_send.seqnr,
+                   buffer_ptr(&active_state->outgoing_packet),
+                   buffer_len(&active_state->outgoing_packet));
+               DBG(debug("done calc MAC out #%d", active_state->p_send.seqnr));
        }
        /* encrypt packet and append to output buffer. */
        }
        /* encrypt packet and append to output buffer. */
-       cp = buffer_append_space(&output, buffer_len(&outgoing_packet));
-       cipher_crypt(&send_context, cp, buffer_ptr(&outgoing_packet),
-           buffer_len(&outgoing_packet));
+       cp = buffer_append_space(&active_state->output,
+           buffer_len(&active_state->outgoing_packet));
+       cipher_crypt(&active_state->send_context, cp,
+           buffer_ptr(&active_state->outgoing_packet),
+           buffer_len(&active_state->outgoing_packet));
        /* append unencrypted MAC */
        if (mac && mac->enabled)
        /* append unencrypted MAC */
        if (mac && mac->enabled)
-               buffer_append(&output, macbuf, mac->mac_len);
+               buffer_append(&active_state->output, macbuf, mac->mac_len);
 #ifdef PACKET_DEBUG
        fprintf(stderr, "encrypted: ");
 #ifdef PACKET_DEBUG
        fprintf(stderr, "encrypted: ");
-       buffer_dump(&output);
+       buffer_dump(&active_state->output);
 #endif
        /* increment sequence number for outgoing packets */
 #endif
        /* increment sequence number for outgoing packets */
-       if (++p_send.seqnr == 0)
+       if (++active_state->p_send.seqnr == 0)
                logit("outgoing seqnr wraps around");
                logit("outgoing seqnr wraps around");
-       if (++p_send.packets == 0)
+       if (++active_state->p_send.packets == 0)
                if (!(datafellows & SSH_BUG_NOREKEY))
                        fatal("XXX too many packets with same key");
                if (!(datafellows & SSH_BUG_NOREKEY))
                        fatal("XXX too many packets with same key");
-       p_send.blocks += (packet_length + 4) / block_size;
-       p_send.bytes += packet_length + 4;
-       buffer_clear(&outgoing_packet);
+       active_state->p_send.blocks += (packet_length + 4) / block_size;
+       active_state->p_send.bytes += packet_length + 4;
+       buffer_clear(&active_state->outgoing_packet);
 
        if (type == SSH2_MSG_NEWKEYS)
                set_newkeys(MODE_OUT);
 
        if (type == SSH2_MSG_NEWKEYS)
                set_newkeys(MODE_OUT);
-       else if (type == SSH2_MSG_USERAUTH_SUCCESS && server_side)
+       else if (type == SSH2_MSG_USERAUTH_SUCCESS && active_state->server_side)
                packet_enable_delayed_compress();
        return(packet_length);
 }
                packet_enable_delayed_compress();
        return(packet_length);
 }
@@ -894,44 +960,44 @@ packet_send2_wrapped(void)
 static int
 packet_send2(void)
 {
 static int
 packet_send2(void)
 {
-        static int packet_length = 0;
-       static int rekeying = 0;
+       static int packet_length = 0;
        struct packet *p;
        u_char type, *cp;
 
        struct packet *p;
        u_char type, *cp;
 
-       cp = buffer_ptr(&outgoing_packet);
+       cp = buffer_ptr(&active_state->outgoing_packet);
        type = cp[5];
 
        /* during rekeying we can only send key exchange messages */
        type = cp[5];
 
        /* during rekeying we can only send key exchange messages */
-       if (rekeying) {
+       if (active_state->rekeying) {
                if (!((type >= SSH2_MSG_TRANSPORT_MIN) &&
                    (type <= SSH2_MSG_TRANSPORT_MAX))) {
                        debug("enqueue packet: %u", type);
                        p = xmalloc(sizeof(*p));
                        p->type = type;
                if (!((type >= SSH2_MSG_TRANSPORT_MIN) &&
                    (type <= SSH2_MSG_TRANSPORT_MAX))) {
                        debug("enqueue packet: %u", type);
                        p = xmalloc(sizeof(*p));
                        p->type = type;
-                       memcpy(&p->payload, &outgoing_packet, sizeof(Buffer));
-                       buffer_init(&outgoing_packet);
-                       TAILQ_INSERT_TAIL(&outgoing, p, next);
+                       memcpy(&p->payload, &active_state->outgoing_packet,
+                           sizeof(Buffer));
+                       buffer_init(&active_state->outgoing_packet);
+                       TAILQ_INSERT_TAIL(&active_state->outgoing, p, next);
                        return(sizeof(Buffer));
                }
        }
 
        /* rekeying starts with sending KEXINIT */
        if (type == SSH2_MSG_KEXINIT)
                        return(sizeof(Buffer));
                }
        }
 
        /* rekeying starts with sending KEXINIT */
        if (type == SSH2_MSG_KEXINIT)
-               rekeying = 1;
+               active_state->rekeying = 1;
 
        packet_length = packet_send2_wrapped();
 
        /* after a NEWKEYS message we can send the complete queue */
        if (type == SSH2_MSG_NEWKEYS) {
 
        packet_length = packet_send2_wrapped();
 
        /* after a NEWKEYS message we can send the complete queue */
        if (type == SSH2_MSG_NEWKEYS) {
-               rekeying = 0;
-               while ((p = TAILQ_FIRST(&outgoing))) {
+               active_state->rekeying = 0;
+               while ((p = TAILQ_FIRST(&active_state->outgoing))) {
                        type = p->type;
                        debug("dequeue packet: %u", type);
                        type = p->type;
                        debug("dequeue packet: %u", type);
-                       buffer_free(&outgoing_packet);
-                       memcpy(&outgoing_packet, &p->payload,
+                       buffer_free(&active_state->outgoing_packet);
+                       memcpy(&active_state->outgoing_packet, &p->payload,
                            sizeof(Buffer));
                            sizeof(Buffer));
-                       TAILQ_REMOVE(&outgoing, p, next);
+                       TAILQ_REMOVE(&active_state->outgoing, p, next);
                        xfree(p);
                        packet_length += packet_send2_wrapped();
                }
                        xfree(p);
                        packet_length += packet_send2_wrapped();
                }
@@ -960,15 +1026,15 @@ packet_send(void)
 int
 packet_read_seqnr(u_int32_t *seqnr_p)
 {
 int
 packet_read_seqnr(u_int32_t *seqnr_p)
 {
-       int type, len, ret, ms_remain;
+       int type, len, ret, ms_remain, cont;
        fd_set *setp;
        char buf[8192];
        struct timeval timeout, start, *timeoutp = NULL;
 
        DBG(debug("packet_read()"));
 
        fd_set *setp;
        char buf[8192];
        struct timeval timeout, start, *timeoutp = NULL;
 
        DBG(debug("packet_read()"));
 
-       setp = (fd_set *)xcalloc(howmany(connection_in+1, NFDBITS),
-           sizeof(fd_mask));
+       setp = (fd_set *)xcalloc(howmany(active_state->connection_in + 1,
+           NFDBITS), sizeof(fd_mask));
 
        /* Since we are blocking, ensure that all written packets have been sent. */
        packet_write_wait();
 
        /* Since we are blocking, ensure that all written packets have been sent. */
        packet_write_wait();
@@ -992,27 +1058,27 @@ packet_read_seqnr(u_int32_t *seqnr_p)
                 * Otherwise, wait for some data to arrive, add it to the
                 * buffer, and try again.
                 */
                 * Otherwise, wait for some data to arrive, add it to the
                 * buffer, and try again.
                 */
-               memset(setp, 0, howmany(connection_in + 1, NFDBITS) *
-                   sizeof(fd_mask));
-               FD_SET(connection_in, setp);
+               memset(setp, 0, howmany(active_state->connection_in + 1,
+                   NFDBITS) * sizeof(fd_mask));
+               FD_SET(active_state->connection_in, setp);
 
 
-               if (packet_timeout_ms > 0) {
-                       ms_remain = packet_timeout_ms;
+               if (active_state->packet_timeout_ms > 0) {
+                       ms_remain = active_state->packet_timeout_ms;
                        timeoutp = &timeout;
                }
                /* Wait for some data to arrive. */
                for (;;) {
                        timeoutp = &timeout;
                }
                /* Wait for some data to arrive. */
                for (;;) {
-                       if (packet_timeout_ms != -1) {
+                       if (active_state->packet_timeout_ms != -1) {
                                ms_to_timeval(&timeout, ms_remain);
                                gettimeofday(&start, NULL);
                        }
                                ms_to_timeval(&timeout, ms_remain);
                                gettimeofday(&start, NULL);
                        }
-                       if ((ret = select(connection_in + 1, setp, NULL,
-                           NULL, timeoutp)) >= 0)
+                       if ((ret = select(active_state->connection_in + 1, setp,
+                           NULL, NULL, timeoutp)) >= 0)
                                break;
                                break;
-                       if (errno != EAGAIN && errno != EINTR &&
+                       if (errno != EAGAIN && errno != EINTR &&
                            errno != EWOULDBLOCK)
                                break;
                            errno != EWOULDBLOCK)
                                break;
-                       if (packet_timeout_ms == -1)
+                       if (active_state->packet_timeout_ms == -1)
                                continue;
                        ms_subtract_diff(&start, &ms_remain);
                        if (ms_remain <= 0) {
                                continue;
                        ms_subtract_diff(&start, &ms_remain);
                        if (ms_remain <= 0) {
@@ -1026,7 +1092,11 @@ packet_read_seqnr(u_int32_t *seqnr_p)
                        cleanup_exit(255);
                }
                /* Read data from the socket. */
                        cleanup_exit(255);
                }
                /* Read data from the socket. */
-               len = read(connection_in, buf, sizeof(buf));
+               do {
+                       cont = 0;
+                       len = roaming_read(active_state->connection_in, buf,
+                           sizeof(buf), &cont);
+               } while (len == 0 && cont);
                if (len == 0) {
                        logit("Connection closed by %.200s", get_remote_ipaddr());
                        cleanup_exit(255);
                if (len == 0) {
                        logit("Connection closed by %.200s", get_remote_ipaddr());
                        cleanup_exit(255);
@@ -1078,31 +1148,32 @@ packet_read_poll1(void)
        u_int checksum, stored_checksum;
 
        /* Check if input size is less than minimum packet size. */
        u_int checksum, stored_checksum;
 
        /* Check if input size is less than minimum packet size. */
-       if (buffer_len(&input) < 4 + 8)
+       if (buffer_len(&active_state->input) < 4 + 8)
                return SSH_MSG_NONE;
        /* Get length of incoming packet. */
                return SSH_MSG_NONE;
        /* Get length of incoming packet. */
-       cp = buffer_ptr(&input);
+       cp = buffer_ptr(&active_state->input);
        len = get_u32(cp);
        if (len < 1 + 2 + 2 || len > 256 * 1024)
                packet_disconnect("Bad packet length %u.", len);
        padded_len = (len + 8) & ~7;
 
        /* Check if the packet has been entirely received. */
        len = get_u32(cp);
        if (len < 1 + 2 + 2 || len > 256 * 1024)
                packet_disconnect("Bad packet length %u.", len);
        padded_len = (len + 8) & ~7;
 
        /* Check if the packet has been entirely received. */
-       if (buffer_len(&input) < 4 + padded_len)
+       if (buffer_len(&active_state->input) < 4 + padded_len)
                return SSH_MSG_NONE;
 
        /* The entire packet is in buffer. */
 
        /* Consume packet length. */
                return SSH_MSG_NONE;
 
        /* The entire packet is in buffer. */
 
        /* Consume packet length. */
-       buffer_consume(&input, 4);
+       buffer_consume(&active_state->input, 4);
 
        /*
         * Cryptographic attack detector for ssh
         * (C)1998 CORE-SDI, Buenos Aires Argentina
         * Ariel Futoransky(futo@core-sdi.com)
         */
 
        /*
         * Cryptographic attack detector for ssh
         * (C)1998 CORE-SDI, Buenos Aires Argentina
         * Ariel Futoransky(futo@core-sdi.com)
         */
-       if (!receive_context.plaintext) {
-               switch (detect_attack(buffer_ptr(&input), padded_len)) {
+       if (!active_state->receive_context.plaintext) {
+               switch (detect_attack(buffer_ptr(&active_state->input),
+                   padded_len)) {
                case DEATTACK_DETECTED:
                        packet_disconnect("crc32 compensation attack: "
                            "network attack detected");
                case DEATTACK_DETECTED:
                        packet_disconnect("crc32 compensation attack: "
                            "network attack detected");
@@ -1113,45 +1184,48 @@ packet_read_poll1(void)
        }
 
        /* Decrypt data to incoming_packet. */
        }
 
        /* Decrypt data to incoming_packet. */
-       buffer_clear(&incoming_packet);
-       cp = buffer_append_space(&incoming_packet, padded_len);
-       cipher_crypt(&receive_context, cp, buffer_ptr(&input), padded_len);
+       buffer_clear(&active_state->incoming_packet);
+       cp = buffer_append_space(&active_state->incoming_packet, padded_len);
+       cipher_crypt(&active_state->receive_context, cp,
+           buffer_ptr(&active_state->input), padded_len);
 
 
-       buffer_consume(&input, padded_len);
+       buffer_consume(&active_state->input, padded_len);
 
 #ifdef PACKET_DEBUG
        fprintf(stderr, "read_poll plain: ");
 
 #ifdef PACKET_DEBUG
        fprintf(stderr, "read_poll plain: ");
-       buffer_dump(&incoming_packet);
+       buffer_dump(&active_state->incoming_packet);
 #endif
 
        /* Compute packet checksum. */
 #endif
 
        /* Compute packet checksum. */
-       checksum = ssh_crc32(buffer_ptr(&incoming_packet),
-           buffer_len(&incoming_packet) - 4);
+       checksum = ssh_crc32(buffer_ptr(&active_state->incoming_packet),
+           buffer_len(&active_state->incoming_packet) - 4);
 
        /* Skip padding. */
 
        /* Skip padding. */
-       buffer_consume(&incoming_packet, 8 - len % 8);
+       buffer_consume(&active_state->incoming_packet, 8 - len % 8);
 
        /* Test check bytes. */
 
        /* Test check bytes. */
-       if (len != buffer_len(&incoming_packet))
+       if (len != buffer_len(&active_state->incoming_packet))
                packet_disconnect("packet_read_poll1: len %d != buffer_len %d.",
                packet_disconnect("packet_read_poll1: len %d != buffer_len %d.",
-                   len, buffer_len(&incoming_packet));
+                   len, buffer_len(&active_state->incoming_packet));
 
 
-       cp = (u_char *)buffer_ptr(&incoming_packet) + len - 4;
+       cp = (u_char *)buffer_ptr(&active_state->incoming_packet) + len - 4;
        stored_checksum = get_u32(cp);
        if (checksum != stored_checksum)
                packet_disconnect("Corrupted check bytes on input.");
        stored_checksum = get_u32(cp);
        if (checksum != stored_checksum)
                packet_disconnect("Corrupted check bytes on input.");
-       buffer_consume_end(&incoming_packet, 4);
-
-       if (packet_compression) {
-               buffer_clear(&compression_buffer);
-               buffer_uncompress(&incoming_packet, &compression_buffer);
-               buffer_clear(&incoming_packet);
-               buffer_append(&incoming_packet, buffer_ptr(&compression_buffer),
-                   buffer_len(&compression_buffer));
+       buffer_consume_end(&active_state->incoming_packet, 4);
+
+       if (active_state->packet_compression) {
+               buffer_clear(&active_state->compression_buffer);
+               buffer_uncompress(&active_state->incoming_packet,
+                   &active_state->compression_buffer);
+               buffer_clear(&active_state->incoming_packet);
+               buffer_append(&active_state->incoming_packet,
+                   buffer_ptr(&active_state->compression_buffer),
+                   buffer_len(&active_state->compression_buffer));
        }
        }
-       p_read.packets++;
-       p_read.bytes += padded_len + 4;
-       type = buffer_get_char(&incoming_packet);
+       active_state->p_read.packets++;
+       active_state->p_read.bytes += padded_len + 4;
+       type = buffer_get_char(&active_state->incoming_packet);
        if (type < SSH_MSG_MIN || type > SSH_MSG_MAX)
                packet_disconnect("Invalid ssh1 packet type: %d", type);
        return type;
        if (type < SSH_MSG_MIN || type > SSH_MSG_MAX)
                packet_disconnect("Invalid ssh1 packet type: %d", type);
        return type;
@@ -1160,7 +1234,6 @@ packet_read_poll1(void)
 static int
 packet_read_poll2(u_int32_t *seqnr_p)
 {
 static int
 packet_read_poll2(u_int32_t *seqnr_p)
 {
-       static u_int packet_length = 0;
        u_int padlen, need;
        u_char *macbuf, *cp, type;
        u_int maclen, block_size;
        u_int padlen, need;
        u_char *macbuf, *cp, type;
        u_int maclen, block_size;
@@ -1168,50 +1241,52 @@ packet_read_poll2(u_int32_t *seqnr_p)
        Mac *mac   = NULL;
        Comp *comp = NULL;
 
        Mac *mac   = NULL;
        Comp *comp = NULL;
 
-       if (packet_discard)
+       if (active_state->packet_discard)
                return SSH_MSG_NONE;
 
                return SSH_MSG_NONE;
 
-       if (newkeys[MODE_IN] != NULL) {
-               enc  = &newkeys[MODE_IN]->enc;
-               mac  = &newkeys[MODE_IN]->mac;
-               comp = &newkeys[MODE_IN]->comp;
+       if (active_state->newkeys[MODE_IN] != NULL) {
+               enc  = &active_state->newkeys[MODE_IN]->enc;
+               mac  = &active_state->newkeys[MODE_IN]->mac;
+               comp = &active_state->newkeys[MODE_IN]->comp;
        }
        maclen = mac && mac->enabled ? mac->mac_len : 0;
        block_size = enc ? enc->block_size : 8;
 
        }
        maclen = mac && mac->enabled ? mac->mac_len : 0;
        block_size = enc ? enc->block_size : 8;
 
-       if (packet_length == 0) {
+       if (active_state->packlen == 0) {
                /*
                 * check if input size is less than the cipher block size,
                 * decrypt first block and extract length of incoming packet
                 */
                /*
                 * check if input size is less than the cipher block size,
                 * decrypt first block and extract length of incoming packet
                 */
-               if (buffer_len(&input) < block_size)
+               if (buffer_len(&active_state->input) < block_size)
                        return SSH_MSG_NONE;
                        return SSH_MSG_NONE;
-               buffer_clear(&incoming_packet);
-               cp = buffer_append_space(&incoming_packet, block_size);
-               cipher_crypt(&receive_context, cp, buffer_ptr(&input),
+               buffer_clear(&active_state->incoming_packet);
+               cp = buffer_append_space(&active_state->incoming_packet,
                    block_size);
                    block_size);
-               cp = buffer_ptr(&incoming_packet);
-               packet_length = get_u32(cp);
-               if (packet_length < 1 + 4 || packet_length > PACKET_MAX_SIZE) {
+               cipher_crypt(&active_state->receive_context, cp,
+                   buffer_ptr(&active_state->input), block_size);
+               cp = buffer_ptr(&active_state->incoming_packet);
+               active_state->packlen = get_u32(cp);
+               if (active_state->packlen < 1 + 4 ||
+                   active_state->packlen > PACKET_MAX_SIZE) {
 #ifdef PACKET_DEBUG
 #ifdef PACKET_DEBUG
-                       buffer_dump(&incoming_packet);
+                       buffer_dump(&active_state->incoming_packet);
 #endif
 #endif
-                       logit("Bad packet length %u.", packet_length);
-                       packet_start_discard(enc, mac, packet_length,
+                       logit("Bad packet length %u.", active_state->packlen);
+                       packet_start_discard(enc, mac, active_state->packlen,
                            PACKET_MAX_SIZE);
                        return SSH_MSG_NONE;
                }
                            PACKET_MAX_SIZE);
                        return SSH_MSG_NONE;
                }
-               DBG(debug("input: packet len %u", packet_length+4));
-               buffer_consume(&input, block_size);
+               DBG(debug("input: packet len %u", active_state->packlen+4));
+               buffer_consume(&active_state->input, block_size);
        }
        /* we have a partial packet of block_size bytes */
        }
        /* we have a partial packet of block_size bytes */
-       need = 4 + packet_length - block_size;
+       need = 4 + active_state->packlen - block_size;
        DBG(debug("partial packet %d, need %d, maclen %d", block_size,
            need, maclen));
        if (need % block_size != 0) {
                logit("padding error: need %d block %d mod %d",
                    need, block_size, need % block_size);
        DBG(debug("partial packet %d, need %d, maclen %d", block_size,
            need, maclen));
        if (need % block_size != 0) {
                logit("padding error: need %d block %d mod %d",
                    need, block_size, need % block_size);
-               packet_start_discard(enc, mac, packet_length,
+               packet_start_discard(enc, mac, active_state->packlen,
                    PACKET_MAX_SIZE - block_size);
                return SSH_MSG_NONE;
        }
                    PACKET_MAX_SIZE - block_size);
                return SSH_MSG_NONE;
        }
@@ -1219,84 +1294,90 @@ packet_read_poll2(u_int32_t *seqnr_p)
         * check if the entire packet has been received and
         * decrypt into incoming_packet
         */
         * check if the entire packet has been received and
         * decrypt into incoming_packet
         */
-       if (buffer_len(&input) < need + maclen)
+       if (buffer_len(&active_state->input) < need + maclen)
                return SSH_MSG_NONE;
 #ifdef PACKET_DEBUG
        fprintf(stderr, "read_poll enc/full: ");
                return SSH_MSG_NONE;
 #ifdef PACKET_DEBUG
        fprintf(stderr, "read_poll enc/full: ");
-       buffer_dump(&input);
+       buffer_dump(&active_state->input);
 #endif
 #endif
-       cp = buffer_append_space(&incoming_packet, need);
-       cipher_crypt(&receive_context, cp, buffer_ptr(&input), need);
-       buffer_consume(&input, need);
+       cp = buffer_append_space(&active_state->incoming_packet, need);
+       cipher_crypt(&active_state->receive_context, cp,
+           buffer_ptr(&active_state->input), need);
+       buffer_consume(&active_state->input, need);
        /*
         * compute MAC over seqnr and packet,
         * increment sequence number for incoming packet
         */
        if (mac && mac->enabled) {
        /*
         * compute MAC over seqnr and packet,
         * increment sequence number for incoming packet
         */
        if (mac && mac->enabled) {
-               macbuf = mac_compute(mac, p_read.seqnr,
-                   buffer_ptr(&incoming_packet),
-                   buffer_len(&incoming_packet));
-               if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0) {
+               macbuf = mac_compute(mac, active_state->p_read.seqnr,
+                   buffer_ptr(&active_state->incoming_packet),
+                   buffer_len(&active_state->incoming_packet));
+               if (memcmp(macbuf, buffer_ptr(&active_state->input),
+                   mac->mac_len) != 0) {
                        logit("Corrupted MAC on input.");
                        if (need > PACKET_MAX_SIZE)
                                fatal("internal error need %d", need);
                        logit("Corrupted MAC on input.");
                        if (need > PACKET_MAX_SIZE)
                                fatal("internal error need %d", need);
-                       packet_start_discard(enc, mac, packet_length,
+                       packet_start_discard(enc, mac, active_state->packlen,
                            PACKET_MAX_SIZE - need);
                        return SSH_MSG_NONE;
                }
                                
                            PACKET_MAX_SIZE - need);
                        return SSH_MSG_NONE;
                }
                                
-               DBG(debug("MAC #%d ok", p_read.seqnr));
-               buffer_consume(&input, mac->mac_len);
+               DBG(debug("MAC #%d ok", active_state->p_read.seqnr));
+               buffer_consume(&active_state->input, mac->mac_len);
        }
        /* XXX now it's safe to use fatal/packet_disconnect */
        if (seqnr_p != NULL)
        }
        /* XXX now it's safe to use fatal/packet_disconnect */
        if (seqnr_p != NULL)
-               *seqnr_p = p_read.seqnr;
-       if (++p_read.seqnr == 0)
+               *seqnr_p = active_state->p_read.seqnr;
+       if (++active_state->p_read.seqnr == 0)
                logit("incoming seqnr wraps around");
                logit("incoming seqnr wraps around");
-       if (++p_read.packets == 0)
+       if (++active_state->p_read.packets == 0)
                if (!(datafellows & SSH_BUG_NOREKEY))
                        fatal("XXX too many packets with same key");
                if (!(datafellows & SSH_BUG_NOREKEY))
                        fatal("XXX too many packets with same key");
-       p_read.blocks += (packet_length + 4) / block_size;
-       p_read.bytes += packet_length + 4;
+       active_state->p_read.blocks += (active_state->packlen + 4) / block_size;
+       active_state->p_read.bytes += active_state->packlen + 4;
 
        /* get padlen */
 
        /* get padlen */
-       cp = buffer_ptr(&incoming_packet);
+       cp = buffer_ptr(&active_state->incoming_packet);
        padlen = cp[4];
        DBG(debug("input: padlen %d", padlen));
        if (padlen < 4)
                packet_disconnect("Corrupted padlen %d on input.", padlen);
 
        /* skip packet size + padlen, discard padding */
        padlen = cp[4];
        DBG(debug("input: padlen %d", padlen));
        if (padlen < 4)
                packet_disconnect("Corrupted padlen %d on input.", padlen);
 
        /* skip packet size + padlen, discard padding */
-       buffer_consume(&incoming_packet, 4 + 1);
-       buffer_consume_end(&incoming_packet, padlen);
+       buffer_consume(&active_state->incoming_packet, 4 + 1);
+       buffer_consume_end(&active_state->incoming_packet, padlen);
 
 
-       DBG(debug("input: len before de-compress %d", buffer_len(&incoming_packet)));
+       DBG(debug("input: len before de-compress %d",
+           buffer_len(&active_state->incoming_packet)));
        if (comp && comp->enabled) {
        if (comp && comp->enabled) {
-               buffer_clear(&compression_buffer);
-               buffer_uncompress(&incoming_packet, &compression_buffer);
-               buffer_clear(&incoming_packet);
-               buffer_append(&incoming_packet, buffer_ptr(&compression_buffer),
-                   buffer_len(&compression_buffer));
+               buffer_clear(&active_state->compression_buffer);
+               buffer_uncompress(&active_state->incoming_packet,
+                   &active_state->compression_buffer);
+               buffer_clear(&active_state->incoming_packet);
+               buffer_append(&active_state->incoming_packet,
+                   buffer_ptr(&active_state->compression_buffer),
+                   buffer_len(&active_state->compression_buffer));
                DBG(debug("input: len after de-compress %d",
                DBG(debug("input: len after de-compress %d",
-                   buffer_len(&incoming_packet)));
+                   buffer_len(&active_state->incoming_packet)));
        }
        /*
         * get packet type, implies consume.
         * return length of payload (without type field)
         */
        }
        /*
         * get packet type, implies consume.
         * return length of payload (without type field)
         */
-       type = buffer_get_char(&incoming_packet);
+       type = buffer_get_char(&active_state->incoming_packet);
        if (type < SSH2_MSG_MIN || type >= SSH2_MSG_LOCAL_MIN)
                packet_disconnect("Invalid ssh2 packet type: %d", type);
        if (type == SSH2_MSG_NEWKEYS)
                set_newkeys(MODE_IN);
        if (type < SSH2_MSG_MIN || type >= SSH2_MSG_LOCAL_MIN)
                packet_disconnect("Invalid ssh2 packet type: %d", type);
        if (type == SSH2_MSG_NEWKEYS)
                set_newkeys(MODE_IN);
-       else if (type == SSH2_MSG_USERAUTH_SUCCESS && !server_side)
+       else if (type == SSH2_MSG_USERAUTH_SUCCESS &&
+           !active_state->server_side)
                packet_enable_delayed_compress();
 #ifdef PACKET_DEBUG
        fprintf(stderr, "read/plain[%d]:\r\n", type);
                packet_enable_delayed_compress();
 #ifdef PACKET_DEBUG
        fprintf(stderr, "read/plain[%d]:\r\n", type);
-       buffer_dump(&incoming_packet);
+       buffer_dump(&active_state->incoming_packet);
 #endif
        /* reset for next packet */
 #endif
        /* reset for next packet */
-       packet_length = 0;
+       active_state->packlen = 0;
        return type;
 }
 
        return type;
 }
 
@@ -1311,7 +1392,7 @@ packet_read_poll_seqnr(u_int32_t *seqnr_p)
                if (compat20) {
                        type = packet_read_poll2(seqnr_p);
                        if (type) {
                if (compat20) {
                        type = packet_read_poll2(seqnr_p);
                        if (type) {
-                               keep_alive_timeouts = 0;
+                               active_state->keep_alive_timeouts = 0;
                                DBG(debug("received packet type %d", type));
                        }
                        switch (type) {
                                DBG(debug("received packet type %d", type));
                        }
                        switch (type) {
@@ -1381,14 +1462,14 @@ packet_read_poll(void)
 void
 packet_process_incoming(const char *buf, u_int len)
 {
 void
 packet_process_incoming(const char *buf, u_int len)
 {
-       if (packet_discard) {
-               keep_alive_timeouts = 0; /* ?? */
-               if (len >= packet_discard)
+       if (active_state->packet_discard) {
+               active_state->keep_alive_timeouts = 0; /* ?? */
+               if (len >= active_state->packet_discard)
                        packet_stop_discard();
                        packet_stop_discard();
-               packet_discard -= len;
+               active_state->packet_discard -= len;
                return;
        }
                return;
        }
-       buffer_append(&input, buf, len);
+       buffer_append(&active_state->input, buf, len);
 }
 
 /* Returns a character from the packet. */
 }
 
 /* Returns a character from the packet. */
@@ -1398,7 +1479,7 @@ packet_get_char(void)
 {
        char ch;
 
 {
        char ch;
 
-       buffer_get(&incoming_packet, &ch, 1);
+       buffer_get(&active_state->incoming_packet, &ch, 1);
        return (u_char) ch;
 }
 
        return (u_char) ch;
 }
 
@@ -1407,7 +1488,15 @@ packet_get_char(void)
 u_int
 packet_get_int(void)
 {
 u_int
 packet_get_int(void)
 {
-       return buffer_get_int(&incoming_packet);
+       return buffer_get_int(&active_state->incoming_packet);
+}
+
+/* Returns an 64 bit integer from the packet data. */
+
+u_int64_t
+packet_get_int64(void)
+{
+       return buffer_get_int64(&active_state->incoming_packet);
 }
 
 /*
 }
 
 /*
@@ -1418,29 +1507,29 @@ packet_get_int(void)
 void
 packet_get_bignum(BIGNUM * value)
 {
 void
 packet_get_bignum(BIGNUM * value)
 {
-       buffer_get_bignum(&incoming_packet, value);
+       buffer_get_bignum(&active_state->incoming_packet, value);
 }
 
 void
 packet_get_bignum2(BIGNUM * value)
 {
 }
 
 void
 packet_get_bignum2(BIGNUM * value)
 {
-       buffer_get_bignum2(&incoming_packet, value);
+       buffer_get_bignum2(&active_state->incoming_packet, value);
 }
 
 void *
 packet_get_raw(u_int *length_ptr)
 {
 }
 
 void *
 packet_get_raw(u_int *length_ptr)
 {
-       u_int bytes = buffer_len(&incoming_packet);
+       u_int bytes = buffer_len(&active_state->incoming_packet);
 
        if (length_ptr != NULL)
                *length_ptr = bytes;
 
        if (length_ptr != NULL)
                *length_ptr = bytes;
-       return buffer_ptr(&incoming_packet);
+       return buffer_ptr(&active_state->incoming_packet);
 }
 
 int
 packet_remaining(void)
 {
 }
 
 int
 packet_remaining(void)
 {
-       return buffer_len(&incoming_packet);
+       return buffer_len(&active_state->incoming_packet);
 }
 
 /*
 }
 
 /*
@@ -1453,13 +1542,13 @@ packet_remaining(void)
 void *
 packet_get_string(u_int *length_ptr)
 {
 void *
 packet_get_string(u_int *length_ptr)
 {
-       return buffer_get_string(&incoming_packet, length_ptr);
+       return buffer_get_string(&active_state->incoming_packet, length_ptr);
 }
 
 void *
 packet_get_string_ptr(u_int *length_ptr)
 {
 }
 
 void *
 packet_get_string_ptr(u_int *length_ptr)
 {
-       return buffer_get_string_ptr(&incoming_packet, length_ptr);
+       return buffer_get_string_ptr(&active_state->incoming_packet, length_ptr);
 }
 
 /*
 }
 
 /*
@@ -1553,24 +1642,27 @@ int
 packet_write_poll(void)
 {
        int len = 0;
 packet_write_poll(void)
 {
        int len = 0;
-       len = buffer_len(&output);
+       int cont;
+
+       len = buffer_len(&active_state->output);
 
        if (len > 0) {
 
        if (len > 0) {
-               len = write(connection_out, buffer_ptr(&output), len);
+               cont = 0;
+               len = roaming_write(active_state->connection_out,
+                   buffer_ptr(&active_state->output), len, &cont);
                if (len == -1) {
                        if (errno == EINTR || errno == EAGAIN ||
                            errno == EWOULDBLOCK)
                                return (0);
                        fatal("Write failed: %.100s", strerror(errno));
                }
                if (len == -1) {
                        if (errno == EINTR || errno == EAGAIN ||
                            errno == EWOULDBLOCK)
                                return (0);
                        fatal("Write failed: %.100s", strerror(errno));
                }
-               if (len == 0)
+               if (len == 0 && !cont)
                        fatal("Write connection closed");
                        fatal("Write connection closed");
-               buffer_consume(&output, len);
+               buffer_consume(&active_state->output, len);
        }
        return(len);
 }
 
        }
        return(len);
 }
 
-
 /*
  * Calls packet_write_poll repeatedly until all pending output data has been
  * written.
 /*
  * Calls packet_write_poll repeatedly until all pending output data has been
  * written.
@@ -1584,30 +1676,30 @@ packet_write_wait(void)
        struct timeval start, timeout, *timeoutp = NULL;
        u_int bytes_sent = 0;
 
        struct timeval start, timeout, *timeoutp = NULL;
        u_int bytes_sent = 0;
 
-       setp = (fd_set *)xcalloc(howmany(connection_out + 1, NFDBITS),
-           sizeof(fd_mask));
+       setp = (fd_set *)xcalloc(howmany(active_state->connection_out + 1,
+           NFDBITS), sizeof(fd_mask));
        bytes_sent += packet_write_poll();
        while (packet_have_data_to_write()) {
        bytes_sent += packet_write_poll();
        while (packet_have_data_to_write()) {
-               memset(setp, 0, howmany(connection_out + 1, NFDBITS) *
-                   sizeof(fd_mask));
-               FD_SET(connection_out, setp);
+               memset(setp, 0, howmany(active_state->connection_out + 1,
+                   NFDBITS) * sizeof(fd_mask));
+               FD_SET(active_state->connection_out, setp);
 
 
-               if (packet_timeout_ms > 0) {
-                       ms_remain = packet_timeout_ms;
+               if (active_state->packet_timeout_ms > 0) {
+                       ms_remain = active_state->packet_timeout_ms;
                        timeoutp = &timeout;
                }
                for (;;) {
                        timeoutp = &timeout;
                }
                for (;;) {
-                       if (packet_timeout_ms != -1) {
+                       if (active_state->packet_timeout_ms != -1) {
                                ms_to_timeval(&timeout, ms_remain);
                                gettimeofday(&start, NULL);
                        }
                                ms_to_timeval(&timeout, ms_remain);
                                gettimeofday(&start, NULL);
                        }
-                       if ((ret = select(connection_out + 1, NULL, setp,
-                           NULL, timeoutp)) >= 0)
+                       if ((ret = select(active_state->connection_out + 1,
+                           NULL, setp, NULL, timeoutp)) >= 0)
                                break;
                                break;
-                       if (errno != EAGAIN && errno != EINTR &&
+                       if (errno != EAGAIN && errno != EINTR &&
                            errno != EWOULDBLOCK)
                                break;
                            errno != EWOULDBLOCK)
                                break;
-                       if (packet_timeout_ms == -1)
+                       if (active_state->packet_timeout_ms == -1)
                                continue;
                        ms_subtract_diff(&start, &ms_remain);
                        if (ms_remain <= 0) {
                                continue;
                        ms_subtract_diff(&start, &ms_remain);
                        if (ms_remain <= 0) {
@@ -1631,7 +1723,7 @@ packet_write_wait(void)
 int
 packet_have_data_to_write(void)
 {
 int
 packet_have_data_to_write(void)
 {
-       return buffer_len(&output) != 0;
+       return buffer_len(&active_state->output) != 0;
 }
 
 /* Returns true if there is not too much data to write to the connection. */
 }
 
 /* Returns true if there is not too much data to write to the connection. */
@@ -1639,13 +1731,12 @@ packet_have_data_to_write(void)
 int
 packet_not_very_much_data_to_write(void)
 {
 int
 packet_not_very_much_data_to_write(void)
 {
-       if (interactive_mode)
-               return buffer_len(&output) < 16384;
+       if (active_state->interactive_mode)
+               return buffer_len(&active_state->output) < 16384;
        else
        else
-               return buffer_len(&output) < 128 * 1024;
+               return buffer_len(&active_state->output) < 128 * 1024;
 }
 
 }
 
-
 static void
 packet_set_tos(int interactive)
 {
 static void
 packet_set_tos(int interactive)
 {
@@ -1655,7 +1746,7 @@ packet_set_tos(int interactive)
        if (!packet_connection_is_on_socket() ||
            !packet_connection_is_ipv4())
                return;
        if (!packet_connection_is_on_socket() ||
            !packet_connection_is_ipv4())
                return;
-       if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, &tos,
+       if (setsockopt(active_state->connection_in, IPPROTO_IP, IP_TOS, &tos,
            sizeof(tos)) < 0)
                error("setsockopt IP_TOS %d: %.100s:",
                    tos, strerror(errno));
            sizeof(tos)) < 0)
                error("setsockopt IP_TOS %d: %.100s:",
                    tos, strerror(errno));
@@ -1667,19 +1758,17 @@ packet_set_tos(int interactive)
 void
 packet_set_interactive(int interactive)
 {
 void
 packet_set_interactive(int interactive)
 {
-       static int called = 0;
-
-       if (called)
+       if (active_state->set_interactive_called)
                return;
                return;
-       called = 1;
+       active_state->set_interactive_called = 1;
 
        /* Record that we are in interactive mode. */
 
        /* Record that we are in interactive mode. */
-       interactive_mode = interactive;
+       active_state->interactive_mode = interactive;
 
        /* Only set socket options if using a socket.  */
        if (!packet_connection_is_on_socket())
                return;
 
        /* Only set socket options if using a socket.  */
        if (!packet_connection_is_on_socket())
                return;
-       set_nodelay(connection_in);
+       set_nodelay(active_state->connection_in);
        packet_set_tos(interactive);
 }
 
        packet_set_tos(interactive);
 }
 
@@ -1688,34 +1777,50 @@ packet_set_interactive(int interactive)
 int
 packet_is_interactive(void)
 {
 int
 packet_is_interactive(void)
 {
-       return interactive_mode;
+       return active_state->interactive_mode;
 }
 
 int
 packet_set_maxsize(u_int s)
 {
 }
 
 int
 packet_set_maxsize(u_int s)
 {
-       static int called = 0;
-
-       if (called) {
+       if (active_state->set_maxsize_called) {
                logit("packet_set_maxsize: called twice: old %d new %d",
                logit("packet_set_maxsize: called twice: old %d new %d",
-                   max_packet_size, s);
+                   active_state->max_packet_size, s);
                return -1;
        }
        if (s < 4 * 1024 || s > 1024 * 1024) {
                logit("packet_set_maxsize: bad size %d", s);
                return -1;
        }
                return -1;
        }
        if (s < 4 * 1024 || s > 1024 * 1024) {
                logit("packet_set_maxsize: bad size %d", s);
                return -1;
        }
-       called = 1;
+       active_state->set_maxsize_called = 1;
        debug("packet_set_maxsize: setting to %d", s);
        debug("packet_set_maxsize: setting to %d", s);
-       max_packet_size = s;
+       active_state->max_packet_size = s;
        return s;
 }
 
        return s;
 }
 
+int
+packet_inc_alive_timeouts(void)
+{
+       return ++active_state->keep_alive_timeouts;
+}
+
+void
+packet_set_alive_timeouts(int ka)
+{
+       active_state->keep_alive_timeouts = ka;
+}
+
+u_int
+packet_get_maxsize(void)
+{
+       return active_state->max_packet_size;
+}
+
 /* roundup current message to pad bytes */
 void
 packet_add_padding(u_char pad)
 {
 /* roundup current message to pad bytes */
 void
 packet_add_padding(u_char pad)
 {
-       extra_pad = pad;
+       active_state->extra_pad = pad;
 }
 
 /*
 }
 
 /*
@@ -1764,32 +1869,99 @@ packet_need_rekeying(void)
                return 1;
        }
        return
                return 1;
        }
        return
-           (p_send.packets > MAX_PACKETS) ||
-           (p_read.packets > MAX_PACKETS) ||
-           (max_blocks_out && (p_send.blocks > max_blocks_out)) ||
-           (max_blocks_in  && (p_read.blocks > max_blocks_in));
+           (active_state->p_send.packets > MAX_PACKETS) ||
+           (active_state->p_read.packets > MAX_PACKETS) ||
+           (active_state->max_blocks_out &&
+               (active_state->p_send.blocks > active_state->max_blocks_out)) ||
+           (active_state->max_blocks_in &&
+               (active_state->p_read.blocks > active_state->max_blocks_in));
 }
 
 void
 packet_set_rekey_limit(u_int32_t bytes)
 {
 }
 
 void
 packet_set_rekey_limit(u_int32_t bytes)
 {
-       rekey_limit = bytes;
+       active_state->rekey_limit = bytes;
 }
 
 void
 packet_set_server(void)
 {
 }
 
 void
 packet_set_server(void)
 {
-       server_side = 1;
+       active_state->server_side = 1;
 }
 
 void
 packet_set_authenticated(void)
 {
 }
 
 void
 packet_set_authenticated(void)
 {
-       after_authentication = 1;
+       active_state->after_authentication = 1;
+}
+
+void *
+packet_get_input(void)
+{
+       return (void *)&active_state->input;
+}
+
+void *
+packet_get_output(void)
+{
+       return (void *)&active_state->output;
+}
+
+void *
+packet_get_newkeys(int mode)
+{
+       return (void *)active_state->newkeys[mode];
+}
+
+/*
+ * Save the state for the real connection, and use a separate state when
+ * resuming a suspended connection.
+ */
+void
+packet_backup_state(void)
+{
+       struct session_state *tmp;
+
+       close(active_state->connection_in);
+       active_state->connection_in = -1;
+       close(active_state->connection_out);
+       active_state->connection_out = -1;
+       if (backup_state)
+               tmp = backup_state;
+       else
+               tmp = alloc_session_state();
+       backup_state = active_state;
+       active_state = tmp;
+}
+
+/*
+ * Swap in the old state when resuming a connecion.
+ */
+void
+packet_restore_state(void)
+{
+       struct session_state *tmp;
+       void *buf;
+       u_int len;
+
+       tmp = backup_state;
+       backup_state = active_state;
+       active_state = tmp;
+       active_state->connection_in = backup_state->connection_in;
+       backup_state->connection_in = -1;
+       active_state->connection_out = backup_state->connection_out;
+       backup_state->connection_out = -1;
+       len = buffer_len(&backup_state->input);
+       if (len > 0) {
+               buf = buffer_ptr(&backup_state->input);
+               buffer_append(&active_state->input, buf, len);
+               buffer_clear(&backup_state->input);
+               add_recv_bytes(len);
+       }
 }
 
 int
 packet_authentication_state(void)
 {
 }
 
 int
 packet_authentication_state(void)
 {
-       return(after_authentication);
+       return(active_state->after_authentication);
 }
 }
index a52107883696ca11cdaa94176747cfb5e6f03175..0345d732cc5e0c524496358363f494cad7d61676 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: packet.h,v 1.49 2008/07/10 18:08:11 markus Exp $ */
+/* $OpenBSD: packet.h,v 1.52 2009/06/27 09:29:06 andreas Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -43,6 +43,7 @@ int    packet_authentication_state(void);
 void     packet_start(u_char);
 void     packet_put_char(int ch);
 void     packet_put_int(u_int value);
 void     packet_start(u_char);
 void     packet_put_char(int ch);
 void     packet_put_int(u_int value);
+void     packet_put_int64(u_int64_t value);
 void     packet_put_bignum(BIGNUM * value);
 void     packet_put_bignum2(BIGNUM * value);
 void     packet_put_string(const void *buf, u_int len);
 void     packet_put_bignum(BIGNUM * value);
 void     packet_put_bignum2(BIGNUM * value);
 void     packet_put_string(const void *buf, u_int len);
@@ -59,6 +60,7 @@ int      packet_read_poll_seqnr(u_int32_t *seqnr_p);
 
 u_int   packet_get_char(void);
 u_int   packet_get_int(void);
 
 u_int   packet_get_char(void);
 u_int   packet_get_int(void);
+u_int64_t packet_get_int64(void);
 void     packet_get_bignum(BIGNUM * value);
 void     packet_get_bignum2(BIGNUM * value);
 void   *packet_get_raw(u_int *length_ptr);
 void     packet_get_bignum(BIGNUM * value);
 void     packet_get_bignum2(BIGNUM * value);
 void   *packet_get_raw(u_int *length_ptr);
@@ -76,6 +78,7 @@ void   packet_get_state(int, u_int32_t *, u_int64_t *, u_int32_t *, u_int64_t *);
 void    packet_set_state(int, u_int32_t, u_int64_t, u_int32_t, u_int64_t);
 int     packet_get_ssh1_cipher(void);
 void    packet_set_iv(int, u_char *);
 void    packet_set_state(int, u_int32_t, u_int64_t, u_int32_t, u_int64_t);
 int     packet_get_ssh1_cipher(void);
 void    packet_set_iv(int, u_char *);
+void   *packet_get_newkeys(int);
 
 int      packet_write_poll(void);
 int      packet_write_wait(void);
 
 int      packet_write_poll(void);
 int      packet_write_wait(void);
@@ -91,10 +94,10 @@ void         packet_add_padding(u_char);
 void    tty_make_modes(int, struct termios *);
 void    tty_parse_modes(int, int *);
 
 void    tty_make_modes(int, struct termios *);
 void    tty_parse_modes(int, int *);
 
-extern u_int max_packet_size;
-extern int keep_alive_timeouts;
+void    packet_set_alive_timeouts(int);
+int     packet_inc_alive_timeouts(void);
 int     packet_set_maxsize(u_int);
 int     packet_set_maxsize(u_int);
-#define  packet_get_maxsize() max_packet_size
+u_int   packet_get_maxsize(void);
 
 /* don't allow remaining bytes after the end of the message */
 #define packet_check_eom() \
 
 /* don't allow remaining bytes after the end of the message */
 #define packet_check_eom() \
@@ -110,4 +113,10 @@ do { \
 int     packet_need_rekeying(void);
 void    packet_set_rekey_limit(u_int32_t);
 
 int     packet_need_rekeying(void);
 void    packet_set_rekey_limit(u_int32_t);
 
+void    packet_backup_state(void);
+void    packet_restore_state(void);
+
+void   *packet_get_input(void);
+void   *packet_get_output(void);
+
 #endif                         /* PACKET_H */
 #endif                         /* PACKET_H */
index dc5e5ae6b6a3aa3aaba1aecd6c49c4fa537c9f39..cadf9c166a1c59b46f403c7e0a4f2e6afde7388b 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.c,v 1.176 2009/02/12 03:00:56 djm Exp $ */
+/* $OpenBSD: readconf.c,v 1.177 2009/06/27 09:35:06 andreas Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -131,7 +131,7 @@ typedef enum {
        oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
        oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
        oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
        oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
        oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
        oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
-       oVisualHostKey, oZeroKnowledgePasswordAuthentication,
+       oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication,
        oNoneEnabled, oTcpRcvBufPoll, oTcpRcvBuf, oNoneSwitch, oHPNDisabled,
        oHPNBufferSize,
        oDeprecated, oUnsupported
        oNoneEnabled, oTcpRcvBufPoll, oTcpRcvBuf, oNoneSwitch, oHPNDisabled,
        oHPNBufferSize,
        oDeprecated, oUnsupported
@@ -239,6 +239,7 @@ static struct {
        { "localcommand", oLocalCommand },
        { "permitlocalcommand", oPermitLocalCommand },
        { "visualhostkey", oVisualHostKey },
        { "localcommand", oLocalCommand },
        { "permitlocalcommand", oPermitLocalCommand },
        { "visualhostkey", oVisualHostKey },
+       { "useroaming", oUseRoaming },
 #ifdef JPAKE
        { "zeroknowledgepasswordauthentication",
            oZeroKnowledgePasswordAuthentication },
 #ifdef JPAKE
        { "zeroknowledgepasswordauthentication",
            oZeroKnowledgePasswordAuthentication },
@@ -981,6 +982,10 @@ parse_int:
                intptr = &options->visual_host_key;
                goto parse_flag;
 
                intptr = &options->visual_host_key;
                goto parse_flag;
 
+       case oUseRoaming:
+               intptr = &options->use_roaming;
+               goto parse_flag;
+
        case oDeprecated:
                debug("%s line %d: Deprecated option \"%s\"",
                    filename, linenum, keyword);
        case oDeprecated:
                debug("%s line %d: Deprecated option \"%s\"",
                    filename, linenum, keyword);
@@ -1134,6 +1139,7 @@ initialize_options(Options * options)
        options->tun_remote = -1;
        options->local_command = NULL;
        options->permit_local_command = -1;
        options->tun_remote = -1;
        options->local_command = NULL;
        options->permit_local_command = -1;
+       options->use_roaming = -1;
        options->visual_host_key = -1;
        options->zero_knowledge_password_authentication = -1;
        options->none_switch = -1;
        options->visual_host_key = -1;
        options->zero_knowledge_password_authentication = -1;
        options->none_switch = -1;
@@ -1305,6 +1311,8 @@ fill_default_options(Options * options)
                options->tun_remote = SSH_TUNID_ANY;
        if (options->permit_local_command == -1)
                options->permit_local_command = 0;
                options->tun_remote = SSH_TUNID_ANY;
        if (options->permit_local_command == -1)
                options->permit_local_command = 0;
+       if (options->use_roaming == -1)
+               options->use_roaming = 1;
        if (options->visual_host_key == -1)
                options->visual_host_key = 0;
        if (options->zero_knowledge_password_authentication == -1)
        if (options->visual_host_key == -1)
                options->visual_host_key = 0;
        if (options->zero_knowledge_password_authentication == -1)
index 12477c05681b36dbfa5323ef5c142683a3749c80..283a8552ce18c59012128c6395476897ce87504f 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.h,v 1.78 2009/02/12 03:00:56 djm Exp $ */
+/* $OpenBSD: readconf.h,v 1.79 2009/06/27 09:35:06 andreas Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -136,6 +136,8 @@ typedef struct {
        int     permit_local_command;
        int     visual_host_key;
 
        int     permit_local_command;
        int     visual_host_key;
 
+       int     use_roaming;
+
 }       Options;
 
 #define SSHCTL_MASTER_NO       0
 }       Options;
 
 #define SSHCTL_MASTER_NO       0
index 73db09d798ebd8cd61e5869423ccaedfd851d7a8..be7b98ce4d680864b533e541bd266ee9ec806a4f 100644 (file)
@@ -145,8 +145,6 @@ roaming_write(int fd, const void *buf, size_t count, int *cont)
                if (out_buf_size > 0)
                        buf_append(buf, ret);
        }
                if (out_buf_size > 0)
                        buf_append(buf, ret);
        }
-       debug3("Wrote %ld bytes for a total of %llu", (long)ret,
-           (unsigned long long)write_bytes);
        return ret;
 }
 
        return ret;
 }
 
index c7f55c5556688b0f046ae06d6be9e652d3772de7..c17ff3241b7c35a942536111c58e07e0bea6cc53 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: schnorr.c,v 1.2 2009/02/18 04:31:21 djm Exp $ */
+/* $OpenBSD: schnorr.c,v 1.3 2009/03/05 07:18:19 djm Exp $ */
 /*
  * Copyright (c) 2008 Damien Miller.  All rights reserved.
  *
 /*
  * Copyright (c) 2008 Damien Miller.  All rights reserved.
  *
 #include "buffer.h"
 #include "log.h"
 
 #include "buffer.h"
 #include "log.h"
 
-#include "jpake.h"
+#include "schnorr.h"
+
+#include "openbsd-compat/openssl-compat.h"
 
 /* #define SCHNORR_DEBUG */            /* Privacy-violating debugging */
 /* #define SCHNORR_MAIN */             /* Include main() selftest */
 
 
 /* #define SCHNORR_DEBUG */            /* Privacy-violating debugging */
 /* #define SCHNORR_MAIN */             /* Include main() selftest */
 
-/* XXX */
-/* Parametise signature hash? (sha256, sha1, etc.) */
-/* Signature format - include type name, hash type, group params? */
-
 #ifndef SCHNORR_DEBUG
 # define SCHNORR_DEBUG_BN(a)
 # define SCHNORR_DEBUG_BUF(a)
 #else
 #ifndef SCHNORR_DEBUG
 # define SCHNORR_DEBUG_BN(a)
 # define SCHNORR_DEBUG_BUF(a)
 #else
-# define SCHNORR_DEBUG_BN(a)   jpake_debug3_bn a
-# define SCHNORR_DEBUG_BUF(a)  jpake_debug3_buf a
+# define SCHNORR_DEBUG_BN(a)   debug3_bn a
+# define SCHNORR_DEBUG_BUF(a)  debug3_buf a
 #endif /* SCHNORR_DEBUG */
 
 /*
  * Calculate hash component of Schnorr signature H(g || g^v || g^x || id)
 #endif /* SCHNORR_DEBUG */
 
 /*
  * Calculate hash component of Schnorr signature H(g || g^v || g^x || id)
- * using SHA1. Returns signature as bignum or NULL on error.
+ * using the hash function defined by "evp_md". Returns signature as
+ * bignum or NULL on error.
  */
 static BIGNUM *
 schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g,
  */
 static BIGNUM *
 schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g,
-    const BIGNUM *g_v, const BIGNUM *g_x,
+    const EVP_MD *evp_md, const BIGNUM *g_v, const BIGNUM *g_x,
     const u_char *id, u_int idlen)
 {
        u_char *digest;
        u_int digest_len;
        BIGNUM *h;
     const u_char *id, u_int idlen)
 {
        u_char *digest;
        u_int digest_len;
        BIGNUM *h;
-       EVP_MD_CTX evp_md_ctx;
        Buffer b;
        int success = -1;
 
        Buffer b;
        int success = -1;
 
@@ -79,7 +77,6 @@ schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g,
        }
 
        buffer_init(&b);
        }
 
        buffer_init(&b);
-       EVP_MD_CTX_init(&evp_md_ctx);
 
        /* h = H(g || p || q || g^v || g^x || id) */
        buffer_put_bignum2(&b, g);
 
        /* h = H(g || p || q || g^v || g^x || id) */
        buffer_put_bignum2(&b, g);
@@ -91,7 +88,7 @@ schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g,
 
        SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b),
            "%s: hashblob", __func__));
 
        SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b),
            "%s: hashblob", __func__));
-       if (hash_buffer(buffer_ptr(&b), buffer_len(&b), (const EVP_MD *)EVP_sha256(),
+       if (hash_buffer(buffer_ptr(&b), buffer_len(&b), evp_md,
            &digest, &digest_len) != 0) {
                error("%s: hash_buffer", __func__);
                goto out;
            &digest, &digest_len) != 0) {
                error("%s: hash_buffer", __func__);
                goto out;
@@ -104,7 +101,6 @@ schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g,
        SCHNORR_DEBUG_BN((h, "%s: h = ", __func__));
  out:
        buffer_free(&b);
        SCHNORR_DEBUG_BN((h, "%s: h = ", __func__));
  out:
        buffer_free(&b);
-       EVP_MD_CTX_cleanup(&evp_md_ctx);
        bzero(digest, digest_len);
        xfree(digest);
        digest_len = 0;
        bzero(digest, digest_len);
        xfree(digest);
        digest_len = 0;
@@ -117,18 +113,20 @@ schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g,
 /*
  * Generate Schnorr signature to prove knowledge of private value 'x' used
  * in public exponent g^x, under group defined by 'grp_p', 'grp_q' and 'grp_g'
 /*
  * Generate Schnorr signature to prove knowledge of private value 'x' used
  * in public exponent g^x, under group defined by 'grp_p', 'grp_q' and 'grp_g'
+ * using the hash function "evp_md".
  * 'idlen' bytes from 'id' will be included in the signature hash as an anti-
  * replay salt.
  * 'idlen' bytes from 'id' will be included in the signature hash as an anti-
  * replay salt.
- * On success, 0 is returned and *siglen bytes of signature are returned in
- * *sig (caller to free). Returns -1 on failure.
+ * 
+ * On success, 0 is returned. The signature values are returned as *e_p
+ * (g^v mod p) and *r_p (v - xh mod q). The caller must free these values.
+ * On failure, -1 is returned.
  */
 int
 schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
  */
 int
 schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
-    const BIGNUM *x, const BIGNUM *g_x, const u_char *id, u_int idlen,
-    u_char **sig, u_int *siglen)
+    const EVP_MD *evp_md, const BIGNUM *x, const BIGNUM *g_x,
+    const u_char *id, u_int idlen, BIGNUM **r_p, BIGNUM **e_p)
 {
        int success = -1;
 {
        int success = -1;
-       Buffer b;
        BIGNUM *h, *tmp, *v, *g_v, *r;
        BN_CTX *bn_ctx;
 
        BIGNUM *h, *tmp, *v, *g_v, *r;
        BN_CTX *bn_ctx;
 
@@ -171,7 +169,7 @@ schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
        SCHNORR_DEBUG_BN((g_v, "%s: g_v = ", __func__));
 
        /* h = H(g || g^v || g^x || id) */
        SCHNORR_DEBUG_BN((g_v, "%s: g_v = ", __func__));
 
        /* h = H(g || g^v || g^x || id) */
-       if ((h = schnorr_hash(grp_p, grp_q, grp_g, g_v, g_x,
+       if ((h = schnorr_hash(grp_p, grp_q, grp_g, evp_md, g_v, g_x,
            id, idlen)) == NULL) {
                error("%s: schnorr_hash failed", __func__);
                goto out;
            id, idlen)) == NULL) {
                error("%s: schnorr_hash failed", __func__);
                goto out;
@@ -186,12 +184,49 @@ schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
                error("%s: BN_mod_mul (r = v - tmp)", __func__);
                goto out;
        }
                error("%s: BN_mod_mul (r = v - tmp)", __func__);
                goto out;
        }
+       SCHNORR_DEBUG_BN((g_v, "%s: e = ", __func__));
        SCHNORR_DEBUG_BN((r, "%s: r = ", __func__));
 
        SCHNORR_DEBUG_BN((r, "%s: r = ", __func__));
 
-       /* Signature is (g_v, r) */
+       *e_p = g_v;
+       *r_p = r;
+
+       success = 0;
+ out:
+       BN_CTX_free(bn_ctx);
+       if (h != NULL)
+               BN_clear_free(h);
+       if (v != NULL)
+               BN_clear_free(v);
+       BN_clear_free(tmp);
+
+       return success;
+}
+
+/*
+ * Generate Schnorr signature to prove knowledge of private value 'x' used
+ * in public exponent g^x, under group defined by 'grp_p', 'grp_q' and 'grp_g'
+ * using a SHA256 hash.
+ * 'idlen' bytes from 'id' will be included in the signature hash as an anti-
+ * replay salt.
+ * On success, 0 is returned and *siglen bytes of signature are returned in
+ * *sig (caller to free). Returns -1 on failure.
+ */
+int
+schnorr_sign_buf(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
+    const BIGNUM *x, const BIGNUM *g_x, const u_char *id, u_int idlen,
+    u_char **sig, u_int *siglen)
+{
+       Buffer b;
+       BIGNUM *r, *e;
+
+       if (schnorr_sign(grp_p, grp_q, grp_g, EVP_sha256(),
+           x, g_x, id, idlen, &r, &e) != 0)
+               return -1;
+
+       /* Signature is (e, r) */
        buffer_init(&b);
        /* XXX sigtype-hash as string? */
        buffer_init(&b);
        /* XXX sigtype-hash as string? */
-       buffer_put_bignum2(&b, g_v);
+       buffer_put_bignum2(&b, e);
        buffer_put_bignum2(&b, r);
        *siglen = buffer_len(&b);
        *sig = xmalloc(*siglen);
        buffer_put_bignum2(&b, r);
        *siglen = buffer_len(&b);
        *sig = xmalloc(*siglen);
@@ -199,36 +234,28 @@ schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
        SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b),
            "%s: sigblob", __func__));
        buffer_free(&b);
        SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b),
            "%s: sigblob", __func__));
        buffer_free(&b);
-       success = 0;
- out:
-       BN_CTX_free(bn_ctx);
-       if (h != NULL)
-               BN_clear_free(h);
-       if (v != NULL)
-               BN_clear_free(v);
+
        BN_clear_free(r);
        BN_clear_free(r);
-       BN_clear_free(g_v);
-       BN_clear_free(tmp);
+       BN_clear_free(e);
 
 
-       return success;
+       return 0;
 }
 
 /*
 }
 
 /*
- * Verify Schnorr signature 'sig' of length 'siglen' against public exponent
- * g_x (g^x) under group defined by 'grp_p', 'grp_q' and 'grp_g'.
+ * Verify Schnorr signature { r (v - xh mod q), e (g^v mod p) } against
+ * public exponent g_x (g^x) under group defined by 'grp_p', 'grp_q' and
+ * 'grp_g' using hash "evp_md".
  * Signature hash will be salted with 'idlen' bytes from 'id'.
  * Returns -1 on failure, 0 on incorrect signature or 1 on matching signature.
  */
 int
 schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
  * Signature hash will be salted with 'idlen' bytes from 'id'.
  * Returns -1 on failure, 0 on incorrect signature or 1 on matching signature.
  */
 int
 schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
-    const BIGNUM *g_x, const u_char *id, u_int idlen,
-    const u_char *sig, u_int siglen)
+    const EVP_MD *evp_md, const BIGNUM *g_x, const u_char *id, u_int idlen,
+    const BIGNUM *r, const BIGNUM *e)
 {
        int success = -1;
 {
        int success = -1;
-       Buffer b;
-       BIGNUM *g_v, *h, *r, *g_xh, *g_r, *expected;
+       BIGNUM *h, *g_xh, *g_r, *expected;
        BN_CTX *bn_ctx;
        BN_CTX *bn_ctx;
-       u_int rlen;
 
        SCHNORR_DEBUG_BN((g_x, "%s: g_x = ", __func__));
 
 
        SCHNORR_DEBUG_BN((g_x, "%s: g_x = ", __func__));
 
@@ -238,39 +265,23 @@ schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
                return -1;
        }
 
                return -1;
        }
 
-       g_v = h = r = g_xh = g_r = expected = NULL;
+       h = g_xh = g_r = expected = NULL;
        if ((bn_ctx = BN_CTX_new()) == NULL) {
                error("%s: BN_CTX_new", __func__);
                goto out;
        }
        if ((bn_ctx = BN_CTX_new()) == NULL) {
                error("%s: BN_CTX_new", __func__);
                goto out;
        }
-       if ((g_v = BN_new()) == NULL ||
-           (r = BN_new()) == NULL ||
-           (g_xh = BN_new()) == NULL ||
+       if ((g_xh = BN_new()) == NULL ||
            (g_r = BN_new()) == NULL ||
            (expected = BN_new()) == NULL) {
                error("%s: BN_new", __func__);
                goto out;
        }
 
            (g_r = BN_new()) == NULL ||
            (expected = BN_new()) == NULL) {
                error("%s: BN_new", __func__);
                goto out;
        }
 
-       /* Extract g^v and r from signature blob */
-       buffer_init(&b);
-       buffer_append(&b, sig, siglen);
-       SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b),
-           "%s: sigblob", __func__));
-       buffer_get_bignum2(&b, g_v);
-       buffer_get_bignum2(&b, r);
-       rlen = buffer_len(&b);
-       buffer_free(&b);
-       if (rlen != 0) {
-               error("%s: remaining bytes in signature %d", __func__, rlen);
-               goto out;
-       }
-       buffer_free(&b);
-       SCHNORR_DEBUG_BN((g_v, "%s: g_v = ", __func__));
+       SCHNORR_DEBUG_BN((e, "%s: e = ", __func__));
        SCHNORR_DEBUG_BN((r, "%s: r = ", __func__));
 
        /* h = H(g || g^v || g^x || id) */
        SCHNORR_DEBUG_BN((r, "%s: r = ", __func__));
 
        /* h = H(g || g^v || g^x || id) */
-       if ((h = schnorr_hash(grp_p, grp_q, grp_g, g_v, g_x,
+       if ((h = schnorr_hash(grp_p, grp_q, grp_g, evp_md, e, g_x,
            id, idlen)) == NULL) {
                error("%s: schnorr_hash failed", __func__);
                goto out;
            id, idlen)) == NULL) {
                error("%s: schnorr_hash failed", __func__);
                goto out;
@@ -297,20 +308,248 @@ schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
        }
        SCHNORR_DEBUG_BN((expected, "%s: expected = ", __func__));
 
        }
        SCHNORR_DEBUG_BN((expected, "%s: expected = ", __func__));
 
-       /* Check g_v == expected */
-       success = BN_cmp(expected, g_v) == 0;
+       /* Check e == expected */
+       success = BN_cmp(expected, e) == 0;
  out:
        BN_CTX_free(bn_ctx);
        if (h != NULL)
                BN_clear_free(h);
  out:
        BN_CTX_free(bn_ctx);
        if (h != NULL)
                BN_clear_free(h);
-       BN_clear_free(g_v);
-       BN_clear_free(r);
        BN_clear_free(g_xh);
        BN_clear_free(g_r);
        BN_clear_free(expected);
        return success;
 }
 
        BN_clear_free(g_xh);
        BN_clear_free(g_r);
        BN_clear_free(expected);
        return success;
 }
 
+/*
+ * Verify Schnorr signature 'sig' of length 'siglen' against public exponent
+ * g_x (g^x) under group defined by 'grp_p', 'grp_q' and 'grp_g' using a
+ * SHA256 hash.
+ * Signature hash will be salted with 'idlen' bytes from 'id'.
+ * Returns -1 on failure, 0 on incorrect signature or 1 on matching signature.
+ */
+int
+schnorr_verify_buf(const BIGNUM *grp_p, const BIGNUM *grp_q,
+    const BIGNUM *grp_g,
+    const BIGNUM *g_x, const u_char *id, u_int idlen,
+    const u_char *sig, u_int siglen)
+{
+       Buffer b;
+       int ret = -1;
+       u_int rlen;
+       BIGNUM *r, *e;
+
+       e = r = NULL;
+       if ((e = BN_new()) == NULL ||
+           (r = BN_new()) == NULL) {
+               error("%s: BN_new", __func__);
+               goto out;
+       }
+
+       /* Extract g^v and r from signature blob */
+       buffer_init(&b);
+       buffer_append(&b, sig, siglen);
+       SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b),
+           "%s: sigblob", __func__));
+       buffer_get_bignum2(&b, e);
+       buffer_get_bignum2(&b, r);
+       rlen = buffer_len(&b);
+       buffer_free(&b);
+       if (rlen != 0) {
+               error("%s: remaining bytes in signature %d", __func__, rlen);
+               goto out;
+       }
+
+       ret = schnorr_verify(grp_p, grp_q, grp_g, EVP_sha256(),
+           g_x, id, idlen, r, e);
+ out:
+       BN_clear_free(e);
+       BN_clear_free(r);
+
+       return ret;
+}
+
+/* Helper functions */
+
+/*
+ * Generate uniformly distributed random number in range (1, high).
+ * Return number on success, NULL on failure.
+ */
+BIGNUM *
+bn_rand_range_gt_one(const BIGNUM *high)
+{
+       BIGNUM *r, *tmp;
+       int success = -1;
+
+       if ((tmp = BN_new()) == NULL) {
+               error("%s: BN_new", __func__);
+               return NULL;
+       }
+       if ((r = BN_new()) == NULL) {
+               error("%s: BN_new failed", __func__);
+               goto out;
+       }
+       if (BN_set_word(tmp, 2) != 1) {
+               error("%s: BN_set_word(tmp, 2)", __func__);
+               goto out;
+       }
+       if (BN_sub(tmp, high, tmp) == -1) {
+               error("%s: BN_sub failed (tmp = high - 2)", __func__);
+               goto out;
+       }
+       if (BN_rand_range(r, tmp) == -1) {
+               error("%s: BN_rand_range failed", __func__);
+               goto out;
+       }
+       if (BN_set_word(tmp, 2) != 1) {
+               error("%s: BN_set_word(tmp, 2)", __func__);
+               goto out;
+       }
+       if (BN_add(r, r, tmp) == -1) {
+               error("%s: BN_add failed (r = r + 2)", __func__);
+               goto out;
+       }
+       success = 0;
+ out:
+       BN_clear_free(tmp);
+       if (success == 0)
+               return r;
+       BN_clear_free(r);
+       return NULL;
+}
+
+/*
+ * Hash contents of buffer 'b' with hash 'md'. Returns 0 on success,
+ * with digest via 'digestp' (caller to free) and length via 'lenp'.
+ * Returns -1 on failure.
+ */
+int
+hash_buffer(const u_char *buf, u_int len, const EVP_MD *md,
+    u_char **digestp, u_int *lenp)
+{
+       u_char digest[EVP_MAX_MD_SIZE];
+       u_int digest_len;
+       EVP_MD_CTX evp_md_ctx;
+       int success = -1;
+
+       EVP_MD_CTX_init(&evp_md_ctx);
+
+       if (EVP_DigestInit_ex(&evp_md_ctx, md, NULL) != 1) {
+               error("%s: EVP_DigestInit_ex", __func__);
+               goto out;
+       }
+       if (EVP_DigestUpdate(&evp_md_ctx, buf, len) != 1) {
+               error("%s: EVP_DigestUpdate", __func__);
+               goto out;
+       }
+       if (EVP_DigestFinal_ex(&evp_md_ctx, digest, &digest_len) != 1) {
+               error("%s: EVP_DigestFinal_ex", __func__);
+               goto out;
+       }
+       *digestp = xmalloc(digest_len);
+       *lenp = digest_len;
+       memcpy(*digestp, digest, *lenp);
+       success = 0;
+ out:
+       EVP_MD_CTX_cleanup(&evp_md_ctx);
+       bzero(digest, sizeof(digest));
+       digest_len = 0;
+       return success;
+}
+
+/* print formatted string followed by bignum */
+void
+debug3_bn(const BIGNUM *n, const char *fmt, ...)
+{
+       char *out, *h;
+       va_list args;
+
+       out = NULL;
+       va_start(args, fmt);
+       vasprintf(&out, fmt, args);
+       va_end(args);
+       if (out == NULL)
+               fatal("%s: vasprintf failed", __func__);
+
+       if (n == NULL)
+               debug3("%s(null)", out);
+       else {
+               h = BN_bn2hex(n);
+               debug3("%s0x%s", out, h);
+               free(h);
+       }
+       free(out);
+}
+
+/* print formatted string followed by buffer contents in hex */
+void
+debug3_buf(const u_char *buf, u_int len, const char *fmt, ...)
+{
+       char *out, h[65];
+       u_int i, j;
+       va_list args;
+
+       out = NULL;
+       va_start(args, fmt);
+       vasprintf(&out, fmt, args);
+       va_end(args);
+       if (out == NULL)
+               fatal("%s: vasprintf failed", __func__);
+
+       debug3("%s length %u%s", out, len, buf == NULL ? " (null)" : "");
+       free(out);
+       if (buf == NULL)
+               return;
+
+       *h = '\0';
+       for (i = j = 0; i < len; i++) {
+               snprintf(h + j, sizeof(h) - j, "%02x", buf[i]);
+               j += 2;
+               if (j >= sizeof(h) - 1 || i == len - 1) {
+                       debug3("    %s", h);
+                       *h = '\0';
+                       j = 0;
+               }
+       }
+}
+
+/*
+ * Construct a MODP group from hex strings p (which must be a safe
+ * prime) and g, automatically calculating subgroup q as (p / 2)
+ */
+struct modp_group *
+modp_group_from_g_and_safe_p(const char *grp_g, const char *grp_p)
+{
+       struct modp_group *ret;
+
+       ret = xmalloc(sizeof(*ret));
+       ret->p = ret->q = ret->g = NULL;
+       if (BN_hex2bn(&ret->p, grp_p) == 0 ||
+           BN_hex2bn(&ret->g, grp_g) == 0)
+               fatal("%s: BN_hex2bn", __func__);
+       /* Subgroup order is p/2 (p is a safe prime) */
+       if ((ret->q = BN_new()) == NULL)
+               fatal("%s: BN_new", __func__);
+       if (BN_rshift1(ret->q, ret->p) != 1)
+               fatal("%s: BN_rshift1", __func__);
+
+       return ret;
+}
+
+void
+modp_group_free(struct modp_group *grp)
+{
+       if (grp->g != NULL)
+               BN_clear_free(grp->g);
+       if (grp->p != NULL)
+               BN_clear_free(grp->p);
+       if (grp->q != NULL)
+               BN_clear_free(grp->q);
+       bzero(grp, sizeof(*grp));
+       xfree(grp);
+}
+
+/* main() function for self-test */
+
 #ifdef SCHNORR_MAIN
 static void
 schnorr_selftest_one(const BIGNUM *grp_p, const BIGNUM *grp_q,
 #ifdef SCHNORR_MAIN
 static void
 schnorr_selftest_one(const BIGNUM *grp_p, const BIGNUM *grp_q,
@@ -328,16 +567,17 @@ schnorr_selftest_one(const BIGNUM *grp_p, const BIGNUM *grp_q,
 
        if (BN_mod_exp(g_x, grp_g, x, grp_p, bn_ctx) == -1)
                fatal("%s: g_x", __func__);
 
        if (BN_mod_exp(g_x, grp_g, x, grp_p, bn_ctx) == -1)
                fatal("%s: g_x", __func__);
-       if (schnorr_sign(grp_p, grp_q, grp_g, x, g_x, "junk", 4, &sig, &siglen))
+       if (schnorr_sign_buf(grp_p, grp_q, grp_g, x, g_x, "junk", 4,
+           &sig, &siglen))
                fatal("%s: schnorr_sign", __func__);
                fatal("%s: schnorr_sign", __func__);
-       if (schnorr_verify(grp_p, grp_q, grp_g, g_x, "junk", 4,
+       if (schnorr_verify_buf(grp_p, grp_q, grp_g, g_x, "junk", 4,
            sig, siglen) != 1)
                fatal("%s: verify fail", __func__);
            sig, siglen) != 1)
                fatal("%s: verify fail", __func__);
-       if (schnorr_verify(grp_p, grp_q, grp_g, g_x, "JUNK", 4,
+       if (schnorr_verify_buf(grp_p, grp_q, grp_g, g_x, "JUNK", 4,
            sig, siglen) != 0)
                fatal("%s: verify should have failed (bad ID)", __func__);
        sig[4] ^= 1;
            sig, siglen) != 0)
                fatal("%s: verify should have failed (bad ID)", __func__);
        sig[4] ^= 1;
-       if (schnorr_verify(grp_p, grp_q, grp_g, g_x, "junk", 4,
+       if (schnorr_verify_buf(grp_p, grp_q, grp_g, g_x, "junk", 4,
            sig, siglen) != 0)
                fatal("%s: verify should have failed (bit error)", __func__);
        xfree(sig);
            sig, siglen) != 0)
                fatal("%s: verify should have failed (bit error)", __func__);
        xfree(sig);
@@ -349,7 +589,7 @@ static void
 schnorr_selftest(void)
 {
        BIGNUM *x;
 schnorr_selftest(void)
 {
        BIGNUM *x;
-       struct jpake_group *grp;
+       struct modp_group *grp;
        u_int i;
        char *hh;
 
        u_int i;
        char *hh;
 
index c3c44c17f9d000bc24c139b105a66456b9173b10..bb2f9d6f4fbe09846a79f3658fa3a2c36b4932e7 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: servconf.c,v 1.194 2009/01/22 10:02:34 djm Exp $ */
+/* $OpenBSD: servconf.c,v 1.195 2009/04/14 21:10:54 jj Exp $ */
 /*
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  *                    All rights reserved
 /*
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  *                    All rights reserved
@@ -422,7 +422,7 @@ static struct {
        { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_GLOBAL },
        { "rsaauthentication", sRSAAuthentication, SSHCFG_ALL },
        { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
        { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_GLOBAL },
        { "rsaauthentication", sRSAAuthentication, SSHCFG_ALL },
        { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
-       { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL },  /* alias */
+       { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
 #ifdef KRB5
        { "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
        { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
 #ifdef KRB5
        { "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
        { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
@@ -517,10 +517,10 @@ static struct {
        { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
        { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
        { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
        { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
        { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
        { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
-       { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
+       { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL},
        { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
        { "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
        { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
        { "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
-       { "match", sMatch, SSHCFG_ALL },
+       { "match", sMatch, SSHCFG_ALL },
        { "permitopen", sPermitOpen, SSHCFG_ALL },
        { "forcecommand", sForceCommand, SSHCFG_ALL },
        { "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
        { "permitopen", sPermitOpen, SSHCFG_ALL },
        { "forcecommand", sForceCommand, SSHCFG_ALL },
        { "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
@@ -1544,7 +1544,7 @@ parse_server_match_config(ServerOptions *options, const char *user,
 /*
  * Copy any supported values that are set.
  *
 /*
  * Copy any supported values that are set.
  *
- * If the preauth flag is set, we do not bother copying the the string or
+ * If the preauth flag is set, we do not bother copying the string or
  * array values that are not used pre-authentication, because any that we
  * do use must be explictly sent in mm_getpwnamallow().
  */
  * array values that are not used pre-authentication, because any that we
  * do use must be explictly sent in mm_getpwnamallow().
  */
index 49e4c79dd9bac42bd3b1934fbd65cfa3b630638f..7ab9ff5662d8fe751d06eee502fc454001a4c406 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: serverloop.c,v 1.157 2009/02/12 03:16:01 djm Exp $ */
+/* $OpenBSD: serverloop.c,v 1.159 2009/05/28 16:50:16 andreas Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -78,6 +78,7 @@
 #include "auth-options.h"
 #include "serverloop.h"
 #include "misc.h"
 #include "auth-options.h"
 #include "serverloop.h"
 #include "misc.h"
+#include "roaming.h"
 
 extern ServerOptions options;
 
 
 extern ServerOptions options;
 
@@ -263,7 +264,7 @@ client_alive_check(void)
        int channel_id;
 
        /* timeout, check to see how many we have had */
        int channel_id;
 
        /* timeout, check to see how many we have had */
-       if (++keep_alive_timeouts > options.client_alive_count_max) {
+       if (packet_inc_alive_timeouts() > options.client_alive_count_max) {
                logit("Timeout, client not responding.");
                cleanup_exit(255);
        }
                logit("Timeout, client not responding.");
                cleanup_exit(255);
        }
@@ -405,8 +406,11 @@ process_input(fd_set *readset)
 
        /* Read and buffer any input data from the client. */
        if (FD_ISSET(connection_in, readset)) {
 
        /* Read and buffer any input data from the client. */
        if (FD_ISSET(connection_in, readset)) {
-               len = read(connection_in, buf, sizeof(buf));
+               int cont = 0;
+               len = roaming_read(connection_in, buf, sizeof(buf), &cont);
                if (len == 0) {
                if (len == 0) {
+                       if (cont)
+                               return;
                        verbose("Connection closed by %.100s",
                            get_remote_ipaddr());
                        connection_closed = 1;
                        verbose("Connection closed by %.100s",
                            get_remote_ipaddr());
                        connection_closed = 1;
@@ -913,7 +917,7 @@ server_input_keep_alive(int type, u_int32_t seq, void *ctxt)
         * even if this was generated by something other than
         * the bogus CHANNEL_REQUEST we send for keepalives.
         */
         * even if this was generated by something other than
         * the bogus CHANNEL_REQUEST we send for keepalives.
         */
-       keep_alive_timeouts = 0;
+       packet_set_alive_timeouts(0);
 }
 
 static void
 }
 
 static void
@@ -1149,7 +1153,8 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt)
                    no_port_forwarding_flag ||
                    (!want_reply && listen_port == 0)
 #ifndef NO_IPPORT_RESERVED_CONCEPT
                    no_port_forwarding_flag ||
                    (!want_reply && listen_port == 0)
 #ifndef NO_IPPORT_RESERVED_CONCEPT
-                   || (listen_port < IPPORT_RESERVED && pw->pw_uid != 0)
+                   || (listen_port != 0 && listen_port < IPPORT_RESERVED &&
+                    pw->pw_uid != 0)
 #endif
                    ) {
                        success = 0;
 #endif
                    ) {
                        success = 0;
index b06bf389b854591bc23c6ae04d5ae273e85f185d..52a8a0be53c7e2cd5f298650555350e5f5c0118b 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: session.c,v 1.245 2009/01/22 09:46:01 djm Exp $ */
+/* $OpenBSD: session.c,v 1.246 2009/04/17 19:23:06 stevesk Exp $ */
 /*
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  *                    All rights reserved
 /*
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  *                    All rights reserved
@@ -592,8 +592,7 @@ do_exec_no_pty(Session *s, const char *command)
        signal(WJSIGNAL, cray_job_termination_handler);
 #endif /* _UNICOS */
 #ifdef HAVE_CYGWIN
        signal(WJSIGNAL, cray_job_termination_handler);
 #endif /* _UNICOS */
 #ifdef HAVE_CYGWIN
-       if (is_winnt)
-               cygwin_set_impersonation_token(INVALID_HANDLE_VALUE);
+       cygwin_set_impersonation_token(INVALID_HANDLE_VALUE);
 #endif
 
        s->pid = pid;
 #endif
 
        s->pid = pid;
@@ -737,8 +736,8 @@ do_exec_pty(Session *s, const char *command)
                 * Do common processing for the child, such as execing
                 * the command.
                 */
                 * Do common processing for the child, such as execing
                 * the command.
                 */
-               do_child(s, command);
-               /* NOTREACHED */
+               do_child(s, command);
+               /* NOTREACHED */
        default:
                break;
        }
        default:
                break;
        }
@@ -747,8 +746,7 @@ do_exec_pty(Session *s, const char *command)
        signal(WJSIGNAL, cray_job_termination_handler);
 #endif /* _UNICOS */
 #ifdef HAVE_CYGWIN
        signal(WJSIGNAL, cray_job_termination_handler);
 #endif /* _UNICOS */
 #ifdef HAVE_CYGWIN
-       if (is_winnt)
-               cygwin_set_impersonation_token(INVALID_HANDLE_VALUE);
+       cygwin_set_impersonation_token(INVALID_HANDLE_VALUE);
 #endif
 
        s->pid = pid;
 #endif
 
        s->pid = pid;
@@ -888,7 +886,7 @@ do_login(Session *s, const char *command)
        fromlen = sizeof(from);
        if (packet_connection_is_on_socket()) {
                if (getpeername(packet_get_connection_in(),
        fromlen = sizeof(from);
        if (packet_connection_is_on_socket()) {
                if (getpeername(packet_get_connection_in(),
-                   (struct sockaddr *) & from, &fromlen) < 0) {
+                   (struct sockaddr *)&from, &fromlen) < 0) {
                        debug("getpeername: %.100s", strerror(errno));
                        cleanup_exit(255);
                }
                        debug("getpeername: %.100s", strerror(errno));
                        cleanup_exit(255);
                }
@@ -1268,7 +1266,7 @@ do_setup_env(Session *s, const char *shell)
        u_int i, envsize;
        char **env, *laddr;
        struct passwd *pw = s->pw;
        u_int i, envsize;
        char **env, *laddr;
        struct passwd *pw = s->pw;
-#ifndef HAVE_LOGIN_CAP
+#if !defined (HAVE_LOGIN_CAP) && !defined (HAVE_CYGWIN)
        char *path = NULL;
 #endif
 
        char *path = NULL;
 #endif
 
@@ -1637,11 +1635,6 @@ do_setusercontext(struct passwd *pw)
        if (getuid() == 0 || geteuid() == 0)
 #endif /* HAVE_CYGWIN */
        {
        if (getuid() == 0 || geteuid() == 0)
 #endif /* HAVE_CYGWIN */
        {
-
-#ifdef HAVE_SETPCRED
-               if (setpcred(pw->pw_name, (char **)NULL) == -1)
-                       fatal("Failed to set process credentials");
-#endif /* HAVE_SETPCRED */
 #ifdef HAVE_LOGIN_CAP
 # ifdef __bsdi__
                setpgid(0, 0);
 #ifdef HAVE_LOGIN_CAP
 # ifdef __bsdi__
                setpgid(0, 0);
@@ -1709,6 +1702,10 @@ do_setusercontext(struct passwd *pw)
                        free(chroot_path);
                }
 
                        free(chroot_path);
                }
 
+#ifdef HAVE_SETPCRED
+               if (setpcred(pw->pw_name, (char **)NULL) == -1)
+                       fatal("Failed to set process credentials");
+#endif /* HAVE_SETPCRED */
 #ifdef HAVE_LOGIN_CAP
                if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETUSER) < 0) {
                        perror("unable to set user context (setuser)");
 #ifdef HAVE_LOGIN_CAP
                if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETUSER) < 0) {
                        perror("unable to set user context (setuser)");
@@ -1720,9 +1717,6 @@ do_setusercontext(struct passwd *pw)
 #endif
        }
 
 #endif
        }
 
-#ifdef HAVE_CYGWIN
-       if (is_winnt)
-#endif
        if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
                fatal("Failed to set uids to %u.", (u_int) pw->pw_uid);
 
        if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
                fatal("Failed to set uids to %u.", (u_int) pw->pw_uid);
 
@@ -2010,7 +2004,7 @@ do_child(Session *s, const char *command)
                int i;
                char *p, *args;
 
                int i;
                char *p, *args;
 
-               setproctitle("%s@internal-sftp-server", s->pw->pw_name);
+               setproctitle("%s@%s", s->pw->pw_name, INTERNAL_SFTP_NAME);
                args = xstrdup(command ? command : "sftp-server");
                for (i = 0, (p = strtok(args, " ")); p; (p = strtok(NULL, " ")))
                        if (i < ARGV_MAX - 1)
                args = xstrdup(command ? command : "sftp-server");
                for (i = 0, (p = strtok(args, " ")); p; (p = strtok(NULL, " ")))
                        if (i < ARGV_MAX - 1)
index 9123cfe6baf886b087c95c139ef2d96811231634..f77dea3a63655ccae4dabc9c117b9b5252d98d5d 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-agent.c,v 1.159 2008/06/28 14:05:15 djm Exp $ */
+/* $OpenBSD: ssh-agent.c,v 1.161 2009/03/23 19:38:04 tobias Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -1061,6 +1061,7 @@ main(int ac, char **av)
        pid_t pid;
        char pidstrbuf[1 + 3 * sizeof pid];
        struct timeval *tvp = NULL;
        pid_t pid;
        char pidstrbuf[1 + 3 * sizeof pid];
        struct timeval *tvp = NULL;
+       size_t len;
 
        /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
        sanitise_stdfd();
 
        /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
        sanitise_stdfd();
@@ -1121,8 +1122,8 @@ main(int ac, char **av)
 
        if (ac == 0 && !c_flag && !s_flag) {
                shell = getenv("SHELL");
 
        if (ac == 0 && !c_flag && !s_flag) {
                shell = getenv("SHELL");
-               if (shell != NULL &&
-                   strncmp(shell + strlen(shell) - 3, "csh", 3) == 0)
+               if (shell != NULL && (len = strlen(shell)) > 2 &&
+                   strncmp(shell + len - 3, "csh", 3) == 0)
                        c_flag = 1;
        }
        if (k_flag) {
                        c_flag = 1;
        }
        if (k_flag) {
index 421783be36989519d189e707a88ff9bfea91df68..6c6271ee4f74dc6a109b466ea513f224a4da7251 100644 (file)
@@ -34,8 +34,8 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.\" $OpenBSD: ssh.1,v 1.282 2009/02/12 03:44:25 djm Exp $
-.Dd $Mdocdate: February 12 2009 $
+.\" $OpenBSD: ssh.1,v 1.283 2009/03/19 15:15:09 jmc Exp $
+.Dd $Mdocdate: March 19 2009 $
 .Dt SSH 1
 .Os
 .Sh NAME
 .Dt SSH 1
 .Os
 .Sh NAME
@@ -191,26 +191,9 @@ For protocol version 2,
 .Ar cipher_spec
 is a comma-separated list of ciphers
 listed in order of preference.
 .Ar cipher_spec
 is a comma-separated list of ciphers
 listed in order of preference.
-The supported ciphers are:
-3des-cbc,
-aes128-cbc,
-aes192-cbc,
-aes256-cbc,
-aes128-ctr,
-aes192-ctr,
-aes256-ctr,
-arcfour128,
-arcfour256,
-arcfour,
-blowfish-cbc,
-and
-cast128-cbc.
-The default is:
-.Bd -literal -offset indent
-aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour128,
-arcfour256,arcfour,aes192-cbc,aes256-cbc,aes128-ctr,
-aes192-ctr,aes256-ctr
-.Ed
+See the
+.Cm Ciphers
+keyword for more information.
 .It Fl D Xo
 .Sm off
 .Oo Ar bind_address : Oc
 .It Fl D Xo
 .Sm off
 .Oo Ar bind_address : Oc
index f1121341c3a24a4a7906dd4361d0eb4d7d5c56c6..21f4c84e9bfb0a4cbd4267a3aacfdd4d489765fa 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh.c,v 1.324 2009/02/12 03:00:56 djm Exp $ */
+/* $OpenBSD: ssh.c,v 1.326 2009/07/02 02:11:47 dtucker Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -48,6 +48,7 @@
 #endif
 #include <sys/resource.h>
 #include <sys/ioctl.h>
 #endif
 #include <sys/resource.h>
 #include <sys/ioctl.h>
+#include <sys/param.h>
 #include <sys/socket.h>
 
 #include <ctype.h>
 #include <sys/socket.h>
 
 #include <ctype.h>
@@ -203,8 +204,8 @@ void muxserver_listen(void);
 int
 main(int ac, char **av)
 {
 int
 main(int ac, char **av)
 {
-       int i, opt, exit_status, use_syslog;
-       char *p, *cp, *line, buf[256];
+       int i, r, opt, exit_status, use_syslog;
+       char *p, *cp, *line, *argv0, buf[MAXPATHLEN];
        struct stat st;
        struct passwd *pw;
        int dummy, timeout_ms;
        struct stat st;
        struct passwd *pw;
        int dummy, timeout_ms;
@@ -270,6 +271,7 @@ main(int ac, char **av)
        /* Parse command-line arguments. */
        host = NULL;
        use_syslog = 0;
        /* Parse command-line arguments. */
        host = NULL;
        use_syslog = 0;
+       argv0 = av[0];
 
  again:
        while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx"
 
  again:
        while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx"
@@ -604,7 +606,7 @@ main(int ac, char **av)
         * Initialize "log" output.  Since we are the client all output
         * actually goes to stderr.
         */
         * Initialize "log" output.  Since we are the client all output
         * actually goes to stderr.
         */
-       log_init(av[0],
+       log_init(argv0,
            options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level,
            SYSLOG_FACILITY_USER, !use_syslog);
 
            options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level,
            SYSLOG_FACILITY_USER, !use_syslog);
 
@@ -626,23 +628,27 @@ main(int ac, char **av)
             * options.
             */
 #ifdef GSSAPI
             * options.
             */
 #ifdef GSSAPI
-               snprintf(buf, sizeof buf, "%.100s/%.100s.gssapi", pw->pw_dir,
+               r = snprintf(buf, sizeof buf, "%s/%s.gssapi", pw->pw_dir,
                    _PATH_SSH_USER_CONFFILE);
                    _PATH_SSH_USER_CONFFILE);
-               (void)read_config_file(buf, host, &options, 1);
+               if (r > 0 && (size_t)r < sizeof(buf))
+                       (void)read_config_file(buf, host, &options, 1);
 #ifdef GSI
 #ifdef GSI
-               snprintf(buf, sizeof buf, "%.100s/%.100s.gsi", pw->pw_dir,
+               r = snprintf(buf, sizeof buf, "%s/%s.gsi", pw->pw_dir,
                    _PATH_SSH_USER_CONFFILE);
                    _PATH_SSH_USER_CONFFILE);
-               (void)read_config_file(buf, host, &options, 1);
+               if (r > 0 && (size_t)r < sizeof(buf))
+                       (void)read_config_file(buf, host, &options, 1);
 #endif
 #if defined(KRB5)
 #endif
 #if defined(KRB5)
-               snprintf(buf, sizeof buf, "%.100s/%.100s.krb", pw->pw_dir,
+               r = snprintf(buf, sizeof buf, "%s/%s.krb", pw->pw_dir,
                    _PATH_SSH_USER_CONFFILE);
                    _PATH_SSH_USER_CONFFILE);
-               (void)read_config_file(buf, host, &options, 1);
+               if (r > 0 && (size_t)r < sizeof(buf))
+                       (void)read_config_file(buf, host, &options, 1);
 #endif
 #endif
 #endif
 #endif
-               snprintf(buf, sizeof buf, "%.100s/%.100s", pw->pw_dir,
+               r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir,
                    _PATH_SSH_USER_CONFFILE);
                    _PATH_SSH_USER_CONFFILE);
-               (void)read_config_file(buf, host, &options, 1);
+               if (r > 0 && (size_t)r < sizeof(buf))
+                       (void)read_config_file(buf, host, &options, 1);
 
                /* Read systemwide configuration file after use config. */
                (void)read_config_file(_PATH_HOST_CONFIG_FILE, host,
 
                /* Read systemwide configuration file after use config. */
                (void)read_config_file(_PATH_HOST_CONFIG_FILE, host,
@@ -655,7 +661,7 @@ main(int ac, char **av)
        channel_set_af(options.address_family);
 
        /* reinit */
        channel_set_af(options.address_family);
 
        /* reinit */
-       log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, !use_syslog);
+       log_init(argv0, options.log_level, SYSLOG_FACILITY_USER, !use_syslog);
 
        seed_rng();
 
 
        seed_rng();
 
@@ -796,9 +802,9 @@ main(int ac, char **av)
         * Now that we are back to our own permissions, create ~/.ssh
         * directory if it doesn't already exist.
         */
         * Now that we are back to our own permissions, create ~/.ssh
         * directory if it doesn't already exist.
         */
-       snprintf(buf, sizeof buf, "%.100s%s%.100s", pw->pw_dir,
+       r = snprintf(buf, sizeof buf, "%s%s%s", pw->pw_dir,
            strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR);
            strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR);
-       if (stat(buf, &st) < 0)
+       if (r > 0 && (size_t)r < sizeof(buf) && stat(buf, &st) < 0)
                if (mkdir(buf, 0700) < 0)
                        error("Could not create directory '%.200s'.", buf);
 
                if (mkdir(buf, 0700) < 0)
                        error("Could not create directory '%.200s'.", buf);
 
index 706318d49b06e2eab21bf04d7f0818827e68501b..033c4f4993ed32e058e132f4033459cfbd89af17 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect.c,v 1.212 2008/10/14 18:11:33 stevesk Exp $ */
+/* $OpenBSD: sshconnect.c,v 1.214 2009/05/28 16:50:16 andreas Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -56,6 +56,7 @@
 #include "atomicio.h"
 #include "misc.h"
 #include "dns.h"
 #include "atomicio.h"
 #include "misc.h"
 #include "dns.h"
+#include "roaming.h"
 #include "version.h"
 
 char *client_version_string = NULL;
 #include "version.h"
 
 char *client_version_string = NULL;
@@ -448,7 +449,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
  * Waits for the server identification string, and sends our own
  * identification string.
  */
  * Waits for the server identification string, and sends our own
  * identification string.
  */
-static void
+void
 ssh_exchange_identification(int timeout_ms)
 {
        char buf[256], remote_version[256];     /* must be same size! */
 ssh_exchange_identification(int timeout_ms)
 {
        char buf[256], remote_version[256];     /* must be same size! */
@@ -487,7 +488,7 @@ ssh_exchange_identification(int timeout_ms)
                                }
                        }
 
                                }
                        }
 
-                       len = atomicio(read, connection_in, &buf[i], 1);
+                       len = roaming_atomicio(read, connection_in, &buf[i], 1);
 
                        if (len != 1 && errno == EPIPE)
                                fatal("ssh_exchange_identification: "
 
                        if (len != 1 && errno == EPIPE)
                                fatal("ssh_exchange_identification: "
@@ -572,7 +573,8 @@ ssh_exchange_identification(int timeout_ms)
            compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
            compat20 ? PROTOCOL_MINOR_2 : minor1,
            SSH_RELEASE, compat20 ? "\r\n" : "\n");
            compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
            compat20 ? PROTOCOL_MINOR_2 : minor1,
            SSH_RELEASE, compat20 ? "\r\n" : "\n");
-       if (atomicio(vwrite, connection_out, buf, strlen(buf)) != strlen(buf))
+       if (roaming_atomicio(vwrite, connection_out, buf, strlen(buf))
+           != strlen(buf))
                fatal("write: %.100s", strerror(errno));
        client_version_string = xstrdup(buf);
        chop(client_version_string);
                fatal("write: %.100s", strerror(errno));
        client_version_string = xstrdup(buf);
        chop(client_version_string);
index c7aadb4a9526c5433d685ee0b1c9c07d0e720c06..4744e377dc891ff54d5133b31d64e75fe4aef846 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect2.c,v 1.170 2008/11/04 08:22:13 djm Exp $ */
+/* $OpenBSD: sshconnect2.c,v 1.171 2009/03/05 07:18:19 djm Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  * Copyright (c) 2008 Damien Miller.  All rights reserved.
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  * Copyright (c) 2008 Damien Miller.  All rights reserved.
@@ -68,6 +68,7 @@
 #include "msg.h"
 #include "pathnames.h"
 #include "uidswap.h"
 #include "msg.h"
 #include "pathnames.h"
 #include "uidswap.h"
+#include "schnorr.h"
 #include "jpake.h"
 
 #ifdef GSSAPI
 #include "jpake.h"
 
 #ifdef GSSAPI
index a4b9e90c718a10380fd78c0dbbf0676c76c2b246..111d491d9a71fb0a07a0ceefa7d105cddb3e8fc6 100644 (file)
@@ -34,8 +34,8 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.\" $OpenBSD: sshd.8,v 1.247 2008/10/03 13:08:12 jmc Exp $
-.Dd $Mdocdate: October 3 2008 $
+.\" $OpenBSD: sshd.8,v 1.248 2009/03/26 08:38:39 sobrado Exp $
+.Dd $Mdocdate: March 26 2009 $
 .Dt SSHD 8
 .Os
 .Sh NAME
 .Dt SSHD 8
 .Os
 .Sh NAME
@@ -543,7 +543,7 @@ for more information on patterns.
 In addition to the wildcard matching that may be applied to hostnames or
 addresses, a
 .Cm from
 In addition to the wildcard matching that may be applied to hostnames or
 addresses, a
 .Cm from
-stanza may match IP addressess using CIDR address/masklen notation.
+stanza may match IP addresses using CIDR address/masklen notation.
 .Pp
 The purpose of this option is to optionally increase security: public key
 authentication by itself does not trust the network or name servers or
 .Pp
 The purpose of this option is to optionally increase security: public key
 authentication by itself does not trust the network or name servers or
index 1805bdef230295bcedabcb860195b8a26602a83f..12000b1bf5a625add52e281b2c3b878b75aaa4c9 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshd.c,v 1.366 2009/01/22 10:02:34 djm Exp $ */
+/* $OpenBSD: sshd.c,v 1.367 2009/05/28 16:50:16 andreas Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
 #include "ssh-gss.h"
 #endif
 #include "monitor_wrap.h"
 #include "ssh-gss.h"
 #endif
 #include "monitor_wrap.h"
+#include "roaming.h"
 #include "version.h"
 
 #ifdef USE_SECURITY_SESSION_API
 #include "version.h"
 
 #ifdef USE_SECURITY_SESSION_API
@@ -426,7 +427,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
        server_version_string = xstrdup(buf);
 
        /* Send our protocol version identification. */
        server_version_string = xstrdup(buf);
 
        /* Send our protocol version identification. */
-       if (atomicio(vwrite, sock_out, server_version_string,
+       if (roaming_atomicio(vwrite, sock_out, server_version_string,
            strlen(server_version_string))
            != strlen(server_version_string)) {
                logit("Could not write ident string to %s", get_remote_ipaddr());
            strlen(server_version_string))
            != strlen(server_version_string)) {
                logit("Could not write ident string to %s", get_remote_ipaddr());
@@ -436,7 +437,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
        /* Read other sides version identification. */
        memset(buf, 0, sizeof(buf));
        for (i = 0; i < sizeof(buf) - 1; i++) {
        /* Read other sides version identification. */
        memset(buf, 0, sizeof(buf));
        for (i = 0; i < sizeof(buf) - 1; i++) {
-               if (atomicio(read, sock_in, &buf[i], 1) != 1) {
+               if (roaming_atomicio(read, sock_in, &buf[i], 1) != 1) {
                        logit("Did not receive identification string from %s",
                            get_remote_ipaddr());
                        cleanup_exit(255);
                        logit("Did not receive identification string from %s",
                            get_remote_ipaddr());
                        cleanup_exit(255);
@@ -587,7 +588,7 @@ demote_sensitive_data(void)
 static void
 privsep_preauth_child(void)
 {
 static void
 privsep_preauth_child(void)
 {
-       u_int32_t rnd[256];
+       u_int32_t rnd[256];
        gid_t gidset[1];
 
        /* Enable challenge-response authentication for privilege separation */
        gid_t gidset[1];
 
        /* Enable challenge-response authentication for privilege separation */
index 060249535a9a604f5aa9a5a4995602b8bc08209a..5a214bfd0f8d257ed738a0bb663ede1f86021795 100644 (file)
@@ -34,8 +34,8 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.\" $OpenBSD: sshd_config.5,v 1.102 2009/02/22 23:59:25 djm Exp $
-.Dd $Mdocdate: February 22 2009 $
+.\" $OpenBSD: sshd_config.5,v 1.106 2009/04/21 15:13:17 stevesk Exp $
+.Dd $Mdocdate: April 21 2009 $
 .Dt SSHD_CONFIG 5
 .Os
 .Sh NAME
 .Dt SSHD_CONFIG 5
 .Os
 .Sh NAME
@@ -176,10 +176,9 @@ then no banner is displayed.
 This option is only available for protocol version 2.
 By default, no banner is displayed.
 .It Cm ChallengeResponseAuthentication
 This option is only available for protocol version 2.
 By default, no banner is displayed.
 .It Cm ChallengeResponseAuthentication
-Specifies whether challenge-response authentication is allowed.
-All authentication styles from
-.Xr login.conf 5
-are supported.
+Specifies whether challenge-response authentication is allowed (e.g. via
+PAM or though authentication styles supported in
+.Xr login.conf 5 )
 The default is
 .Dq yes .
 .It Cm ChrootDirectory
 The default is
 .Dq yes .
 .It Cm ChrootDirectory
@@ -188,6 +187,9 @@ Specifies a path to
 to after authentication.
 This path, and all its components, must be root-owned directories that are
 not writable by any other user or group.
 to after authentication.
 This path, and all its components, must be root-owned directories that are
 not writable by any other user or group.
+After the chroot,
+.Xr sshd 8
+changes the working directory to the user's home directory.
 .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 '%',
 .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 '%',
@@ -197,7 +199,7 @@ the connecting user has been authenticated: %% is replaced by a literal '%',
 The
 .Cm ChrootDirectory
 must contain the necessary files and directories to support the
 The
 .Cm ChrootDirectory
 must contain the necessary files and directories to support the
-users' session.
+user's session.
 For an interactive session this requires at least a shell, typically
 .Xr sh 1 ,
 and basic
 For an interactive session this requires at least a shell, typically
 .Xr sh 1 ,
 and basic
@@ -215,8 +217,11 @@ devices.
 For file transfer sessions using
 .Dq sftp ,
 no additional configuration of the environment is necessary if the
 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
+in-process sftp server is used,
+though sessions which use logging do require
+.Pa /dev/log
+inside the chroot directory (see
+.Xr sftp-server 8
 for details).
 .Pp
 The default is not to
 for details).
 .Pp
 The default is not to
index 127f104749632558c557633ecb620bc4eab11863..432014a64f90808b97bc9523660c3ade39100a05 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: version.h,v 1.55 2009/02/23 00:06:15 djm Exp $ */
+/* $OpenBSD: version.h,v 1.56 2009/06/30 14:54:40 markus Exp $ */
 
 #ifdef GSI
 #define GSI_VERSION    " GSI"
 
 #ifdef GSI
 #define GSI_VERSION    " GSI"
@@ -18,9 +18,9 @@
 #define MGLUE_VERSION  ""
 #endif
 
 #define MGLUE_VERSION  ""
 #endif
 
-#define NCSA_VERSION   " GLOBUS_GSSAPI_20090928"
+#define NCSA_VERSION   " GLOBUS_GSSAPI_20091001"
 
 
-#define SSH_VERSION    "OpenSSH_5.2"
+#define SSH_VERSION    "OpenSSH_5.3"
 
 #define SSH_PORTABLE   "p1"
 #define SSH_HPN         "-hpn13v6"
 
 #define SSH_PORTABLE   "p1"
 #define SSH_HPN         "-hpn13v6"
This page took 0.384126 seconds and 5 git commands to generate.