]> git.ipfire.org Git - thirdparty/openssh-portable.git/commitdiff
- OpenBSD CVS updates:
authorDamien Miller <djm@mindrot.org>
Wed, 12 Apr 2000 10:17:38 +0000 (20:17 +1000)
committerDamien Miller <djm@mindrot.org>
Wed, 12 Apr 2000 10:17:38 +0000 (20:17 +1000)
   - [channels.c]
     repair x11-fwd
   - [sshconnect.c]
     fix passwd prompt for ssh2, less debugging output.
   - [clientloop.c compat.c dsa.c kex.c sshd.c]
     less debugging output
   - [kex.c kex.h sshconnect.c sshd.c]
     check for reasonable public DH values
   - [README.openssh2 cipher.c cipher.h compat.c compat.h readconf.c]
     [readconf.h servconf.c servconf.h ssh.c ssh.h sshconnect.c sshd.c]
     add Cipher and Protocol options to ssh/sshd, e.g.:
     ssh -o 'Protocol 1,2' if you prefer proto 1, ssh -o 'Ciphers
     arcfour,3des-cbc'
   - [sshd.c]
     print 1.99 only if server supports both

19 files changed:
ChangeLog
README.openssh2
channels.c
cipher.c
cipher.h
clientloop.c
compat.c
compat.h
dsa.c
kex.c
kex.h
readconf.c
readconf.h
servconf.c
servconf.h
ssh.c
ssh.h
sshconnect.c
sshd.c

index 976c3834fb3302bf3547281aa43433ba40dad7ff..af54ab6d8b19359b49ee2463dea3816155b1857b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+20000412
+ - OpenBSD CVS updates:
+   - [channels.c]
+     repair x11-fwd
+   - [sshconnect.c]
+     fix passwd prompt for ssh2, less debugging output.
+   - [clientloop.c compat.c dsa.c kex.c sshd.c]
+     less debugging output
+   - [kex.c kex.h sshconnect.c sshd.c]
+     check for reasonable public DH values
+   - [README.openssh2 cipher.c cipher.h compat.c compat.h readconf.c]
+     [readconf.h servconf.c servconf.h ssh.c ssh.h sshconnect.c sshd.c]
+     add Cipher and Protocol options to ssh/sshd, e.g.:
+     ssh -o 'Protocol 1,2' if you prefer proto 1, ssh -o 'Ciphers
+     arcfour,3des-cbc'
+   - [sshd.c]
+     print 1.99 only if server supports both
+
 20000408
  - Avoid some compiler warnings in fake-get*.c
  - Add IPTOS macros for systems which lack them
index 59f8cf9f689b6ef8a2319387700a653b001926c2..bdf78bf584379711a6185a74794d6e3e4f0c9d43 100644 (file)
@@ -1,4 +1,13 @@
-$Id: README.openssh2,v 1.2 2000/04/06 21:28:22 markus Exp $
+$Id: README.openssh2,v 1.3 2000/04/12 07:45:43 markus Exp $
+
+howto:
+       1) generate server key:
+               $ umask 077
+               $ openssl dsaparam 1024 -out dsa1024.pem
+               $ openssl gendsa -out /etc/ssh_dsa_key dsa1024.pem -rand /dev/arandom
+       2) enable ssh2:
+               server: add 'Protocol 2,1' to /etc/sshd_config
+               client: ssh -o 'Protocol 2,1', or add to .ssh/config
 
 works:
        secsh-transport: works w/o rekey
@@ -11,11 +20,7 @@ works:
                tcp-forwarding: -L works
        dss: verification works,
                key database in ~/.ssh/known_hosts with bits == 0 hack
-       dss: signature works, keygen w/ openssl:
-               $ umask 077
-               $ openssl dsaparam 1024 -out dsa1024.pem
-               $ openssl gendsa -out /etc/ssh_dsa_key dsa1024.pem -rand /dev/arandom
-               start sshd with '-2' flag
+       dss: signature works, keygen w/ openssl
        client interops w/ sshd2, lshd
        server interops w/ ssh2, lsh, ssh.com's Windows client, SecureCRT
        server supports multiple concurrent sessions (e.g. with SSH.com Windows client)
@@ -33,4 +38,4 @@ todo:
        sftp
 
 -markus
-$Date: 2000/04/06 21:28:22 $
+$Date: 2000/04/12 07:45:43 $
index c140b77dcaf9bb66158f1201539d6770b41500e8..957b4a428aae3c4dc1319bf5ce8c0546dadc3151 100644 (file)
@@ -17,7 +17,7 @@
  */
 
 #include "includes.h"
-RCSID("$Id: channels.c,v 1.23 2000/04/12 08:45:06 damien Exp $");
+RCSID("$Id: channels.c,v 1.24 2000/04/12 10:17:38 damien Exp $");
 
 #include "ssh.h"
 #include "packet.h"
