]> andersk Git - openssh.git/commitdiff
- markus@cvs.openbsd.org 2005/07/25 11:59:40
authordjm <djm>
Tue, 26 Jul 2005 11:54:56 +0000 (11:54 +0000)
committerdjm <djm>
Tue, 26 Jul 2005 11:54:56 +0000 (11:54 +0000)
     [kex.c kex.h myproposal.h packet.c packet.h servconf.c session.c]
     [sshconnect2.c sshd.c sshd_config sshd_config.5]
     add a new compression method that delays compression until the user
     has been authenticated successfully and set compression to 'delayed'
     for sshd.
     this breaks older openssh clients (< 3.5) if they insist on
     compression, so you have to re-enable compression in sshd_config.
     ok djm@

12 files changed:
ChangeLog
kex.c
kex.h
myproposal.h
packet.c
packet.h
servconf.c
session.c
sshconnect2.c
sshd.c
sshd_config
sshd_config.5

index 0418a7d7e9bb77f34e70cc066295a008a2947a9b..e0f7ffce35308dc6038c32715e6d286e9e5c6d9c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,6 +6,15 @@
      [auth-passwd.c]
      auth_usercheck(3) can return NULL, so check for that. Report from
      mpech@. ok markus@
      [auth-passwd.c]
      auth_usercheck(3) can return NULL, so check for that. Report from
      mpech@. ok markus@
+   - markus@cvs.openbsd.org 2005/07/25 11:59:40
+     [kex.c kex.h myproposal.h packet.c packet.h servconf.c session.c]
+     [sshconnect2.c sshd.c sshd_config sshd_config.5]
+     add a new compression method that delays compression until the user
+     has been authenticated successfully and set compression to 'delayed'
+     for sshd.
+     this breaks older openssh clients (< 3.5) if they insist on
+     compression, so you have to re-enable compression in sshd_config.
+     ok djm@
 
 20050725
  - (dtucker) [configure.ac] Update zlib version check for CAN-2005-2096.
 
 20050725
  - (dtucker) [configure.ac] Update zlib version check for CAN-2005-2096.
diff --git a/kex.c b/kex.c
index 06a3ad4ccd0cf313e8c2726d2de450be4a420b65..5dce335fe5f11d1fe3533425544a5760263011ef 100644 (file)
--- a/kex.c
+++ b/kex.c
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: kex.c,v 1.63 2005/07/17 07:17:55 djm Exp $");
+RCSID("$OpenBSD: kex.c,v 1.64 2005/07/25 11:59:39 markus Exp $");
 
 #include <openssl/crypto.h>
 
 
 #include <openssl/crypto.h>
 
@@ -275,10 +275,12 @@ choose_comp(Comp *comp, char *client, char *server)
        char *name = match_list(client, server, NULL);
        if (name == NULL)
                fatal("no matching comp found: client %s server %s", client, server);
        char *name = match_list(client, server, NULL);
        if (name == NULL)
                fatal("no matching comp found: client %s server %s", client, server);
-       if (strcmp(name, "zlib") == 0) {
-               comp->type = 1;
+       if (strcmp(name, "zlib@openssh.com") == 0) {
+               comp->type = COMP_DELAYED;
+       } else if (strcmp(name, "zlib") == 0) {
+               comp->type = COMP_ZLIB;
        } else if (strcmp(name, "none") == 0) {
        } else if (strcmp(name, "none") == 0) {
-               comp->type = 0;
+               comp->type = COMP_NONE;
        } else {
                fatal("unsupported comp %s", name);
        }
        } else {
                fatal("unsupported comp %s", name);
        }
diff --git a/kex.h b/kex.h
index 059d83cd5495ab3078560a8515fc7e46fbc0fb61..3024a27172eae078da61dbe08e705a3c1e03732f 100644 (file)
--- a/kex.h
+++ b/kex.h
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kex.h,v 1.36 2005/06/17 02:44:32 djm Exp $    */
+/*     $OpenBSD: kex.h,v 1.37 2005/07/25 11:59:39 markus Exp $ */
 
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
 
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
 #define        KEX_DH14        "diffie-hellman-group14-sha1"
 #define        KEX_DHGEX       "diffie-hellman-group-exchange-sha1"
 
 #define        KEX_DH14        "diffie-hellman-group14-sha1"
 #define        KEX_DHGEX       "diffie-hellman-group-exchange-sha1"
 
