diff options
author | Colin Watson <cjwatson@debian.org> | 2003-09-01 18:42:19 +0000 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2003-09-01 18:42:19 +0000 |
commit | 8d6b7f4c46de3feb66f704ab483e51ea1a3bb0e1 (patch) | |
tree | 41fe3dd71501bbec5b0393f1536c925eaee180e9 /kex.c | |
parent | f045c69060bfdd5cf8759a5f29d7008d02e4de5b (diff) | |
parent | 58bfa257481a1c6938ada9bbd38801cc45633fb0 (diff) |
Debian release 3.6p1-1.
Diffstat (limited to 'kex.c')
-rw-r--r-- | kex.c | 66 |
1 files changed, 45 insertions, 21 deletions
@@ -23,7 +23,7 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "includes.h" | 25 | #include "includes.h" |
26 | RCSID("$OpenBSD: kex.c,v 1.51 2002/06/24 14:55:38 markus Exp $"); | 26 | RCSID("$OpenBSD: kex.c,v 1.54 2003/02/16 17:09:57 markus Exp $"); |
27 | 27 | ||
28 | #include <openssl/crypto.h> | 28 | #include <openssl/crypto.h> |
29 | 29 | ||
@@ -44,11 +44,6 @@ RCSID("$OpenBSD: kex.c,v 1.51 2002/06/24 14:55:38 markus Exp $"); | |||
44 | 44 | ||
45 | #define KEX_COOKIE_LEN 16 | 45 | #define KEX_COOKIE_LEN 16 |
46 | 46 | ||
47 | /* Use privilege separation for sshd */ | ||
48 | int use_privsep; | ||
49 | struct monitor *pmonitor; | ||
50 | |||
51 | |||
52 | /* prototype */ | 47 | /* prototype */ |
53 | static void kex_kexinit_finish(Kex *); | 48 | static void kex_kexinit_finish(Kex *); |
54 | static void kex_choose_conf(Kex *); | 49 | static void kex_choose_conf(Kex *); |
@@ -74,7 +69,7 @@ kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX]) | |||
74 | 69 | ||
75 | /* parse buffer and return algorithm proposal */ | 70 | /* parse buffer and return algorithm proposal */ |
76 | static char ** | 71 | static char ** |
77 | kex_buf2prop(Buffer *raw) | 72 | kex_buf2prop(Buffer *raw, int *first_kex_follows) |
78 | { | 73 | { |
79 | Buffer b; | 74 | Buffer b; |
80 | int i; | 75 | int i; |
@@ -94,6 +89,8 @@ kex_buf2prop(Buffer *raw) | |||
94 | } | 89 | } |
95 | /* first kex follows / reserved */ | 90 | /* first kex follows / reserved */ |
96 | i = buffer_get_char(&b); | 91 | i = buffer_get_char(&b); |
92 | if (first_kex_follows != NULL) | ||
93 | *first_kex_follows = i; | ||
97 | debug2("kex_parse_kexinit: first_kex_follows %d ", i); | 94 | debug2("kex_parse_kexinit: first_kex_follows %d ", i); |
98 | i = buffer_get_int(&b); | 95 | i = buffer_get_int(&b); |
99 | debug2("kex_parse_kexinit: reserved %d ", i); | 96 | debug2("kex_parse_kexinit: reserved %d ", i); |
@@ -135,7 +132,7 @@ kex_finish(Kex *kex) | |||
135 | /* packet_write_wait(); */ | 132 | /* packet_write_wait(); */ |
136 | debug("SSH2_MSG_NEWKEYS sent"); | 133 | debug("SSH2_MSG_NEWKEYS sent"); |
137 | 134 | ||
138 | debug("waiting for SSH2_MSG_NEWKEYS"); | 135 | debug("expecting SSH2_MSG_NEWKEYS"); |
139 | packet_read_expect(SSH2_MSG_NEWKEYS); | 136 | packet_read_expect(SSH2_MSG_NEWKEYS); |
140 | packet_check_eom(); | 137 | packet_check_eom(); |
141 | debug("SSH2_MSG_NEWKEYS received"); | 138 | debug("SSH2_MSG_NEWKEYS received"); |
@@ -235,14 +232,10 @@ kex_kexinit_finish(Kex *kex) | |||
235 | 232 | ||
236 | kex_choose_conf(kex); | 233 | kex_choose_conf(kex); |
237 | 234 | ||
238 | switch (kex->kex_type) { | 235 | if (kex->kex_type >= 0 && kex->kex_type < KEX_MAX && |
239 | case DH_GRP1_SHA1: | 236 | kex->kex[kex->kex_type] != NULL) { |
240 | kexdh(kex); | 237 | (kex->kex[kex->kex_type])(kex); |
241 | break; | 238 | } else { |
242 | case DH_GEX_SHA1: | ||
243 | kexgex(kex); | ||
244 | break; | ||
245 | default: | ||
246 | fatal("Unsupported key exchange %d", kex->kex_type); | 239 | fatal("Unsupported key exchange %d", kex->kex_type); |
247 | } | 240 | } |
248 | } | 241 | } |
@@ -299,9 +292,9 @@ choose_kex(Kex *k, char *client, char *server) | |||
299 | if (k->name == NULL) | 292 | if (k->name == NULL) |
300 | fatal("no kex alg"); | 293 | fatal("no kex alg"); |
301 | if (strcmp(k->name, KEX_DH1) == 0) { | 294 | if (strcmp(k->name, KEX_DH1) == 0) { |
302 | k->kex_type = DH_GRP1_SHA1; | 295 | k->kex_type = KEX_DH_GRP1_SHA1; |
303 | } else if (strcmp(k->name, KEX_DHGEX) == 0) { | 296 | } else if (strcmp(k->name, KEX_DHGEX) == 0) { |
304 | k->kex_type = DH_GEX_SHA1; | 297 | k->kex_type = KEX_DH_GEX_SHA1; |
305 | } else | 298 | } else |
306 | fatal("bad kex alg %s", k->name); | 299 | fatal("bad kex alg %s", k->name); |
307 | } | 300 | } |
@@ -317,6 +310,30 @@ choose_hostkeyalg(Kex *k, char *client, char *server) | |||
317 | xfree(hostkeyalg); | 310 | xfree(hostkeyalg); |
318 | } | 311 | } |
319 | 312 | ||
313 | static int | ||
314 | proposals_match(char *my[PROPOSAL_MAX], char *peer[PROPOSAL_MAX]) | ||
315 | { | ||
316 | static int check[] = { | ||
317 | PROPOSAL_KEX_ALGS, PROPOSAL_SERVER_HOST_KEY_ALGS, -1 | ||
318 | }; | ||
319 | int *idx; | ||
320 | char *p; | ||
321 | |||
322 | for (idx = &check[0]; *idx != -1; idx++) { | ||
323 | if ((p = strchr(my[*idx], ',')) != NULL) | ||
324 | *p = '\0'; | ||
325 | if ((p = strchr(peer[*idx], ',')) != NULL) | ||
326 | *p = '\0'; | ||
327 | if (strcmp(my[*idx], peer[*idx]) != 0) { | ||
328 | debug2("proposal mismatch: my %s peer %s", | ||
329 | my[*idx], peer[*idx]); | ||
330 | return (0); | ||
331 | } | ||
332 | } | ||
333 | debug2("proposals match"); | ||
334 | return (1); | ||
335 | } | ||
336 | |||
320 | static void | 337 | static void |
321 | kex_choose_conf(Kex *kex) | 338 | kex_choose_conf(Kex *kex) |
322 | { | 339 | { |
@@ -327,9 +344,10 @@ kex_choose_conf(Kex *kex) | |||
327 | int mode; | 344 | int mode; |
328 | int ctos; /* direction: if true client-to-server */ | 345 | int ctos; /* direction: if true client-to-server */ |
329 | int need; | 346 | int need; |
347 | int first_kex_follows, type; | ||
330 | 348 | ||
331 | my = kex_buf2prop(&kex->my); | 349 | my = kex_buf2prop(&kex->my, NULL); |
332 | peer = kex_buf2prop(&kex->peer); | 350 | peer = kex_buf2prop(&kex->peer, &first_kex_follows); |
333 | 351 | ||
334 | if (kex->server) { | 352 | if (kex->server) { |
335 | cprop=peer; | 353 | cprop=peer; |
@@ -373,6 +391,12 @@ kex_choose_conf(Kex *kex) | |||
373 | /* XXX need runden? */ | 391 | /* XXX need runden? */ |
374 | kex->we_need = need; | 392 | kex->we_need = need; |
375 | 393 | ||
394 | /* ignore the next message if the proposals do not match */ | ||
395 | if (first_kex_follows && !proposals_match(my, peer)) { | ||
396 | type = packet_read(); | ||
397 | debug2("skipping next packet (type %u)", type); | ||
398 | } | ||
399 | |||
376 | kex_prop_free(my); | 400 | kex_prop_free(my); |
377 | kex_prop_free(peer); | 401 | kex_prop_free(peer); |
378 | } | 402 | } |
@@ -433,7 +457,7 @@ kex_derive_keys(Kex *kex, u_char *hash, BIGNUM *shared_secret) | |||
433 | for (i = 0; i < NKEYS; i++) | 457 | for (i = 0; i < NKEYS; i++) |
434 | keys[i] = derive_key(kex, 'A'+i, kex->we_need, hash, shared_secret); | 458 | keys[i] = derive_key(kex, 'A'+i, kex->we_need, hash, shared_secret); |
435 | 459 | ||
436 | debug("kex_derive_keys"); | 460 | debug2("kex_derive_keys"); |
437 | for (mode = 0; mode < MODE_MAX; mode++) { | 461 | for (mode = 0; mode < MODE_MAX; mode++) { |
438 | current_keys[mode] = kex->newkeys[mode]; | 462 | current_keys[mode] = kex->newkeys[mode]; |
439 | kex->newkeys[mode] = NULL; | 463 | kex->newkeys[mode] = NULL; |