@@ -437,6 +437,7 @@ channel_pre_x11_open_13(Channel *c, fd_set * readset, fd_set * writeset)
        if (ret == 1) {
                /* Start normal processing for the channel. */
                c->type = SSH_CHANNEL_OPEN;
+               channel_pre_open_13(c, readset, writeset);
        } else if (ret == -1) {
                /*
                 * We have received an X11 connection that has bad
@@ -460,6 +461,7 @@ channel_pre_x11_open_15(Channel *c, fd_set * readset, fd_set * writeset)
        int ret = x11_open_helper(c);
        if (ret == 1) {
                c->type = SSH_CHANNEL_OPEN;
+               channel_pre_open_15(c, readset, writeset);
        } else if (ret == -1) {
                debug("X11 rejected %d i%d/o%d", c->self, c->istate, c->ostate);
                chan_read_failed(c);
index 8911ffef628c1b13ab0f56b600c6977f12072c3f..27debf90f6f212161cd6eabc7f26ff32e4a0a822 100644 (file)
--- a/cipher.c
+++ b/cipher.c
  */
 
 #include "includes.h"
-RCSID("$Id: cipher.c,v 1.16 2000/04/06 02:32:39 damien Exp $");
+RCSID("$Id: cipher.c,v 1.17 2000/04/12 10:17:39 damien Exp $");
 
 #include "ssh.h"
 #include "cipher.h"
-#include "config.h"
+#include "xmalloc.h"
 
 #ifdef HAVE_OPENSSL
 #include <openssl/md5.h>
@@ -26,7 +26,9 @@ RCSID("$Id: cipher.c,v 1.16 2000/04/06 02:32:39 damien Exp $");
 #endif
 
 /*
- * What kind of tripple DES are these 2 routines?
+ * This is used by SSH1:
+ *
+ * What kind of triple DES are these 2 routines?
  *
  * Why is there a redundant initialization vector?
  *
@@ -81,7 +83,7 @@ SSH_3CBC_DECRYPT(des_key_schedule ks1,
 }
 
 /*
- * SSH uses a variation on Blowfish, all bytes must be swapped before
+ * SSH1 uses a variation on Blowfish, all bytes must be swapped before
  * and after encryption/decryption. Thus the swap_bytes stuff (yuk).
  */
 static void
@@ -167,10 +169,34 @@ cipher_name(int cipher)
 {
        if (cipher < 0 || cipher >= sizeof(cipher_names) / sizeof(cipher_names[0]) ||
            cipher_names[cipher] == NULL)
-               fatal("cipher_name: bad cipher number: %d", cipher);
+               fatal("cipher_name: bad cipher name: %d", cipher);
        return cipher_names[cipher];
 }
 
+/* Returns 1 if the name of the ciphers are valid. */
+
+#define        CIPHER_SEP      ","
+int
+ciphers_valid(const char *names)
+{
+       char *ciphers;
+       char *p;
+       int i;
+
+       if (strcmp(names, "") == 0)
+               return 0;
+       ciphers = xstrdup(names);
+       for ((p = strtok(ciphers, CIPHER_SEP)); p; (p = strtok(NULL, CIPHER_SEP))) {
+               i = cipher_number(p);
+               if (i == -1 || !(cipher_mask2() & (1 << i))) {
+                       xfree(ciphers);
+                       return 0;
+               }
+       }
+       xfree(ciphers);
+       return 1;
+}
+
 /*
  * Parses the name of the cipher.  Returns the number of the corresponding
  * cipher, or -1 on error.
@@ -271,7 +297,6 @@ cipher_set_key(CipherContext *context, int cipher, const unsigned char *key,
        memset(padded, 0, sizeof(padded));
 }
 
-
 void 
 cipher_set_key_iv(CipherContext * context, int cipher,
     const unsigned char *key, int keylen, 
index 94c0ceee52a41411ef293fd13c1c437a2f4cc627..ee0e312fb88fcac0670bc8ef2fc7f3cb5d4cad4e 100644 (file)
--- a/cipher.h
+++ b/cipher.h
@@ -11,7 +11,7 @@
  * 
  */
 
-/* RCSID("$Id: cipher.h,v 1.8 2000/04/06 02:32:39 damien Exp $"); */
+/* RCSID("$Id: cipher.h,v 1.9 2000/04/12 10:17:39 damien Exp $"); */
 
 #ifndef CIPHER_H
 #define CIPHER_H
@@ -88,6 +88,9 @@ const char *cipher_name(int cipher);
  */
 int     cipher_number(const char *name);
 
+/* returns 1 if all ciphers are supported (ssh2 only) */
+int     ciphers_valid(const char *names);
+
 /*
  * Selects the cipher to use and sets the key.  If for_encryption is true,
  * the key is setup for encryption; otherwise it is setup for decryption.
index 4f2e5037dbe62347961123cf5ccfc4295b6f00e1..91a200663e15c916327dc793e8495667305d6613 100644 (file)
@@ -16,7 +16,7 @@
  */
 
 #include "includes.h"
-RCSID("$Id: clientloop.c,v 1.9 2000/04/06 02:32:39 damien Exp $");
+RCSID("$Id: clientloop.c,v 1.10 2000/04/12 10:17:39 damien Exp $");
 
 #include "xmalloc.h"
 #include "ssh.h"
@@ -1013,7 +1013,7 @@ client_input_channel_req(int id, void *arg)
        rtype = packet_get_string(&len);
        reply = packet_get_char();
 
-       log("session_input_channel_req: rtype %s reply %d", rtype, reply);
+       debug("session_input_channel_req: rtype %s reply %d", rtype, reply);
 
        c = channel_lookup(id);
        if (c == NULL)
index c183866c3f9852b706c7c119cc5b8f29d66578fe..d56e3e81da1c876a2e3c0023242a42dae8e13475 100644 (file)
--- a/compat.c
+++ b/compat.c
  */
 
 #include "includes.h"
-RCSID("$Id: compat.c,v 1.6 2000/04/12 08:45:06 damien Exp $");
+RCSID("$Id: compat.c,v 1.7 2000/04/12 10:17:39 damien Exp $");
 
 #include "ssh.h"
 #include "packet.h"
+#include "xmalloc.h"
+#include "compat.h"
 
 int compat13 = 0;
 int compat20 = 0;
@@ -65,9 +67,36 @@ compat_datafellows(const char *version)
                len = strlen(check[i]);
                if (strlen(version) >= len &&
                   (strncmp(version, check[i], len) == 0)) {
-                       log("datafellows: %.200s", version);
+                       verbose("datafellows: %.200s", version);
                        datafellows = 1;
                        return;
                }
        }
 }
+
+#define        SEP     ","
+int
+proto_spec(const char *spec)
+{
+       char *s = xstrdup(spec);
+       char *p;
+       int ret = SSH_PROTO_UNKNOWN;
+
+       for ((p = strtok(s, SEP)); p; (p = strtok(NULL, SEP))) {
+               switch(atoi(p)) {
+               case 1:
+                       if (ret == SSH_PROTO_UNKNOWN)
+                               ret |= SSH_PROTO_1_PREFERRED;
+                       ret |= SSH_PROTO_1;
+                       break;
+               case 2:
+                       ret |= SSH_PROTO_2;
+                       break;
+               default:
+                       log("ignoring bad proto spec: '%s'.", p);
+                       break;
+               }
+       }
+       xfree(s);
+       return ret;
+}
index 4247f53b47930a6f1c345fc2a9b5de79f03f679b..4943e5a29e86518a062dd2c0ed415855f035c81a 100644 (file)
--- a/compat.h
+++ b/compat.h
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-/* RCSID("$Id: compat.h,v 1.4 2000/04/04 04:39:01 damien Exp $"); */
+/* RCSID("$Id: compat.h,v 1.5 2000/04/12 10:17:39 damien Exp $"); */
 
 #ifndef COMPAT_H
 #define COMPAT_H
