diff options
-rw-r--r-- | ChangeLog | 18 | ||||
-rw-r--r-- | README.openssh2 | 19 | ||||
-rw-r--r-- | channels.c | 4 | ||||
-rw-r--r-- | cipher.c | 37 | ||||
-rw-r--r-- | cipher.h | 5 | ||||
-rw-r--r-- | clientloop.c | 4 | ||||
-rw-r--r-- | compat.c | 33 | ||||
-rw-r--r-- | compat.h | 9 | ||||
-rw-r--r-- | dsa.c | 24 | ||||
-rw-r--r-- | kex.c | 56 | ||||
-rw-r--r-- | kex.h | 3 | ||||
-rw-r--r-- | readconf.c | 31 | ||||
-rw-r--r-- | readconf.h | 4 | ||||
-rw-r--r-- | servconf.c | 67 | ||||
-rw-r--r-- | servconf.h | 4 | ||||
-rw-r--r-- | ssh.c | 9 | ||||
-rw-r--r-- | ssh.h | 14 | ||||
-rw-r--r-- | sshconnect.c | 91 | ||||
-rw-r--r-- | sshd.c | 76 |
19 files changed, 363 insertions, 145 deletions
@@ -1,3 +1,21 @@ | |||
1 | 20000412 | ||
2 | - OpenBSD CVS updates: | ||
3 | - [channels.c] | ||
4 | repair x11-fwd | ||
5 | - [sshconnect.c] | ||
6 | fix passwd prompt for ssh2, less debugging output. | ||
7 | - [clientloop.c compat.c dsa.c kex.c sshd.c] | ||
8 | less debugging output | ||
9 | - [kex.c kex.h sshconnect.c sshd.c] | ||
10 | check for reasonable public DH values | ||
11 | - [README.openssh2 cipher.c cipher.h compat.c compat.h readconf.c] | ||
12 | [readconf.h servconf.c servconf.h ssh.c ssh.h sshconnect.c sshd.c] | ||
13 | add Cipher and Protocol options to ssh/sshd, e.g.: | ||
14 | ssh -o 'Protocol 1,2' if you prefer proto 1, ssh -o 'Ciphers | ||
15 | arcfour,3des-cbc' | ||
16 | - [sshd.c] | ||
17 | print 1.99 only if server supports both | ||
18 | |||
1 | 20000408 | 19 | 20000408 |
2 | - Avoid some compiler warnings in fake-get*.c | 20 | - Avoid some compiler warnings in fake-get*.c |
3 | - Add IPTOS macros for systems which lack them | 21 | - Add IPTOS macros for systems which lack them |
diff --git a/README.openssh2 b/README.openssh2 index 59f8cf9f6..bdf78bf58 100644 --- a/README.openssh2 +++ b/README.openssh2 | |||
@@ -1,4 +1,13 @@ | |||
1 | $Id: README.openssh2,v 1.2 2000/04/06 21:28:22 markus Exp $ | 1 | $Id: README.openssh2,v 1.3 2000/04/12 07:45:43 markus Exp $ |
2 | |||
3 | howto: | ||
4 | 1) generate server key: | ||
5 | $ umask 077 | ||
6 | $ openssl dsaparam 1024 -out dsa1024.pem | ||
7 | $ openssl gendsa -out /etc/ssh_dsa_key dsa1024.pem -rand /dev/arandom | ||
8 | 2) enable ssh2: | ||
9 | server: add 'Protocol 2,1' to /etc/sshd_config | ||
10 | client: ssh -o 'Protocol 2,1', or add to .ssh/config | ||
2 | 11 | ||
3 | works: | 12 | works: |
4 | secsh-transport: works w/o rekey | 13 | secsh-transport: works w/o rekey |
@@ -11,11 +20,7 @@ works: | |||
11 | tcp-forwarding: -L works | 20 | tcp-forwarding: -L works |
12 | dss: verification works, | 21 | dss: verification works, |
13 | key database in ~/.ssh/known_hosts with bits == 0 hack | 22 | key database in ~/.ssh/known_hosts with bits == 0 hack |
14 | dss: signature works, keygen w/ openssl: | 23 | dss: signature works, keygen w/ openssl |
15 | $ umask 077 | ||
16 | $ openssl dsaparam 1024 -out dsa1024.pem | ||
17 | $ openssl gendsa -out /etc/ssh_dsa_key dsa1024.pem -rand /dev/arandom | ||
18 | start sshd with '-2' flag | ||
19 | client interops w/ sshd2, lshd | 24 | client interops w/ sshd2, lshd |
20 | server interops w/ ssh2, lsh, ssh.com's Windows client, SecureCRT | 25 | server interops w/ ssh2, lsh, ssh.com's Windows client, SecureCRT |
21 | server supports multiple concurrent sessions (e.g. with SSH.com Windows client) | 26 | server supports multiple concurrent sessions (e.g. with SSH.com Windows client) |
@@ -33,4 +38,4 @@ todo: | |||
33 | sftp | 38 | sftp |
34 | 39 | ||
35 | -markus | 40 | -markus |
36 | $Date: 2000/04/06 21:28:22 $ | 41 | $Date: 2000/04/12 07:45:43 $ |
diff --git a/channels.c b/channels.c index c140b77dc..957b4a428 100644 --- a/channels.c +++ b/channels.c | |||
@@ -17,7 +17,7 @@ | |||
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include "includes.h" | 19 | #include "includes.h" |
20 | RCSID("$Id: channels.c,v 1.23 2000/04/12 08:45:06 damien Exp $"); | 20 | RCSID("$Id: channels.c,v 1.24 2000/04/12 10:17:38 damien Exp $"); |
21 | 21 | ||
22 | #include "ssh.h" | 22 | #include "ssh.h" |
23 | #include "packet.h" | 23 | #include "packet.h" |
@@ -437,6 +437,7 @@ channel_pre_x11_open_13(Channel *c, fd_set * readset, fd_set * writeset) | |||
437 | if (ret == 1) { | 437 | if (ret == 1) { |
438 | /* Start normal processing for the channel. */ | 438 | /* Start normal processing for the channel. */ |
439 | c->type = SSH_CHANNEL_OPEN; | 439 | c->type = SSH_CHANNEL_OPEN; |
440 | channel_pre_open_13(c, readset, writeset); | ||
440 | } else if (ret == -1) { | 441 | } else if (ret == -1) { |
441 | /* | 442 | /* |
442 | * We have received an X11 connection that has bad | 443 | * 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) | |||
460 | int ret = x11_open_helper(c); | 461 | int ret = x11_open_helper(c); |
461 | if (ret == 1) { | 462 | if (ret == 1) { |
462 | c->type = SSH_CHANNEL_OPEN; | 463 | c->type = SSH_CHANNEL_OPEN; |
464 | channel_pre_open_15(c, readset, writeset); | ||
463 | } else if (ret == -1) { | 465 | } else if (ret == -1) { |
464 | debug("X11 rejected %d i%d/o%d", c->self, c->istate, c->ostate); | 466 | debug("X11 rejected %d i%d/o%d", c->self, c->istate, c->ostate); |
465 | chan_read_failed(c); | 467 | chan_read_failed(c); |
@@ -12,11 +12,11 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include "includes.h" | 14 | #include "includes.h" |
15 | RCSID("$Id: cipher.c,v 1.16 2000/04/06 02:32:39 damien Exp $"); | 15 | RCSID("$Id: cipher.c,v 1.17 2000/04/12 10:17:39 damien Exp $"); |
16 | 16 | ||
17 | #include "ssh.h" | 17 | #include "ssh.h" |
18 | #include "cipher.h" | 18 | #include "cipher.h" |
19 | #include "config.h" | 19 | #include "xmalloc.h" |
20 | 20 | ||
21 | #ifdef HAVE_OPENSSL | 21 | #ifdef HAVE_OPENSSL |
22 | #include <openssl/md5.h> | 22 | #include <openssl/md5.h> |
@@ -26,7 +26,9 @@ RCSID("$Id: cipher.c,v 1.16 2000/04/06 02:32:39 damien Exp $"); | |||
26 | #endif | 26 | #endif |
27 | 27 | ||
28 | /* | 28 | /* |
29 | * What kind of tripple DES are these 2 routines? | 29 | * This is used by SSH1: |
30 | * | ||
31 | * What kind of triple DES are these 2 routines? | ||
30 | * | 32 | * |
31 | * Why is there a redundant initialization vector? | 33 | * Why is there a redundant initialization vector? |
32 | * | 34 | * |
@@ -81,7 +83,7 @@ SSH_3CBC_DECRYPT(des_key_schedule ks1, | |||
81 | } | 83 | } |
82 | 84 | ||
83 | /* | 85 | /* |
84 | * SSH uses a variation on Blowfish, all bytes must be swapped before | 86 | * SSH1 uses a variation on Blowfish, all bytes must be swapped before |
85 | * and after encryption/decryption. Thus the swap_bytes stuff (yuk). | 87 | * and after encryption/decryption. Thus the swap_bytes stuff (yuk). |
86 | */ | 88 | */ |
87 | static void | 89 | static void |
@@ -167,10 +169,34 @@ cipher_name(int cipher) | |||
167 | { | 169 | { |
168 | if (cipher < 0 || cipher >= sizeof(cipher_names) / sizeof(cipher_names[0]) || | 170 | if (cipher < 0 || cipher >= sizeof(cipher_names) / sizeof(cipher_names[0]) || |
169 | cipher_names[cipher] == NULL) | 171 | cipher_names[cipher] == NULL) |
170 | fatal("cipher_name: bad cipher number: %d", cipher); | 172 | fatal("cipher_name: bad cipher name: %d", cipher); |
171 | return cipher_names[cipher]; | 173 | return cipher_names[cipher]; |
172 | } | 174 | } |
173 | 175 | ||
176 | /* Returns 1 if the name of the ciphers are valid. */ | ||
177 | |||
178 | #define CIPHER_SEP "," | ||
179 | int | ||
180 | ciphers_valid(const char *names) | ||
181 | { | ||
182 | char *ciphers; | ||
183 | char *p; | ||
184 | int i; | ||
185 | |||
186 | if (strcmp(names, "") == 0) | ||
187 | return 0; | ||
188 | ciphers = xstrdup(names); | ||
189 | for ((p = strtok(ciphers, CIPHER_SEP)); p; (p = strtok(NULL, CIPHER_SEP))) { | ||
190 | i = cipher_number(p); | ||
191 | if (i == -1 || !(cipher_mask2() & (1 << i))) { | ||
192 | xfree(ciphers); | ||
193 | return 0; | ||
194 | } | ||
195 | } | ||
196 | xfree(ciphers); | ||
197 | return 1; | ||
198 | } | ||
199 | |||
174 | /* | 200 | /* |
175 | * Parses the name of the cipher. Returns the number of the corresponding | 201 | * Parses the name of the cipher. Returns the number of the corresponding |
176 | * cipher, or -1 on error. | 202 | * cipher, or -1 on error. |
@@ -271,7 +297,6 @@ cipher_set_key(CipherContext *context, int cipher, const unsigned char *key, | |||
271 | memset(padded, 0, sizeof(padded)); | 297 | memset(padded, 0, sizeof(padded)); |
272 | } | 298 | } |
273 | 299 | ||
274 | |||
275 | void | 300 | void |
276 | cipher_set_key_iv(CipherContext * context, int cipher, | 301 | cipher_set_key_iv(CipherContext * context, int cipher, |
277 | const unsigned char *key, int keylen, | 302 | const unsigned char *key, int keylen, |
@@ -11,7 +11,7 @@ | |||
11 | * | 11 | * |
12 | */ | 12 | */ |
13 | 13 | ||
14 | /* RCSID("$Id: cipher.h,v 1.8 2000/04/06 02:32:39 damien Exp $"); */ | 14 | /* RCSID("$Id: cipher.h,v 1.9 2000/04/12 10:17:39 damien Exp $"); */ |
15 | 15 | ||
16 | #ifndef CIPHER_H | 16 | #ifndef CIPHER_H |
17 | #define CIPHER_H | 17 | #define CIPHER_H |
@@ -88,6 +88,9 @@ const char *cipher_name(int cipher); | |||
88 | */ | 88 | */ |
89 | int cipher_number(const char *name); | 89 | int cipher_number(const char *name); |
90 | 90 | ||
91 | /* returns 1 if all ciphers are supported (ssh2 only) */ | ||
92 | int ciphers_valid(const char *names); | ||
93 | |||
91 | /* | 94 | /* |
92 | * Selects the cipher to use and sets the key. If for_encryption is true, | 95 | * Selects the cipher to use and sets the key. If for_encryption is true, |
93 | * the key is setup for encryption; otherwise it is setup for decryption. | 96 | * the key is setup for encryption; otherwise it is setup for decryption. |
diff --git a/clientloop.c b/clientloop.c index 4f2e5037d..91a200663 100644 --- a/clientloop.c +++ b/clientloop.c | |||
@@ -16,7 +16,7 @@ | |||
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include "includes.h" | 18 | #include "includes.h" |
19 | RCSID("$Id: clientloop.c,v 1.9 2000/04/06 02:32:39 damien Exp $"); | 19 | RCSID("$Id: clientloop.c,v 1.10 2000/04/12 10:17:39 damien Exp $"); |
20 | 20 | ||
21 | #include "xmalloc.h" | 21 | #include "xmalloc.h" |
22 | #include "ssh.h" | 22 | #include "ssh.h" |
@@ -1013,7 +1013,7 @@ client_input_channel_req(int id, void *arg) | |||
1013 | rtype = packet_get_string(&len); | 1013 | rtype = packet_get_string(&len); |
1014 | reply = packet_get_char(); | 1014 | reply = packet_get_char(); |
1015 | 1015 | ||
1016 | log("session_input_channel_req: rtype %s reply %d", rtype, reply); | 1016 | debug("session_input_channel_req: rtype %s reply %d", rtype, reply); |
1017 | 1017 | ||
1018 | c = channel_lookup(id); | 1018 | c = channel_lookup(id); |
1019 | if (c == NULL) | 1019 | if (c == NULL) |
@@ -28,10 +28,12 @@ | |||
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include "includes.h" | 30 | #include "includes.h" |
31 | RCSID("$Id: compat.c,v 1.6 2000/04/12 08:45:06 damien Exp $"); | 31 | RCSID("$Id: compat.c,v 1.7 2000/04/12 10:17:39 damien Exp $"); |
32 | 32 | ||
33 | #include "ssh.h" | 33 | #include "ssh.h" |
34 | #include "packet.h" | 34 | #include "packet.h" |
35 | #include "xmalloc.h" | ||
36 | #include "compat.h" | ||
35 | 37 | ||
36 | int compat13 = 0; | 38 | int compat13 = 0; |
37 | int compat20 = 0; | 39 | int compat20 = 0; |
@@ -65,9 +67,36 @@ compat_datafellows(const char *version) | |||
65 | len = strlen(check[i]); | 67 | len = strlen(check[i]); |
66 | if (strlen(version) >= len && | 68 | if (strlen(version) >= len && |
67 | (strncmp(version, check[i], len) == 0)) { | 69 | (strncmp(version, check[i], len) == 0)) { |
68 | log("datafellows: %.200s", version); | 70 | verbose("datafellows: %.200s", version); |
69 | datafellows = 1; | 71 | datafellows = 1; |
70 | return; | 72 | return; |
71 | } | 73 | } |
72 | } | 74 | } |
73 | } | 75 | } |
76 | |||
77 | #define SEP "," | ||
78 | int | ||
79 | proto_spec(const char *spec) | ||
80 | { | ||
81 | char *s = xstrdup(spec); | ||
82 | char *p; | ||
83 | int ret = SSH_PROTO_UNKNOWN; | ||
84 | |||
85 | for ((p = strtok(s, SEP)); p; (p = strtok(NULL, SEP))) { | ||
86 | switch(atoi(p)) { | ||
87 | case 1: | ||
88 | if (ret == SSH_PROTO_UNKNOWN) | ||
89 | ret |= SSH_PROTO_1_PREFERRED; | ||
90 | ret |= SSH_PROTO_1; | ||
91 | break; | ||
92 | case 2: | ||
93 | ret |= SSH_PROTO_2; | ||
94 | break; | ||
95 | default: | ||
96 | log("ignoring bad proto spec: '%s'.", p); | ||
97 | break; | ||
98 | } | ||
99 | } | ||
100 | xfree(s); | ||
101 | return ret; | ||
102 | } | ||
@@ -26,13 +26,20 @@ | |||
26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
27 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 27 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 | */ | 28 | */ |
29 | /* RCSID("$Id: compat.h,v 1.4 2000/04/04 04:39:01 damien Exp $"); */ | 29 | /* RCSID("$Id: compat.h,v 1.5 2000/04/12 10:17:39 damien Exp $"); */ |
30 | 30 | ||
31 | #ifndef COMPAT_H | 31 | #ifndef COMPAT_H |
32 | #define COMPAT_H | 32 | #define COMPAT_H |
33 | |||
34 | #define SSH_PROTO_UNKNOWN 0x00 | ||
35 | #define SSH_PROTO_1 0x01 | ||
36 | #define SSH_PROTO_1_PREFERRED 0x02 | ||
37 | #define SSH_PROTO_2 0x04 | ||
38 | |||
33 | void enable_compat13(void); | 39 | void enable_compat13(void); |
34 | void enable_compat20(void); | 40 | void enable_compat20(void); |
35 | void compat_datafellows(const char *s); | 41 | void compat_datafellows(const char *s); |
42 | int proto_spec(const char *spec); | ||
36 | extern int compat13; | 43 | extern int compat13; |
37 | extern int compat20; | 44 | extern int compat20; |
38 | extern int datafellows; | 45 | extern int datafellows; |
@@ -28,7 +28,7 @@ | |||
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include "includes.h" | 30 | #include "includes.h" |
31 | RCSID("$Id: dsa.c,v 1.1 2000/04/04 04:39:01 damien Exp $"); | 31 | RCSID("$Id: dsa.c,v 1.2 2000/04/12 06:37:02 markus Exp $"); |
32 | 32 | ||
33 | #include "ssh.h" | 33 | #include "ssh.h" |
34 | #include "xmalloc.h" | 34 | #include "xmalloc.h" |
@@ -80,7 +80,7 @@ dsa_serverkey_from_blob( | |||
80 | buffer_append(&b, serverhostkey, serverhostkeylen); | 80 | buffer_append(&b, serverhostkey, serverhostkeylen); |
81 | ktype = buffer_get_string(&b, NULL); | 81 | ktype = buffer_get_string(&b, NULL); |
82 | if (strcmp(KEX_DSS, ktype) != 0) { | 82 | if (strcmp(KEX_DSS, ktype) != 0) { |
83 | log("dsa_serverkey_from_blob: cannot handle type %s", ktype); | 83 | error("dsa_serverkey_from_blob: cannot handle type %s", ktype); |
84 | key_free(key); | 84 | key_free(key); |
85 | return NULL; | 85 | return NULL; |
86 | } | 86 | } |
@@ -90,10 +90,10 @@ dsa_serverkey_from_blob( | |||
90 | buffer_get_bignum2(&b, dsa->pub_key); | 90 | buffer_get_bignum2(&b, dsa->pub_key); |
91 | rlen = buffer_len(&b); | 91 | rlen = buffer_len(&b); |
92 | if(rlen != 0) | 92 | if(rlen != 0) |
93 | log("dsa_serverkey_from_blob: remaining bytes in serverhostkey %d", rlen); | 93 | error("dsa_serverkey_from_blob: remaining bytes in serverhostkey %d", rlen); |
94 | buffer_free(&b); | 94 | buffer_free(&b); |
95 | 95 | ||
96 | log("keytype %s", ktype); | 96 | debug("keytype %s", ktype); |
97 | #ifdef DEBUG_DSS | 97 | #ifdef DEBUG_DSS |
98 | DSA_print_fp(stderr, dsa, 8); | 98 | DSA_print_fp(stderr, dsa, 8); |
99 | #endif | 99 | #endif |
@@ -172,7 +172,7 @@ dsa_sign( | |||
172 | Buffer b; | 172 | Buffer b; |
173 | 173 | ||
174 | if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) { | 174 | if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) { |
175 | log("dsa_sign: no DSA key"); | 175 | error("dsa_sign: no DSA key"); |
176 | return -1; | 176 | return -1; |
177 | } | 177 | } |
178 | digest = xmalloc(evp_md->md_size); | 178 | digest = xmalloc(evp_md->md_size); |
@@ -185,11 +185,11 @@ dsa_sign( | |||
185 | rlen = BN_num_bytes(sig->r); | 185 | rlen = BN_num_bytes(sig->r); |
186 | slen = BN_num_bytes(sig->s); | 186 | slen = BN_num_bytes(sig->s); |
187 | if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) { | 187 | if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) { |
188 | log("bad sig size %d %d", rlen, slen); | 188 | error("bad sig size %d %d", rlen, slen); |
189 | DSA_SIG_free(sig); | 189 | DSA_SIG_free(sig); |
190 | return -1; | 190 | return -1; |
191 | } | 191 | } |
192 | log("sig size %d %d", rlen, slen); | 192 | debug("sig size %d %d", rlen, slen); |
193 | 193 | ||
194 | memset(sigblob, 0, SIGBLOB_LEN); | 194 | memset(sigblob, 0, SIGBLOB_LEN); |
195 | BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen); | 195 | BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen); |
@@ -197,7 +197,7 @@ dsa_sign( | |||
197 | DSA_SIG_free(sig); | 197 | DSA_SIG_free(sig); |
198 | 198 | ||
199 | if (datafellows) { | 199 | if (datafellows) { |
200 | log("datafellows"); | 200 | debug("datafellows"); |
201 | ret = xmalloc(SIGBLOB_LEN); | 201 | ret = xmalloc(SIGBLOB_LEN); |
202 | memcpy(ret, sigblob, SIGBLOB_LEN); | 202 | memcpy(ret, sigblob, SIGBLOB_LEN); |
203 | if (lenp != NULL) | 203 | if (lenp != NULL) |
@@ -239,7 +239,7 @@ dsa_verify( | |||
239 | int ret; | 239 | int ret; |
240 | 240 | ||
241 | if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) { | 241 | if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) { |
242 | log("dsa_verify: no DSA key"); | 242 | error("dsa_verify: no DSA key"); |
243 | return -1; | 243 | return -1; |
244 | } | 244 | } |
245 | 245 | ||
@@ -248,7 +248,7 @@ dsa_verify( | |||
248 | datafellows = 0; | 248 | datafellows = 0; |
249 | } | 249 | } |
250 | 250 | ||
251 | log("len %d datafellows %d", signaturelen, datafellows); | 251 | debug("len %d datafellows %d", signaturelen, datafellows); |
252 | 252 | ||
253 | /* fetch signature */ | 253 | /* fetch signature */ |
254 | if (datafellows) { | 254 | if (datafellows) { |
@@ -262,7 +262,7 @@ dsa_verify( | |||
262 | sigblob = (unsigned char *)buffer_get_string(&b, &len); | 262 | sigblob = (unsigned char *)buffer_get_string(&b, &len); |
263 | rlen = buffer_len(&b); | 263 | rlen = buffer_len(&b); |
264 | if(rlen != 0) | 264 | if(rlen != 0) |
265 | log("remaining bytes in signature %d", rlen); | 265 | error("remaining bytes in signature %d", rlen); |
266 | buffer_free(&b); | 266 | buffer_free(&b); |
267 | } | 267 | } |
268 | 268 | ||
@@ -305,6 +305,6 @@ dsa_verify( | |||
305 | txt = "error"; | 305 | txt = "error"; |
306 | break; | 306 | break; |
307 | } | 307 | } |
308 | log("dsa_verify: signature %s", txt); | 308 | debug("dsa_verify: signature %s", txt); |
309 | return ret; | 309 | return ret; |
310 | } | 310 | } |
@@ -28,7 +28,7 @@ | |||
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include "includes.h" | 30 | #include "includes.h" |
31 | RCSID("$Id: kex.c,v 1.2 2000/04/04 04:57:08 damien Exp $"); | 31 | RCSID("$Id: kex.c,v 1.3 2000/04/12 10:17:39 damien Exp $"); |
32 | 32 | ||
33 | #include "ssh.h" | 33 | #include "ssh.h" |
34 | #include "ssh2.h" | 34 | #include "ssh2.h" |
@@ -43,8 +43,6 @@ RCSID("$Id: kex.c,v 1.2 2000/04/04 04:57:08 damien Exp $"); | |||
43 | # include <openssl/dh.h> | 43 | # include <openssl/dh.h> |
44 | # include <openssl/crypto.h> | 44 | # include <openssl/crypto.h> |
45 | # include <openssl/bio.h> | 45 | # include <openssl/bio.h> |
46 | # include <openssl/bn.h> | ||
47 | # include <openssl/dh.h> | ||
48 | # include <openssl/pem.h> | 46 | # include <openssl/pem.h> |
49 | #endif /* HAVE_OPENSSL */ | 47 | #endif /* HAVE_OPENSSL */ |
50 | #if HAVE_SSL | 48 | #if HAVE_SSL |
@@ -52,12 +50,9 @@ RCSID("$Id: kex.c,v 1.2 2000/04/04 04:57:08 damien Exp $"); | |||
52 | # include <ssl/dh.h> | 50 | # include <ssl/dh.h> |
53 | # include <ssl/crypto.h> | 51 | # include <ssl/crypto.h> |
54 | # include <ssl/bio.h> | 52 | # include <ssl/bio.h> |
55 | # include <ssl/bn.h> | ||
56 | # include <ssl/dh.h> | ||
57 | # include <ssl/pem.h> | 53 | # include <ssl/pem.h> |
58 | #endif /* HAVE_SSL */ | 54 | #endif /* HAVE_SSL */ |
59 | 55 | ||
60 | #include "entropy.h" | ||
61 | #include "kex.h" | 56 | #include "kex.h" |
62 | 57 | ||
63 | Buffer * | 58 | Buffer * |
@@ -85,8 +80,36 @@ kex_init(char *myproposal[PROPOSAL_MAX]) | |||
85 | 80 | ||
86 | /* diffie-hellman-group1-sha1 */ | 81 | /* diffie-hellman-group1-sha1 */ |
87 | 82 | ||
83 | int | ||
84 | dh_pub_is_valid(DH *dh, BIGNUM *dh_pub) | ||
85 | { | ||
86 | int i; | ||
87 | int n = BN_num_bits(dh_pub); | ||
88 | int bits_set = 0; | ||
89 | |||
90 | /* we only accept g==2 */ | ||
91 | if (!BN_is_word(dh->g, 2)) { | ||
92 | log("invalid DH base != 2"); | ||
93 | return 0; | ||
94 | } | ||
95 | if (dh_pub->neg) { | ||
96 | log("invalid public DH value: negativ"); | ||
97 | return 0; | ||
98 | } | ||
99 | for (i = 0; i <= n; i++) | ||
100 | if (BN_is_bit_set(dh_pub, i)) | ||
101 | bits_set++; | ||
102 | debug("bits set: %d/%d", bits_set, BN_num_bits(dh->p)); | ||
103 | |||
104 | /* if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial */ | ||
105 | if (bits_set > 1 && (BN_cmp(dh_pub, dh->p) == -1)) | ||
106 | return 1; | ||
107 | log("invalid public DH value (%d/%d)", bits_set, BN_num_bits(dh->p)); | ||
108 | return 0; | ||
109 | } | ||
110 | |||
88 | DH * | 111 | DH * |
89 | new_dh_group1() | 112 | dh_new_group1() |
90 | { | 113 | { |
91 | static char *group1 = | 114 | static char *group1 = |
92 | "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" | 115 | "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1" |
@@ -96,22 +119,23 @@ new_dh_group1() | |||
96 | "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381" | 119 | "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381" |
97 | "FFFFFFFF" "FFFFFFFF"; | 120 | "FFFFFFFF" "FFFFFFFF"; |
98 | DH *dh; | 121 | DH *dh; |
99 | int ret; | 122 | int ret, tries = 0; |
100 | dh = DH_new(); | 123 | dh = DH_new(); |
101 | if(dh == NULL) | 124 | if(dh == NULL) |
102 | fatal("DH_new"); | 125 | fatal("DH_new"); |
103 | ret = BN_hex2bn(&dh->p,group1); | 126 | ret = BN_hex2bn(&dh->p, group1); |
104 | if(ret<0) | 127 | if(ret<0) |
105 | fatal("BN_hex2bn"); | 128 | fatal("BN_hex2bn"); |
106 | dh->g = BN_new(); | 129 | dh->g = BN_new(); |
107 | if(dh->g == NULL) | 130 | if(dh->g == NULL) |
108 | fatal("DH_new g"); | 131 | fatal("DH_new g"); |
109 | BN_set_word(dh->g,2); | 132 | BN_set_word(dh->g, 2); |
110 | 133 | do { | |
111 | seed_rng(); | 134 | if (DH_generate_key(dh) == 0) |
112 | if (DH_generate_key(dh) == 0) | 135 | fatal("DH_generate_key"); |
113 | fatal("DH_generate_key"); | 136 | if (tries++ > 10) |
114 | 137 | fatal("dh_new_group1: too many bad keys: giving up"); | |
138 | } while (!dh_pub_is_valid(dh, dh->pub_key)); | ||
115 | return dh; | 139 | return dh; |
116 | } | 140 | } |
117 | 141 | ||
@@ -356,7 +380,7 @@ kex_choose_conf(char *cprop[PROPOSAL_MAX], char *sprop[PROPOSAL_MAX], int server | |||
356 | choose_enc (&k->enc [mode], cprop[nenc], sprop[nenc]); | 380 | choose_enc (&k->enc [mode], cprop[nenc], sprop[nenc]); |
357 | choose_mac (&k->mac [mode], cprop[nmac], sprop[nmac]); | 381 | choose_mac (&k->mac [mode], cprop[nmac], sprop[nmac]); |
358 | choose_comp(&k->comp[mode], cprop[ncomp], sprop[ncomp]); | 382 | choose_comp(&k->comp[mode], cprop[ncomp], sprop[ncomp]); |
359 | log("kex: %s %s %s %s", | 383 | debug("kex: %s %s %s %s", |
360 | ctos ? "client->server" : "server->client", | 384 | ctos ? "client->server" : "server->client", |
361 | k->enc[mode].name, | 385 | k->enc[mode].name, |
362 | k->mac[mode].name, | 386 | k->mac[mode].name, |
@@ -102,7 +102,8 @@ struct Kex { | |||
102 | }; | 102 | }; |
103 | 103 | ||
104 | Buffer *kex_init(char *myproposal[PROPOSAL_MAX]); | 104 | Buffer *kex_init(char *myproposal[PROPOSAL_MAX]); |
105 | DH *new_dh_group1(); | 105 | int dh_pub_is_valid(DH *dh, BIGNUM *dh_pub); |
106 | DH *dh_new_group1(); | ||
106 | Kex *kex_choose_conf(char *cprop[PROPOSAL_MAX], char *sprop[PROPOSAL_MAX], int server); | 107 | Kex *kex_choose_conf(char *cprop[PROPOSAL_MAX], char *sprop[PROPOSAL_MAX], int server); |
107 | int kex_derive_keys(Kex *k, unsigned char *hash, BIGNUM *shared_secret); | 108 | int kex_derive_keys(Kex *k, unsigned char *hash, BIGNUM *shared_secret); |
108 | void bignum_print(BIGNUM *b); | 109 | void bignum_print(BIGNUM *b); |
diff --git a/readconf.c b/readconf.c index bb420ac05..1ba70c36a 100644 --- a/readconf.c +++ b/readconf.c | |||
@@ -14,13 +14,14 @@ | |||
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include "includes.h" | 16 | #include "includes.h" |
17 | RCSID("$Id: readconf.c,v 1.9 2000/04/01 01:09:25 damien Exp $"); | 17 | RCSID("$Id: readconf.c,v 1.10 2000/04/12 10:17:40 damien Exp $"); |
18 | 18 | ||
19 | #include "ssh.h" | 19 | #include "ssh.h" |
20 | #include "cipher.h" | 20 | #include "cipher.h" |
21 | #include "readconf.h" | 21 | #include "readconf.h" |
22 | #include "match.h" | 22 | #include "match.h" |
23 | #include "xmalloc.h" | 23 | #include "xmalloc.h" |
24 | #include "compat.h" | ||
24 | 25 | ||
25 | /* Format of the configuration file: | 26 | /* Format of the configuration file: |
26 | 27 | ||
@@ -103,7 +104,7 @@ typedef enum { | |||
103 | oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts, | 104 | oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts, |
104 | oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, | 105 | oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, |
105 | oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts, oTISAuthentication, | 106 | oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts, oTISAuthentication, |
106 | oUsePrivilegedPort, oLogLevel | 107 | oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol |
107 | } OpCodes; | 108 | } OpCodes; |
108 | 109 | ||
109 | /* Textual representations of the tokens. */ | 110 | /* Textual representations of the tokens. */ |
@@ -134,6 +135,8 @@ static struct { | |||
134 | { "proxycommand", oProxyCommand }, | 135 | { "proxycommand", oProxyCommand }, |
135 | { "port", oPort }, | 136 | { "port", oPort }, |
136 | { "cipher", oCipher }, | 137 | { "cipher", oCipher }, |
138 | { "ciphers", oCiphers }, | ||
139 | { "protocol", oProtocol }, | ||
137 | { "remoteforward", oRemoteForward }, | 140 | { "remoteforward", oRemoteForward }, |
138 | { "localforward", oLocalForward }, | 141 | { "localforward", oLocalForward }, |
139 | { "user", oUser }, | 142 | { "user", oUser }, |
@@ -444,6 +447,26 @@ parse_int: | |||
444 | *intptr = value; | 447 | *intptr = value; |
445 | break; | 448 | break; |
446 | 449 | ||
450 | case oCiphers: | ||
451 | cp = strtok(NULL, WHITESPACE); | ||
452 | if (!ciphers_valid(cp)) | ||
453 | fatal("%.200s line %d: Bad cipher spec '%s'.", | ||
454 | filename, linenum, cp ? cp : "<NONE>"); | ||
455 | if (*activep && options->ciphers == NULL) | ||
456 | options->ciphers = xstrdup(cp); | ||
457 | break; | ||
458 | |||
459 | case oProtocol: | ||
460 | intptr = &options->protocol; | ||
461 | cp = strtok(NULL, WHITESPACE); | ||
462 | value = proto_spec(cp); | ||
463 | if (value == SSH_PROTO_UNKNOWN) | ||
464 | fatal("%.200s line %d: Bad protocol spec '%s'.", | ||
465 | filename, linenum, cp ? cp : "<NONE>"); | ||
466 | if (*activep && *intptr == SSH_PROTO_UNKNOWN) | ||
467 | *intptr = value; | ||
468 | break; | ||
469 | |||
447 | case oLogLevel: | 470 | case oLogLevel: |
448 | intptr = (int *) &options->log_level; | 471 | intptr = (int *) &options->log_level; |
449 | cp = strtok(NULL, WHITESPACE); | 472 | cp = strtok(NULL, WHITESPACE); |
@@ -616,6 +639,8 @@ initialize_options(Options * options) | |||
616 | options->connection_attempts = -1; | 639 | options->connection_attempts = -1; |
617 | options->number_of_password_prompts = -1; | 640 | options->number_of_password_prompts = -1; |
618 | options->cipher = -1; | 641 | options->cipher = -1; |
642 | options->ciphers = NULL; | ||
643 | options->protocol = SSH_PROTO_UNKNOWN; | ||
619 | options->num_identity_files = 0; | 644 | options->num_identity_files = 0; |
620 | options->hostname = NULL; | 645 | options->hostname = NULL; |
621 | options->proxy_command = NULL; | 646 | options->proxy_command = NULL; |
@@ -689,6 +714,8 @@ fill_default_options(Options * options) | |||
689 | /* Selected in ssh_login(). */ | 714 | /* Selected in ssh_login(). */ |
690 | if (options->cipher == -1) | 715 | if (options->cipher == -1) |
691 | options->cipher = SSH_CIPHER_NOT_SET; | 716 | options->cipher = SSH_CIPHER_NOT_SET; |
717 | if (options->protocol == SSH_PROTO_UNKNOWN) | ||
718 | options->protocol = SSH_PROTO_1; | ||
692 | if (options->num_identity_files == 0) { | 719 | if (options->num_identity_files == 0) { |
693 | options->identity_files[0] = | 720 | options->identity_files[0] = |
694 | xmalloc(2 + strlen(SSH_CLIENT_IDENTITY) + 1); | 721 | xmalloc(2 + strlen(SSH_CLIENT_IDENTITY) + 1); |
diff --git a/readconf.h b/readconf.h index 09f051401..86f342d37 100644 --- a/readconf.h +++ b/readconf.h | |||
@@ -13,7 +13,7 @@ | |||
13 | * | 13 | * |
14 | */ | 14 | */ |
15 | 15 | ||
16 | /* RCSID("$Id: readconf.h,v 1.6 1999/12/06 00:47:29 damien Exp $"); */ | 16 | /* RCSID("$Id: readconf.h,v 1.7 2000/04/12 10:17:40 damien Exp $"); */ |
17 | 17 | ||
18 | #ifndef READCONF_H | 18 | #ifndef READCONF_H |
19 | #define READCONF_H | 19 | #define READCONF_H |
@@ -64,6 +64,8 @@ typedef struct { | |||
64 | int number_of_password_prompts; /* Max number of password | 64 | int number_of_password_prompts; /* Max number of password |
65 | * prompts. */ | 65 | * prompts. */ |
66 | int cipher; /* Cipher to use. */ | 66 | int cipher; /* Cipher to use. */ |
67 | char *ciphers; /* Ciphers in order of preference. */ | ||
68 | int protocol; /* Protocol in order of preference. */ | ||
67 | char *hostname; /* Real host to connect. */ | 69 | char *hostname; /* Real host to connect. */ |
68 | char *proxy_command; /* Proxy command for connecting the host. */ | 70 | char *proxy_command; /* Proxy command for connecting the host. */ |
69 | char *user; /* User to log in as. */ | 71 | char *user; /* User to log in as. */ |
diff --git a/servconf.c b/servconf.c index 800c4d5f4..918fb8ed2 100644 --- a/servconf.c +++ b/servconf.c | |||
@@ -12,11 +12,12 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include "includes.h" | 14 | #include "includes.h" |
15 | RCSID("$Id: servconf.c,v 1.10 2000/04/12 08:45:06 damien Exp $"); | 15 | RCSID("$Id: servconf.c,v 1.11 2000/04/12 10:17:40 damien Exp $"); |
16 | 16 | ||
17 | #include "ssh.h" | 17 | #include "ssh.h" |
18 | #include "servconf.h" | 18 | #include "servconf.h" |
19 | #include "xmalloc.h" | 19 | #include "xmalloc.h" |
20 | #include "compat.h" | ||
20 | 21 | ||
21 | /* add listen address */ | 22 | /* add listen address */ |
22 | void add_listen_addr(ServerOptions *options, char *addr); | 23 | void add_listen_addr(ServerOptions *options, char *addr); |
@@ -68,6 +69,8 @@ initialize_server_options(ServerOptions *options) | |||
68 | options->num_deny_users = 0; | 69 | options->num_deny_users = 0; |
69 | options->num_allow_groups = 0; | 70 | options->num_allow_groups = 0; |
70 | options->num_deny_groups = 0; | 71 | options->num_deny_groups = 0; |
72 | options->ciphers = NULL; | ||
73 | options->protocol = SSH_PROTO_UNKNOWN; | ||
71 | } | 74 | } |
72 | 75 | ||
73 | void | 76 | void |
@@ -139,6 +142,8 @@ fill_default_server_options(ServerOptions *options) | |||
139 | options->permit_empty_passwd = 0; | 142 | options->permit_empty_passwd = 0; |
140 | if (options->use_login == -1) | 143 | if (options->use_login == -1) |
141 | options->use_login = 0; | 144 | options->use_login = 0; |
145 | if (options->protocol == SSH_PROTO_UNKNOWN) | ||
146 | options->protocol = SSH_PROTO_1; | ||
142 | } | 147 | } |
143 | 148 | ||
144 | #define WHITESPACE " \t\r\n" | 149 | #define WHITESPACE " \t\r\n" |
@@ -162,7 +167,7 @@ typedef enum { | |||
162 | sPrintMotd, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset, | 167 | sPrintMotd, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset, |
163 | sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail, | 168 | sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail, |
164 | sUseLogin, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, | 169 | sUseLogin, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, |
165 | sIgnoreUserKnownHosts, sDSAKeyFile | 170 | sIgnoreUserKnownHosts, sDSAKeyFile, sCiphers, sProtocol |
166 | } ServerOpCodes; | 171 | } ServerOpCodes; |
167 | 172 | ||
168 | /* Textual representation of the tokens. */ | 173 | /* Textual representation of the tokens. */ |
@@ -211,6 +216,8 @@ static struct { | |||
211 | { "denyusers", sDenyUsers }, | 216 | { "denyusers", sDenyUsers }, |
212 | { "allowgroups", sAllowGroups }, | 217 | { "allowgroups", sAllowGroups }, |
213 | { "denygroups", sDenyGroups }, | 218 | { "denygroups", sDenyGroups }, |
219 | { "ciphers", sCiphers }, | ||
220 | { "protocol", sProtocol }, | ||
214 | { NULL, 0 } | 221 | { NULL, 0 } |
215 | }; | 222 | }; |
216 | 223 | ||
@@ -494,7 +501,7 @@ parse_flag: | |||
494 | value = log_facility_number(cp); | 501 | value = log_facility_number(cp); |
495 | if (value == (SyslogFacility) - 1) | 502 | if (value == (SyslogFacility) - 1) |
496 | fatal("%.200s line %d: unsupported log facility '%s'\n", | 503 | fatal("%.200s line %d: unsupported log facility '%s'\n", |
497 | filename, linenum, cp ? cp : "<NONE>"); | 504 | filename, linenum, cp ? cp : "<NONE>"); |
498 | if (*intptr == -1) | 505 | if (*intptr == -1) |
499 | *intptr = (SyslogFacility) value; | 506 | *intptr = (SyslogFacility) value; |
500 | break; | 507 | break; |
@@ -505,55 +512,67 @@ parse_flag: | |||
505 | value = log_level_number(cp); | 512 | value = log_level_number(cp); |
506 | if (value == (LogLevel) - 1) | 513 | if (value == (LogLevel) - 1) |
507 | fatal("%.200s line %d: unsupported log level '%s'\n", | 514 | fatal("%.200s line %d: unsupported log level '%s'\n", |
508 | filename, linenum, cp ? cp : "<NONE>"); | 515 | filename, linenum, cp ? cp : "<NONE>"); |
509 | if (*intptr == -1) | 516 | if (*intptr == -1) |
510 | *intptr = (LogLevel) value; | 517 | *intptr = (LogLevel) value; |
511 | break; | 518 | break; |
512 | 519 | ||
513 | case sAllowUsers: | 520 | case sAllowUsers: |
514 | while ((cp = strtok(NULL, WHITESPACE))) { | 521 | while ((cp = strtok(NULL, WHITESPACE))) { |
515 | if (options->num_allow_users >= MAX_ALLOW_USERS) { | 522 | if (options->num_allow_users >= MAX_ALLOW_USERS) |
516 | fprintf(stderr, "%s line %d: too many allow users.\n", | 523 | fatal("%s line %d: too many allow users.\n", |
517 | filename, linenum); | 524 | filename, linenum); |
518 | exit(1); | ||
519 | } | ||
520 | options->allow_users[options->num_allow_users++] = xstrdup(cp); | 525 | options->allow_users[options->num_allow_users++] = xstrdup(cp); |
521 | } | 526 | } |
522 | break; | 527 | break; |
523 | 528 | ||
524 | case sDenyUsers: | 529 | case sDenyUsers: |
525 | while ((cp = strtok(NULL, WHITESPACE))) { | 530 | while ((cp = strtok(NULL, WHITESPACE))) { |
526 | if (options->num_deny_users >= MAX_DENY_USERS) { | 531 | if (options->num_deny_users >= MAX_DENY_USERS) |
527 | fprintf(stderr, "%s line %d: too many deny users.\n", | 532 | fatal( "%s line %d: too many deny users.\n", |
528 | filename, linenum); | 533 | filename, linenum); |
529 | exit(1); | ||
530 | } | ||
531 | options->deny_users[options->num_deny_users++] = xstrdup(cp); | 534 | options->deny_users[options->num_deny_users++] = xstrdup(cp); |
532 | } | 535 | } |
533 | break; | 536 | break; |
534 | 537 | ||
535 | case sAllowGroups: | 538 | case sAllowGroups: |
536 | while ((cp = strtok(NULL, WHITESPACE))) { | 539 | while ((cp = strtok(NULL, WHITESPACE))) { |
537 | if (options->num_allow_groups >= MAX_ALLOW_GROUPS) { | 540 | if (options->num_allow_groups >= MAX_ALLOW_GROUPS) |
538 | fprintf(stderr, "%s line %d: too many allow groups.\n", | 541 | fatal("%s line %d: too many allow groups.\n", |
539 | filename, linenum); | 542 | filename, linenum); |
540 | exit(1); | ||
541 | } | ||
542 | options->allow_groups[options->num_allow_groups++] = xstrdup(cp); | 543 | options->allow_groups[options->num_allow_groups++] = xstrdup(cp); |
543 | } | 544 | } |
544 | break; | 545 | break; |
545 | 546 | ||
546 | case sDenyGroups: | 547 | case sDenyGroups: |
547 | while ((cp = strtok(NULL, WHITESPACE))) { | 548 | while ((cp = strtok(NULL, WHITESPACE))) { |
548 | if (options->num_deny_groups >= MAX_DENY_GROUPS) { | 549 | if (options->num_deny_groups >= MAX_DENY_GROUPS) |
549 | fprintf(stderr, "%s line %d: too many deny groups.\n", | 550 | fatal("%s line %d: too many deny groups.\n", |
550 | filename, linenum); | 551 | filename, linenum); |
551 | exit(1); | ||
552 | } | ||
553 | options->deny_groups[options->num_deny_groups++] = xstrdup(cp); | 552 | options->deny_groups[options->num_deny_groups++] = xstrdup(cp); |
554 | } | 553 | } |
555 | break; | 554 | break; |
556 | 555 | ||
556 | case sCiphers: | ||
557 | cp = strtok(NULL, WHITESPACE); | ||
558 | if (!ciphers_valid(cp)) | ||
559 | fatal("%s line %d: Bad cipher spec '%s'.", | ||
560 | filename, linenum, cp ? cp : "<NONE>"); | ||
561 | if (options->ciphers == NULL) | ||
562 | options->ciphers = xstrdup(cp); | ||
563 | break; | ||
564 | |||
565 | case sProtocol: | ||
566 | intptr = &options->protocol; | ||
567 | cp = strtok(NULL, WHITESPACE); | ||
568 | value = proto_spec(cp); | ||
569 | if (value == SSH_PROTO_UNKNOWN) | ||
570 | fatal("%s line %d: Bad protocol spec '%s'.", | ||
571 | filename, linenum, cp ? cp : "<NONE>"); | ||
572 | if (*intptr == SSH_PROTO_UNKNOWN) | ||
573 | *intptr = value; | ||
574 | break; | ||
575 | |||
557 | default: | 576 | default: |
558 | fprintf(stderr, "%s line %d: Missing handler for opcode %s (%d)\n", | 577 | fprintf(stderr, "%s line %d: Missing handler for opcode %s (%d)\n", |
559 | filename, linenum, cp, opcode); | 578 | filename, linenum, cp, opcode); |
diff --git a/servconf.h b/servconf.h index 5ce3f1594..2a3686245 100644 --- a/servconf.h +++ b/servconf.h | |||
@@ -13,7 +13,7 @@ | |||
13 | * | 13 | * |
14 | */ | 14 | */ |
15 | 15 | ||
16 | /* RCSID("$Id: servconf.h,v 1.7 2000/04/12 08:45:07 damien Exp $"); */ | 16 | /* RCSID("$Id: servconf.h,v 1.8 2000/04/12 10:17:40 damien Exp $"); */ |
17 | 17 | ||
18 | #ifndef SERVCONF_H | 18 | #ifndef SERVCONF_H |
19 | #define SERVCONF_H | 19 | #define SERVCONF_H |
@@ -48,6 +48,8 @@ typedef struct { | |||
48 | * searching at */ | 48 | * searching at */ |
49 | int strict_modes; /* If true, require string home dir modes. */ | 49 | int strict_modes; /* If true, require string home dir modes. */ |
50 | int keepalives; /* If true, set SO_KEEPALIVE. */ | 50 | int keepalives; /* If true, set SO_KEEPALIVE. */ |
51 | char *ciphers; /* Ciphers in order of preference. */ | ||
52 | int protocol; /* Protocol in order of preference. */ | ||
51 | SyslogFacility log_facility; /* Facility for system logging. */ | 53 | SyslogFacility log_facility; /* Facility for system logging. */ |
52 | LogLevel log_level; /* Level for system logging. */ | 54 | LogLevel log_level; /* Level for system logging. */ |
53 | int rhosts_authentication; /* If true, permit rhosts | 55 | int rhosts_authentication; /* If true, permit rhosts |
@@ -11,7 +11,7 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include "includes.h" | 13 | #include "includes.h" |
14 | RCSID("$Id: ssh.c,v 1.24 2000/04/06 02:32:40 damien Exp $"); | 14 | RCSID("$Id: ssh.c,v 1.25 2000/04/12 10:17:40 damien Exp $"); |
15 | 15 | ||
16 | #include "xmalloc.h" | 16 | #include "xmalloc.h" |
17 | #include "ssh.h" | 17 | #include "ssh.h" |
@@ -42,6 +42,7 @@ int IPv4or6 = AF_UNSPEC; | |||
42 | /* Flag indicating whether debug mode is on. This can be set on the command line. */ | 42 | /* Flag indicating whether debug mode is on. This can be set on the command line. */ |
43 | int debug_flag = 0; | 43 | int debug_flag = 0; |
44 | 44 | ||
45 | /* Flag indicating whether a tty should be allocated */ | ||
45 | int tty_flag = 0; | 46 | int tty_flag = 0; |
46 | 47 | ||
47 | /* don't exec a shell */ | 48 | /* don't exec a shell */ |
@@ -336,8 +337,10 @@ main(int ac, char **av) | |||
336 | 337 | ||
337 | case 'v': | 338 | case 'v': |
338 | case 'V': | 339 | case 'V': |
339 | fprintf(stderr, "SSH Version %s, protocol version %d.%d.\n", | 340 | fprintf(stderr, "SSH Version %s, protocol versions %d.%d/%d.%d.\n", |
340 | SSH_VERSION, PROTOCOL_MAJOR, PROTOCOL_MINOR); | 341 | SSH_VERSION, |
342 | PROTOCOL_MAJOR_1, PROTOCOL_MINOR_1, | ||
343 | PROTOCOL_MAJOR_2, PROTOCOL_MINOR_2); | ||
341 | fprintf(stderr, "Compiled with SSL (0x%8.8lx).\n", SSLeay()); | 344 | fprintf(stderr, "Compiled with SSL (0x%8.8lx).\n", SSLeay()); |
342 | if (opt == 'V') | 345 | if (opt == 'V') |
343 | exit(0); | 346 | exit(0); |
@@ -13,7 +13,7 @@ | |||
13 | * | 13 | * |
14 | */ | 14 | */ |
15 | 15 | ||
16 | /* RCSID("$Id: ssh.h,v 1.30 2000/04/12 08:45:07 damien Exp $"); */ | 16 | /* RCSID("$Id: ssh.h,v 1.31 2000/04/12 10:17:41 damien Exp $"); */ |
17 | 17 | ||
18 | #ifndef SSH_H | 18 | #ifndef SSH_H |
19 | #define SSH_H | 19 | #define SSH_H |
@@ -54,14 +54,16 @@ | |||
54 | /* | 54 | /* |
55 | * Major protocol version. Different version indicates major incompatiblity | 55 | * Major protocol version. Different version indicates major incompatiblity |
56 | * that prevents communication. | 56 | * that prevents communication. |
57 | */ | 57 | * |
58 | #define PROTOCOL_MAJOR 1 | ||
59 | |||
60 | /* | ||
61 | * Minor protocol version. Different version indicates minor incompatibility | 58 | * Minor protocol version. Different version indicates minor incompatibility |
62 | * that does not prevent interoperation. | 59 | * that does not prevent interoperation. |
63 | */ | 60 | */ |
64 | #define PROTOCOL_MINOR 5 | 61 | #define PROTOCOL_MAJOR_1 1 |
62 | #define PROTOCOL_MINOR_1 5 | ||
63 | |||
64 | /* We support both SSH1 and SSH2 */ | ||
65 | #define PROTOCOL_MAJOR_2 2 | ||
66 | #define PROTOCOL_MINOR_2 0 | ||
65 | 67 | ||
66 | /* | 68 | /* |
67 | * Name for the service. The port named by this service overrides the | 69 | * Name for the service. The port named by this service overrides the |
diff --git a/sshconnect.c b/sshconnect.c index 2f9496090..167b8e63a 100644 --- a/sshconnect.c +++ b/sshconnect.c | |||
@@ -10,7 +10,7 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include "includes.h" | 12 | #include "includes.h" |
13 | RCSID("$OpenBSD: sshconnect.c,v 1.61 2000/04/04 21:37:27 markus Exp $"); | 13 | RCSID("$OpenBSD: sshconnect.c,v 1.65 2000/04/12 07:56:16 markus Exp $"); |
14 | 14 | ||
15 | #ifdef HAVE_OPENSSL | 15 | #ifdef HAVE_OPENSSL |
16 | #include <openssl/bn.h> | 16 | #include <openssl/bn.h> |
@@ -993,7 +993,7 @@ void | |||
993 | ssh_exchange_identification() | 993 | ssh_exchange_identification() |
994 | { | 994 | { |
995 | char buf[256], remote_version[256]; /* must be same size! */ | 995 | char buf[256], remote_version[256]; /* must be same size! */ |
996 | int remote_major, remote_minor, i; | 996 | int remote_major, remote_minor, i, mismatch; |
997 | int connection_in = packet_get_connection_in(); | 997 | int connection_in = packet_get_connection_in(); |
998 | int connection_out = packet_get_connection_out(); | 998 | int connection_out = packet_get_connection_out(); |
999 | 999 | ||
@@ -1027,39 +1027,51 @@ ssh_exchange_identification() | |||
1027 | debug("Remote protocol version %d.%d, remote software version %.100s", | 1027 | debug("Remote protocol version %d.%d, remote software version %.100s", |
1028 | remote_major, remote_minor, remote_version); | 1028 | remote_major, remote_minor, remote_version); |
1029 | 1029 | ||
1030 | /*** XXX option for disabling 2.0 or 1.5 */ | ||
1031 | compat_datafellows(remote_version); | 1030 | compat_datafellows(remote_version); |
1032 | 1031 | mismatch = 0; | |
1033 | /* Check if the remote protocol version is too old. */ | 1032 | |
1034 | if (remote_major == 1 && remote_minor < 3) | 1033 | switch(remote_major) { |
1035 | fatal("Remote machine has too old SSH software version."); | 1034 | case 1: |
1036 | 1035 | if (remote_minor == 99 && | |
1037 | /* We speak 1.3, too. */ | 1036 | (options.protocol & SSH_PROTO_2) && |
1038 | if (remote_major == 1 && remote_minor == 3) { | 1037 | !(options.protocol & SSH_PROTO_1_PREFERRED)) { |
1039 | enable_compat13(); | 1038 | enable_compat20(); |
1040 | if (options.forward_agent) { | 1039 | break; |
1041 | log("Agent forwarding disabled for protocol 1.3"); | ||
1042 | options.forward_agent = 0; | ||
1043 | } | 1040 | } |
1041 | if (!(options.protocol & SSH_PROTO_1)) { | ||
1042 | mismatch = 1; | ||
1043 | break; | ||
1044 | } | ||
1045 | if (remote_minor < 3) { | ||
1046 | fatal("Remote machine has too old SSH software version."); | ||
1047 | } else if (remote_minor == 3) { | ||
1048 | /* We speak 1.3, too. */ | ||
1049 | enable_compat13(); | ||
1050 | if (options.forward_agent) { | ||
1051 | log("Agent forwarding disabled for protocol 1.3"); | ||
1052 | options.forward_agent = 0; | ||
1053 | } | ||
1054 | } | ||
1055 | break; | ||
1056 | case 2: | ||
1057 | if (options.protocol & SSH_PROTO_2) { | ||
1058 | enable_compat20(); | ||
1059 | break; | ||
1060 | } | ||
1061 | /* FALLTHROUGH */ | ||
1062 | default: | ||
1063 | mismatch = 1; | ||
1064 | break; | ||
1044 | } | 1065 | } |
1045 | if ((remote_major == 2 && remote_minor == 0) || | 1066 | if (mismatch) |
1046 | (remote_major == 1 && remote_minor == 99)) { | ||
1047 | enable_compat20(); | ||
1048 | } | ||
1049 | #if 0 | ||
1050 | /* | ||
1051 | * Removed for now, to permit compatibility with latter versions. The | ||
1052 | * server will reject our version and disconnect if it doesn't | ||
1053 | * support it. | ||
1054 | */ | ||
1055 | if (remote_major != PROTOCOL_MAJOR) | ||
1056 | fatal("Protocol major versions differ: %d vs. %d", | 1067 | fatal("Protocol major versions differ: %d vs. %d", |
1057 | PROTOCOL_MAJOR, remote_major); | 1068 | (options.protocol & SSH_PROTO_2) ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1, |
1058 | #endif | 1069 | remote_major); |
1070 | |||
1059 | /* Send our own protocol version identification. */ | 1071 | /* Send our own protocol version identification. */ |
1060 | snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", | 1072 | snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", |
1061 | compat20 ? 2 : PROTOCOL_MAJOR, | 1073 | compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1, |
1062 | compat20 ? 0 : PROTOCOL_MINOR, | 1074 | compat20 ? PROTOCOL_MINOR_2 : PROTOCOL_MINOR_1, |
1063 | SSH_VERSION); | 1075 | SSH_VERSION); |
1064 | if (atomicio(write, connection_out, buf, strlen(buf)) != strlen(buf)) | 1076 | if (atomicio(write, connection_out, buf, strlen(buf)) != strlen(buf)) |
1065 | fatal("write: %.100s", strerror(errno)); | 1077 | fatal("write: %.100s", strerror(errno)); |
@@ -1350,11 +1362,15 @@ ssh_kex2(char *host, struct sockaddr *hostaddr) | |||
1350 | /* KEXINIT */ | 1362 | /* KEXINIT */ |
1351 | 1363 | ||
1352 | debug("Sending KEX init."); | 1364 | debug("Sending KEX init."); |
1353 | if (options.cipher == SSH_CIPHER_ARCFOUR || | 1365 | if (options.ciphers != NULL) { |
1366 | myproposal[PROPOSAL_ENC_ALGS_CTOS] = | ||
1367 | myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; | ||
1368 | } else if ( | ||
1369 | options.cipher == SSH_CIPHER_ARCFOUR || | ||
1354 | options.cipher == SSH_CIPHER_3DES_CBC || | 1370 | options.cipher == SSH_CIPHER_3DES_CBC || |
1355 | options.cipher == SSH_CIPHER_CAST128_CBC || | 1371 | options.cipher == SSH_CIPHER_CAST128_CBC || |
1356 | options.cipher == SSH_CIPHER_BLOWFISH_CBC) { | 1372 | options.cipher == SSH_CIPHER_BLOWFISH_CBC) { |
1357 | myproposal[PROPOSAL_ENC_ALGS_CTOS] = cipher_name(options.cipher); | 1373 | myproposal[PROPOSAL_ENC_ALGS_CTOS] = |
1358 | myproposal[PROPOSAL_ENC_ALGS_STOC] = cipher_name(options.cipher); | 1374 | myproposal[PROPOSAL_ENC_ALGS_STOC] = cipher_name(options.cipher); |
1359 | } | 1375 | } |
1360 | if (options.compression) { | 1376 | if (options.compression) { |
@@ -1404,7 +1420,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr) | |||
1404 | debug("Sending SSH2_MSG_KEXDH_INIT."); | 1420 | debug("Sending SSH2_MSG_KEXDH_INIT."); |
1405 | 1421 | ||
1406 | /* generate and send 'e', client DH public key */ | 1422 | /* generate and send 'e', client DH public key */ |
1407 | dh = new_dh_group1(); | 1423 | dh = dh_new_group1(); |
1408 | packet_start(SSH2_MSG_KEXDH_INIT); | 1424 | packet_start(SSH2_MSG_KEXDH_INIT); |
1409 | packet_put_bignum2(dh->pub_key); | 1425 | packet_put_bignum2(dh->pub_key); |
1410 | packet_send(); | 1426 | packet_send(); |
@@ -1451,6 +1467,9 @@ ssh_kex2(char *host, struct sockaddr *hostaddr) | |||
1451 | /* signed H */ | 1467 | /* signed H */ |
1452 | signature = packet_get_string(&slen); | 1468 | signature = packet_get_string(&slen); |
1453 | 1469 | ||
1470 | if (!dh_pub_is_valid(dh, dh_server_pub)) | ||
1471 | packet_disconnect("bad server public DH value"); | ||
1472 | |||
1454 | klen = DH_size(dh); | 1473 | klen = DH_size(dh); |
1455 | kbuf = xmalloc(klen); | 1474 | kbuf = xmalloc(klen); |
1456 | kout = DH_compute_key(kbuf, dh_server_pub, dh); | 1475 | kout = DH_compute_key(kbuf, dh_server_pub, dh); |
@@ -1507,12 +1526,13 @@ ssh_kex2(char *host, struct sockaddr *hostaddr) | |||
1507 | packet_write_wait(); | 1526 | packet_write_wait(); |
1508 | debug("done: send SSH2_MSG_NEWKEYS."); | 1527 | debug("done: send SSH2_MSG_NEWKEYS."); |
1509 | 1528 | ||
1529 | #ifdef DEBUG_KEXDH | ||
1510 | /* send 1st encrypted/maced/compressed message */ | 1530 | /* send 1st encrypted/maced/compressed message */ |
1511 | packet_start(SSH2_MSG_IGNORE); | 1531 | packet_start(SSH2_MSG_IGNORE); |
1512 | packet_put_cstring("markus"); | 1532 | packet_put_cstring("markus"); |
1513 | packet_send(); | 1533 | packet_send(); |
1514 | packet_write_wait(); | 1534 | packet_write_wait(); |
1515 | 1535 | #endif | |
1516 | debug("done: KEX2."); | 1536 | debug("done: KEX2."); |
1517 | } | 1537 | } |
1518 | /* | 1538 | /* |
@@ -1527,6 +1547,7 @@ ssh_userauth2(int host_key_valid, RSA *own_host_key, | |||
1527 | unsigned int dlen; | 1547 | unsigned int dlen; |
1528 | int partial; | 1548 | int partial; |
1529 | struct passwd *pw; | 1549 | struct passwd *pw; |
1550 | char prompt[80]; | ||
1530 | char *server_user, *local_user; | 1551 | char *server_user, *local_user; |
1531 | char *auths; | 1552 | char *auths; |
1532 | char *password; | 1553 | char *password; |
@@ -1578,7 +1599,9 @@ ssh_userauth2(int host_key_valid, RSA *own_host_key, | |||
1578 | fatal("passwd auth not supported: %s", auths); | 1599 | fatal("passwd auth not supported: %s", auths); |
1579 | xfree(auths); | 1600 | xfree(auths); |
1580 | /* try passwd */ | 1601 | /* try passwd */ |
1581 | password = read_passphrase("password: ", 0); | 1602 | snprintf(prompt, sizeof(prompt), "%.30s@%.40s's password: ", |
1603 | server_user, host); | ||
1604 | password = read_passphrase(prompt, 0); | ||
1582 | packet_start(SSH2_MSG_USERAUTH_REQUEST); | 1605 | packet_start(SSH2_MSG_USERAUTH_REQUEST); |
1583 | packet_put_cstring(server_user); | 1606 | packet_put_cstring(server_user); |
1584 | packet_put_cstring(service); | 1607 | packet_put_cstring(service); |
@@ -14,7 +14,7 @@ | |||
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include "includes.h" | 16 | #include "includes.h" |
17 | RCSID("$OpenBSD: sshd.c,v 1.99 2000/04/07 09:17:39 markus Exp $"); | 17 | RCSID("$OpenBSD: sshd.c,v 1.103 2000/04/12 08:11:36 markus Exp $"); |
18 | 18 | ||
19 | #include "xmalloc.h" | 19 | #include "xmalloc.h" |
20 | #include "rsa.h" | 20 | #include "rsa.h" |
@@ -77,9 +77,6 @@ int IPv4or6 = AF_INET; | |||
77 | int IPv4or6 = AF_UNSPEC; | 77 | int IPv4or6 = AF_UNSPEC; |
78 | #endif | 78 | #endif |
79 | 79 | ||
80 | /* Flag indicating whether SSH2 is enabled */ | ||
81 | int allow_ssh2 = 0; | ||
82 | |||
83 | /* | 80 | /* |
84 | * Debug mode flag. This can be set on the command line. If debug | 81 | * Debug mode flag. This can be set on the command line. If debug |
85 | * mode is enabled, extra debugging output will be sent to the system | 82 | * mode is enabled, extra debugging output will be sent to the system |
@@ -284,16 +281,25 @@ chop(char *s) | |||
284 | void | 281 | void |
285 | sshd_exchange_identification(int sock_in, int sock_out) | 282 | sshd_exchange_identification(int sock_in, int sock_out) |
286 | { | 283 | { |
287 | int i; | 284 | int i, mismatch; |
288 | int remote_major, remote_minor; | 285 | int remote_major, remote_minor; |
286 | int major, minor; | ||
289 | char *s; | 287 | char *s; |
290 | char buf[256]; /* Must not be larger than remote_version. */ | 288 | char buf[256]; /* Must not be larger than remote_version. */ |
291 | char remote_version[256]; /* Must be at least as big as buf. */ | 289 | char remote_version[256]; /* Must be at least as big as buf. */ |
292 | 290 | ||
293 | snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", | 291 | if ((options.protocol & SSH_PROTO_1) && |
294 | allow_ssh2 ? 1 : PROTOCOL_MAJOR, | 292 | (options.protocol & SSH_PROTO_2)) { |
295 | allow_ssh2 ? 99 : PROTOCOL_MINOR, | 293 | major = PROTOCOL_MAJOR_1; |
296 | SSH_VERSION); | 294 | minor = 99; |
295 | } else if (options.protocol & SSH_PROTO_2) { | ||
296 | major = PROTOCOL_MAJOR_2; | ||
297 | minor = PROTOCOL_MINOR_2; | ||
298 | } else { | ||
299 | major = PROTOCOL_MAJOR_1; | ||
300 | minor = PROTOCOL_MINOR_1; | ||
301 | } | ||
302 | snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", major, minor, SSH_VERSION); | ||
297 | server_version_string = xstrdup(buf); | 303 | server_version_string = xstrdup(buf); |
298 | 304 | ||
299 | if (client_version_string == NULL) { | 305 | if (client_version_string == NULL) { |
@@ -314,7 +320,6 @@ sshd_exchange_identification(int sock_in, int sock_out) | |||
314 | buf[i] = '\n'; | 320 | buf[i] = '\n'; |
315 | buf[i + 1] = 0; | 321 | buf[i + 1] = 0; |
316 | continue; | 322 | continue; |
317 | //break; | ||
318 | } | 323 | } |
319 | if (buf[i] == '\n') { | 324 | if (buf[i] == '\n') { |
320 | /* buf[i] == '\n' */ | 325 | /* buf[i] == '\n' */ |
@@ -345,8 +350,13 @@ sshd_exchange_identification(int sock_in, int sock_out) | |||
345 | 350 | ||
346 | compat_datafellows(remote_version); | 351 | compat_datafellows(remote_version); |
347 | 352 | ||
353 | mismatch = 0; | ||
348 | switch(remote_major) { | 354 | switch(remote_major) { |
349 | case 1: | 355 | case 1: |
356 | if (!(options.protocol & SSH_PROTO_1)) { | ||
357 | mismatch = 1; | ||
358 | break; | ||
359 | } | ||
350 | if (remote_minor < 3) { | 360 | if (remote_minor < 3) { |
351 | packet_disconnect("Your ssh version is too old and" | 361 | packet_disconnect("Your ssh version is too old and" |
352 | "is no longer supported. Please install a newer version."); | 362 | "is no longer supported. Please install a newer version."); |
@@ -354,27 +364,37 @@ sshd_exchange_identification(int sock_in, int sock_out) | |||
354 | /* note that this disables agent-forwarding */ | 364 | /* note that this disables agent-forwarding */ |
355 | enable_compat13(); | 365 | enable_compat13(); |
356 | } | 366 | } |
357 | if (remote_minor != 99) | 367 | if (remote_minor == 99) { |
358 | break; | 368 | if (options.protocol & SSH_PROTO_2) |
359 | /* FALLTHROUGH */ | 369 | enable_compat20(); |
370 | else | ||
371 | mismatch = 1; | ||
372 | } | ||
373 | break; | ||
360 | case 2: | 374 | case 2: |
361 | if (allow_ssh2) { | 375 | if (options.protocol & SSH_PROTO_2) { |
362 | enable_compat20(); | 376 | enable_compat20(); |
363 | break; | 377 | break; |
364 | } | 378 | } |
365 | /* FALLTHROUGH */ | 379 | /* FALLTHROUGH */ |
366 | default: | 380 | default: |
381 | mismatch = 1; | ||
382 | break; | ||
383 | } | ||
384 | chop(server_version_string); | ||
385 | chop(client_version_string); | ||
386 | debug("Local version string %.200s", server_version_string); | ||
387 | |||
388 | if (mismatch) { | ||
367 | s = "Protocol major versions differ.\n"; | 389 | s = "Protocol major versions differ.\n"; |
368 | (void) atomicio(write, sock_out, s, strlen(s)); | 390 | (void) atomicio(write, sock_out, s, strlen(s)); |
369 | close(sock_in); | 391 | close(sock_in); |
370 | close(sock_out); | 392 | close(sock_out); |
371 | log("Protocol major versions differ for %s: %d vs. %d", | 393 | log("Protocol major versions differ for %s: %.200s vs. %.200s", |
372 | get_remote_ipaddr(), PROTOCOL_MAJOR, remote_major); | 394 | get_remote_ipaddr(), |
395 | server_version_string, client_version_string); | ||
373 | fatal_cleanup(); | 396 | fatal_cleanup(); |
374 | break; | ||
375 | } | 397 | } |
376 | chop(server_version_string); | ||
377 | chop(client_version_string); | ||
378 | } | 398 | } |
379 | 399 | ||
380 | /* | 400 | /* |
@@ -410,11 +430,8 @@ main(int ac, char **av) | |||
410 | initialize_server_options(&options); | 430 | initialize_server_options(&options); |
411 | 431 | ||
412 | /* Parse command-line arguments. */ | 432 | /* Parse command-line arguments. */ |
413 | while ((opt = getopt(ac, av, "f:p:b:k:h:g:V:diqQ246")) != EOF) { | 433 | while ((opt = getopt(ac, av, "f:p:b:k:h:g:V:diqQ46")) != EOF) { |
414 | switch (opt) { | 434 | switch (opt) { |
415 | case '2': | ||
416 | allow_ssh2 = 1; | ||
417 | break; | ||
418 | case '4': | 435 | case '4': |
419 | IPv4or6 = AF_INET; | 436 | IPv4or6 = AF_INET; |
420 | break; | 437 | break; |
@@ -593,6 +610,7 @@ main(int ac, char **av) | |||
593 | public_key = RSA_new(); | 610 | public_key = RSA_new(); |
594 | sensitive_data.private_key = RSA_new(); | 611 | sensitive_data.private_key = RSA_new(); |
595 | 612 | ||
613 | /* XXX check options.protocol */ | ||
596 | log("Generating %d bit RSA key.", options.server_key_bits); | 614 | log("Generating %d bit RSA key.", options.server_key_bits); |
597 | rsa_generate_key(sensitive_data.private_key, public_key, | 615 | rsa_generate_key(sensitive_data.private_key, public_key, |
598 | options.server_key_bits); | 616 | options.server_key_bits); |
@@ -1126,6 +1144,11 @@ do_ssh2_kex() | |||
1126 | 1144 | ||
1127 | /* KEXINIT */ | 1145 | /* KEXINIT */ |
1128 | 1146 | ||
1147 | if (options.ciphers != NULL) { | ||
1148 | myproposal[PROPOSAL_ENC_ALGS_CTOS] = | ||
1149 | myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; | ||
1150 | } | ||
1151 | |||
1129 | debug("Sending KEX init."); | 1152 | debug("Sending KEX init."); |
1130 | 1153 | ||
1131 | for (i = 0; i < PROPOSAL_MAX; i++) | 1154 | for (i = 0; i < PROPOSAL_MAX; i++) |
@@ -1185,7 +1208,7 @@ do_ssh2_kex() | |||
1185 | #endif | 1208 | #endif |
1186 | 1209 | ||
1187 | /* generate DH key */ | 1210 | /* generate DH key */ |
1188 | dh = new_dh_group1(); /* XXX depends on 'kex' */ | 1211 | dh = dh_new_group1(); /* XXX depends on 'kex' */ |
1189 | 1212 | ||
1190 | #ifdef DEBUG_KEXDH | 1213 | #ifdef DEBUG_KEXDH |
1191 | fprintf(stderr, "\np= "); | 1214 | fprintf(stderr, "\np= "); |
@@ -1196,6 +1219,8 @@ do_ssh2_kex() | |||
1196 | bignum_print(dh->pub_key); | 1219 | bignum_print(dh->pub_key); |
1197 | fprintf(stderr, "\n"); | 1220 | fprintf(stderr, "\n"); |
1198 | #endif | 1221 | #endif |
1222 | if (!dh_pub_is_valid(dh, dh_client_pub)) | ||
1223 | packet_disconnect("bad client public DH value"); | ||
1199 | 1224 | ||
1200 | klen = DH_size(dh); | 1225 | klen = DH_size(dh); |
1201 | kbuf = xmalloc(klen); | 1226 | kbuf = xmalloc(klen); |
@@ -1267,11 +1292,12 @@ do_ssh2_kex() | |||
1267 | packet_read_expect(&payload_len, SSH2_MSG_NEWKEYS); | 1292 | packet_read_expect(&payload_len, SSH2_MSG_NEWKEYS); |
1268 | debug("GOT SSH2_MSG_NEWKEYS."); | 1293 | debug("GOT SSH2_MSG_NEWKEYS."); |
1269 | 1294 | ||
1295 | #ifdef DEBUG_KEXDH | ||
1270 | /* send 1st encrypted/maced/compressed message */ | 1296 | /* send 1st encrypted/maced/compressed message */ |
1271 | packet_start(SSH2_MSG_IGNORE); | 1297 | packet_start(SSH2_MSG_IGNORE); |
1272 | packet_put_cstring("markus"); | 1298 | packet_put_cstring("markus"); |
1273 | packet_send(); | 1299 | packet_send(); |
1274 | packet_write_wait(); | 1300 | packet_write_wait(); |
1275 | 1301 | #endif | |
1276 | debug("done: KEX2."); | 1302 | debug("done: KEX2."); |
1277 | } | 1303 | } |