summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog17
-rw-r--r--cipher.c6
-rw-r--r--compat.c8
-rw-r--r--kex.c96
-rw-r--r--kex.h13
-rw-r--r--key.c18
-rw-r--r--myproposal.h2
-rw-r--r--readconf.c10
-rw-r--r--servconf.c6
-rw-r--r--serverloop.c51
-rw-r--r--session.c34
-rw-r--r--ssh.112
-rw-r--r--ssh.c6
-rw-r--r--sshconnect2.c137
-rw-r--r--sshd.c47
15 files changed, 256 insertions, 207 deletions
diff --git a/ChangeLog b/ChangeLog
index 3037eac38..f8dcd9ce9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
620000520 2320000520
7 - Xauth fix from Markus Friedl <markus.friedl@informatik.uni-erlangen.de> 24 - Xauth fix from Markus Friedl <markus.friedl@informatik.uni-erlangen.de>
diff --git a/cipher.c b/cipher.c
index 639c1abbd..4117cb772 100644
--- a/cipher.c
+++ b/cipher.c
@@ -12,7 +12,7 @@
12 */ 12 */
13 13
14#include "includes.h" 14#include "includes.h"
15RCSID("$Id: cipher.c,v 1.20 2000/04/16 02:31:50 damien Exp $"); 15RCSID("$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
201cipher_number(const char *name) 201cipher_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)))
diff --git a/compat.c b/compat.c
index 00f031b8b..967e0b6b8 100644
--- a/compat.c
+++ b/compat.c
@@ -28,7 +28,7 @@
28 */ 28 */
29 29
30#include "includes.h" 30#include "includes.h"
31RCSID("$Id: compat.c,v 1.10 2000/05/09 01:03:00 damien Exp $"); 31RCSID("$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)
80int 80int
81proto_spec(const char *spec) 81proto_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:
diff --git a/kex.c b/kex.c
index 221e03041..199e04264 100644
--- a/kex.c
+++ b/kex.c
@@ -28,13 +28,14 @@
28 */ 28 */
29 29
30#include "includes.h" 30#include "includes.h"
31RCSID("$Id: kex.c,v 1.8 2000/05/09 01:03:01 damien Exp $"); 31RCSID("$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
52Buffer * 55Buffer *
53kex_init(char *myproposal[PROPOSAL_MAX]) 56kex_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 */
79void
80kex_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
77int 124int
@@ -134,12 +181,6 @@ dh_new_group1()
134} 181}
135 182
136void 183void
137bignum_print(BIGNUM *b)
138{
139 BN_print_fp(stderr,b);
140}
141
142void
143dump_digest(unsigned char *digest, int len) 184dump_digest(unsigned char *digest, int len)
144{ 185{
145 int i; 186 int i;
@@ -246,10 +287,13 @@ char *
246get_match(char *client, char *server) 287get_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}
267void 318void
@@ -355,7 +406,6 @@ choose_hostkeyalg(Kex *k, char *client, char *server)
355Kex * 406Kex *
356kex_choose_conf(char *cprop[PROPOSAL_MAX], char *sprop[PROPOSAL_MAX], int server) 407kex_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}
diff --git a/kex.h b/kex.h
index 5395ebc3f..7e5c67024 100644
--- a/kex.h
+++ b/kex.h
@@ -91,12 +91,17 @@ struct Kex {
91}; 91};
92 92
93Buffer *kex_init(char *myproposal[PROPOSAL_MAX]); 93Buffer *kex_init(char *myproposal[PROPOSAL_MAX]);
94int dh_pub_is_valid(DH *dh, BIGNUM *dh_pub); 94void
95DH *dh_new_group1(); 95kex_exchange_kexinit(
96Kex *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]);
98Kex *
99kex_choose_conf(char *cprop[PROPOSAL_MAX],
100 char *sprop[PROPOSAL_MAX], int server);
97int kex_derive_keys(Kex *k, unsigned char *hash, BIGNUM *shared_secret); 101int kex_derive_keys(Kex *k, unsigned char *hash, BIGNUM *shared_secret);
98void bignum_print(BIGNUM *b);
99void packet_set_kex(Kex *k); 102void packet_set_kex(Kex *k);
103int dh_pub_is_valid(DH *dh, BIGNUM *dh_pub);
104DH *dh_new_group1();
100 105
101unsigned char * 106unsigned char *
102kex_hash( 107kex_hash(
diff --git a/key.c b/key.c
index ae355a3fc..d474f85c6 100644
--- a/key.c
+++ b/key.c
@@ -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
9static const char *myproposal[PROPOSAL_MAX] = { 9static 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"
17RCSID("$Id: readconf.c,v 1.14 2000/05/09 01:03:01 damien Exp $"); 17RCSID("$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
691fill_default_options(Options * options) 697fill_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"
15RCSID("$Id: servconf.c,v 1.16 2000/05/09 01:03:01 damien Exp $"); 15RCSID("$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()
377void 376void
378server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) 377server_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);
diff --git a/session.c b/session.c
index 4b7404f73..4791857c0 100644
--- a/session.c
+++ b/session.c
@@ -8,7 +8,7 @@
8 */ 8 */
9 9
10#include "includes.h" 10#include "includes.h"
11RCSID("$OpenBSD: session.c,v 1.12 2000/05/03 18:03:07 markus Exp $"); 11RCSID("$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");
diff --git a/ssh.1 b/ssh.1
index d8e9eb0b9..6c1d3763e 100644
--- a/ssh.1
+++ b/ssh.1
@@ -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
334Disables forwarding of the authentication agent connection. 334Disables forwarding of the authentication agent connection.
335This may also be specified on a per-host basis in the configuration file. 335.It Fl A
336Enables forwarding of the authentication agent connection.
337This 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
337Selects the cipher to use for encrypting the session. 339Selects 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
460challenges, if the user entered "s/key" as password. 462challenges, if the user entered "s/key" as password.
461.It Fl x 463.It Fl x
462Disables X11 forwarding. 464Disables X11 forwarding.
463This can also be specified on a per-host basis in a configuration file.
464.It Fl X 465.It Fl X
465Enables X11 forwarding. 466Enables X11 forwarding.
467This can also be specified on a per-host basis in a configuration file.
466.It Fl C 468.It Fl C
467Requests compression of all data (including stdin, stdout, stderr, and 469Requests compression of all data (including stdin, stdout, stderr, and
468data for forwarded X11 and TCP/IP connections). 470data for forwarded X11 and TCP/IP connections).
@@ -671,6 +673,8 @@ The argument must be
671.Dq yes 673.Dq yes
672or 674or
673.Dq no . 675.Dq no .
676The default is
677.Dq no .
674.It Cm ForwardX11 678.It Cm ForwardX11
675Specifies whether X11 connections will be automatically redirected 679Specifies whether X11 connections will be automatically redirected
676over the secure channel and 680over the secure channel and
diff --git a/ssh.c b/ssh.c
index 1cc8dbbf3..2934c3a4a 100644
--- a/ssh.c
+++ b/ssh.c
@@ -11,7 +11,7 @@
11 */ 11 */
12 12
13#include "includes.h" 13#include "includes.h"
14RCSID("$Id: ssh.c,v 1.32 2000/05/20 05:22:37 damien Exp $"); 14RCSID("$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"
31RCSID("$OpenBSD: sshconnect2.c,v 1.10 2000/05/08 17:42:25 markus Exp $"); 31RCSID("$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;
68int session_id2_len = 0; 68int session_id2_len = 0;
69 69
70void 70void
71ssh_kex2(char *host, struct sockaddr *hostaddr) 71ssh_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
190void
191ssh_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 */
diff --git a/sshd.c b/sshd.c
index 39fbcba40..ec860024b 100644
--- a/sshd.c
+++ b/sshd.c
@@ -14,7 +14,7 @@
14 */ 14 */
15 15
16#include "includes.h" 16#include "includes.h"
17RCSID("$OpenBSD: sshd.c,v 1.117 2000/05/18 13:27:36 djm Exp $"); 17RCSID("$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