+
+#define        SSH_PROTO_UNKNOWN       0x00
+#define        SSH_PROTO_1             0x01
+#define        SSH_PROTO_1_PREFERRED   0x02
+#define        SSH_PROTO_2             0x04
+
 void    enable_compat13(void);
 void    enable_compat20(void);
 void    compat_datafellows(const char *s);
+int    proto_spec(const char *spec);
 extern int compat13;
 extern int compat20;
 extern int datafellows;
diff --git a/dsa.c b/dsa.c
index eeb4ead108c4dbaa0bcfe4b5c0d6c7db2eaf07d0..a35d85bf583972e03b49345dee4ba5ce77d3a897 100644 (file)
--- a/dsa.c
+++ b/dsa.c
@@ -28,7 +28,7 @@
  */
 
 #include "includes.h"
-RCSID("$Id: dsa.c,v 1.1 2000/04/04 04:39:01 damien Exp $");
+RCSID("$Id: dsa.c,v 1.2 2000/04/12 06:37:02 markus Exp $");
 
 #include "ssh.h"
 #include "xmalloc.h"
@@ -80,7 +80,7 @@ dsa_serverkey_from_blob(
        buffer_append(&b, serverhostkey, serverhostkeylen);
        ktype = buffer_get_string(&b, NULL);
        if (strcmp(KEX_DSS, ktype) != 0) {
-               log("dsa_serverkey_from_blob: cannot handle type  %s", ktype);
+               error("dsa_serverkey_from_blob: cannot handle type  %s", ktype);
                key_free(key);
                return NULL;
        }
@@ -90,10 +90,10 @@ dsa_serverkey_from_blob(
        buffer_get_bignum2(&b, dsa->pub_key);
        rlen = buffer_len(&b);
        if(rlen != 0)
-               log("dsa_serverkey_from_blob: remaining bytes in serverhostkey %d", rlen);
+               error("dsa_serverkey_from_blob: remaining bytes in serverhostkey %d", rlen);
        buffer_free(&b);
 
-       log("keytype %s", ktype);
+       debug("keytype %s", ktype);
 #ifdef DEBUG_DSS
        DSA_print_fp(stderr, dsa, 8);
 #endif
@@ -172,7 +172,7 @@ dsa_sign(
        Buffer b;
 
        if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) {
-               log("dsa_sign: no DSA key");
+               error("dsa_sign: no DSA key");
                return -1;
        }
        digest = xmalloc(evp_md->md_size);
@@ -185,11 +185,11 @@ dsa_sign(
         rlen = BN_num_bytes(sig->r);
         slen = BN_num_bytes(sig->s);
         if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) {
-               log("bad sig size %d %d", rlen, slen);
+               error("bad sig size %d %d", rlen, slen);
                DSA_SIG_free(sig);
                return -1;
        }
-       log("sig size %d %d", rlen, slen);
+       debug("sig size %d %d", rlen, slen);
 
        memset(sigblob, 0, SIGBLOB_LEN);
        BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen);
@@ -197,7 +197,7 @@ dsa_sign(
        DSA_SIG_free(sig);
 
        if (datafellows) {
-               log("datafellows");
+               debug("datafellows");
                ret = xmalloc(SIGBLOB_LEN);
                memcpy(ret, sigblob, SIGBLOB_LEN);
                if (lenp != NULL)
@@ -239,7 +239,7 @@ dsa_verify(
        int ret;
 
        if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) {
-               log("dsa_verify: no DSA key");
+               error("dsa_verify: no DSA key");
                return -1;
        }
 
@@ -248,7 +248,7 @@ dsa_verify(
                datafellows = 0;
        }
 
-       log("len %d datafellows %d", signaturelen, datafellows);
+       debug("len %d datafellows %d", signaturelen, datafellows);
 
        /* fetch signature */
        if (datafellows) {
@@ -262,7 +262,7 @@ dsa_verify(
                sigblob = (unsigned char *)buffer_get_string(&b, &len);
                rlen = buffer_len(&b);
                if(rlen != 0)
-                       log("remaining bytes in signature %d", rlen);
+                       error("remaining bytes in signature %d", rlen);
                buffer_free(&b);
        }
 
@@ -305,6 +305,6 @@ dsa_verify(
                txt = "error";
                break;
        }
-       log("dsa_verify: signature %s", txt);
+       debug("dsa_verify: signature %s", txt);
        return ret;
 }
diff --git a/kex.c b/kex.c
index d2047d6f1c04bc0d6415e4db15009d544797a0ba..9ec75ee0e2e146d7bee531c9fe453450ba84616c 100644 (file)
--- a/kex.c
+++ b/kex.c
@@ -28,7 +28,7 @@
  */
 
 #include "includes.h"
-RCSID("$Id: kex.c,v 1.2 2000/04/04 04:57:08 damien Exp $");
+RCSID("$Id: kex.c,v 1.3 2000/04/12 10:17:39 damien Exp $");
 
 #include "ssh.h"
 #include "ssh2.h"
@@ -43,8 +43,6 @@ RCSID("$Id: kex.c,v 1.2 2000/04/04 04:57:08 damien Exp $");
 # include <openssl/dh.h>
 # include <openssl/crypto.h>
 # include <openssl/bio.h>
-# include <openssl/bn.h>
-# include <openssl/dh.h>
 # include <openssl/pem.h>
 #endif /* HAVE_OPENSSL */
 #if HAVE_SSL
@@ -52,12 +50,9 @@ RCSID("$Id: kex.c,v 1.2 2000/04/04 04:57:08 damien Exp $");
 # include <ssl/dh.h>
 # include <ssl/crypto.h>
 # include <ssl/bio.h>
-# include <ssl/bn.h>
-# include <ssl/dh.h>
 # include <ssl/pem.h>
 #endif /* HAVE_SSL */
 
-#include "entropy.h"
 #include "kex.h"
 
 Buffer *
@@ -85,8 +80,36 @@ kex_init(char *myproposal[PROPOSAL_MAX])
 
 /* diffie-hellman-group1-sha1 */
 
+int
+dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
+{
+       int i;
+       int n = BN_num_bits(dh_pub);
+       int bits_set = 0;
+
+       /* we only accept g==2 */
+       if (!BN_is_word(dh->g, 2)) {
+               log("invalid DH base != 2");
+               return 0;
+       }
+       if (dh_pub->neg) {
+               log("invalid public DH value: negativ");
+               return 0;
+       }
+       for (i = 0; i <= n; i++)
+               if (BN_is_bit_set(dh_pub, i))
+                       bits_set++;
+       debug("bits set: %d/%d", bits_set, BN_num_bits(dh->p));
+
+       /* if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial */
+       if (bits_set > 1 && (BN_cmp(dh_pub, dh->p) == -1))
+               return 1;
+       log("invalid public DH value (%d/%d)", bits_set, BN_num_bits(dh->p));
+       return 0;
+}
+
 DH *
-new_dh_group1()
+dh_new_group1()
 {
        static char *group1 =
            "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
@@ -96,22 +119,23 @@ new_dh_group1()
            "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
            "FFFFFFFF" "FFFFFFFF";
        DH *dh;
-       int ret;
+       int ret, tries = 0;
        dh = DH_new();
        if(dh == NULL)
                fatal("DH_new");
-       ret = BN_hex2bn(&dh->p,group1);
+       ret = BN_hex2bn(&dh->p, group1);
        if(ret<0)
                fatal("BN_hex2bn");
        dh->g = BN_new();
        if(dh->g == NULL)
                fatal("DH_new g");
-       BN_set_word(dh->g,2);
-
-       seed_rng();
-       if (DH_generate_key(dh) == 0)
-               fatal("DH_generate_key");
-
+       BN_set_word(dh->g, 2);
+       do {
+               if (DH_generate_key(dh) == 0)
+                       fatal("DH_generate_key");
+               if (tries++ > 10)
+                       fatal("dh_new_group1: too many bad keys: giving up");
+       } while (!dh_pub_is_valid(dh, dh->pub_key));
        return dh;
 }
 
@@ -356,7 +380,7 @@ kex_choose_conf(char *cprop[PROPOSAL_MAX], char *sprop[PROPOSAL_MAX], int server
                choose_enc (&k->enc [mode], cprop[nenc],  sprop[nenc]);
                choose_mac (&k->mac [mode], cprop[nmac],  sprop[nmac]);
                choose_comp(&k->comp[mode], cprop[ncomp], sprop[ncomp]);
-               log("kex: %s %s %s %s",
+               debug("kex: %s %s %s %s",
                    ctos ? "client->server" : "server->client",
                    k->enc[mode].name,
                    k->mac[mode].name,
diff --git a/kex.h b/kex.h
index 81c41342a4e1d2fa392884ddb82ee625a56e4709..29e1e887fb15b1112cc5c234fc3167668ca355b8 100644 (file)
--- a/kex.h
+++ b/kex.h
@@ -102,7 +102,8 @@ struct Kex {
 };
 
 Buffer *kex_init(char *myproposal[PROPOSAL_MAX]);
-DH     *new_dh_group1();
+int    dh_pub_is_valid(DH *dh, BIGNUM *dh_pub);
+DH     *dh_new_group1();
 Kex    *kex_choose_conf(char *cprop[PROPOSAL_MAX], char *sprop[PROPOSAL_MAX], int server);
 int    kex_derive_keys(Kex *k, unsigned char *hash, BIGNUM *shared_secret);
 void   bignum_print(BIGNUM *b);
index bb420ac05af371ab5d51a77168f2f50eaba825b6..1ba70c36a1c338cdbf0baeb62aee0308ccd0e0b7 100644 (file)
  */
 
 #include "includes.h"
-RCSID("$Id: readconf.c,v 1.9 2000/04/01 01:09:25 damien Exp $");
+RCSID("$Id: readconf.c,v 1.10 2000/04/12 10:17:40 damien Exp $");
 
 #include "ssh.h"
 #include "cipher.h"
 #include "readconf.h"
 #include "match.h"
 #include "xmalloc.h"
+#include "compat.h"
 
 /* Format of the configuration file:
 
@@ -103,7 +104,7 @@ typedef enum {
        oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
        oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
        oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts, oTISAuthentication,
-       oUsePrivilegedPort, oLogLevel
+       oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol
 } OpCodes;
 
 /* Textual representations of the tokens. */
@@ -134,6 +135,8 @@ static struct {
        { "proxycommand", oProxyCommand },
        { "port", oPort },
        { "cipher", oCipher },
+       { "ciphers", oCiphers },
+       { "protocol", oProtocol },
        { "remoteforward", oRemoteForward },
        { "localforward", oLocalForward },
        { "user", oUser },
@@ -444,6 +447,26 @@ parse_int:
                        *intptr = value;
                break;
 
+       case oCiphers:
+               cp = strtok(NULL, WHITESPACE);
+               if (!ciphers_valid(cp))
+                       fatal("%.200s line %d: Bad cipher spec '%s'.",
+                             filename, linenum, cp ? cp : "<NONE>");
+               if (*activep && options->ciphers == NULL)
+                       options->ciphers = xstrdup(cp);
+               break;
+
+       case oProtocol:
+               intptr = &options->protocol;
+               cp = strtok(NULL, WHITESPACE);
+               value = proto_spec(cp);
+               if (value == SSH_PROTO_UNKNOWN)
+                       fatal("%.200s line %d: Bad protocol spec '%s'.",
+                             filename, linenum, cp ? cp : "<NONE>");
+               if (*activep && *intptr == SSH_PROTO_UNKNOWN)
+                       *intptr = value;
+               break;
+
        case oLogLevel:
                intptr = (int *) &options->log_level;
                cp = strtok(NULL, WHITESPACE);
@@ -616,6 +639,8 @@ initialize_options(Options * options)
        options->connection_attempts = -1;
        options->number_of_password_prompts = -1;
        options->cipher = -1;
+       options->ciphers = NULL;
+       options->protocol = SSH_PROTO_UNKNOWN;
        options->num_identity_files = 0;
        options->hostname = NULL;
        options->proxy_command = NULL;
@@ -689,6 +714,8 @@ fill_default_options(Options * options)
        /* Selected in ssh_login(). */
        if (options->cipher == -1)
                options->cipher = SSH_CIPHER_NOT_SET;
+       if (options->protocol == SSH_PROTO_UNKNOWN)
+               options->protocol = SSH_PROTO_1;
        if (options->num_identity_files == 0) {
                options->identity_files[0] =
                        xmalloc(2 + strlen(SSH_CLIENT_IDENTITY) + 1);
index 09f051401e7cd099e0b298217f0c2401ee5bbb85..86f342d370059163347822f220416e936eae44ca 100644 (file)
@@ -13,7 +13,7 @@
  * 
  */
 
-/* RCSID("$Id: readconf.h,v 1.6 1999/12/06 00:47:29 damien Exp $"); */
+/* RCSID("$Id: readconf.h,v 1.7 2000/04/12 10:17:40 damien Exp $"); */
 
 #ifndef READCONF_H
 #define READCONF_H
@@ -64,6 +64,8 @@ typedef struct {
        int     number_of_password_prompts;     /* Max number of password
                                                 * prompts. */
        int     cipher;         /* Cipher to use. */
+       char   *ciphers;        /* Ciphers in order of preference. */
+       int     protocol;       /* Protocol in order of preference. */
        char   *hostname;       /* Real host to connect. */
        char   *proxy_command;  /* Proxy command for connecting the host. */
        char   *user;           /* User to log in as. */
index 800c4d5f44faf43a5aaa02ab499a25b357f4d192..918fb8ed2c7c4f76b66e068f55f57da0e13dccde 100644 (file)
  */
 
 #include "includes.h"
-RCSID("$Id: servconf.c,v 1.10 2000/04/12 08:45:06 damien Exp $");
+RCSID("$Id: servconf.c,v 1.11 2000/04/12 10:17:40 damien Exp $");
 
 #include "ssh.h"
 #include "servconf.h"
 #include "xmalloc.h"
+#include "compat.h"
 
 /* add listen address */
 void add_listen_addr(ServerOptions *options, char *addr);
@@ -68,6 +69,8 @@ initialize_server_options(ServerOptions *options)
        options->num_deny_users = 0;
        options->num_allow_groups = 0;
        options->num_deny_groups = 0;
+       options->ciphers = NULL;
+       options->protocol = SSH_PROTO_UNKNOWN;
 }
 
 void 
@@ -139,6 +142,8 @@ fill_default_server_options(ServerOptions *options)
                options->permit_empty_passwd = 0;
        if (options->use_login == -1)
                options->use_login = 0;
+       if (options->protocol == SSH_PROTO_UNKNOWN)
+               options->protocol = SSH_PROTO_1;
 }
 
 #define WHITESPACE " \t\r\n"
@@ -162,7 +167,7 @@ typedef enum {
        sPrintMotd, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset,
        sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail,
        sUseLogin, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
-       sIgnoreUserKnownHosts, sDSAKeyFile
+       sIgnoreUserKnownHosts, sDSAKeyFile, sCiphers, sProtocol
 } ServerOpCodes;
 
 /* Textual representation of the tokens. */
@@ -211,6 +216,8 @@ static struct {
        { "denyusers", sDenyUsers },
        { "allowgroups", sAllowGroups },
        { "denygroups", sDenyGroups },
+       { "ciphers", sCiphers },
+       { "protocol", sProtocol },
        { NULL, 0 }
 };
 
@@ -494,7 +501,7 @@ parse_flag:
                        value = log_facility_number(cp);
                        if (value == (SyslogFacility) - 1)
                                fatal("%.200s line %d: unsupported log facility '%s'\n",
-                                 filename, linenum, cp ? cp : "<NONE>");
+                                   filename, linenum, cp ? cp : "<NONE>");
                        if (*intptr == -1)
                                *intptr = (SyslogFacility) value;
                        break;
@@ -505,55 +512,67 @@ parse_flag:
                        value = log_level_number(cp);
                        if (value == (LogLevel) - 1)
                                fatal("%.200s line %d: unsupported log level '%s'\n",
-                                 filename, linenum, cp ? cp : "<NONE>");
+                                   filename, linenum, cp ? cp : "<NONE>");
                        if (*intptr == -1)
                                *intptr = (LogLevel) value;
                        break;
 
                case sAllowUsers:
                        while ((cp = strtok(NULL, WHITESPACE))) {
-                               if (options->num_allow_users >= MAX_ALLOW_USERS) {
-                                       fprintf(stderr, "%s line %d: too many allow users.\n",
-                                               filename, linenum);
-                                       exit(1);
-                               }
+                               if (options->num_allow_users >= MAX_ALLOW_USERS)
+                                       fatal("%s line %d: too many allow users.\n",
+                                           filename, linenum);
                                options->allow_users[options->num_allow_users++] = xstrdup(cp);
                        }
                        break;
 
                case sDenyUsers:
                        while ((cp = strtok(NULL, WHITESPACE))) {
-                               if (options->num_deny_users >= MAX_DENY_USERS) {
-                                       fprintf(stderr, "%s line %d: too many deny users.\n",
-                                               filename, linenum);
-                                       exit(1);
-                               }
+                               if (options->num_deny_users >= MAX_DENY_USERS)
+                                       fatal( "%s line %d: too many deny users.\n",
+                                           filename, linenum);
                                options->deny_users[options->num_deny_users++] = xstrdup(cp);
                        }
                        break;
 
                case sAllowGroups:
                        while ((cp = strtok(NULL, WHITESPACE))) {
-                               if (options->num_allow_groups >= MAX_ALLOW_GROUPS) {
-                                       fprintf(stderr, "%s line %d: too many allow groups.\n",
-                                               filename, linenum);
-                                       exit(1);
-                               }
+                               if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
+                                       fatal("%s line %d: too many allow groups.\n",
+                                           filename, linenum);
                                options->allow_groups[options->num_allow_groups++] = xstrdup(cp);
                        }
                        break;
 
                case sDenyGroups:
                        while ((cp = strtok(NULL, WHITESPACE))) {
-                               if (options->num_deny_groups >= MAX_DENY_GROUPS) {
-                                       fprintf(stderr, "%s line %d: too many deny groups.\n",
-                                               filename, linenum);
-                                       exit(1);
-                               }
+                               if (options->num_deny_groups >= MAX_DENY_GROUPS)
+                                       fatal("%s line %d: too many deny groups.\n",
+                                           filename, linenum);
                                options->deny_groups[options->num_deny_groups++] = xstrdup(cp);
                        }
                        break;
 
+               case sCiphers:
+                       cp = strtok(NULL, WHITESPACE);
+                       if (!ciphers_valid(cp))
+                               fatal("%s line %d: Bad cipher spec '%s'.",
+                                   filename, linenum, cp ? cp : "<NONE>");
+                       if (options->ciphers == NULL)
+                               options->ciphers = xstrdup(cp);
+                       break;
+
+               case sProtocol:
+                       intptr = &options->protocol;
+                       cp = strtok(NULL, WHITESPACE);
+                       value = proto_spec(cp);
+                       if (value == SSH_PROTO_UNKNOWN)
+                               fatal("%s line %d: Bad protocol spec '%s'.",
+                                     filename, linenum, cp ? cp : "<NONE>");
+                       if (*intptr == SSH_PROTO_UNKNOWN)
+                               *intptr = value;
+                       break;
+
                default:
                        fprintf(stderr, "%s line %d: Missing handler for opcode %s (%d)\n",
                                filename, linenum, cp, opcode);
index 5ce3f15948ddde42c055a2e4ab033cdb6ccabfc5..2a36862457b3c1159a9bc6ac17655cb42b396b7b 100644 (file)
@@ -13,7 +13,7 @@
  * 
  */
 
-/* RCSID("$Id: servconf.h,v 1.7 2000/04/12 08:45:07 damien Exp $"); */
+/* RCSID("$Id: servconf.h,v 1.8 2000/04/12 10:17:40 damien Exp $"); */
 
 #ifndef SERVCONF_H
 #define SERVCONF_H
@@ -48,6 +48,8 @@ typedef struct {
                                         * searching at */
        int     strict_modes;   /* If true, require string home dir modes. */
        int     keepalives;     /* If true, set SO_KEEPALIVE. */
+       char   *ciphers;        /* Ciphers in order of preference. */
+       int     protocol;       /* Protocol in order of preference. */
        SyslogFacility log_facility;    /* Facility for system logging. */
        LogLevel log_level;     /* Level for system logging. */
        int     rhosts_authentication;  /* If true, permit rhosts
diff --git a/ssh.c b/ssh.c
index cce0e6b7fc602c4d70699654f417e1dc426b4297..f23694247ab3a089560e00bc8ef607168ef9b5c7 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -11,7 +11,7 @@
  */
 
 #include "includes.h"
-RCSID("$Id: ssh.c,v 1.24 2000/04/06 02:32:40 damien Exp $");
+RCSID("$Id: ssh.c,v 1.25 2000/04/12 10:17:40 damien Exp $");
 
 #include "xmalloc.h"
 #include "ssh.h"
@@ -42,6 +42,7 @@ int IPv4or6 = AF_UNSPEC;
 /* Flag indicating whether debug mode is on.  This can be set on the command line. */
 int debug_flag = 0;
 
+/* Flag indicating whether a tty should be allocated */
 int tty_flag = 0;
 
 /* don't exec a shell */
@@ -336,8 +337,10 @@ main(int ac, char **av)
 
                case 'v':
                case 'V':
-                       fprintf(stderr, "SSH Version %s, protocol version %d.%d.\n",
-                           SSH_VERSION, PROTOCOL_MAJOR, PROTOCOL_MINOR);
+                       fprintf(stderr, "SSH Version %s, protocol versions %d.%d/%d.%d.\n",
+                           SSH_VERSION,
+                           PROTOCOL_MAJOR_1, PROTOCOL_MINOR_1,
+                           PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2);
                        fprintf(stderr, "Compiled with SSL (0x%8.8lx).\n", SSLeay());
                        if (opt == 'V')
                                exit(0);
diff --git a/ssh.h b/ssh.h
index 7c5bf9c5241c0e28b0fb3b2fd2c7d5340f6e210b..ea2dc032cdf732b8ff08e9caa7bf54e12872b192 100644 (file)
--- a/ssh.h
+++ b/ssh.h
@@ -13,7 +13,7 @@
  * 
  */
 
-/* RCSID("$Id: ssh.h,v 1.30 2000/04/12 08:45:07 damien Exp $"); */
+/* RCSID("$Id: ssh.h,v 1.31 2000/04/12 10:17:41 damien Exp $"); */
 
 #ifndef SSH_H
 #define SSH_H
 /*
  * Major protocol version.  Different version indicates major incompatiblity
  * that prevents communication.
- */
-#define PROTOCOL_MAJOR         1
-
-/*
+ *
  * Minor protocol version.  Different version indicates minor incompatibility
  * that does not prevent interoperation.
  */
-#define PROTOCOL_MINOR         5
+#define PROTOCOL_MAJOR_1       1
+#define PROTOCOL_MINOR_1       5
+
+/* We support both SSH1 and SSH2 */
+#define PROTOCOL_MAJOR_2       2
+#define PROTOCOL_MINOR_2       0
 
 /*
  * Name for the service.  The port named by this service overrides the
index 2f9496090beda1f628d9d8b300856696373eaf77..167b8e63af8cd10026fc2a21201b128acd42edfd 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshconnect.c,v 1.61 2000/04/04 21:37:27 markus Exp $");
+RCSID("$OpenBSD: sshconnect.c,v 1.65 2000/04/12 07:56:16 markus Exp $");
 
 #ifdef HAVE_OPENSSL
 #include <openssl/bn.h>
@@ -993,7 +993,7 @@ void
 ssh_exchange_identification()
 {
        char buf[256], remote_version[256];     /* must be same size! */
-       int remote_major, remote_minor, i;
+       int remote_major, remote_minor, i, mismatch;
        int connection_in = packet_get_connection_in();
        int connection_out = packet_get_connection_out();
 
@@ -1027,39 +1027,51 @@ ssh_exchange_identification()
        debug("Remote protocol version %d.%d, remote software version %.100s",
              remote_major, remote_minor, remote_version);
 
-/*** XXX option for disabling 2.0 or 1.5 */
        compat_datafellows(remote_version);
-
-       /* Check if the remote protocol version is too old. */
-       if (remote_major == 1 && remote_minor < 3)
-               fatal("Remote machine has too old SSH software version.");
-
-       /* We speak 1.3, too. */
-       if (remote_major == 1 && remote_minor == 3) {
-               enable_compat13();
-               if (options.forward_agent) {
-                       log("Agent forwarding disabled for protocol 1.3");
-                       options.forward_agent = 0;
+       mismatch = 0;
+
+       switch(remote_major) {
+       case 1:
+               if (remote_minor == 99 &&
+                   (options.protocol & SSH_PROTO_2) &&
+                   !(options.protocol & SSH_PROTO_1_PREFERRED)) {
+                       enable_compat20();
+                       break;
                }
+               if (!(options.protocol & SSH_PROTO_1)) {
+                       mismatch = 1;
+                       break;
+               }
+               if (remote_minor < 3) {
+                       fatal("Remote machine has too old SSH software version.");
+               } else if (remote_minor == 3) {
+                       /* We speak 1.3, too. */
+                       enable_compat13();
+                       if (options.forward_agent) {
+                               log("Agent forwarding disabled for protocol 1.3");
+                               options.forward_agent = 0;
+                       }
+               }
+               break;
+       case 2:
+               if (options.protocol & SSH_PROTO_2) {
+                       enable_compat20();
+                       break;
+               }
+               /* FALLTHROUGH */
+       default: 
+               mismatch = 1;
+               break;
        }
-       if ((remote_major == 2 && remote_minor == 0) ||
-           (remote_major == 1 && remote_minor == 99)) {
-               enable_compat20();
-       }
-#if 0
-       /*
-        * Removed for now, to permit compatibility with latter versions. The
-        * server will reject our version and disconnect if it doesn't
-        * support it.
-        */
-       if (remote_major != PROTOCOL_MAJOR)
+       if (mismatch)
                fatal("Protocol major versions differ: %d vs. %d",
-                     PROTOCOL_MAJOR, remote_major);
-#endif
+                   (options.protocol & SSH_PROTO_2) ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
+                   remote_major);
+
        /* Send our own protocol version identification. */
        snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n",
-           compat20 ? 2 : PROTOCOL_MAJOR,
-           compat20 ? 0 : PROTOCOL_MINOR,
+           compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
+           compat20 ? PROTOCOL_MINOR_2 : PROTOCOL_MINOR_1,
            SSH_VERSION);
        if (atomicio(write, connection_out, buf, strlen(buf)) != strlen(buf))
                fatal("write: %.100s", strerror(errno));
@@ -1350,11 +1362,15 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
 /* KEXINIT */
 
        debug("Sending KEX init.");
-        if (options.cipher == SSH_CIPHER_ARCFOUR ||
+       if (options.ciphers != NULL) {
+               myproposal[PROPOSAL_ENC_ALGS_CTOS] = 
+               myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
+       } else if (
+           options.cipher == SSH_CIPHER_ARCFOUR ||
             options.cipher == SSH_CIPHER_3DES_CBC ||
             options.cipher == SSH_CIPHER_CAST128_CBC ||
             options.cipher == SSH_CIPHER_BLOWFISH_CBC) {
-               myproposal[PROPOSAL_ENC_ALGS_CTOS] = cipher_name(options.cipher);
+               myproposal[PROPOSAL_ENC_ALGS_CTOS] =
                myproposal[PROPOSAL_ENC_ALGS_STOC] = cipher_name(options.cipher);
        }
        if (options.compression) {
@@ -1404,7 +1420,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
        debug("Sending SSH2_MSG_KEXDH_INIT.");
 
        /* generate and send 'e', client DH public key */
-       dh = new_dh_group1();
+       dh = dh_new_group1();
        packet_start(SSH2_MSG_KEXDH_INIT);
        packet_put_bignum2(dh->pub_key);
        packet_send();
@@ -1451,6 +1467,9 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
        /* signed H */
        signature = packet_get_string(&slen);
 
+       if (!dh_pub_is_valid(dh, dh_server_pub))
+               packet_disconnect("bad server public DH value");
+
        klen = DH_size(dh);
        kbuf = xmalloc(klen);
        kout = DH_compute_key(kbuf, dh_server_pub, dh);
@@ -1507,12 +1526,13 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
        packet_write_wait();
        debug("done: send SSH2_MSG_NEWKEYS.");
 
+#ifdef DEBUG_KEXDH
        /* send 1st encrypted/maced/compressed message */
        packet_start(SSH2_MSG_IGNORE);
        packet_put_cstring("markus");
        packet_send();
        packet_write_wait();
-
+#endif
        debug("done: KEX2.");
 }
 /*
@@ -1527,6 +1547,7 @@ ssh_userauth2(int host_key_valid, RSA *own_host_key,
        unsigned int dlen;
        int partial;
        struct passwd *pw;
+       char prompt[80];
        char *server_user, *local_user;
        char *auths;
        char *password;
@@ -1578,7 +1599,9 @@ ssh_userauth2(int host_key_valid, RSA *own_host_key,
                        fatal("passwd auth not supported: %s", auths);
                xfree(auths);
                /* try passwd */
-               password = read_passphrase("password: ", 0);
+               snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ",
+                   server_user, host);
+               password = read_passphrase(prompt, 0);
                packet_start(SSH2_MSG_USERAUTH_REQUEST);
                packet_put_cstring(server_user);
                packet_put_cstring(service);
diff --git a/sshd.c b/sshd.c
index 44782e397edb3ad9cbfdcf3976bd3588b2ec8000..266146bf0655d99063cfb705fda55a1e425de4e3 100644 (file)
--- a/sshd.c
+++ b/sshd.c
@@ -14,7 +14,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshd.c,v 1.99 2000/04/07 09:17:39 markus Exp $");
+RCSID("$OpenBSD: sshd.c,v 1.103 2000/04/12 08:11:36 markus Exp $");
 
 #include "xmalloc.h"
 #include "rsa.h"
@@ -77,9 +77,6 @@ int IPv4or6 = AF_INET;
 int IPv4or6 = AF_UNSPEC;
 #endif
 
-/* Flag indicating whether SSH2 is enabled */
-int allow_ssh2 = 0;
-
 /*
  * Debug mode flag.  This can be set on the command line.  If debug
  * mode is enabled, extra debugging output will be sent to the system
@@ -284,16 +281,25 @@ chop(char *s)
 void
 sshd_exchange_identification(int sock_in, int sock_out)
 {
-       int i;
+       int i, mismatch;
        int remote_major, remote_minor;
+       int major, minor;
        char *s;
        char buf[256];                  /* Must not be larger than remote_version. */
        char remote_version[256];       /* Must be at least as big as buf. */
 
-       snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n",
-                allow_ssh2 ? 1  : PROTOCOL_MAJOR,
-                allow_ssh2 ? 99 : PROTOCOL_MINOR,
-                SSH_VERSION);
+       if ((options.protocol & SSH_PROTO_1) &&
+           (options.protocol & SSH_PROTO_2)) {
+               major = PROTOCOL_MAJOR_1;
+               minor = 99;
+       } else if (options.protocol & SSH_PROTO_2) {
+               major = PROTOCOL_MAJOR_2;
+               minor = PROTOCOL_MINOR_2;
+       } else {
+               major = PROTOCOL_MAJOR_1;
+               minor = PROTOCOL_MINOR_1;
+       }
+       snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", major, minor, SSH_VERSION);
        server_version_string = xstrdup(buf);
 
        if (client_version_string == NULL) {
@@ -314,7 +320,6 @@ sshd_exchange_identification(int sock_in, int sock_out)
                                buf[i] = '\n';
                                buf[i + 1] = 0;
                                continue;
-                               //break;
                        }
                        if (buf[i] == '\n') {
                                /* buf[i] == '\n' */
@@ -345,8 +350,13 @@ sshd_exchange_identification(int sock_in, int sock_out)
 
        compat_datafellows(remote_version);
 
+       mismatch = 0;
        switch(remote_major) {
        case 1:
+               if (!(options.protocol & SSH_PROTO_1)) {
+                       mismatch = 1;
+                       break;
+               }
                if (remote_minor < 3) {
                        packet_disconnect("Your ssh version is too old and"
                            "is no longer supported.  Please install a newer version.");
@@ -354,27 +364,37 @@ sshd_exchange_identification(int sock_in, int sock_out)
                        /* note that this disables agent-forwarding */
                        enable_compat13();
                }
-               if (remote_minor != 99)
-                      break;
-               /* FALLTHROUGH */
+               if (remote_minor == 99) {
+                       if (options.protocol & SSH_PROTO_2)
+                               enable_compat20();
+                       else
+                               mismatch = 1;
+               }
+               break;
        case 2:
-               if (allow_ssh2) {
+               if (options.protocol & SSH_PROTO_2) {
                        enable_compat20();
                        break;
                }
                /* FALLTHROUGH */
        default: 
+               mismatch = 1;
+               break;
+       }
+       chop(server_version_string);
+       chop(client_version_string);
+       debug("Local version string %.200s", server_version_string);
+
+       if (mismatch) {
                s = "Protocol major versions differ.\n";
                (void) atomicio(write, sock_out, s, strlen(s));
                close(sock_in);
                close(sock_out);
-               log("Protocol major versions differ for %s: %d vs. %d",
-                   get_remote_ipaddr(), PROTOCOL_MAJOR, remote_major);
+               log("Protocol major versions differ for %s: %.200s vs. %.200s",
+                   get_remote_ipaddr(),
+                   server_version_string, client_version_string);
                fatal_cleanup();
-               break;
        }
-       chop(server_version_string);
-       chop(client_version_string);
 }
 
 /*
@@ -410,11 +430,8 @@ main(int ac, char **av)
        initialize_server_options(&options);
 
        /* Parse command-line arguments. */
-       while ((opt = getopt(ac, av, "f:p:b:k:h:g:V:diqQ246")) != EOF) {
+       while ((opt = getopt(ac, av, "f:p:b:k:h:g:V:diqQ46")) != EOF) {
                switch (opt) {
-               case '2':
-                       allow_ssh2 = 1;
-                       break;
                case '4':
                        IPv4or6 = AF_INET;
                        break;
@@ -593,6 +610,7 @@ main(int ac, char **av)
                public_key = RSA_new();
                sensitive_data.private_key = RSA_new();
 
+               /* XXX check options.protocol */
                log("Generating %d bit RSA key.", options.server_key_bits);
                rsa_generate_key(sensitive_data.private_key, public_key,
                                 options.server_key_bits);
@@ -1126,6 +1144,11 @@ do_ssh2_kex()
 
 /* KEXINIT */
 
+       if (options.ciphers != NULL) {
+               myproposal[PROPOSAL_ENC_ALGS_CTOS] = 
+               myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
+       }
+
        debug("Sending KEX init.");
 
        for (i = 0; i < PROPOSAL_MAX; i++)
@@ -1185,7 +1208,7 @@ do_ssh2_kex()
 #endif
 
        /* generate DH key */
-       dh = new_dh_group1();                   /* XXX depends on 'kex' */
+       dh = dh_new_group1();                   /* XXX depends on 'kex' */
 
 #ifdef DEBUG_KEXDH
        fprintf(stderr, "\np= ");
@@ -1196,6 +1219,8 @@ do_ssh2_kex()
        bignum_print(dh->pub_key);
        fprintf(stderr, "\n");
 #endif
+       if (!dh_pub_is_valid(dh, dh_client_pub))
+               packet_disconnect("bad client public DH value");
 
        klen = DH_size(dh);
        kbuf = xmalloc(klen);
@@ -1267,11 +1292,12 @@ do_ssh2_kex()
        packet_read_expect(&payload_len, SSH2_MSG_NEWKEYS);
        debug("GOT SSH2_MSG_NEWKEYS.");
 
+#ifdef DEBUG_KEXDH
        /* send 1st encrypted/maced/compressed message */
        packet_start(SSH2_MSG_IGNORE);
        packet_put_cstring("markus");
        packet_send();
        packet_write_wait();
-
+#endif
        debug("done: KEX2.");
 }