+#define COMP_NONE      0
+#define COMP_ZLIB      1
+#define COMP_DELAYED   2
+
 enum kex_init_proposals {
        PROPOSAL_KEX_ALGS,
        PROPOSAL_SERVER_HOST_KEY_ALGS,
 enum kex_init_proposals {
        PROPOSAL_KEX_ALGS,
        PROPOSAL_SERVER_HOST_KEY_ALGS,
index 2edbe1624838aaafc4fccb0eb1fad53a3ab3041e..d8cba1caf818fc7da272781561a90399668ad2fd 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: myproposal.h,v 1.17 2005/05/23 23:32:46 djm Exp $     */
+/*     $OpenBSD: myproposal.h,v 1.18 2005/07/25 11:59:39 markus Exp $  */
 
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
 
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
@@ -36,7 +36,7 @@
        "hmac-md5,hmac-sha1,hmac-ripemd160," \
        "hmac-ripemd160@openssh.com," \
        "hmac-sha1-96,hmac-md5-96"
        "hmac-md5,hmac-sha1,hmac-ripemd160," \
        "hmac-ripemd160@openssh.com," \
        "hmac-sha1-96,hmac-md5-96"
-#define        KEX_DEFAULT_COMP        "none,zlib"
+#define        KEX_DEFAULT_COMP        "none,zlib@openssh.com,zlib"
 #define        KEX_DEFAULT_LANG        ""
 
 
 #define        KEX_DEFAULT_LANG        ""
 
 
index d5b50f2f4ff7cb076be18b13b12e02ecd538d6f9..c855970fc7d151e1e31e52208ba916c1a71b4185 100644 (file)
--- a/packet.c
+++ b/packet.c
@@ -37,7 +37,7 @@
  */
 
 #include "includes.h"
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: packet.c,v 1.117 2005/06/17 02:44:32 djm Exp $");
+RCSID("$OpenBSD: packet.c,v 1.118 2005/07/25 11:59:39 markus Exp $");
 
 #include "openbsd-compat/sys-queue.h"
 
 
 #include "openbsd-compat/sys-queue.h"
 
@@ -116,6 +116,12 @@ static int initialized = 0;
 /* Set to true if the connection is interactive. */
 static int interactive_mode = 0;
 
 /* Set to true if the connection is interactive. */
 static int interactive_mode = 0;
 
+/* Set to true if we are the server side. */
+static int server_side = 0;
+
+/* Set to true if we are authenticated. */
+static int after_authentication = 0;
+
 /* Session key information for Encryption and MAC */
 Newkeys *newkeys[MODE_MAX];
 static struct packet_state {
 /* Session key information for Encryption and MAC */
 Newkeys *newkeys[MODE_MAX];
 static struct packet_state {
@@ -624,7 +630,9 @@ set_newkeys(int mode)
        /* Deleting the keys does not gain extra security */
        /* memset(enc->iv,  0, enc->block_size);
           memset(enc->key, 0, enc->key_len); */
        /* Deleting the keys does not gain extra security */
        /* memset(enc->iv,  0, enc->block_size);
           memset(enc->key, 0, enc->key_len); */
-       if (comp->type != 0 && comp->enabled == 0) {
+       if ((comp->type == COMP_ZLIB ||
+           (comp->type == COMP_DELAYED && 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);
@@ -644,6 +652,34 @@ set_newkeys(int mode)
                *max_blocks = MIN(*max_blocks, rekey_limit / enc->block_size);
 }
 
                *max_blocks = MIN(*max_blocks, rekey_limit / enc->block_size);
 }
 
+/*
+ * Delayed compression for SSH2 is enabled after authentication:
+ * This happans on the server side after a SSH2_MSG_USERAUTH_SUCCESS is sent,
+ * and on the client side after a SSH2_MSG_USERAUTH_SUCCESS is received.
+ */
+static void
+packet_enable_delayed_compress(void)
+{
+       Comp *comp = NULL;
+       int mode;
+
+       /*
+        * Remember that we are past the authentication step, so rekeying
+        * with COMP_DELAYED will turn on compression immediately.
+        */
+       after_authentication = 1;
+       for (mode = 0; mode < MODE_MAX; mode++) {
+               comp = &newkeys[mode]->comp;
+               if (comp && !comp->enabled && comp->type == COMP_DELAYED) {
+                       if (mode == MODE_OUT)
+                               buffer_compress_init_send(6);
+                       else
+                               buffer_compress_init_recv();
+                       comp->enabled = 1;
+               }
+       }
+}
+
 /*
  * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue)
  */
 /*
  * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue)
  */
@@ -757,6 +793,8 @@ packet_send2_wrapped(void)
 
        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)
+               packet_enable_delayed_compress();
 }
 
 static void
 }
 
 static void
@@ -1099,6 +1137,8 @@ packet_read_poll2(u_int32_t *seqnr_p)
                packet_disconnect("Invalid ssh2 packet type: %d", type);
        if (type == SSH2_MSG_NEWKEYS)
                set_newkeys(MODE_IN);
                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)
+               packet_enable_delayed_compress();
 #ifdef PACKET_DEBUG
        fprintf(stderr, "read/plain[%d]:\r\n", type);
        buffer_dump(&incoming_packet);
 #ifdef PACKET_DEBUG
        fprintf(stderr, "read/plain[%d]:\r\n", type);
        buffer_dump(&incoming_packet);
@@ -1524,3 +1564,15 @@ packet_set_rekey_limit(u_int32_t bytes)
 {
        rekey_limit = bytes;
 }
 {
        rekey_limit = bytes;
 }
+
+void
+packet_set_server(void)
+{
+       server_side = 1;
+}
+
+void
+packet_set_authenticated(void)
+{
+       after_authentication = 1;
+}
index 1ab6d8572a5afe74224b8d0837957cb823d90db3..8c23646aaae45c84c1bcdaa3f722254b66631e08 100644 (file)
--- a/packet.h
+++ b/packet.h
@@ -1,4 +1,4 @@
-/*     $OpenBSD: packet.h,v 1.42 2005/06/17 02:44:33 djm Exp $ */
+/*     $OpenBSD: packet.h,v 1.43 2005/07/25 11:59:40 markus Exp $      */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -30,6 +30,8 @@ u_int  packet_get_protocol_flags(void);
 void     packet_start_compression(int);
 void     packet_set_interactive(int);
 int      packet_is_interactive(void);
 void     packet_start_compression(int);
 void     packet_set_interactive(int);
 int      packet_is_interactive(void);
+void     packet_set_server(void);
+void     packet_set_authenticated(void);
 
 void     packet_start(u_char);
 void     packet_put_char(int ch);
 
 void     packet_start(u_char);
 void     packet_put_char(int ch);
index deec167becb91080eeab8dcac70f685bfcaba2aa..7ef7b234e1fab86c9c1ba3711d760040ac439be3 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 #include "includes.h"
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: servconf.c,v 1.142 2005/06/17 02:44:33 djm Exp $");
+RCSID("$OpenBSD: servconf.c,v 1.143 2005/07/25 11:59:40 markus Exp $");
 
 #include "ssh.h"
 #include "log.h"
 
 #include "ssh.h"
 #include "log.h"
@@ -201,7 +201,7 @@ fill_default_server_options(ServerOptions *options)
        if (options->use_login == -1)
                options->use_login = 0;
        if (options->compression == -1)
        if (options->use_login == -1)
                options->use_login = 0;
        if (options->compression == -1)
-               options->compression = 1;
+               options->compression = COMP_DELAYED;
        if (options->allow_tcp_forwarding == -1)
                options->allow_tcp_forwarding = 1;
        if (options->gateway_ports == -1)
        if (options->allow_tcp_forwarding == -1)
                options->allow_tcp_forwarding = 1;
        if (options->gateway_ports == -1)
@@ -725,7 +725,23 @@ parse_flag:
 
        case sCompression:
                intptr = &options->compression;
 
        case sCompression:
                intptr = &options->compression;
-               goto parse_flag;
+               arg = strdelim(&cp);
+               if (!arg || *arg == '\0')
+                       fatal("%s line %d: missing yes/no/delayed "
+                           "argument.", filename, linenum);
+               value = 0;      /* silence compiler */
+               if (strcmp(arg, "delayed") == 0)
+                       value = COMP_DELAYED;
+               else if (strcmp(arg, "yes") == 0)
+                       value = COMP_ZLIB;
+               else if (strcmp(arg, "no") == 0)
+                       value = COMP_NONE;
+               else
+                       fatal("%s line %d: Bad yes/no/delayed "
+                           "argument: %s", filename, linenum, arg);
+               if (*intptr == -1)
+                       *intptr = value;
+               break;
 
        case sGatewayPorts:
                intptr = &options->gateway_ports;
 
        case sGatewayPorts:
                intptr = &options->gateway_ports;
index 171c239e241b7c607c7d181d7fbcfc6b6dc194c1..95084aec6c2158decd619bf64f655d2ed8a52a96 100644 (file)
--- a/session.c
+++ b/session.c
@@ -33,7 +33,7 @@
  */
 
 #include "includes.h"
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: session.c,v 1.185 2005/07/17 07:17:55 djm Exp $");
+RCSID("$OpenBSD: session.c,v 1.186 2005/07/25 11:59:40 markus Exp $");
 
 #include "ssh.h"
 #include "ssh1.h"
 
 #include "ssh.h"
 #include "ssh1.h"
@@ -56,6 +56,7 @@ RCSID("$OpenBSD: session.c,v 1.185 2005/07/17 07:17:55 djm Exp $");
 #include "serverloop.h"
 #include "canohost.h"
 #include "session.h"
 #include "serverloop.h"
 #include "canohost.h"
 #include "session.h"
+#include "kex.h"
 #include "monitor_wrap.h"
 
 #if defined(KRB5) && defined(USE_AFS)
 #include "monitor_wrap.h"
 
 #if defined(KRB5) && defined(USE_AFS)
@@ -272,7 +273,7 @@ do_authenticated1(Authctxt *authctxt)
                                    compression_level);
                                break;
                        }
                                    compression_level);
                                break;
                        }
