diff options
-rw-r--r-- | ChangeLog | 17 | ||||
-rw-r--r-- | cipher.c | 6 | ||||
-rw-r--r-- | compat.c | 8 | ||||
-rw-r--r-- | kex.c | 96 | ||||
-rw-r--r-- | kex.h | 13 | ||||
-rw-r--r-- | key.c | 18 | ||||
-rw-r--r-- | myproposal.h | 2 | ||||
-rw-r--r-- | readconf.c | 10 | ||||
-rw-r--r-- | servconf.c | 6 | ||||
-rw-r--r-- | serverloop.c | 51 | ||||
-rw-r--r-- | session.c | 34 | ||||
-rw-r--r-- | ssh.1 | 12 | ||||
-rw-r--r-- | ssh.c | 6 | ||||
-rw-r--r-- | sshconnect2.c | 137 | ||||
-rw-r--r-- | sshd.c | 47 |
15 files changed, 256 insertions, 207 deletions
@@ -2,6 +2,23 @@ | |||
2 | - Define atexit for old Solaris | 2 | - Define atexit for old Solaris |
3 | - Fix buffer overrun in login.c for systems which use syslen in utmpx. | 3 | - Fix buffer overrun in login.c for systems which use syslen in utmpx. |
4 | patch from YOSHIFUJI Hideaki <yoshfuji@cerberus.nemoto.ecei.tohoku.ac.jp> | 4 | patch from YOSHIFUJI Hideaki <yoshfuji@cerberus.nemoto.ecei.tohoku.ac.jp> |
5 | - OpenBSD CVS updates: | ||
6 | - markus@cvs.openbsd.org | ||
7 | [session.c] | ||
8 | make x11-fwd work w/ localhost (xauth add host/unix:11) | ||
9 | [cipher.c compat.c readconf.c servconf.c] | ||
10 | check strtok() != NULL; ok niels@ | ||
11 | [key.c] | ||
12 | fix key_read() for uuencoded keys w/o '=' | ||
13 | [serverloop.c] | ||
14 | group ssh1 vs. ssh2 in serverloop | ||
15 | [kex.c kex.h myproposal.h sshconnect2.c sshd.c] | ||
16 | split kexinit/kexdh, factor out common code | ||
17 | [readconf.c ssh.1 ssh.c] | ||
18 | forwardagent defaults to no, add ssh -A | ||
19 | - theo@cvs.openbsd.org | ||
20 | [session.c] | ||
21 | just some line shortening | ||
5 | 22 | ||
6 | 20000520 | 23 | 20000520 |
7 | - Xauth fix from Markus Friedl <markus.friedl@informatik.uni-erlangen.de> | 24 | - Xauth fix from Markus Friedl <markus.friedl@informatik.uni-erlangen.de> |
@@ -12,7 +12,7 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include "includes.h" | 14 | #include "includes.h" |
15 | RCSID("$Id: cipher.c,v 1.20 2000/04/16 02:31:50 damien Exp $"); | 15 | RCSID("$Id: cipher.c,v 1.21 2000/05/30 03:44:52 damien Exp $"); |
16 | 16 | ||
17 | #include "ssh.h" | 17 | #include "ssh.h" |
18 | #include "cipher.h" | 18 | #include "cipher.h" |
@@ -178,7 +178,7 @@ ciphers_valid(const char *names) | |||
178 | char *p; | 178 | char *p; |
179 | int i; | 179 | int i; |
180 | 180 | ||
181 | if (strcmp(names, "") == 0) | 181 | if (names == NULL || strcmp(names, "") == 0) |
182 | return 0; | 182 | return 0; |
183 | ciphers = xstrdup(names); | 183 | ciphers = xstrdup(names); |
184 | for ((p = strtok(ciphers, CIPHER_SEP)); p; (p = strtok(NULL, CIPHER_SEP))) { | 184 | for ((p = strtok(ciphers, CIPHER_SEP)); p; (p = strtok(NULL, CIPHER_SEP))) { |
@@ -201,6 +201,8 @@ int | |||
201 | cipher_number(const char *name) | 201 | cipher_number(const char *name) |
202 | { | 202 | { |
203 | int i; | 203 | int i; |
204 | if (name == NULL) | ||
205 | return -1; | ||
204 | for (i = 0; i < sizeof(cipher_names) / sizeof(cipher_names[0]); i++) | 206 | for (i = 0; i < sizeof(cipher_names) / sizeof(cipher_names[0]); i++) |
205 | if (strcmp(cipher_names[i], name) == 0 && | 207 | if (strcmp(cipher_names[i], name) == 0 && |
206 | (cipher_mask() & (1 << i))) | 208 | (cipher_mask() & (1 << i))) |
@@ -28,7 +28,7 @@ | |||
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include "includes.h" | 30 | #include "includes.h" |
31 | RCSID("$Id: compat.c,v 1.10 2000/05/09 01:03:00 damien Exp $"); | 31 | RCSID("$Id: compat.c,v 1.11 2000/05/30 03:44:53 damien Exp $"); |
32 | 32 | ||
33 | #include "ssh.h" | 33 | #include "ssh.h" |
34 | #include "packet.h" | 34 | #include "packet.h" |
@@ -80,10 +80,12 @@ compat_datafellows(const char *version) | |||
80 | int | 80 | int |
81 | proto_spec(const char *spec) | 81 | proto_spec(const char *spec) |
82 | { | 82 | { |
83 | char *s = xstrdup(spec); | 83 | char *s, *p; |
84 | char *p; | ||
85 | int ret = SSH_PROTO_UNKNOWN; | 84 | int ret = SSH_PROTO_UNKNOWN; |
86 | 85 | ||
86 | if (spec == NULL) | ||
87 | return ret; | ||
88 | s = xstrdup(spec); | ||
87 | for ((p = strtok(s, SEP)); p; (p = strtok(NULL, SEP))) { | 89 | for ((p = strtok(s, SEP)); p; (p = strtok(NULL, SEP))) { |
88 | switch(atoi(p)) { | 90 | switch(atoi(p)) { |
89 | case 1: | 91 | case 1: |
@@ -28,13 +28,14 @@ | |||
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include "includes.h" | 30 | #include "includes.h" |
31 | RCSID("$Id: kex.c,v 1.8 2000/05/09 01:03:01 damien Exp $"); | 31 | RCSID("$Id: kex.c,v 1.9 2000/05/30 03:44:53 damien Exp $"); |
32 | 32 | ||
33 | #include "ssh.h" | 33 | #include "ssh.h" |
34 | #include "ssh2.h" | 34 | #include "ssh2.h" |
35 | #include "xmalloc.h" | 35 | #include "xmalloc.h" |
36 | #include "buffer.h" | 36 | #include "buffer.h" |
37 | #include "bufaux.h" | 37 | #include "bufaux.h" |
38 | #include "packet.h" | ||
38 | #include "cipher.h" | 39 | #include "cipher.h" |
39 | #include "compat.h" | 40 | #include "compat.h" |
40 | 41 | ||
@@ -49,15 +50,17 @@ RCSID("$Id: kex.c,v 1.8 2000/05/09 01:03:01 damien Exp $"); | |||
49 | 50 | ||
50 | #include "kex.h" | 51 | #include "kex.h" |
51 | 52 | ||
53 | #define KEX_COOKIE_LEN 16 | ||
54 | |||
52 | Buffer * | 55 | Buffer * |
53 | kex_init(char *myproposal[PROPOSAL_MAX]) | 56 | kex_init(char *myproposal[PROPOSAL_MAX]) |
54 | { | 57 | { |
55 | char c = 0; | 58 | int first_kex_packet_follows = 0; |
56 | unsigned char cookie[16]; | 59 | unsigned char cookie[KEX_COOKIE_LEN]; |
57 | u_int32_t rand = 0; | 60 | u_int32_t rand = 0; |
58 | int i; | 61 | int i; |
59 | Buffer *ki = xmalloc(sizeof(*ki)); | 62 | Buffer *ki = xmalloc(sizeof(*ki)); |
60 | for (i = 0; i < 16; i++) { | 63 | for (i = 0; i < KEX_COOKIE_LEN; i++) { |
61 | if (i % 4 == 0) | 64 | if (i % 4 == 0) |
62 | rand = arc4random(); | 65 | rand = arc4random(); |
63 | cookie[i] = rand & 0xff; | 66 | cookie[i] = rand & 0xff; |
@@ -67,11 +70,55 @@ kex_init(char *myproposal[PROPOSAL_MAX]) | |||
67 | buffer_append(ki, (char *)cookie, sizeof cookie); | 70 | buffer_append(ki, (char *)cookie, sizeof cookie); |
68 | for (i = 0; i < PROPOSAL_MAX; i++) | 71 | for (i = 0; i < PROPOSAL_MAX; i++) |
69 | buffer_put_cstring(ki, myproposal[i]); | 72 | buffer_put_cstring(ki, myproposal[i]); |
70 | buffer_append(ki, &c, 1); /* boolean first_kex_packet_follows */ | 73 | buffer_put_char(ki, first_kex_packet_follows); |
71 | buffer_put_int(ki, 0); /* uint32 0 (reserved for future extension) */ | 74 | buffer_put_int(ki, 0); /* uint32 reserved */ |
72 | return ki; | 75 | return ki; |
73 | } | 76 | } |
74 | 77 | ||
78 | /* send kexinit, parse and save reply */ | ||
79 | void | ||
80 | kex_exchange_kexinit( | ||
81 | Buffer *my_kexinit, Buffer *peer_kexint, | ||
82 | char *peer_proposal[PROPOSAL_MAX]) | ||
83 | { | ||
84 | int i; | ||
85 | char *ptr; | ||
86 | int plen; | ||
87 | |||
88 | debug("send KEXINIT"); | ||
89 | packet_start(SSH2_MSG_KEXINIT); | ||
90 | packet_put_raw(buffer_ptr(my_kexinit), buffer_len(my_kexinit)); | ||
91 | packet_send(); | ||
92 | packet_write_wait(); | ||
93 | debug("done"); | ||
94 | |||
95 | /* | ||
96 | * read and save raw KEXINIT payload in buffer. this is used during | ||
97 | * computation of the session_id and the session keys. | ||
98 | */ | ||
99 | debug("wait KEXINIT"); | ||
100 | packet_read_expect(&plen, SSH2_MSG_KEXINIT); | ||
101 | ptr = packet_get_raw(&plen); | ||
102 | buffer_append(peer_kexint, ptr, plen); | ||
103 | |||
104 | /* parse packet and save algorithm proposal */ | ||
105 | /* skip cookie */ | ||
106 | for (i = 0; i < KEX_COOKIE_LEN; i++) | ||
107 | packet_get_char(); | ||
108 | /* extract kex init proposal strings */ | ||
109 | for (i = 0; i < PROPOSAL_MAX; i++) { | ||
110 | peer_proposal[i] = packet_get_string(NULL); | ||
111 | debug("got kexinit: %s", peer_proposal[i]); | ||
112 | } | ||
113 | /* first kex follow / reserved */ | ||
114 | i = packet_get_char(); | ||
115 | debug("first kex follow: %d ", i); | ||
116 | i = packet_get_int(); | ||
117 | debug("reserved: %d ", i); | ||
118 | packet_done(); | ||
119 | debug("done"); | ||
120 | } | ||
121 | |||
75 | /* diffie-hellman-group1-sha1 */ | 122 | /* diffie-hellman-group1-sha1 */ |
76 | 123 | ||
77 | int | 124 | int |
@@ -134,12 +181,6 @@ dh_new_group1() | |||
134 | } | 181 | } |
135 | 182 | ||
136 | void | 183 | void |
137 | bignum_print(BIGNUM *b) | ||
138 | { | ||
139 | BN_print_fp(stderr,b); | ||
140 | } | ||
141 | |||
142 | void | ||
143 | dump_digest(unsigned char *digest, int len) | 184 | dump_digest(unsigned char *digest, int len) |
144 | { | 185 | { |
145 | int i; | 186 | int i; |
@@ -246,10 +287,13 @@ char * | |||
246 | get_match(char *client, char *server) | 287 | get_match(char *client, char *server) |
247 | { | 288 | { |
248 | char *sproposals[MAX_PROP]; | 289 | char *sproposals[MAX_PROP]; |
249 | char *p; | 290 | char *c, *s, *p, *ret; |
250 | int i, j, nproposals; | 291 | int i, j, nproposals; |
251 | 292 | ||
252 | for ((p = strtok(server, SEP)), i=0; p; (p = strtok(NULL, SEP)), i++) { | 293 | c = xstrdup(client); |
294 | s = xstrdup(server); | ||
295 | |||
296 | for ((p = strtok(s, SEP)), i=0; p; (p = strtok(NULL, SEP)), i++) { | ||
253 | if (i < MAX_PROP) | 297 | if (i < MAX_PROP) |
254 | sproposals[i] = p; | 298 | sproposals[i] = p; |
255 | else | 299 | else |
@@ -257,11 +301,18 @@ get_match(char *client, char *server) | |||
257 | } | 301 | } |
258 | nproposals = i; | 302 | nproposals = i; |
259 | 303 | ||
260 | for ((p = strtok(client, SEP)), i=0; p; (p = strtok(NULL, SEP)), i++) { | 304 | for ((p = strtok(c, SEP)), i=0; p; (p = strtok(NULL, SEP)), i++) { |
261 | for (j = 0; j < nproposals; j++) | 305 | for (j = 0; j < nproposals; j++) { |
262 | if (strcmp(p, sproposals[j]) == 0) | 306 | if (strcmp(p, sproposals[j]) == 0) { |
263 | return xstrdup(p); | 307 | ret = xstrdup(p); |
308 | xfree(c); | ||
309 | xfree(s); | ||
310 | return ret; | ||
311 | } | ||
312 | } | ||
264 | } | 313 | } |
314 | xfree(c); | ||
315 | xfree(s); | ||
265 | return NULL; | 316 | return NULL; |
266 | } | 317 | } |
267 | void | 318 | void |
@@ -355,7 +406,6 @@ choose_hostkeyalg(Kex *k, char *client, char *server) | |||
355 | Kex * | 406 | Kex * |
356 | kex_choose_conf(char *cprop[PROPOSAL_MAX], char *sprop[PROPOSAL_MAX], int server) | 407 | kex_choose_conf(char *cprop[PROPOSAL_MAX], char *sprop[PROPOSAL_MAX], int server) |
357 | { | 408 | { |
358 | int i; | ||
359 | int mode; | 409 | int mode; |
360 | int ctos; /* direction: if true client-to-server */ | 410 | int ctos; /* direction: if true client-to-server */ |
361 | int need; | 411 | int need; |
@@ -383,10 +433,6 @@ kex_choose_conf(char *cprop[PROPOSAL_MAX], char *sprop[PROPOSAL_MAX], int server | |||
383 | choose_kex(k, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]); | 433 | choose_kex(k, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]); |
384 | choose_hostkeyalg(k, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS], | 434 | choose_hostkeyalg(k, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS], |
385 | sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]); | 435 | sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]); |
386 | for (i = 0; i < PROPOSAL_MAX; i++) { | ||
387 | xfree(cprop[i]); | ||
388 | xfree(sprop[i]); | ||
389 | } | ||
390 | need = 0; | 436 | need = 0; |
391 | for (mode = 0; mode < MODE_MAX; mode++) { | 437 | for (mode = 0; mode < MODE_MAX; mode++) { |
392 | if (need < k->enc[mode].key_len) | 438 | if (need < k->enc[mode].key_len) |
@@ -396,9 +442,7 @@ kex_choose_conf(char *cprop[PROPOSAL_MAX], char *sprop[PROPOSAL_MAX], int server | |||
396 | if (need < k->mac[mode].key_len) | 442 | if (need < k->mac[mode].key_len) |
397 | need = k->mac[mode].key_len; | 443 | need = k->mac[mode].key_len; |
398 | } | 444 | } |
399 | /* need runden? */ | 445 | /* XXX need runden? */ |
400 | #define WE_NEED 32 | ||
401 | k->we_need = WE_NEED; | ||
402 | k->we_need = need; | 446 | k->we_need = need; |
403 | return k; | 447 | return k; |
404 | } | 448 | } |
@@ -91,12 +91,17 @@ struct Kex { | |||
91 | }; | 91 | }; |
92 | 92 | ||
93 | Buffer *kex_init(char *myproposal[PROPOSAL_MAX]); | 93 | Buffer *kex_init(char *myproposal[PROPOSAL_MAX]); |
94 | int dh_pub_is_valid(DH *dh, BIGNUM *dh_pub); | 94 | void |
95 | DH *dh_new_group1(); | 95 | kex_exchange_kexinit( |
96 | Kex *kex_choose_conf(char *cprop[PROPOSAL_MAX], char *sprop[PROPOSAL_MAX], int server); | 96 | Buffer *my_kexinit, Buffer *peer_kexint, |
97 | char *peer_proposal[PROPOSAL_MAX]); | ||
98 | Kex * | ||
99 | kex_choose_conf(char *cprop[PROPOSAL_MAX], | ||
100 | char *sprop[PROPOSAL_MAX], int server); | ||
97 | int kex_derive_keys(Kex *k, unsigned char *hash, BIGNUM *shared_secret); | 101 | int kex_derive_keys(Kex *k, unsigned char *hash, BIGNUM *shared_secret); |
98 | void bignum_print(BIGNUM *b); | ||
99 | void packet_set_kex(Kex *k); | 102 | void packet_set_kex(Kex *k); |
103 | int dh_pub_is_valid(DH *dh, BIGNUM *dh_pub); | ||
104 | DH *dh_new_group1(); | ||
100 | 105 | ||
101 | unsigned char * | 106 | unsigned char * |
102 | kex_hash( | 107 | kex_hash( |
@@ -256,12 +256,14 @@ key_read(Key *ret, char **cpp) | |||
256 | blob = xmalloc(len); | 256 | blob = xmalloc(len); |
257 | n = uudecode(cp, blob, len); | 257 | n = uudecode(cp, blob, len); |
258 | if (n < 0) { | 258 | if (n < 0) { |
259 | error("uudecode %s failed", cp); | 259 | error("key_read: uudecode %s failed", cp); |
260 | return 0; | 260 | return 0; |
261 | } | 261 | } |
262 | k = dsa_key_from_blob(blob, n); | 262 | k = dsa_key_from_blob(blob, n); |
263 | if (k == NULL) | 263 | if (k == NULL) { |
264 | return 0; | 264 | error("key_read: dsa_key_from_blob %s failed", cp); |
265 | return 0; | ||
266 | } | ||
265 | xfree(blob); | 267 | xfree(blob); |
266 | if (ret->dsa != NULL) | 268 | if (ret->dsa != NULL) |
267 | DSA_free(ret->dsa); | 269 | DSA_free(ret->dsa); |
@@ -269,10 +271,12 @@ key_read(Key *ret, char **cpp) | |||
269 | k->dsa = NULL; | 271 | k->dsa = NULL; |
270 | key_free(k); | 272 | key_free(k); |
271 | bits = BN_num_bits(ret->dsa->p); | 273 | bits = BN_num_bits(ret->dsa->p); |
272 | cp = strchr(cp, '='); | 274 | /* advance cp: skip whitespace and data */ |
273 | if (cp == NULL) | 275 | while (*cp == ' ' || *cp == '\t') |
274 | return 0; | 276 | cp++; |
275 | *cpp = cp + 1; | 277 | while (*cp != '\0' && *cp != ' ' && *cp != '\t') |
278 | cp++; | ||
279 | *cpp = cp; | ||
276 | break; | 280 | break; |
277 | default: | 281 | default: |
278 | fatal("key_read: bad key type: %d", ret->type); | 282 | fatal("key_read: bad key type: %d", ret->type); |
diff --git a/myproposal.h b/myproposal.h index 8b2417972..9611d8951 100644 --- a/myproposal.h +++ b/myproposal.h | |||
@@ -6,7 +6,7 @@ | |||
6 | #define KEX_DEFAULT_LANG "" | 6 | #define KEX_DEFAULT_LANG "" |
7 | 7 | ||
8 | 8 | ||
9 | static const char *myproposal[PROPOSAL_MAX] = { | 9 | static char *myproposal[PROPOSAL_MAX] = { |
10 | KEX_DEFAULT_KEX, | 10 | KEX_DEFAULT_KEX, |
11 | KEX_DEFAULT_PK_ALG, | 11 | KEX_DEFAULT_PK_ALG, |
12 | KEX_DEFAULT_ENCRYPT, | 12 | KEX_DEFAULT_ENCRYPT, |
diff --git a/readconf.c b/readconf.c index 9c5638b07..d7011d7f7 100644 --- a/readconf.c +++ b/readconf.c | |||
@@ -14,7 +14,7 @@ | |||
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include "includes.h" | 16 | #include "includes.h" |
17 | RCSID("$Id: readconf.c,v 1.14 2000/05/09 01:03:01 damien Exp $"); | 17 | RCSID("$Id: readconf.c,v 1.15 2000/05/30 03:44:53 damien Exp $"); |
18 | 18 | ||
19 | #include "ssh.h" | 19 | #include "ssh.h" |
20 | #include "cipher.h" | 20 | #include "cipher.h" |
@@ -464,6 +464,8 @@ parse_int: | |||
464 | case oCipher: | 464 | case oCipher: |
465 | intptr = &options->cipher; | 465 | intptr = &options->cipher; |
466 | cp = strtok(NULL, WHITESPACE); | 466 | cp = strtok(NULL, WHITESPACE); |
467 | if (!cp) | ||
468 | fatal("%.200s line %d: Missing argument.", filename, linenum); | ||
467 | value = cipher_number(cp); | 469 | value = cipher_number(cp); |
468 | if (value == -1) | 470 | if (value == -1) |
469 | fatal("%.200s line %d: Bad cipher '%s'.", | 471 | fatal("%.200s line %d: Bad cipher '%s'.", |
@@ -474,6 +476,8 @@ parse_int: | |||
474 | 476 | ||
475 | case oCiphers: | 477 | case oCiphers: |
476 | cp = strtok(NULL, WHITESPACE); | 478 | cp = strtok(NULL, WHITESPACE); |
479 | if (!cp) | ||
480 | fatal("%.200s line %d: Missing argument.", filename, linenum); | ||
477 | if (!ciphers_valid(cp)) | 481 | if (!ciphers_valid(cp)) |
478 | fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.", | 482 | fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.", |
479 | filename, linenum, cp ? cp : "<NONE>"); | 483 | filename, linenum, cp ? cp : "<NONE>"); |
@@ -484,6 +488,8 @@ parse_int: | |||
484 | case oProtocol: | 488 | case oProtocol: |
485 | intptr = &options->protocol; | 489 | intptr = &options->protocol; |
486 | cp = strtok(NULL, WHITESPACE); | 490 | cp = strtok(NULL, WHITESPACE); |
491 | if (!cp) | ||
492 | fatal("%.200s line %d: Missing argument.", filename, linenum); | ||
487 | value = proto_spec(cp); | 493 | value = proto_spec(cp); |
488 | if (value == SSH_PROTO_UNKNOWN) | 494 | if (value == SSH_PROTO_UNKNOWN) |
489 | fatal("%.200s line %d: Bad protocol spec '%s'.", | 495 | fatal("%.200s line %d: Bad protocol spec '%s'.", |
@@ -691,7 +697,7 @@ void | |||
691 | fill_default_options(Options * options) | 697 | fill_default_options(Options * options) |
692 | { | 698 | { |
693 | if (options->forward_agent == -1) | 699 | if (options->forward_agent == -1) |
694 | options->forward_agent = 1; | 700 | options->forward_agent = 0; |
695 | if (options->forward_x11 == -1) | 701 | if (options->forward_x11 == -1) |
696 | options->forward_x11 = 0; | 702 | options->forward_x11 = 0; |
697 | if (options->gateway_ports == -1) | 703 | if (options->gateway_ports == -1) |
diff --git a/servconf.c b/servconf.c index 05630c766..1aa4fe06d 100644 --- a/servconf.c +++ b/servconf.c | |||
@@ -12,7 +12,7 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include "includes.h" | 14 | #include "includes.h" |
15 | RCSID("$Id: servconf.c,v 1.16 2000/05/09 01:03:01 damien Exp $"); | 15 | RCSID("$Id: servconf.c,v 1.17 2000/05/30 03:44:53 damien Exp $"); |
16 | 16 | ||
17 | #include "ssh.h" | 17 | #include "ssh.h" |
18 | #include "servconf.h" | 18 | #include "servconf.h" |
@@ -588,6 +588,8 @@ parse_flag: | |||
588 | 588 | ||
589 | case sCiphers: | 589 | case sCiphers: |
590 | cp = strtok(NULL, WHITESPACE); | 590 | cp = strtok(NULL, WHITESPACE); |
591 | if (!cp) | ||
592 | fatal("%s line %d: Missing argument.", filename, linenum); | ||
591 | if (!ciphers_valid(cp)) | 593 | if (!ciphers_valid(cp)) |
592 | fatal("%s line %d: Bad SSH2 cipher spec '%s'.", | 594 | fatal("%s line %d: Bad SSH2 cipher spec '%s'.", |
593 | filename, linenum, cp ? cp : "<NONE>"); | 595 | filename, linenum, cp ? cp : "<NONE>"); |
@@ -598,6 +600,8 @@ parse_flag: | |||
598 | case sProtocol: | 600 | case sProtocol: |
599 | intptr = &options->protocol; | 601 | intptr = &options->protocol; |
600 | cp = strtok(NULL, WHITESPACE); | 602 | cp = strtok(NULL, WHITESPACE); |
603 | if (!cp) | ||
604 | fatal("%s line %d: Missing argument.", filename, linenum); | ||
601 | value = proto_spec(cp); | 605 | value = proto_spec(cp); |
602 | if (value == SSH_PROTO_UNKNOWN) | 606 | if (value == SSH_PROTO_UNKNOWN) |
603 | fatal("%s line %d: Bad protocol spec '%s'.", | 607 | fatal("%s line %d: Bad protocol spec '%s'.", |
diff --git a/serverloop.c b/serverloop.c index 977ed41f6..b08fcfd92 100644 --- a/serverloop.c +++ b/serverloop.c | |||
@@ -164,33 +164,37 @@ retry_select: | |||
164 | 164 | ||
165 | /* Initialize select() masks. */ | 165 | /* Initialize select() masks. */ |
166 | FD_ZERO(readset); | 166 | FD_ZERO(readset); |
167 | FD_ZERO(writeset); | ||
167 | 168 | ||
168 | /* | ||
169 | * Read packets from the client unless we have too much buffered | ||
170 | * stdin or channel data. | ||
171 | */ | ||
172 | if (compat20) { | 169 | if (compat20) { |
173 | /* wrong: bad condition XXX */ | 170 | /* wrong: bad condition XXX */ |
174 | if (channel_not_very_much_buffered_data()) | 171 | if (channel_not_very_much_buffered_data()) |
175 | FD_SET(connection_in, readset); | 172 | FD_SET(connection_in, readset); |
176 | } else { | 173 | } else { |
177 | if (buffer_len(&stdin_buffer) < 4096 && | 174 | /* |
175 | * Read packets from the client unless we have too much | ||
176 | * buffered stdin or channel data. | ||
177 | */ | ||
178 | if (buffer_len(&stdin_buffer) < buffer_high && | ||
178 | channel_not_very_much_buffered_data()) | 179 | channel_not_very_much_buffered_data()) |
179 | FD_SET(connection_in, readset); | 180 | FD_SET(connection_in, readset); |
181 | /* | ||
182 | * If there is not too much data already buffered going to | ||
183 | * the client, try to get some more data from the program. | ||
184 | */ | ||
185 | if (packet_not_very_much_data_to_write()) { | ||
186 | if (!fdout_eof) | ||
187 | FD_SET(fdout, readset); | ||
188 | if (!fderr_eof) | ||
189 | FD_SET(fderr, readset); | ||
190 | } | ||
191 | /* | ||
192 | * If we have buffered data, try to write some of that data | ||
193 | * to the program. | ||
194 | */ | ||
195 | if (fdin != -1 && buffer_len(&stdin_buffer) > 0) | ||
196 | FD_SET(fdin, writeset); | ||
180 | } | 197 | } |
181 | |||
182 | /* | ||
183 | * If there is not too much data already buffered going to the | ||
184 | * client, try to get some more data from the program. | ||
185 | */ | ||
186 | if (!compat20 && packet_not_very_much_data_to_write()) { | ||
187 | if (!fdout_eof) | ||
188 | FD_SET(fdout, readset); | ||
189 | if (!fderr_eof) | ||
190 | FD_SET(fderr, readset); | ||
191 | } | ||
192 | FD_ZERO(writeset); | ||
193 | |||
194 | /* Set masks for channel descriptors. */ | 198 | /* Set masks for channel descriptors. */ |
195 | channel_prepare_select(readset, writeset); | 199 | channel_prepare_select(readset, writeset); |
196 | 200 | ||
@@ -201,11 +205,6 @@ retry_select: | |||
201 | if (packet_have_data_to_write()) | 205 | if (packet_have_data_to_write()) |
202 | FD_SET(connection_out, writeset); | 206 | FD_SET(connection_out, writeset); |
203 | 207 | ||
204 | /* If we have buffered data, try to write some of that data to the | ||
205 | program. */ | ||
206 | if (!compat20 && fdin != -1 && buffer_len(&stdin_buffer) > 0) | ||
207 | FD_SET(fdin, writeset); | ||
208 | |||
209 | /* Update the maximum descriptor number if appropriate. */ | 208 | /* Update the maximum descriptor number if appropriate. */ |
210 | if (channel_max_fd() > max_fd) | 209 | if (channel_max_fd() > max_fd) |
211 | max_fd = channel_max_fd(); | 210 | max_fd = channel_max_fd(); |
@@ -377,6 +376,7 @@ process_buffered_input_packets() | |||
377 | void | 376 | void |
378 | server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) | 377 | server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) |
379 | { | 378 | { |
379 | fd_set readset, writeset; | ||
380 | int wait_status; /* Status returned by wait(). */ | 380 | int wait_status; /* Status returned by wait(). */ |
381 | pid_t wait_pid; /* pid returned by wait(). */ | 381 | pid_t wait_pid; /* pid returned by wait(). */ |
382 | int waiting_termination = 0; /* Have displayed waiting close message. */ | 382 | int waiting_termination = 0; /* Have displayed waiting close message. */ |
@@ -445,7 +445,6 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) | |||
445 | 445 | ||
446 | /* Main loop of the server for the interactive session mode. */ | 446 | /* Main loop of the server for the interactive session mode. */ |
447 | for (;;) { | 447 | for (;;) { |
448 | fd_set readset, writeset; | ||
449 | 448 | ||
450 | /* Process buffered packets from the client. */ | 449 | /* Process buffered packets from the client. */ |
451 | process_buffered_input_packets(); | 450 | process_buffered_input_packets(); |
@@ -717,6 +716,9 @@ input_direct_tcpip(void) | |||
717 | originator = packet_get_string(NULL); | 716 | originator = packet_get_string(NULL); |
718 | originator_port = packet_get_int(); | 717 | originator_port = packet_get_int(); |
719 | packet_done(); | 718 | packet_done(); |
719 | |||
720 | debug("open direct-tcpip: from %s port %d to %s port %d", | ||
721 | originator, originator_port, target, target_port); | ||
720 | /* XXX check permission */ | 722 | /* XXX check permission */ |
721 | sock = channel_connect_to(target, target_port); | 723 | sock = channel_connect_to(target, target_port); |
722 | xfree(target); | 724 | xfree(target); |
@@ -768,7 +770,6 @@ server_input_channel_open(int type, int plen) | |||
768 | channel_free(id); | 770 | channel_free(id); |
769 | } | 771 | } |
770 | } else if (strcmp(ctype, "direct-tcpip") == 0) { | 772 | } else if (strcmp(ctype, "direct-tcpip") == 0) { |
771 | debug("open direct-tcpip"); | ||
772 | id = input_direct_tcpip(); | 773 | id = input_direct_tcpip(); |
773 | if (id >= 0) | 774 | if (id >= 0) |
774 | c = channel_lookup(id); | 775 | c = channel_lookup(id); |
@@ -8,7 +8,7 @@ | |||
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include "includes.h" | 10 | #include "includes.h" |
11 | RCSID("$OpenBSD: session.c,v 1.12 2000/05/03 18:03:07 markus Exp $"); | 11 | RCSID("$OpenBSD: session.c,v 1.14 2000/05/25 03:10:18 deraadt Exp $"); |
12 | 12 | ||
13 | #include "xmalloc.h" | 13 | #include "xmalloc.h" |
14 | #include "ssh.h" | 14 | #include "ssh.h" |
@@ -645,7 +645,8 @@ do_exec_pty(Session *s, const char *command, struct passwd * pw) | |||
645 | } | 645 | } |
646 | #endif | 646 | #endif |
647 | /* Do common processing for the child, such as execing the command. */ | 647 | /* Do common processing for the child, such as execing the command. */ |
648 | do_child(command, pw, s->term, s->display, s->auth_proto, s->auth_data, s->tty); | 648 | do_child(command, pw, s->term, s->display, s->auth_proto, |
649 | s->auth_data, s->tty); | ||
649 | /* NOTREACHED */ | 650 | /* NOTREACHED */ |
650 | } | 651 | } |
651 | if (pid < 0) | 652 | if (pid < 0) |
@@ -749,7 +750,10 @@ read_environment_file(char ***env, unsigned int *envsize, | |||
749 | fprintf(stderr, "Bad line in %.100s: %.200s\n", filename, buf); | 750 | fprintf(stderr, "Bad line in %.100s: %.200s\n", filename, buf); |
750 | continue; | 751 | continue; |
751 | } | 752 | } |
752 | /* Replace the equals sign by nul, and advance value to the value string. */ | 753 | /* |
754 | * Replace the equals sign by nul, and advance value to | ||
755 | * the value string. | ||
756 | */ | ||
753 | *value = '\0'; | 757 | *value = '\0'; |
754 | value++; | 758 | value++; |
755 | child_set_env(env, envsize, cp, value); | 759 | child_set_env(env, envsize, cp, value); |
@@ -948,7 +952,8 @@ do_child(const char *command, struct passwd * pw, const char *term, | |||
948 | 952 | ||
949 | /* read $HOME/.ssh/environment. */ | 953 | /* read $HOME/.ssh/environment. */ |
950 | if (!options.use_login) { | 954 | if (!options.use_login) { |
951 | snprintf(buf, sizeof buf, "%.200s/.ssh/environment", pw->pw_dir); | 955 | snprintf(buf, sizeof buf, "%.200s/.ssh/environment", |
956 | pw->pw_dir); | ||
952 | read_environment_file(&env, &envsize, buf); | 957 | read_environment_file(&env, &envsize, buf); |
953 | } | 958 | } |
954 | if (debug_flag) { | 959 | if (debug_flag) { |
@@ -1037,21 +1042,27 @@ do_child(const char *command, struct passwd * pw, const char *term, | |||
1037 | if (auth_proto != NULL && auth_data != NULL) { | 1042 | if (auth_proto != NULL && auth_data != NULL) { |
1038 | char *screen = strchr(display, ':'); | 1043 | char *screen = strchr(display, ':'); |
1039 | if (debug_flag) { | 1044 | if (debug_flag) { |
1040 | fprintf(stderr, "Running %.100s add %.100s %.100s %.100s\n", | 1045 | fprintf(stderr, |
1046 | "Running %.100s add %.100s %.100s %.100s\n", | ||
1041 | XAUTH_PATH, display, auth_proto, auth_data); | 1047 | XAUTH_PATH, display, auth_proto, auth_data); |
1042 | if (screen != NULL) | 1048 | if (screen != NULL) |
1043 | fprintf(stderr, "Adding %.*s/unix%s %s %s\n", | 1049 | fprintf(stderr, |
1044 | screen-display, display, screen, auth_proto, auth_data); | 1050 | "Adding %.*s/unix%s %s %s\n", |
1051 | screen-display, display, | ||
1052 | screen, auth_proto, auth_data); | ||
1045 | } | 1053 | } |
1046 | f = popen(XAUTH_PATH " -q -", "w"); | 1054 | f = popen(XAUTH_PATH " -q -", "w"); |
1047 | if (f) { | 1055 | if (f) { |
1048 | fprintf(f, "add %s %s %s\n", display, auth_proto, auth_data); | 1056 | fprintf(f, "add %s %s %s\n", display, |
1057 | auth_proto, auth_data); | ||
1049 | if (screen != NULL) | 1058 | if (screen != NULL) |
1050 | fprintf(f, "add %.*s/unix%s %s %s\n", | 1059 | fprintf(f, "add %.*s/unix%s %s %s\n", |
1051 | screen-display, display, screen, auth_proto, auth_data); | 1060 | screen-display, display, |
1061 | screen, auth_proto, auth_data); | ||
1052 | pclose(f); | 1062 | pclose(f); |
1053 | } else | 1063 | } else |
1054 | fprintf(stderr, "Could not run %s -q -\n", XAUTH_PATH); | 1064 | fprintf(stderr, "Could not run %s -q -\n", |
1065 | XAUTH_PATH); | ||
1055 | } | 1066 | } |
1056 | } | 1067 | } |
1057 | #endif /* XAUTH_PATH */ | 1068 | #endif /* XAUTH_PATH */ |
@@ -1081,7 +1092,8 @@ do_child(const char *command, struct passwd * pw, const char *term, | |||
1081 | struct stat mailstat; | 1092 | struct stat mailstat; |
1082 | mailbox = getenv("MAIL"); | 1093 | mailbox = getenv("MAIL"); |
1083 | if (mailbox != NULL) { | 1094 | if (mailbox != NULL) { |
1084 | if (stat(mailbox, &mailstat) != 0 || mailstat.st_size == 0) | 1095 | if (stat(mailbox, &mailstat) != 0 || |
1096 | mailstat.st_size == 0) | ||
1085 | printf("No mail.\n"); | 1097 | printf("No mail.\n"); |
1086 | else if (mailstat.st_mtime < mailstat.st_atime) | 1098 | else if (mailstat.st_mtime < mailstat.st_atime) |
1087 | printf("You have mail.\n"); | 1099 | printf("You have mail.\n"); |
@@ -9,7 +9,7 @@ | |||
9 | .\" | 9 | .\" |
10 | .\" Created: Sat Apr 22 21:55:14 1995 ylo | 10 | .\" Created: Sat Apr 22 21:55:14 1995 ylo |
11 | .\" | 11 | .\" |
12 | .\" $Id: ssh.1,v 1.26 2000/05/17 12:34:24 damien Exp $ | 12 | .\" $Id: ssh.1,v 1.27 2000/05/30 03:44:54 damien Exp $ |
13 | .\" | 13 | .\" |
14 | .Dd September 25, 1999 | 14 | .Dd September 25, 1999 |
15 | .Dt SSH 1 | 15 | .Dt SSH 1 |
@@ -24,7 +24,7 @@ | |||
24 | .Op Ar command | 24 | .Op Ar command |
25 | .Pp | 25 | .Pp |
26 | .Nm ssh | 26 | .Nm ssh |
27 | .Op Fl afgknqtvxCNPTX246 | 27 | .Op Fl afgknqtvxACNPTX246 |
28 | .Op Fl c Ar cipher_spec | 28 | .Op Fl c Ar cipher_spec |
29 | .Op Fl e Ar escape_char | 29 | .Op Fl e Ar escape_char |
30 | .Op Fl i Ar identity_file | 30 | .Op Fl i Ar identity_file |
@@ -332,7 +332,9 @@ host key is not known or has changed. | |||
332 | .Bl -tag -width Ds | 332 | .Bl -tag -width Ds |
333 | .It Fl a | 333 | .It Fl a |
334 | Disables forwarding of the authentication agent connection. | 334 | Disables forwarding of the authentication agent connection. |
335 | This may also be specified on a per-host basis in the configuration file. | 335 | .It Fl A |
336 | Enables forwarding of the authentication agent connection. | ||
337 | This can also be specified on a per-host basis in a configuration file. | ||
336 | .It Fl c Ar blowfish|3des | 338 | .It Fl c Ar blowfish|3des |
337 | Selects the cipher to use for encrypting the session. | 339 | Selects the cipher to use for encrypting the session. |
338 | .Ar 3des | 340 | .Ar 3des |
@@ -460,9 +462,9 @@ The verbose mode is also used to display | |||
460 | challenges, if the user entered "s/key" as password. | 462 | challenges, if the user entered "s/key" as password. |
461 | .It Fl x | 463 | .It Fl x |
462 | Disables X11 forwarding. | 464 | Disables X11 forwarding. |
463 | This can also be specified on a per-host basis in a configuration file. | ||
464 | .It Fl X | 465 | .It Fl X |
465 | Enables X11 forwarding. | 466 | Enables X11 forwarding. |
467 | This can also be specified on a per-host basis in a configuration file. | ||
466 | .It Fl C | 468 | .It Fl C |
467 | Requests compression of all data (including stdin, stdout, stderr, and | 469 | Requests compression of all data (including stdin, stdout, stderr, and |
468 | data for forwarded X11 and TCP/IP connections). | 470 | data for forwarded X11 and TCP/IP connections). |
@@ -671,6 +673,8 @@ The argument must be | |||
671 | .Dq yes | 673 | .Dq yes |
672 | or | 674 | or |
673 | .Dq no . | 675 | .Dq no . |
676 | The default is | ||
677 | .Dq no . | ||
674 | .It Cm ForwardX11 | 678 | .It Cm ForwardX11 |
675 | Specifies whether X11 connections will be automatically redirected | 679 | Specifies whether X11 connections will be automatically redirected |
676 | over the secure channel and | 680 | over the secure channel and |
@@ -11,7 +11,7 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include "includes.h" | 13 | #include "includes.h" |
14 | RCSID("$Id: ssh.c,v 1.32 2000/05/20 05:22:37 damien Exp $"); | 14 | RCSID("$Id: ssh.c,v 1.33 2000/05/30 03:44:54 damien Exp $"); |
15 | 15 | ||
16 | #include <openssl/evp.h> | 16 | #include <openssl/evp.h> |
17 | #include <openssl/dsa.h> | 17 | #include <openssl/dsa.h> |
@@ -116,6 +116,7 @@ usage() | |||
116 | fprintf(stderr, "Options:\n"); | 116 | fprintf(stderr, "Options:\n"); |
117 | fprintf(stderr, " -l user Log in using this user name.\n"); | 117 | fprintf(stderr, " -l user Log in using this user name.\n"); |
118 | fprintf(stderr, " -n Redirect input from /dev/null.\n"); | 118 | fprintf(stderr, " -n Redirect input from /dev/null.\n"); |
119 | fprintf(stderr, " -A Enable authentication agent forwarding.\n"); | ||
119 | fprintf(stderr, " -a Disable authentication agent forwarding.\n"); | 120 | fprintf(stderr, " -a Disable authentication agent forwarding.\n"); |
120 | #ifdef AFS | 121 | #ifdef AFS |
121 | fprintf(stderr, " -k Disable Kerberos ticket and AFS token forwarding.\n"); | 122 | fprintf(stderr, " -k Disable Kerberos ticket and AFS token forwarding.\n"); |
@@ -315,6 +316,9 @@ main(int ac, char **av) | |||
315 | case 'a': | 316 | case 'a': |
316 | options.forward_agent = 0; | 317 | options.forward_agent = 0; |
317 | break; | 318 | break; |
319 | case 'A': | ||
320 | options.forward_agent = 1; | ||
321 | break; | ||
318 | #ifdef AFS | 322 | #ifdef AFS |
319 | case 'k': | 323 | case 'k': |
320 | options.kerberos_tgt_passing = 0; | 324 | options.kerberos_tgt_passing = 0; |
diff --git a/sshconnect2.c b/sshconnect2.c index 99ffb2c47..0abcf89a0 100644 --- a/sshconnect2.c +++ b/sshconnect2.c | |||
@@ -28,7 +28,7 @@ | |||
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include "includes.h" | 30 | #include "includes.h" |
31 | RCSID("$OpenBSD: sshconnect2.c,v 1.10 2000/05/08 17:42:25 markus Exp $"); | 31 | RCSID("$OpenBSD: sshconnect2.c,v 1.11 2000/05/25 20:45:20 markus Exp $"); |
32 | 32 | ||
33 | #include <openssl/bn.h> | 33 | #include <openssl/bn.h> |
34 | #include <openssl/rsa.h> | 34 | #include <openssl/rsa.h> |
@@ -68,16 +68,12 @@ unsigned char *session_id2 = NULL; | |||
68 | int session_id2_len = 0; | 68 | int session_id2_len = 0; |
69 | 69 | ||
70 | void | 70 | void |
71 | ssh_kex2(char *host, struct sockaddr *hostaddr) | 71 | ssh_kex_dh(Kex *kex, char *host, struct sockaddr *hostaddr, |
72 | Buffer *client_kexinit, Buffer *server_kexinit) | ||
72 | { | 73 | { |
73 | Kex *kex; | 74 | int i; |
74 | char *cprop[PROPOSAL_MAX]; | 75 | int plen, dlen; |
75 | char *sprop[PROPOSAL_MAX]; | ||
76 | Buffer *client_kexinit; | ||
77 | Buffer *server_kexinit; | ||
78 | int payload_len, dlen; | ||
79 | unsigned int klen, kout; | 76 | unsigned int klen, kout; |
80 | char *ptr; | ||
81 | char *signature = NULL; | 77 | char *signature = NULL; |
82 | unsigned int slen; | 78 | unsigned int slen; |
83 | char *server_host_key_blob = NULL; | 79 | char *server_host_key_blob = NULL; |
@@ -86,72 +82,10 @@ ssh_kex2(char *host, struct sockaddr *hostaddr) | |||
86 | DH *dh; | 82 | DH *dh; |
87 | BIGNUM *dh_server_pub = 0; | 83 | BIGNUM *dh_server_pub = 0; |
88 | BIGNUM *shared_secret = 0; | 84 | BIGNUM *shared_secret = 0; |
89 | int i; | ||
90 | unsigned char *kbuf; | 85 | unsigned char *kbuf; |
91 | unsigned char *hash; | 86 | unsigned char *hash; |
92 | 87 | ||
93 | /* KEXINIT */ | ||
94 | |||
95 | debug("Sending KEX init."); | ||
96 | if (options.ciphers != NULL) { | ||
97 | myproposal[PROPOSAL_ENC_ALGS_CTOS] = | ||
98 | myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; | ||
99 | } else if (options.cipher == SSH_CIPHER_3DES) { | ||
100 | myproposal[PROPOSAL_ENC_ALGS_CTOS] = | ||
101 | myproposal[PROPOSAL_ENC_ALGS_STOC] = | ||
102 | cipher_name(SSH_CIPHER_3DES_CBC); | ||
103 | } else if (options.cipher == SSH_CIPHER_BLOWFISH) { | ||
104 | myproposal[PROPOSAL_ENC_ALGS_CTOS] = | ||
105 | myproposal[PROPOSAL_ENC_ALGS_STOC] = | ||
106 | cipher_name(SSH_CIPHER_BLOWFISH_CBC); | ||
107 | } | ||
108 | if (options.compression) { | ||
109 | myproposal[PROPOSAL_COMP_ALGS_CTOS] = "zlib"; | ||
110 | myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib"; | ||
111 | } else { | ||
112 | myproposal[PROPOSAL_COMP_ALGS_CTOS] = "none"; | ||
113 | myproposal[PROPOSAL_COMP_ALGS_STOC] = "none"; | ||
114 | } | ||
115 | for (i = 0; i < PROPOSAL_MAX; i++) | ||
116 | cprop[i] = xstrdup(myproposal[i]); | ||
117 | |||
118 | client_kexinit = kex_init(cprop); | ||
119 | packet_start(SSH2_MSG_KEXINIT); | ||
120 | packet_put_raw(buffer_ptr(client_kexinit), buffer_len(client_kexinit)); | ||
121 | packet_send(); | ||
122 | packet_write_wait(); | ||
123 | |||
124 | debug("done"); | ||
125 | |||
126 | packet_read_expect(&payload_len, SSH2_MSG_KEXINIT); | ||
127 | |||
128 | /* save payload for session_id */ | ||
129 | server_kexinit = xmalloc(sizeof(*server_kexinit)); | ||
130 | buffer_init(server_kexinit); | ||
131 | ptr = packet_get_raw(&payload_len); | ||
132 | buffer_append(server_kexinit, ptr, payload_len); | ||
133 | |||
134 | /* skip cookie */ | ||
135 | for (i = 0; i < 16; i++) | ||
136 | (void) packet_get_char(); | ||
137 | /* kex init proposal strings */ | ||
138 | for (i = 0; i < PROPOSAL_MAX; i++) { | ||
139 | sprop[i] = packet_get_string(NULL); | ||
140 | debug("got kexinit string: %s", sprop[i]); | ||
141 | } | ||
142 | i = (int) packet_get_char(); | ||
143 | debug("first kex follow == %d", i); | ||
144 | i = packet_get_int(); | ||
145 | debug("reserved == %d", i); | ||
146 | packet_done(); | ||
147 | |||
148 | debug("done read kexinit"); | ||
149 | kex = kex_choose_conf(cprop, sprop, 0); | ||
150 | |||
151 | /* KEXDH */ | ||
152 | |||
153 | debug("Sending SSH2_MSG_KEXDH_INIT."); | 88 | debug("Sending SSH2_MSG_KEXDH_INIT."); |
154 | |||
155 | /* generate and send 'e', client DH public key */ | 89 | /* generate and send 'e', client DH public key */ |
156 | dh = dh_new_group1(); | 90 | dh = dh_new_group1(); |
157 | packet_start(SSH2_MSG_KEXDH_INIT); | 91 | packet_start(SSH2_MSG_KEXDH_INIT); |
@@ -172,7 +106,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr) | |||
172 | 106 | ||
173 | debug("Wait SSH2_MSG_KEXDH_REPLY."); | 107 | debug("Wait SSH2_MSG_KEXDH_REPLY."); |
174 | 108 | ||
175 | packet_read_expect(&payload_len, SSH2_MSG_KEXDH_REPLY); | 109 | packet_read_expect(&plen, SSH2_MSG_KEXDH_REPLY); |
176 | 110 | ||
177 | debug("Got SSH2_MSG_KEXDH_REPLY."); | 111 | debug("Got SSH2_MSG_KEXDH_REPLY."); |
178 | 112 | ||
@@ -233,10 +167,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr) | |||
233 | shared_secret | 167 | shared_secret |
234 | ); | 168 | ); |
235 | xfree(server_host_key_blob); | 169 | xfree(server_host_key_blob); |
236 | buffer_free(client_kexinit); | 170 | DH_free(dh); |
237 | buffer_free(server_kexinit); | ||
238 | xfree(client_kexinit); | ||
239 | xfree(server_kexinit); | ||
240 | #ifdef DEBUG_KEXDH | 171 | #ifdef DEBUG_KEXDH |
241 | fprintf(stderr, "hash == "); | 172 | fprintf(stderr, "hash == "); |
242 | for (i = 0; i< 20; i++) | 173 | for (i = 0; i< 20; i++) |
@@ -250,16 +181,61 @@ ssh_kex2(char *host, struct sockaddr *hostaddr) | |||
250 | kex_derive_keys(kex, hash, shared_secret); | 181 | kex_derive_keys(kex, hash, shared_secret); |
251 | packet_set_kex(kex); | 182 | packet_set_kex(kex); |
252 | 183 | ||
253 | /* have keys, free DH */ | ||
254 | DH_free(dh); | ||
255 | |||
256 | /* save session id */ | 184 | /* save session id */ |
257 | session_id2_len = 20; | 185 | session_id2_len = 20; |
258 | session_id2 = xmalloc(session_id2_len); | 186 | session_id2 = xmalloc(session_id2_len); |
259 | memcpy(session_id2, hash, session_id2_len); | 187 | memcpy(session_id2, hash, session_id2_len); |
188 | } | ||
189 | |||
190 | void | ||
191 | ssh_kex2(char *host, struct sockaddr *hostaddr) | ||
192 | { | ||
193 | int i, plen; | ||
194 | Kex *kex; | ||
195 | Buffer *client_kexinit, *server_kexinit; | ||
196 | char *sprop[PROPOSAL_MAX]; | ||
197 | |||
198 | if (options.ciphers != NULL) { | ||
199 | myproposal[PROPOSAL_ENC_ALGS_CTOS] = | ||
200 | myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; | ||
201 | } else if (options.cipher == SSH_CIPHER_3DES) { | ||
202 | myproposal[PROPOSAL_ENC_ALGS_CTOS] = | ||
203 | myproposal[PROPOSAL_ENC_ALGS_STOC] = | ||
204 | (char *) cipher_name(SSH_CIPHER_3DES_CBC); | ||
205 | } else if (options.cipher == SSH_CIPHER_BLOWFISH) { | ||
206 | myproposal[PROPOSAL_ENC_ALGS_CTOS] = | ||
207 | myproposal[PROPOSAL_ENC_ALGS_STOC] = | ||
208 | (char *) cipher_name(SSH_CIPHER_BLOWFISH_CBC); | ||
209 | } | ||
210 | if (options.compression) { | ||
211 | myproposal[PROPOSAL_COMP_ALGS_CTOS] = "zlib"; | ||
212 | myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib"; | ||
213 | } else { | ||
214 | myproposal[PROPOSAL_COMP_ALGS_CTOS] = "none"; | ||
215 | myproposal[PROPOSAL_COMP_ALGS_STOC] = "none"; | ||
216 | } | ||
217 | |||
218 | /* buffers with raw kexinit messages */ | ||
219 | server_kexinit = xmalloc(sizeof(*server_kexinit)); | ||
220 | buffer_init(server_kexinit); | ||
221 | client_kexinit = kex_init(myproposal); | ||
222 | |||
223 | /* algorithm negotiation */ | ||
224 | kex_exchange_kexinit(client_kexinit, server_kexinit, sprop); | ||
225 | kex = kex_choose_conf(myproposal, sprop, 0); | ||
226 | for (i = 0; i < PROPOSAL_MAX; i++) | ||
227 | xfree(sprop[i]); | ||
228 | |||
229 | /* server authentication and session key agreement */ | ||
230 | ssh_kex_dh(kex, host, hostaddr, client_kexinit, server_kexinit); | ||
231 | |||
232 | buffer_free(client_kexinit); | ||
233 | buffer_free(server_kexinit); | ||
234 | xfree(client_kexinit); | ||
235 | xfree(server_kexinit); | ||
260 | 236 | ||
261 | debug("Wait SSH2_MSG_NEWKEYS."); | 237 | debug("Wait SSH2_MSG_NEWKEYS."); |
262 | packet_read_expect(&payload_len, SSH2_MSG_NEWKEYS); | 238 | packet_read_expect(&plen, SSH2_MSG_NEWKEYS); |
263 | packet_done(); | 239 | packet_done(); |
264 | debug("GOT SSH2_MSG_NEWKEYS."); | 240 | debug("GOT SSH2_MSG_NEWKEYS."); |
265 | 241 | ||
@@ -278,6 +254,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr) | |||
278 | #endif | 254 | #endif |
279 | debug("done: KEX2."); | 255 | debug("done: KEX2."); |
280 | } | 256 | } |
257 | |||
281 | /* | 258 | /* |
282 | * Authenticate user | 259 | * Authenticate user |
283 | */ | 260 | */ |
@@ -14,7 +14,7 @@ | |||
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include "includes.h" | 16 | #include "includes.h" |
17 | RCSID("$OpenBSD: sshd.c,v 1.117 2000/05/18 13:27:36 djm Exp $"); | 17 | RCSID("$OpenBSD: sshd.c,v 1.118 2000/05/25 20:45:20 markus Exp $"); |
18 | 18 | ||
19 | #include "xmalloc.h" | 19 | #include "xmalloc.h" |
20 | #include "rsa.h" | 20 | #include "rsa.h" |
@@ -1159,7 +1159,6 @@ do_ssh2_kex() | |||
1159 | int payload_len, dlen; | 1159 | int payload_len, dlen; |
1160 | int slen; | 1160 | int slen; |
1161 | unsigned int klen, kout; | 1161 | unsigned int klen, kout; |
1162 | char *ptr; | ||
1163 | unsigned char *signature = NULL; | 1162 | unsigned char *signature = NULL; |
1164 | unsigned char *server_host_key_blob = NULL; | 1163 | unsigned char *server_host_key_blob = NULL; |
1165 | unsigned int sbloblen; | 1164 | unsigned int sbloblen; |
@@ -1171,7 +1170,6 @@ do_ssh2_kex() | |||
1171 | unsigned char *hash; | 1170 | unsigned char *hash; |
1172 | Kex *kex; | 1171 | Kex *kex; |
1173 | char *cprop[PROPOSAL_MAX]; | 1172 | char *cprop[PROPOSAL_MAX]; |
1174 | char *sprop[PROPOSAL_MAX]; | ||
1175 | 1173 | ||
1176 | /* KEXINIT */ | 1174 | /* KEXINIT */ |
1177 | 1175 | ||
@@ -1179,46 +1177,15 @@ do_ssh2_kex() | |||
1179 | myproposal[PROPOSAL_ENC_ALGS_CTOS] = | 1177 | myproposal[PROPOSAL_ENC_ALGS_CTOS] = |
1180 | myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; | 1178 | myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers; |
1181 | } | 1179 | } |
1182 | 1180 | server_kexinit = kex_init(myproposal); | |
1183 | debug("Sending KEX init."); | ||
1184 | |||
1185 | for (i = 0; i < PROPOSAL_MAX; i++) | ||
1186 | sprop[i] = xstrdup(myproposal[i]); | ||
1187 | server_kexinit = kex_init(sprop); | ||
1188 | packet_start(SSH2_MSG_KEXINIT); | ||
1189 | packet_put_raw(buffer_ptr(server_kexinit), buffer_len(server_kexinit)); | ||
1190 | packet_send(); | ||
1191 | packet_write_wait(); | ||
1192 | |||
1193 | debug("done"); | ||
1194 | |||
1195 | packet_read_expect(&payload_len, SSH2_MSG_KEXINIT); | ||
1196 | |||
1197 | /* | ||
1198 | * save raw KEXINIT payload in buffer. this is used during | ||
1199 | * computation of the session_id and the session keys. | ||
1200 | */ | ||
1201 | client_kexinit = xmalloc(sizeof(*client_kexinit)); | 1181 | client_kexinit = xmalloc(sizeof(*client_kexinit)); |
1202 | buffer_init(client_kexinit); | 1182 | buffer_init(client_kexinit); |
1203 | ptr = packet_get_raw(&payload_len); | ||
1204 | buffer_append(client_kexinit, ptr, payload_len); | ||
1205 | 1183 | ||
1206 | /* skip cookie */ | 1184 | /* algorithm negotiation */ |
1207 | for (i = 0; i < 16; i++) | 1185 | kex_exchange_kexinit(server_kexinit, client_kexinit, cprop); |
1208 | (void) packet_get_char(); | 1186 | kex = kex_choose_conf(cprop, myproposal, 1); |
1209 | /* save kex init proposal strings */ | 1187 | for (i = 0; i < PROPOSAL_MAX; i++) |
1210 | for (i = 0; i < PROPOSAL_MAX; i++) { | 1188 | xfree(cprop[i]); |
1211 | cprop[i] = packet_get_string(NULL); | ||
1212 | debug("got kexinit string: %s", cprop[i]); | ||
1213 | } | ||
1214 | |||
1215 | i = (int) packet_get_char(); | ||
1216 | debug("first kex follow == %d", i); | ||
1217 | i = packet_get_int(); | ||
1218 | debug("reserved == %d", i); | ||
1219 | |||
1220 | debug("done read kexinit"); | ||
1221 | kex = kex_choose_conf(cprop, sprop, 1); | ||
1222 | 1189 | ||
1223 | /* KEXDH */ | 1190 | /* KEXDH */ |
1224 | 1191 | ||