Support diffie-hellman-group14-sha1 group exchange. Tested against
[u/mdw/putty] / ssh.c
diff --git a/ssh.c b/ssh.c
index 835a857..a6fba8b 100644 (file)
--- a/ssh.c
+++ b/ssh.c
  * Packet type contexts, so that ssh2_pkt_type can correctly decode
  * the ambiguous type numbers back into the correct type strings.
  */
-#define SSH2_PKTCTX_DHGROUP1         0x0001
+#define SSH2_PKTCTX_DHGROUP          0x0001
 #define SSH2_PKTCTX_DHGEX            0x0002
 #define SSH2_PKTCTX_PUBLICKEY        0x0010
 #define SSH2_PKTCTX_PASSWORD         0x0020
@@ -222,8 +222,8 @@ static char *ssh2_pkt_type(int pkt_ctx, int type)
     translate(SSH2_MSG_SERVICE_ACCEPT);
     translate(SSH2_MSG_KEXINIT);
     translate(SSH2_MSG_NEWKEYS);
-    translatec(SSH2_MSG_KEXDH_INIT, SSH2_PKTCTX_DHGROUP1);
-    translatec(SSH2_MSG_KEXDH_REPLY, SSH2_PKTCTX_DHGROUP1);
+    translatec(SSH2_MSG_KEXDH_INIT, SSH2_PKTCTX_DHGROUP);
+    translatec(SSH2_MSG_KEXDH_REPLY, SSH2_PKTCTX_DHGROUP);
     translatec(SSH2_MSG_KEX_DH_GEX_REQUEST, SSH2_PKTCTX_DHGEX);
     translatec(SSH2_MSG_KEX_DH_GEX_GROUP, SSH2_PKTCTX_DHGEX);
     translatec(SSH2_MSG_KEX_DH_GEX_INIT, SSH2_PKTCTX_DHGEX);
@@ -362,7 +362,8 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen,
 
 const static struct ssh_kex *kex_algs[] = {
     &ssh_diffiehellman_gex,
-    &ssh_diffiehellman
+    &ssh_diffiehellman_group14,
+    &ssh_diffiehellman_group1,
 };
 
 const static struct ssh_signkey *hostkey_algs[] = { &ssh_rsa, &ssh_dss };
@@ -2149,7 +2150,7 @@ static int do_ssh_init(Ssh ssh, unsigned char c)
     ssh->rdpkt2_state.incoming_sequence = 0;
 
     s->vstring[s->vslen] = 0;
-    s->vstring[strcspn(s->vstring, "\r\n")] = '\0';/* remove EOL chars */
+    s->vstring[strcspn(s->vstring, "\015\012")] = '\0';/* remove EOL chars */
     {
        char *vlog;
        vlog = snewn(20 + s->vslen, char);
@@ -2184,13 +2185,13 @@ static int do_ssh_init(Ssh ssh, unsigned char c)
             /*
              * Construct a v2 version string.
              */
-            verstring = dupprintf("SSH-2.0-%s\n", sshver);
+            verstring = dupprintf("SSH-2.0-%s\015\012", sshver);
             ssh->version = 2;
         } else {
             /*
              * Construct a v1 version string.
              */
-            verstring = dupprintf("SSH-%s-%s\n",
+            verstring = dupprintf("SSH-%s-%s\012",
                                   (ssh_versioncmp(s->version, "1.5") <= 0 ?
                                    s->version : "1.5"),
                                   sshver);
@@ -2204,8 +2205,10 @@ static int do_ssh_init(Ssh ssh, unsigned char c)
              * Hash our version string and their version string.
              */
             SHA_Init(&ssh->exhashbase);
-            sha_string(&ssh->exhashbase, verstring, strlen(verstring)-1);
-            sha_string(&ssh->exhashbase, s->vstring, strcspn(s->vstring, "\r\n"));
+            sha_string(&ssh->exhashbase, verstring,
+                       strcspn(verstring, "\015\012"));
+            sha_string(&ssh->exhashbase, s->vstring,
+                       strcspn(s->vstring, "\015\012"));
 
             /*
              * Initialise SSHv2 protocol.
@@ -2222,7 +2225,7 @@ static int do_ssh_init(Ssh ssh, unsigned char c)
             ssh->s_rdpkt = ssh1_rdpkt;
         }
         logeventf(ssh, "We claim version: %.*s",
-                  strlen(verstring)-1, verstring);
+                  strcspn(verstring, "\015\012"), verstring);
        sk_write(ssh->s, verstring, strlen(verstring));
         sfree(verstring);
     }
@@ -4648,7 +4651,7 @@ static int do_ssh2_transport(Ssh ssh, unsigned char *in, int inlen,
      * If we're doing Diffie-Hellman group exchange, start by
      * requesting a group.
      */
-    if (ssh->kex == &ssh_diffiehellman_gex) {
+    if (!ssh->kex->pdata) {
        logevent("Doing Diffie-Hellman group exchange");
        ssh->pkt_ctx |= SSH2_PKTCTX_DHGEX;
        /*
@@ -4671,14 +4674,16 @@ static int do_ssh2_transport(Ssh ssh, unsigned char *in, int inlen,
            bombout(("unable to read mp-ints from incoming group packet"));
            crStop(0);
        }
-       ssh->kex_ctx = dh_setup_group(s->p, s->g);
+       ssh->kex_ctx = dh_setup_gex(s->p, s->g);
        s->kex_init_value = SSH2_MSG_KEX_DH_GEX_INIT;
        s->kex_reply_value = SSH2_MSG_KEX_DH_GEX_REPLY;
     } else {
-       ssh->pkt_ctx |= SSH2_PKTCTX_DHGROUP1;
-       ssh->kex_ctx = dh_setup_group1();
+       ssh->pkt_ctx |= SSH2_PKTCTX_DHGROUP;
+       ssh->kex_ctx = dh_setup_group(ssh->kex);
        s->kex_init_value = SSH2_MSG_KEXDH_INIT;
        s->kex_reply_value = SSH2_MSG_KEXDH_REPLY;
+       logeventf(ssh, "Using Diffie-Hellman with standard group \"%s\"",
+                 ssh->kex->groupname);
     }
 
     logevent("Doing Diffie-Hellman key exchange");
@@ -7233,12 +7238,14 @@ static void ssh_free(void *handle)
            sfree(c);
        }
        freetree234(ssh->channels);
+       ssh->channels = NULL;
     }
 
     if (ssh->rportfwds) {
        while ((pf = delpos234(ssh->rportfwds, 0)) != NULL)
            sfree(pf);
        freetree234(ssh->rportfwds);
+       ssh->rportfwds = NULL;
     }
     sfree(ssh->deferred_send_data);
     if (ssh->x11auth)
@@ -7254,9 +7261,9 @@ static void ssh_free(void *handle)
     if (ssh->s)
        ssh_do_close(ssh);
     expire_timer_context(ssh);
-    sfree(ssh);
     if (ssh->pinger)
        pinger_free(ssh->pinger);
+    sfree(ssh);
 
     random_unref();
 }