-                       if (!options.compression) {
+                       if (options.compression == COMP_NONE) {
                                debug2("compression disabled");
                                break;
                        }
                                debug2("compression disabled");
                                break;
                        }
index 012ce2b423e6fc51129720eb018627bee6f289be..baee664ea5b938bed1abf23268acf72c9103700e 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshconnect2.c,v 1.140 2005/07/17 07:17:55 djm Exp $");
+RCSID("$OpenBSD: sshconnect2.c,v 1.141 2005/07/25 11:59:40 markus Exp $");
 
 #include "openbsd-compat/sys-queue.h"
 
 
 #include "openbsd-compat/sys-queue.h"
 
@@ -101,10 +101,10 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
            compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_STOC]);
        if (options.compression) {
                myproposal[PROPOSAL_COMP_ALGS_CTOS] =
            compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_STOC]);
        if (options.compression) {
                myproposal[PROPOSAL_COMP_ALGS_CTOS] =
-               myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib,none";
+               myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib@openssh.com,zlib,none";
        } else {
                myproposal[PROPOSAL_COMP_ALGS_CTOS] =
        } else {
                myproposal[PROPOSAL_COMP_ALGS_CTOS] =
-               myproposal[PROPOSAL_COMP_ALGS_STOC] = "none,zlib";
+               myproposal[PROPOSAL_COMP_ALGS_STOC] = "none,zlib@openssh.com,zlib";
        }
        if (options.macs != NULL) {
                myproposal[PROPOSAL_MAC_ALGS_CTOS] =
        }
        if (options.macs != NULL) {
                myproposal[PROPOSAL_MAC_ALGS_CTOS] =
diff --git a/sshd.c b/sshd.c
index 40da375139ca14da499a3764e734615817f51dae..92aa9bbd21501e3b17657c869d227babf8778696 100644 (file)
--- a/sshd.c
+++ b/sshd.c
@@ -42,7 +42,7 @@
  */
 
 #include "includes.h"
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshd.c,v 1.311 2005/06/17 02:44:33 djm Exp $");
+RCSID("$OpenBSD: sshd.c,v 1.312 2005/07/25 11:59:40 markus Exp $");
 
 #include <openssl/dh.h>
 #include <openssl/bn.h>
 
 #include <openssl/dh.h>
 #include <openssl/bn.h>
@@ -671,6 +671,12 @@ privsep_postauth(Authctxt *authctxt)
 
        /* It is safe now to apply the key state */
        monitor_apply_keystate(pmonitor);
 
        /* It is safe now to apply the key state */
        monitor_apply_keystate(pmonitor);
+
+       /*
+        * Tell the packet layer that authentication was successful, since
+        * this information is not part of the key state.
+        */
+       packet_set_authenticated();
 }
 
 static char *
 }
 
 static char *
@@ -1621,6 +1627,7 @@ main(int ac, char **av)
         * not have a key.
         */
        packet_set_connection(sock_in, sock_out);
         * not have a key.
         */
        packet_set_connection(sock_in, sock_out);
+       packet_set_server();
 
        /* Set SO_KEEPALIVE if requested. */
        if (options.tcp_keep_alive && packet_connection_is_on_socket() &&
 
        /* Set SO_KEEPALIVE if requested. */
        if (options.tcp_keep_alive && packet_connection_is_on_socket() &&
@@ -1988,10 +1995,14 @@ do_ssh2_kex(void)
                myproposal[PROPOSAL_MAC_ALGS_CTOS] =
                myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs;
        }
                myproposal[PROPOSAL_MAC_ALGS_CTOS] =
                myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs;
        }
-       if (!options.compression) {
+       if (options.compression == COMP_NONE) {
                myproposal[PROPOSAL_COMP_ALGS_CTOS] =
                myproposal[PROPOSAL_COMP_ALGS_STOC] = "none";
                myproposal[PROPOSAL_COMP_ALGS_CTOS] =
                myproposal[PROPOSAL_COMP_ALGS_STOC] = "none";
+       } else if (options.compression == COMP_DELAYED) {
+               myproposal[PROPOSAL_COMP_ALGS_CTOS] =
+               myproposal[PROPOSAL_COMP_ALGS_STOC] = "none,zlib@openssh.com";
        }
        }
+       
        myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types();
 
        /* start key exchange */
        myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types();
 
        /* start key exchange */
index 2c3afb92030fa5da7a95a5f83ef9d87ff34a6794..1440c05ffcaf1e218c3523eda69626702f0be143 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: sshd_config,v 1.71 2005/05/19 02:40:52 djm Exp $
+#      $OpenBSD: sshd_config,v 1.72 2005/07/25 11:59:40 markus Exp $
 
 # This is the sshd server system-wide configuration file.  See
 # sshd_config(5) for more information.
 
 # This is the sshd server system-wide configuration file.  See
 # sshd_config(5) for more information.
@@ -90,7 +90,7 @@
 #UseLogin no
 #UsePrivilegeSeparation yes
 #PermitUserEnvironment no
 #UseLogin no
 #UsePrivilegeSeparation yes
 #PermitUserEnvironment no
-#Compression yes
+#Compression delayed
 #ClientAliveInterval 0
 #ClientAliveCountMax 3
 #UseDNS yes
 #ClientAliveInterval 0
 #ClientAliveCountMax 3
 #UseDNS yes
index cec2a2382bddea7c046b9f97965d27992f1801f5..048e8924e3bc508170e531cfadf936b366008795 100644 (file)
@@ -34,7 +34,7 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
 .\" (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.43 2005/05/23 23:32:46 djm Exp $
+.\" $OpenBSD: sshd_config.5,v 1.44 2005/07/25 11:59:40 markus Exp $
 .Dd September 25, 1999
 .Dt SSHD_CONFIG 5
 .Os
 .Dd September 25, 1999
 .Dt SSHD_CONFIG 5
 .Os
@@ -217,13 +217,15 @@ The default
 is 0, indicating that these messages will not be sent to the client.
 This option applies to protocol version 2 only.
 .It Cm Compression
 is 0, indicating that these messages will not be sent to the client.
 This option applies to protocol version 2 only.
 .It Cm Compression
-Specifies whether compression is allowed.
+Specifies whether compression is allowed, or delayed until
+the user has authenticated successfully.
 The argument must be
 The argument must be
-.Dq yes
+.Dq yes ,
+.Dq delayed ,
 or
 .Dq no .
 The default is
 or
 .Dq no .
 The default is
-.Dq yes .
+.Dq delayed .
 .It Cm DenyGroups
 This keyword can be followed by a list of group name patterns, separated
 by spaces.
 .It Cm DenyGroups
 This keyword can be followed by a list of group name patterns, separated
 by spaces.
This page took 0.069287 seconds and 5 git commands to generate.