diff options
author | Damien Miller <djm@mindrot.org> | 2000-04-06 12:32:37 +1000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2000-04-06 12:32:37 +1000 |
commit | 1383bd8eb91a8ec9c8d283679faec5925b0ccc42 (patch) | |
tree | f71278df6c50983ea3dad850ae79c45c340d9362 | |
parent | 74a333bbe11f67c59c559e0f424d5945eb438577 (diff) |
- OpenBSD CVS update:
- [channels.c]
close efd on eof
- [clientloop.c compat.c ssh.c sshconnect.c myproposal.h]
ssh2 client implementation, interops w/ ssh.com and lsh servers.
- [sshconnect.c]
missing free.
- [authfile.c cipher.c cipher.h packet.c sshconnect.c sshd.c]
remove unused argument, split cipher_mask()
- [clientloop.c]
re-order: group ssh1 vs. ssh2
- Make Redhat spec require openssl >= 0.9.5a
-rw-r--r-- | ChangeLog | 14 | ||||
-rw-r--r-- | authfile.c | 8 | ||||
-rw-r--r-- | channels.c | 10 | ||||
-rw-r--r-- | cipher.c | 24 | ||||
-rw-r--r-- | cipher.h | 8 | ||||
-rw-r--r-- | clientloop.c | 210 | ||||
-rw-r--r-- | compat.c | 6 | ||||
-rw-r--r-- | contrib/redhat/openssh.spec | 4 | ||||
-rw-r--r-- | kex.h | 11 | ||||
-rw-r--r-- | myproposal.h | 20 | ||||
-rw-r--r-- | packet.c | 32 | ||||
-rw-r--r-- | packet.h | 4 | ||||
-rw-r--r-- | ssh.c | 162 | ||||
-rw-r--r-- | sshconnect.c | 350 | ||||
-rw-r--r-- | sshd.c | 4 |
15 files changed, 737 insertions, 130 deletions
@@ -1,3 +1,17 @@ | |||
1 | 20000406 | ||
2 | - OpenBSD CVS update: | ||
3 | - [channels.c] | ||
4 | close efd on eof | ||
5 | - [clientloop.c compat.c ssh.c sshconnect.c myproposal.h] | ||
6 | ssh2 client implementation, interops w/ ssh.com and lsh servers. | ||
7 | - [sshconnect.c] | ||
8 | missing free. | ||
9 | - [authfile.c cipher.c cipher.h packet.c sshconnect.c sshd.c] | ||
10 | remove unused argument, split cipher_mask() | ||
11 | - [clientloop.c] | ||
12 | re-order: group ssh1 vs. ssh2 | ||
13 | - Make Redhat spec require openssl >= 0.9.5a | ||
14 | |||
1 | 20000404 | 15 | 20000404 |
2 | - Add tests for RAND_add function when searching for OpenSSL | 16 | - Add tests for RAND_add function when searching for OpenSSL |
3 | - OpenBSD CVS update: | 17 | - OpenBSD CVS update: |
diff --git a/authfile.c b/authfile.c index a6dab7575..6ce0ac61f 100644 --- a/authfile.c +++ b/authfile.c | |||
@@ -15,7 +15,7 @@ | |||
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include "includes.h" | 17 | #include "includes.h" |
18 | RCSID("$Id: authfile.c,v 1.7 2000/03/02 12:57:18 damien Exp $"); | 18 | RCSID("$Id: authfile.c,v 1.8 2000/04/06 02:32:38 damien Exp $"); |
19 | 19 | ||
20 | #ifdef HAVE_OPENSSL | 20 | #ifdef HAVE_OPENSSL |
21 | #include <openssl/bn.h> | 21 | #include <openssl/bn.h> |
@@ -107,7 +107,7 @@ save_private_key(const char *filename, const char *passphrase, | |||
107 | /* Allocate space for the private part of the key in the buffer. */ | 107 | /* Allocate space for the private part of the key in the buffer. */ |
108 | buffer_append_space(&encrypted, &cp, buffer_len(&buffer)); | 108 | buffer_append_space(&encrypted, &cp, buffer_len(&buffer)); |
109 | 109 | ||
110 | cipher_set_key_string(&cipher, cipher_type, passphrase, 1); | 110 | cipher_set_key_string(&cipher, cipher_type, passphrase); |
111 | cipher_encrypt(&cipher, (unsigned char *) cp, | 111 | cipher_encrypt(&cipher, (unsigned char *) cp, |
112 | (unsigned char *) buffer_ptr(&buffer), | 112 | (unsigned char *) buffer_ptr(&buffer), |
113 | buffer_len(&buffer)); | 113 | buffer_len(&buffer)); |
@@ -286,7 +286,7 @@ load_private_key(const char *filename, const char *passphrase, | |||
286 | xfree(buffer_get_string(&buffer, NULL)); | 286 | xfree(buffer_get_string(&buffer, NULL)); |
287 | 287 | ||
288 | /* Check that it is a supported cipher. */ | 288 | /* Check that it is a supported cipher. */ |
289 | if (((cipher_mask() | SSH_CIPHER_NONE | SSH_AUTHFILE_CIPHER) & | 289 | if (((cipher_mask1() | SSH_CIPHER_NONE | SSH_AUTHFILE_CIPHER) & |
290 | (1 << cipher_type)) == 0) { | 290 | (1 << cipher_type)) == 0) { |
291 | debug("Unsupported cipher %.100s used in key file %.200s.", | 291 | debug("Unsupported cipher %.100s used in key file %.200s.", |
292 | cipher_name(cipher_type), filename); | 292 | cipher_name(cipher_type), filename); |
@@ -298,7 +298,7 @@ load_private_key(const char *filename, const char *passphrase, | |||
298 | buffer_append_space(&decrypted, &cp, buffer_len(&buffer)); | 298 | buffer_append_space(&decrypted, &cp, buffer_len(&buffer)); |
299 | 299 | ||
300 | /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */ | 300 | /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */ |
301 | cipher_set_key_string(&cipher, cipher_type, passphrase, 0); | 301 | cipher_set_key_string(&cipher, cipher_type, passphrase); |
302 | cipher_decrypt(&cipher, (unsigned char *) cp, | 302 | cipher_decrypt(&cipher, (unsigned char *) cp, |
303 | (unsigned char *) buffer_ptr(&buffer), | 303 | (unsigned char *) buffer_ptr(&buffer), |
304 | buffer_len(&buffer)); | 304 | buffer_len(&buffer)); |
diff --git a/channels.c b/channels.c index 18f667f6b..f03cf92b4 100644 --- a/channels.c +++ b/channels.c | |||
@@ -17,7 +17,7 @@ | |||
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include "includes.h" | 19 | #include "includes.h" |
20 | RCSID("$Id: channels.c,v 1.21 2000/04/04 04:39:00 damien Exp $"); | 20 | RCSID("$Id: channels.c,v 1.22 2000/04/06 02:32:38 damien Exp $"); |
21 | 21 | ||
22 | #include "ssh.h" | 22 | #include "ssh.h" |
23 | #include "packet.h" | 23 | #include "packet.h" |
@@ -642,6 +642,7 @@ channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset) | |||
642 | char buf[16*1024]; | 642 | char buf[16*1024]; |
643 | int len; | 643 | int len; |
644 | 644 | ||
645 | /** XXX handle drain efd, too */ | ||
645 | if (c->efd != -1) { | 646 | if (c->efd != -1) { |
646 | if (c->extended_usage == CHAN_EXTENDED_WRITE && | 647 | if (c->extended_usage == CHAN_EXTENDED_WRITE && |
647 | FD_ISSET(c->efd, writeset) && | 648 | FD_ISSET(c->efd, writeset) && |
@@ -659,7 +660,12 @@ channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset) | |||
659 | len = read(c->efd, buf, sizeof(buf)); | 660 | len = read(c->efd, buf, sizeof(buf)); |
660 | debug("channel %d: read %d from efd %d", | 661 | debug("channel %d: read %d from efd %d", |
661 | c->self, len, c->efd); | 662 | c->self, len, c->efd); |
662 | if (len > 0) | 663 | if (len == 0) { |
664 | debug("channel %d: closing efd %d", | ||
665 | c->self, c->efd); | ||
666 | close(c->efd); | ||
667 | c->efd = -1; | ||
668 | } else if (len > 0) | ||
663 | buffer_append(&c->extended, buf, len); | 669 | buffer_append(&c->extended, buf, len); |
664 | } | 670 | } |
665 | } | 671 | } |
@@ -12,7 +12,7 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include "includes.h" | 14 | #include "includes.h" |
15 | RCSID("$Id: cipher.c,v 1.15 2000/04/01 01:09:23 damien Exp $"); | 15 | RCSID("$Id: cipher.c,v 1.16 2000/04/06 02:32:39 damien Exp $"); |
16 | 16 | ||
17 | #include "ssh.h" | 17 | #include "ssh.h" |
18 | #include "cipher.h" | 18 | #include "cipher.h" |
@@ -137,17 +137,28 @@ static char *cipher_names[] = | |||
137 | */ | 137 | */ |
138 | 138 | ||
139 | unsigned int | 139 | unsigned int |
140 | cipher_mask() | 140 | cipher_mask1() |
141 | { | 141 | { |
142 | unsigned int mask = 0; | 142 | unsigned int mask = 0; |
143 | mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */ | 143 | mask |= 1 << SSH_CIPHER_3DES; /* Mandatory */ |
144 | mask |= 1 << SSH_CIPHER_BLOWFISH; | 144 | mask |= 1 << SSH_CIPHER_BLOWFISH; |
145 | return mask; | ||
146 | } | ||
147 | unsigned int | ||
148 | cipher_mask2() | ||
149 | { | ||
150 | unsigned int mask = 0; | ||
145 | mask |= 1 << SSH_CIPHER_BLOWFISH_CBC; | 151 | mask |= 1 << SSH_CIPHER_BLOWFISH_CBC; |
146 | mask |= 1 << SSH_CIPHER_3DES_CBC; | 152 | mask |= 1 << SSH_CIPHER_3DES_CBC; |
147 | mask |= 1 << SSH_CIPHER_ARCFOUR; | 153 | mask |= 1 << SSH_CIPHER_ARCFOUR; |
148 | mask |= 1 << SSH_CIPHER_CAST128_CBC; | 154 | mask |= 1 << SSH_CIPHER_CAST128_CBC; |
149 | return mask; | 155 | return mask; |
150 | } | 156 | } |
157 | unsigned int | ||
158 | cipher_mask() | ||
159 | { | ||
160 | return cipher_mask1() | cipher_mask2(); | ||
161 | } | ||
151 | 162 | ||
152 | /* Returns the name of the cipher. */ | 163 | /* Returns the name of the cipher. */ |
153 | 164 | ||
@@ -182,8 +193,7 @@ cipher_number(const char *name) | |||
182 | */ | 193 | */ |
183 | 194 | ||
184 | void | 195 | void |
185 | cipher_set_key_string(CipherContext *context, int cipher, | 196 | cipher_set_key_string(CipherContext *context, int cipher, const char *passphrase) |
186 | const char *passphrase, int for_encryption) | ||
187 | { | 197 | { |
188 | MD5_CTX md; | 198 | MD5_CTX md; |
189 | unsigned char digest[16]; | 199 | unsigned char digest[16]; |
@@ -192,7 +202,7 @@ cipher_set_key_string(CipherContext *context, int cipher, | |||
192 | MD5_Update(&md, (const unsigned char *) passphrase, strlen(passphrase)); | 202 | MD5_Update(&md, (const unsigned char *) passphrase, strlen(passphrase)); |
193 | MD5_Final(digest, &md); | 203 | MD5_Final(digest, &md); |
194 | 204 | ||
195 | cipher_set_key(context, cipher, digest, 16, for_encryption); | 205 | cipher_set_key(context, cipher, digest, 16); |
196 | 206 | ||
197 | memset(digest, 0, sizeof(digest)); | 207 | memset(digest, 0, sizeof(digest)); |
198 | memset(&md, 0, sizeof(md)); | 208 | memset(&md, 0, sizeof(md)); |
@@ -201,8 +211,8 @@ cipher_set_key_string(CipherContext *context, int cipher, | |||
201 | /* Selects the cipher to use and sets the key. */ | 211 | /* Selects the cipher to use and sets the key. */ |
202 | 212 | ||
203 | void | 213 | void |
204 | cipher_set_key(CipherContext *context, int cipher, | 214 | cipher_set_key(CipherContext *context, int cipher, const unsigned char *key, |
205 | const unsigned char *key, int keylen, int for_encryption) | 215 | int keylen) |
206 | { | 216 | { |
207 | unsigned char padded[32]; | 217 | unsigned char padded[32]; |
208 | 218 | ||
@@ -11,7 +11,7 @@ | |||
11 | * | 11 | * |
12 | */ | 12 | */ |
13 | 13 | ||
14 | /* RCSID("$Id: cipher.h,v 1.7 2000/04/01 01:09:23 damien Exp $"); */ | 14 | /* RCSID("$Id: cipher.h,v 1.8 2000/04/06 02:32:39 damien Exp $"); */ |
15 | 15 | ||
16 | #ifndef CIPHER_H | 16 | #ifndef CIPHER_H |
17 | #define CIPHER_H | 17 | #define CIPHER_H |
@@ -76,6 +76,8 @@ typedef struct { | |||
76 | * supported cipher. | 76 | * supported cipher. |
77 | */ | 77 | */ |
78 | unsigned int cipher_mask(); | 78 | unsigned int cipher_mask(); |
79 | unsigned int cipher_mask1(); | ||
80 | unsigned int cipher_mask2(); | ||
79 | 81 | ||
80 | /* Returns the name of the cipher. */ | 82 | /* Returns the name of the cipher. */ |
81 | const char *cipher_name(int cipher); | 83 | const char *cipher_name(int cipher); |
@@ -92,7 +94,7 @@ int cipher_number(const char *name); | |||
92 | */ | 94 | */ |
93 | void | 95 | void |
94 | cipher_set_key(CipherContext * context, int cipher, | 96 | cipher_set_key(CipherContext * context, int cipher, |
95 | const unsigned char *key, int keylen, int for_encryption); | 97 | const unsigned char *key, int keylen); |
96 | void | 98 | void |
97 | cipher_set_key_iv(CipherContext * context, int cipher, | 99 | cipher_set_key_iv(CipherContext * context, int cipher, |
98 | const unsigned char *key, int keylen, | 100 | const unsigned char *key, int keylen, |
@@ -104,7 +106,7 @@ cipher_set_key_iv(CipherContext * context, int cipher, | |||
104 | */ | 106 | */ |
105 | void | 107 | void |
106 | cipher_set_key_string(CipherContext * context, int cipher, | 108 | cipher_set_key_string(CipherContext * context, int cipher, |
107 | const char *passphrase, int for_encryption); | 109 | const char *passphrase); |
108 | 110 | ||
109 | /* Encrypts data using the cipher. */ | 111 | /* Encrypts data using the cipher. */ |
110 | void | 112 | void |
diff --git a/clientloop.c b/clientloop.c index 1bc6d7e67..4f2e5037d 100644 --- a/clientloop.c +++ b/clientloop.c | |||
@@ -12,10 +12,11 @@ | |||
12 | * | 12 | * |
13 | * The main loop for the interactive session (client side). | 13 | * The main loop for the interactive session (client side). |
14 | * | 14 | * |
15 | * SSH2 support added by Markus Friedl. | ||
15 | */ | 16 | */ |
16 | 17 | ||
17 | #include "includes.h" | 18 | #include "includes.h" |
18 | RCSID("$Id: clientloop.c,v 1.8 2000/04/01 01:09:23 damien Exp $"); | 19 | RCSID("$Id: clientloop.c,v 1.9 2000/04/06 02:32:39 damien Exp $"); |
19 | 20 | ||
20 | #include "xmalloc.h" | 21 | #include "xmalloc.h" |
21 | #include "ssh.h" | 22 | #include "ssh.h" |
@@ -24,6 +25,7 @@ RCSID("$Id: clientloop.c,v 1.8 2000/04/01 01:09:23 damien Exp $"); | |||
24 | #include "authfd.h" | 25 | #include "authfd.h" |
25 | #include "readconf.h" | 26 | #include "readconf.h" |
26 | 27 | ||
28 | #include "ssh2.h" | ||
27 | #include "compat.h" | 29 | #include "compat.h" |
28 | #include "channels.h" | 30 | #include "channels.h" |
29 | #include "dispatch.h" | 31 | #include "dispatch.h" |
@@ -75,6 +77,10 @@ static unsigned long stdin_bytes, stdout_bytes, stderr_bytes; | |||
75 | static int quit_pending; /* Set to non-zero to quit the client loop. */ | 77 | static int quit_pending; /* Set to non-zero to quit the client loop. */ |
76 | static int escape_char; /* Escape character. */ | 78 | static int escape_char; /* Escape character. */ |
77 | 79 | ||
80 | |||
81 | void client_init_dispatch(void); | ||
82 | int session_ident = -1; | ||
83 | |||
78 | /* Returns the user\'s terminal to normal mode if it had been put in raw mode. */ | 84 | /* Returns the user\'s terminal to normal mode if it had been put in raw mode. */ |
79 | 85 | ||
80 | void | 86 | void |
@@ -273,23 +279,32 @@ client_make_packets_from_stdin_data() | |||
273 | void | 279 | void |
274 | client_check_window_change() | 280 | client_check_window_change() |
275 | { | 281 | { |
276 | /* Send possible window change message to the server. */ | 282 | struct winsize ws; |
277 | if (received_window_change_signal) { | 283 | |
278 | struct winsize ws; | 284 | if (! received_window_change_signal) |
279 | 285 | return; | |
280 | /* Clear the window change indicator. */ | 286 | /** XXX race */ |
281 | received_window_change_signal = 0; | 287 | received_window_change_signal = 0; |
282 | 288 | ||
283 | /* Read new window size. */ | 289 | if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) |
284 | if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) >= 0) { | 290 | return; |
285 | /* Successful, send the packet now. */ | 291 | |
286 | packet_start(SSH_CMSG_WINDOW_SIZE); | 292 | debug("client_check_window_change: changed"); |
287 | packet_put_int(ws.ws_row); | 293 | |
288 | packet_put_int(ws.ws_col); | 294 | if (compat20) { |
289 | packet_put_int(ws.ws_xpixel); | 295 | channel_request_start(session_ident, "window-change", 0); |
290 | packet_put_int(ws.ws_ypixel); | 296 | packet_put_int(ws.ws_col); |
291 | packet_send(); | 297 | packet_put_int(ws.ws_row); |
292 | } | 298 | packet_put_int(ws.ws_xpixel); |
299 | packet_put_int(ws.ws_ypixel); | ||
300 | packet_send(); | ||
301 | } else { | ||
302 | packet_start(SSH_CMSG_WINDOW_SIZE); | ||
303 | packet_put_int(ws.ws_row); | ||
304 | packet_put_int(ws.ws_col); | ||
305 | packet_put_int(ws.ws_xpixel); | ||
306 | packet_put_int(ws.ws_ypixel); | ||
307 | packet_send(); | ||
293 | } | 308 | } |
294 | } | 309 | } |
295 | 310 | ||
@@ -301,23 +316,33 @@ client_check_window_change() | |||
301 | void | 316 | void |
302 | client_wait_until_can_do_something(fd_set * readset, fd_set * writeset) | 317 | client_wait_until_can_do_something(fd_set * readset, fd_set * writeset) |
303 | { | 318 | { |
319 | /*debug("client_wait_until_can_do_something"); */ | ||
320 | |||
304 | /* Initialize select masks. */ | 321 | /* Initialize select masks. */ |
305 | FD_ZERO(readset); | 322 | FD_ZERO(readset); |
323 | FD_ZERO(writeset); | ||
306 | 324 | ||
307 | /* Read from the connection, unless our buffers are full. */ | 325 | if (!compat20) { |
308 | if (buffer_len(&stdout_buffer) < buffer_high && | 326 | /* Read from the connection, unless our buffers are full. */ |
309 | buffer_len(&stderr_buffer) < buffer_high && | 327 | if (buffer_len(&stdout_buffer) < buffer_high && |
310 | channel_not_very_much_buffered_data()) | 328 | buffer_len(&stderr_buffer) < buffer_high && |
329 | channel_not_very_much_buffered_data()) | ||
330 | FD_SET(connection_in, readset); | ||
331 | /* | ||
332 | * Read from stdin, unless we have seen EOF or have very much | ||
333 | * buffered data to send to the server. | ||
334 | */ | ||
335 | if (!stdin_eof && packet_not_very_much_data_to_write()) | ||
336 | FD_SET(fileno(stdin), readset); | ||
337 | |||
338 | /* Select stdout/stderr if have data in buffer. */ | ||
339 | if (buffer_len(&stdout_buffer) > 0) | ||
340 | FD_SET(fileno(stdout), writeset); | ||
341 | if (buffer_len(&stderr_buffer) > 0) | ||
342 | FD_SET(fileno(stderr), writeset); | ||
343 | } else { | ||
311 | FD_SET(connection_in, readset); | 344 | FD_SET(connection_in, readset); |
312 | 345 | } | |
313 | /* | ||
314 | * Read from stdin, unless we have seen EOF or have very much | ||
315 | * buffered data to send to the server. | ||
316 | */ | ||
317 | if (!stdin_eof && packet_not_very_much_data_to_write()) | ||
318 | FD_SET(fileno(stdin), readset); | ||
319 | |||
320 | FD_ZERO(writeset); | ||
321 | 346 | ||
322 | /* Add any selections by the channel mechanism. */ | 347 | /* Add any selections by the channel mechanism. */ |
323 | channel_prepare_select(readset, writeset); | 348 | channel_prepare_select(readset, writeset); |
@@ -326,14 +351,7 @@ client_wait_until_can_do_something(fd_set * readset, fd_set * writeset) | |||
326 | if (packet_have_data_to_write()) | 351 | if (packet_have_data_to_write()) |
327 | FD_SET(connection_out, writeset); | 352 | FD_SET(connection_out, writeset); |
328 | 353 | ||
329 | /* Select stdout if have data in buffer. */ | 354 | /* move UP XXX */ |
330 | if (buffer_len(&stdout_buffer) > 0) | ||
331 | FD_SET(fileno(stdout), writeset); | ||
332 | |||
333 | /* Select stderr if have data in buffer. */ | ||
334 | if (buffer_len(&stderr_buffer) > 0) | ||
335 | FD_SET(fileno(stderr), writeset); | ||
336 | |||
337 | /* Update maximum file descriptor number, if appropriate. */ | 355 | /* Update maximum file descriptor number, if appropriate. */ |
338 | if (channel_max_fd() > max_fd) | 356 | if (channel_max_fd() > max_fd) |
339 | max_fd = channel_max_fd(); | 357 | max_fd = channel_max_fd(); |
@@ -408,10 +426,10 @@ client_suspend_self() | |||
408 | } | 426 | } |
409 | 427 | ||
410 | void | 428 | void |
411 | client_process_input(fd_set * readset) | 429 | client_process_net_input(fd_set * readset) |
412 | { | 430 | { |
413 | int len, pid; | 431 | int len; |
414 | char buf[8192], *s; | 432 | char buf[8192]; |
415 | 433 | ||
416 | /* | 434 | /* |
417 | * Read input from the server, and add any such data to the buffer of | 435 | * Read input from the server, and add any such data to the buffer of |
@@ -420,6 +438,7 @@ client_process_input(fd_set * readset) | |||
420 | if (FD_ISSET(connection_in, readset)) { | 438 | if (FD_ISSET(connection_in, readset)) { |
421 | /* Read as much as possible. */ | 439 | /* Read as much as possible. */ |
422 | len = read(connection_in, buf, sizeof(buf)); | 440 | len = read(connection_in, buf, sizeof(buf)); |
441 | /*debug("read connection_in len %d", len); XXX */ | ||
423 | if (len == 0) { | 442 | if (len == 0) { |
424 | /* Received EOF. The remote host has closed the connection. */ | 443 | /* Received EOF. The remote host has closed the connection. */ |
425 | snprintf(buf, sizeof buf, "Connection to %.300s closed by remote host.\r\n", | 444 | snprintf(buf, sizeof buf, "Connection to %.300s closed by remote host.\r\n", |
@@ -447,6 +466,14 @@ client_process_input(fd_set * readset) | |||
447 | } | 466 | } |
448 | packet_process_incoming(buf, len); | 467 | packet_process_incoming(buf, len); |
449 | } | 468 | } |
469 | } | ||
470 | |||
471 | void | ||
472 | client_process_input(fd_set * readset) | ||
473 | { | ||
474 | int len, pid; | ||
475 | char buf[8192], *s; | ||
476 | |||
450 | /* Read input from stdin. */ | 477 | /* Read input from stdin. */ |
451 | if (FD_ISSET(fileno(stdin), readset)) { | 478 | if (FD_ISSET(fileno(stdin), readset)) { |
452 | /* Read as much as possible. */ | 479 | /* Read as much as possible. */ |
@@ -703,8 +730,6 @@ client_process_buffered_input_packets() | |||
703 | * character for terminating or suspending the session. | 730 | * character for terminating or suspending the session. |
704 | */ | 731 | */ |
705 | 732 | ||
706 | void client_init_dispatch(void); | ||
707 | |||
708 | int | 733 | int |
709 | client_loop(int have_pty, int escape_char_arg) | 734 | client_loop(int have_pty, int escape_char_arg) |
710 | { | 735 | { |
@@ -753,7 +778,8 @@ client_loop(int have_pty, int escape_char_arg) | |||
753 | enter_raw_mode(); | 778 | enter_raw_mode(); |
754 | 779 | ||
755 | /* Check if we should immediately send of on stdin. */ | 780 | /* Check if we should immediately send of on stdin. */ |
756 | client_check_initial_eof_on_stdin(); | 781 | if (!compat20) |
782 | client_check_initial_eof_on_stdin(); | ||
757 | 783 | ||
758 | /* Main loop of the client for the interactive session mode. */ | 784 | /* Main loop of the client for the interactive session mode. */ |
759 | while (!quit_pending) { | 785 | while (!quit_pending) { |
@@ -762,11 +788,17 @@ client_loop(int have_pty, int escape_char_arg) | |||
762 | /* Process buffered packets sent by the server. */ | 788 | /* Process buffered packets sent by the server. */ |
763 | client_process_buffered_input_packets(); | 789 | client_process_buffered_input_packets(); |
764 | 790 | ||
791 | if (compat20 && !channel_still_open()) { | ||
792 | debug("!channel_still_open."); | ||
793 | break; | ||
794 | } | ||
795 | |||
765 | /* | 796 | /* |
766 | * Make packets of buffered stdin data, and buffer them for | 797 | * Make packets of buffered stdin data, and buffer them for |
767 | * sending to the server. | 798 | * sending to the server. |
768 | */ | 799 | */ |
769 | client_make_packets_from_stdin_data(); | 800 | if (!compat20) |
801 | client_make_packets_from_stdin_data(); | ||
770 | 802 | ||
771 | /* | 803 | /* |
772 | * Make packets from buffered channel data, and buffer them | 804 | * Make packets from buffered channel data, and buffer them |
@@ -796,17 +828,21 @@ client_loop(int have_pty, int escape_char_arg) | |||
796 | /* Do channel operations. */ | 828 | /* Do channel operations. */ |
797 | channel_after_select(&readset, &writeset); | 829 | channel_after_select(&readset, &writeset); |
798 | 830 | ||
799 | /* | 831 | /* Buffer input from the connection. */ |
800 | * Process input from the connection and from stdin. Buffer | 832 | client_process_net_input(&readset); |
801 | * any data that is available. | ||
802 | */ | ||
803 | client_process_input(&readset); | ||
804 | 833 | ||
805 | /* | 834 | if (quit_pending) |
806 | * Process output to stdout and stderr. Output to the | 835 | break; |
807 | * connection is processed elsewhere (above). | 836 | |
808 | */ | 837 | if (!compat20) { |
809 | client_process_output(&writeset); | 838 | /* Buffer data from stdin */ |
839 | client_process_input(&readset); | ||
840 | /* | ||
841 | * Process output to stdout and stderr. Output to | ||
842 | * the connection is processed elsewhere (above). | ||
843 | */ | ||
844 | client_process_output(&writeset); | ||
845 | } | ||
810 | 846 | ||
811 | /* Send as much buffered packet data as possible to the sender. */ | 847 | /* Send as much buffered packet data as possible to the sender. */ |
812 | if (FD_ISSET(connection_out, &writeset)) | 848 | if (FD_ISSET(connection_out, &writeset)) |
@@ -918,6 +954,19 @@ client_input_exit_status(int type, int plen) | |||
918 | } | 954 | } |
919 | 955 | ||
920 | void | 956 | void |
957 | client_init_dispatch_20() | ||
958 | { | ||
959 | dispatch_init(&dispatch_protocol_error); | ||
960 | dispatch_set(SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose); | ||
961 | dispatch_set(SSH2_MSG_CHANNEL_DATA, &channel_input_data); | ||
962 | dispatch_set(SSH2_MSG_CHANNEL_EOF, &channel_input_ieof); | ||
963 | dispatch_set(SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data); | ||
964 | dispatch_set(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); | ||
965 | dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); | ||
966 | dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &channel_input_channel_request); | ||
967 | dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust); | ||
968 | } | ||
969 | void | ||
921 | client_init_dispatch_13() | 970 | client_init_dispatch_13() |
922 | { | 971 | { |
923 | dispatch_init(NULL); | 972 | dispatch_init(NULL); |
@@ -944,8 +993,55 @@ client_init_dispatch_15() | |||
944 | void | 993 | void |
945 | client_init_dispatch() | 994 | client_init_dispatch() |
946 | { | 995 | { |
947 | if (compat13) | 996 | if (compat20) |
997 | client_init_dispatch_20(); | ||
998 | else if (compat13) | ||
948 | client_init_dispatch_13(); | 999 | client_init_dispatch_13(); |
949 | else | 1000 | else |
950 | client_init_dispatch_15(); | 1001 | client_init_dispatch_15(); |
951 | } | 1002 | } |
1003 | |||
1004 | void | ||
1005 | client_input_channel_req(int id, void *arg) | ||
1006 | { | ||
1007 | Channel *c = NULL; | ||
1008 | unsigned int len; | ||
1009 | int success = 0; | ||
1010 | int reply; | ||
1011 | char *rtype; | ||
1012 | |||
1013 | rtype = packet_get_string(&len); | ||
1014 | reply = packet_get_char(); | ||
1015 | |||
1016 | log("session_input_channel_req: rtype %s reply %d", rtype, reply); | ||
1017 | |||
1018 | c = channel_lookup(id); | ||
1019 | if (c == NULL) | ||
1020 | fatal("session_input_channel_req: channel %d: bad channel", id); | ||
1021 | |||
1022 | if (session_ident == -1) { | ||
1023 | error("client_input_channel_req: no channel %d", id); | ||
1024 | } else if (id != session_ident) { | ||
1025 | error("client_input_channel_req: bad channel %d != %d", | ||
1026 | id, session_ident); | ||
1027 | } else if (strcmp(rtype, "exit-status") == 0) { | ||
1028 | success = 1; | ||
1029 | exit_status = packet_get_int(); | ||
1030 | } | ||
1031 | if (reply) { | ||
1032 | packet_start(success ? | ||
1033 | SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); | ||
1034 | packet_put_int(c->remote_id); | ||
1035 | packet_send(); | ||
1036 | } | ||
1037 | xfree(rtype); | ||
1038 | } | ||
1039 | |||
1040 | void | ||
1041 | client_set_session_ident(int id) | ||
1042 | { | ||
1043 | debug("client_set_session_ident: id %d", id); | ||
1044 | session_ident = id; | ||
1045 | channel_register_callback(id, SSH2_MSG_CHANNEL_REQUEST, | ||
1046 | client_input_channel_req, (void *)0); | ||
1047 | } | ||
@@ -28,7 +28,7 @@ | |||
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include "includes.h" | 30 | #include "includes.h" |
31 | RCSID("$Id: compat.c,v 1.4 2000/04/04 04:39:01 damien Exp $"); | 31 | RCSID("$Id: compat.c,v 1.5 2000/04/06 02:32:39 damien Exp $"); |
32 | 32 | ||
33 | #include "ssh.h" | 33 | #include "ssh.h" |
34 | #include "packet.h" | 34 | #include "packet.h" |
@@ -40,7 +40,9 @@ int datafellows = 0; | |||
40 | void | 40 | void |
41 | enable_compat20(void) | 41 | enable_compat20(void) |
42 | { | 42 | { |
43 | fatal("protocol 2.0 not implemented"); | 43 | verbose("Enabling compatibility mode for protocol 2.0"); |
44 | compat20 = 1; | ||
45 | packet_set_ssh2_format(); | ||
44 | } | 46 | } |
45 | void | 47 | void |
46 | enable_compat13(void) | 48 | enable_compat13(void) |
diff --git a/contrib/redhat/openssh.spec b/contrib/redhat/openssh.spec index 24f0e4280..35affbaa2 100644 --- a/contrib/redhat/openssh.spec +++ b/contrib/redhat/openssh.spec | |||
@@ -15,8 +15,8 @@ Copyright: BSD | |||
15 | Group: Applications/Internet | 15 | Group: Applications/Internet |
16 | BuildRoot: /tmp/openssh-%{version}-buildroot | 16 | BuildRoot: /tmp/openssh-%{version}-buildroot |
17 | Obsoletes: ssh | 17 | Obsoletes: ssh |
18 | PreReq: openssl | 18 | PreReq: openssl >= 0.9.5a |
19 | Requires: openssl | 19 | Requires: openssl >= 0.9.5a |
20 | BuildPreReq: perl | 20 | BuildPreReq: perl |
21 | BuildPreReq: openssl-devel | 21 | BuildPreReq: openssl-devel |
22 | BuildPreReq: tcp_wrappers | 22 | BuildPreReq: tcp_wrappers |
@@ -29,6 +29,17 @@ | |||
29 | #ifndef KEX_H | 29 | #ifndef KEX_H |
30 | #define KEX_H | 30 | #define KEX_H |
31 | 31 | ||
32 | #include "config.h" | ||
33 | |||
34 | #ifdef HAVE_OPENSSL | ||
35 | # include <openssl/bn.h> | ||
36 | # include <openssl/evp.h> | ||
37 | #endif | ||
38 | #ifdef HAVE_SSL | ||
39 | # include <ssl/bn.h> | ||
40 | # include <ssl/evp.h> | ||
41 | #endif | ||
42 | |||
32 | #define KEX_DH1 "diffie-hellman-group1-sha1" | 43 | #define KEX_DH1 "diffie-hellman-group1-sha1" |
33 | #define KEX_DSS "ssh-dss" | 44 | #define KEX_DSS "ssh-dss" |
34 | 45 | ||
diff --git a/myproposal.h b/myproposal.h new file mode 100644 index 000000000..7e4baff9d --- /dev/null +++ b/myproposal.h | |||
@@ -0,0 +1,20 @@ | |||
1 | #define KEX_DEFAULT_KEX "diffie-hellman-group1-sha1" | ||
2 | #define KEX_DEFAULT_PK_ALG "ssh-dss" | ||
3 | #define KEX_DEFAULT_ENCRYPT "blowfish-cbc,3des-cbc,arcfour,cast128-cbc" | ||
4 | #define KEX_DEFAULT_MAC "hmac-sha1,hmac-md5,hmac-ripemd160@openssh.com" | ||
5 | #define KEX_DEFAULT_COMP "zlib,none" | ||
6 | #define KEX_DEFAULT_LANG "" | ||
7 | |||
8 | |||
9 | static const char *myproposal[PROPOSAL_MAX] = { | ||
10 | KEX_DEFAULT_KEX, | ||
11 | KEX_DEFAULT_PK_ALG, | ||
12 | KEX_DEFAULT_ENCRYPT, | ||
13 | KEX_DEFAULT_ENCRYPT, | ||
14 | KEX_DEFAULT_MAC, | ||
15 | KEX_DEFAULT_MAC, | ||
16 | KEX_DEFAULT_COMP, | ||
17 | KEX_DEFAULT_COMP, | ||
18 | KEX_DEFAULT_LANG, | ||
19 | KEX_DEFAULT_LANG | ||
20 | }; | ||
@@ -17,7 +17,18 @@ | |||
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include "includes.h" | 19 | #include "includes.h" |
20 | RCSID("$Id: packet.c,v 1.15 2000/04/04 04:57:08 damien Exp $"); | 20 | RCSID("$Id: packet.c,v 1.16 2000/04/06 02:32:40 damien Exp $"); |
21 | |||
22 | #ifdef HAVE_OPENSSL | ||
23 | # include <openssl/bn.h> | ||
24 | # include <openssl/dh.h> | ||
25 | # include <openssl/hmac.h> | ||
26 | #endif /* HAVE_OPENSSL */ | ||
27 | #ifdef HAVE_SSL | ||
28 | # include <ssl/bn.h> | ||
29 | # include <ssl/dh.h> | ||
30 | # include <ssl/hmac.h> | ||
31 | #endif /* HAVE_SSL */ | ||
21 | 32 | ||
22 | #include "xmalloc.h" | 33 | #include "xmalloc.h" |
23 | #include "buffer.h" | 34 | #include "buffer.h" |
@@ -35,17 +46,6 @@ RCSID("$Id: packet.c,v 1.15 2000/04/04 04:57:08 damien Exp $"); | |||
35 | #include "compat.h" | 46 | #include "compat.h" |
36 | #include "ssh2.h" | 47 | #include "ssh2.h" |
37 | 48 | ||
38 | #ifdef HAVE_OPENSSL | ||
39 | # include <openssl/bn.h> | ||
40 | # include <openssl/dh.h> | ||
41 | # include <openssl/hmac.h> | ||
42 | #endif /* HAVE_OPENSSL */ | ||
43 | #ifdef HAVE_SSL | ||
44 | # include <ssl/bn.h> | ||
45 | # include <ssl/dh.h> | ||
46 | # include <ssl/hmac.h> | ||
47 | #endif /* HAVE_SSL */ | ||
48 | |||
49 | #include "buffer.h" | 49 | #include "buffer.h" |
50 | #include "kex.h" | 50 | #include "kex.h" |
51 | #include "hmac.h" | 51 | #include "hmac.h" |
@@ -152,8 +152,8 @@ packet_set_connection(int fd_in, int fd_out) | |||
152 | connection_in = fd_in; | 152 | connection_in = fd_in; |
153 | connection_out = fd_out; | 153 | connection_out = fd_out; |
154 | cipher_type = SSH_CIPHER_NONE; | 154 | cipher_type = SSH_CIPHER_NONE; |
155 | cipher_set_key(&send_context, SSH_CIPHER_NONE, (unsigned char *) "", 0, 1); | 155 | cipher_set_key(&send_context, SSH_CIPHER_NONE, (unsigned char *) "", 0); |
156 | cipher_set_key(&receive_context, SSH_CIPHER_NONE, (unsigned char *) "", 0, 0); | 156 | cipher_set_key(&receive_context, SSH_CIPHER_NONE, (unsigned char *) "", 0); |
157 | if (!initialized) { | 157 | if (!initialized) { |
158 | initialized = 1; | 158 | initialized = 1; |
159 | buffer_init(&input); | 159 | buffer_init(&input); |
@@ -352,8 +352,8 @@ packet_set_encryption_key(const unsigned char *key, unsigned int keylen, | |||
352 | fatal("keylen too small: %d", keylen); | 352 | fatal("keylen too small: %d", keylen); |
353 | 353 | ||
354 | /* All other ciphers use the same key in both directions for now. */ | 354 | /* All other ciphers use the same key in both directions for now. */ |
355 | cipher_set_key(&receive_context, cipher, key, keylen, 0); | 355 | cipher_set_key(&receive_context, cipher, key, keylen); |
356 | cipher_set_key(&send_context, cipher, key, keylen, 1); | 356 | cipher_set_key(&send_context, cipher, key, keylen); |
357 | } | 357 | } |
358 | 358 | ||
359 | /* Starts constructing a packet to send. */ | 359 | /* Starts constructing a packet to send. */ |
@@ -13,13 +13,11 @@ | |||
13 | * | 13 | * |
14 | */ | 14 | */ |
15 | 15 | ||
16 | /* RCSID("$Id: packet.h,v 1.11 2000/04/04 04:39:03 damien Exp $"); */ | 16 | /* RCSID("$Id: packet.h,v 1.12 2000/04/06 02:32:40 damien Exp $"); */ |
17 | 17 | ||
18 | #ifndef PACKET_H | 18 | #ifndef PACKET_H |
19 | #define PACKET_H | 19 | #define PACKET_H |
20 | 20 | ||
21 | #include "config.h" | ||
22 | |||
23 | #ifdef HAVE_OPENSSL | 21 | #ifdef HAVE_OPENSSL |
24 | #include <openssl/bn.h> | 22 | #include <openssl/bn.h> |
25 | #endif | 23 | #endif |
@@ -11,7 +11,7 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include "includes.h" | 13 | #include "includes.h" |
14 | RCSID("$Id: ssh.c,v 1.23 2000/04/01 01:09:26 damien Exp $"); | 14 | RCSID("$Id: ssh.c,v 1.24 2000/04/06 02:32:40 damien Exp $"); |
15 | 15 | ||
16 | #include "xmalloc.h" | 16 | #include "xmalloc.h" |
17 | #include "ssh.h" | 17 | #include "ssh.h" |
@@ -20,6 +20,9 @@ RCSID("$Id: ssh.c,v 1.23 2000/04/01 01:09:26 damien Exp $"); | |||
20 | #include "authfd.h" | 20 | #include "authfd.h" |
21 | #include "readconf.h" | 21 | #include "readconf.h" |
22 | #include "uidswap.h" | 22 | #include "uidswap.h" |
23 | |||
24 | #include "ssh2.h" | ||
25 | #include "compat.h" | ||
23 | #include "channels.h" | 26 | #include "channels.h" |
24 | 27 | ||
25 | #ifdef HAVE___PROGNAME | 28 | #ifdef HAVE___PROGNAME |
@@ -41,6 +44,10 @@ int debug_flag = 0; | |||
41 | 44 | ||
42 | int tty_flag = 0; | 45 | int tty_flag = 0; |
43 | 46 | ||
47 | /* don't exec a shell */ | ||
48 | int no_shell_flag = 0; | ||
49 | int no_tty_flag = 0; | ||
50 | |||
44 | /* | 51 | /* |
45 | * Flag indicating that nothing should be read from stdin. This can be set | 52 | * Flag indicating that nothing should be read from stdin. This can be set |
46 | * on the command line. | 53 | * on the command line. |
@@ -90,6 +97,9 @@ RSA *host_private_key = NULL; | |||
90 | /* Original real UID. */ | 97 | /* Original real UID. */ |
91 | uid_t original_real_uid; | 98 | uid_t original_real_uid; |
92 | 99 | ||
100 | /* command to be executed */ | ||
101 | Buffer command; | ||
102 | |||
93 | /* Prints a help message to the user. This function never returns. */ | 103 | /* Prints a help message to the user. This function never returns. */ |
94 | 104 | ||
95 | void | 105 | void |
@@ -104,9 +114,9 @@ usage() | |||
104 | fprintf(stderr, " -k Disable Kerberos ticket and AFS token forwarding.\n"); | 114 | fprintf(stderr, " -k Disable Kerberos ticket and AFS token forwarding.\n"); |
105 | #endif /* AFS */ | 115 | #endif /* AFS */ |
106 | fprintf(stderr, " -x Disable X11 connection forwarding.\n"); | 116 | fprintf(stderr, " -x Disable X11 connection forwarding.\n"); |
107 | fprintf(stderr, " -X Enable X11 connection forwarding.\n"); | ||
108 | fprintf(stderr, " -i file Identity for RSA authentication (default: ~/.ssh/identity).\n"); | 117 | fprintf(stderr, " -i file Identity for RSA authentication (default: ~/.ssh/identity).\n"); |
109 | fprintf(stderr, " -t Tty; allocate a tty even if command is given.\n"); | 118 | fprintf(stderr, " -t Tty; allocate a tty even if command is given.\n"); |
119 | fprintf(stderr, " -T Do not allocate a tty.\n"); | ||
110 | fprintf(stderr, " -v Verbose; display verbose debugging messages.\n"); | 120 | fprintf(stderr, " -v Verbose; display verbose debugging messages.\n"); |
111 | fprintf(stderr, " -V Display version number only.\n"); | 121 | fprintf(stderr, " -V Display version number only.\n"); |
112 | fprintf(stderr, " -P Don't allocate a privileged port.\n"); | 122 | fprintf(stderr, " -P Don't allocate a privileged port.\n"); |
@@ -123,6 +133,7 @@ usage() | |||
123 | fprintf(stderr, " These cause %s to listen for connections on a port, and\n", av0); | 133 | fprintf(stderr, " These cause %s to listen for connections on a port, and\n", av0); |
124 | fprintf(stderr, " forward them to the other side by connecting to host:port.\n"); | 134 | fprintf(stderr, " forward them to the other side by connecting to host:port.\n"); |
125 | fprintf(stderr, " -C Enable compression.\n"); | 135 | fprintf(stderr, " -C Enable compression.\n"); |
136 | fprintf(stderr, " -N Do not execute a shell or command.\n"); | ||
126 | fprintf(stderr, " -g Allow remote hosts to connect to forwarded ports.\n"); | 137 | fprintf(stderr, " -g Allow remote hosts to connect to forwarded ports.\n"); |
127 | fprintf(stderr, " -4 Use IPv4 only.\n"); | 138 | fprintf(stderr, " -4 Use IPv4 only.\n"); |
128 | fprintf(stderr, " -6 Use IPv6 only.\n"); | 139 | fprintf(stderr, " -6 Use IPv6 only.\n"); |
@@ -168,23 +179,22 @@ rsh_connect(char *host, char *user, Buffer * command) | |||
168 | exit(1); | 179 | exit(1); |
169 | } | 180 | } |
170 | 181 | ||
182 | int ssh_session(void); | ||
183 | int ssh_session2(void); | ||
184 | |||
171 | /* | 185 | /* |
172 | * Main program for the ssh client. | 186 | * Main program for the ssh client. |
173 | */ | 187 | */ |
174 | int | 188 | int |
175 | main(int ac, char **av) | 189 | main(int ac, char **av) |
176 | { | 190 | { |
177 | int i, opt, optind, type, exit_status, ok, authfd; | 191 | int i, opt, optind, exit_status, ok; |
178 | u_short fwd_port, fwd_host_port; | 192 | u_short fwd_port, fwd_host_port; |
179 | char *optarg, *cp, buf[256]; | 193 | char *optarg, *cp, buf[256]; |
180 | Buffer command; | ||
181 | struct winsize ws; | ||
182 | struct stat st; | 194 | struct stat st; |
183 | struct passwd *pw, pwcopy; | 195 | struct passwd *pw, pwcopy; |
184 | int interactive = 0, dummy; | 196 | int dummy; |
185 | int have_pty = 0; | ||
186 | uid_t original_effective_uid; | 197 | uid_t original_effective_uid; |
187 | int plen; | ||
188 | 198 | ||
189 | /* | 199 | /* |
190 | * Save the original real uid. It will be needed later (uid-swapping | 200 | * Save the original real uid. It will be needed later (uid-swapping |
@@ -328,7 +338,7 @@ main(int ac, char **av) | |||
328 | case 'V': | 338 | case 'V': |
329 | fprintf(stderr, "SSH Version %s, protocol version %d.%d.\n", | 339 | fprintf(stderr, "SSH Version %s, protocol version %d.%d.\n", |
330 | SSH_VERSION, PROTOCOL_MAJOR, PROTOCOL_MINOR); | 340 | SSH_VERSION, PROTOCOL_MAJOR, PROTOCOL_MINOR); |
331 | fprintf(stderr, "Compiled with SSL.\n"); | 341 | fprintf(stderr, "Compiled with SSL (0x%8.8lx).\n", SSLeay()); |
332 | if (opt == 'V') | 342 | if (opt == 'V') |
333 | exit(0); | 343 | exit(0); |
334 | debug_flag = 1; | 344 | debug_flag = 1; |
@@ -397,6 +407,15 @@ main(int ac, char **av) | |||
397 | options.compression = 1; | 407 | options.compression = 1; |
398 | break; | 408 | break; |
399 | 409 | ||
410 | case 'N': | ||
411 | no_shell_flag = 1; | ||
412 | no_tty_flag = 1; | ||
413 | break; | ||
414 | |||
415 | case 'T': | ||
416 | no_tty_flag = 1; | ||
417 | break; | ||
418 | |||
400 | case 'o': | 419 | case 'o': |
401 | dummy = 1; | 420 | dummy = 1; |
402 | if (process_config_line(&options, host ? host : "", optarg, | 421 | if (process_config_line(&options, host ? host : "", optarg, |
@@ -455,6 +474,10 @@ main(int ac, char **av) | |||
455 | fprintf(stderr, "Pseudo-terminal will not be allocated because stdin is not a terminal.\n"); | 474 | fprintf(stderr, "Pseudo-terminal will not be allocated because stdin is not a terminal.\n"); |
456 | tty_flag = 0; | 475 | tty_flag = 0; |
457 | } | 476 | } |
477 | /* force */ | ||
478 | if (no_tty_flag) | ||
479 | tty_flag = 0; | ||
480 | |||
458 | /* Get user data. */ | 481 | /* Get user data. */ |
459 | pw = getpwuid(original_real_uid); | 482 | pw = getpwuid(original_real_uid); |
460 | if (!pw) { | 483 | if (!pw) { |
@@ -620,6 +643,23 @@ main(int ac, char **av) | |||
620 | if (host_private_key_loaded) | 643 | if (host_private_key_loaded) |
621 | RSA_free(host_private_key); /* Destroys contents safely */ | 644 | RSA_free(host_private_key); /* Destroys contents safely */ |
622 | 645 | ||
646 | exit_status = compat20 ? ssh_session2() : ssh_session(); | ||
647 | packet_close(); | ||
648 | return exit_status; | ||
649 | } | ||
650 | |||
651 | int | ||
652 | ssh_session(void) | ||
653 | { | ||
654 | int type; | ||
655 | int i; | ||
656 | int plen; | ||
657 | int interactive = 0; | ||
658 | int have_tty = 0; | ||
659 | struct winsize ws; | ||
660 | int authfd; | ||
661 | char *cp; | ||
662 | |||
623 | /* Enable compression if requested. */ | 663 | /* Enable compression if requested. */ |
624 | if (options.compression) { | 664 | if (options.compression) { |
625 | debug("Requesting compression at level %d.", options.compression_level); | 665 | debug("Requesting compression at level %d.", options.compression_level); |
@@ -673,7 +713,7 @@ main(int ac, char **av) | |||
673 | type = packet_read(&plen); | 713 | type = packet_read(&plen); |
674 | if (type == SSH_SMSG_SUCCESS) { | 714 | if (type == SSH_SMSG_SUCCESS) { |
675 | interactive = 1; | 715 | interactive = 1; |
676 | have_pty = 1; | 716 | have_tty = 1; |
677 | } else if (type == SSH_SMSG_FAILURE) | 717 | } else if (type == SSH_SMSG_FAILURE) |
678 | log("Warning: Remote host failed or refused to allocate a pseudo tty."); | 718 | log("Warning: Remote host failed or refused to allocate a pseudo tty."); |
679 | else | 719 | else |
@@ -802,11 +842,103 @@ main(int ac, char **av) | |||
802 | } | 842 | } |
803 | 843 | ||
804 | /* Enter the interactive session. */ | 844 | /* Enter the interactive session. */ |
805 | exit_status = client_loop(have_pty, tty_flag ? options.escape_char : -1); | 845 | return client_loop(have_tty, tty_flag ? options.escape_char : -1); |
846 | } | ||
806 | 847 | ||
807 | /* Close the connection to the remote host. */ | 848 | void |
808 | packet_close(); | 849 | init_local_fwd(void) |
850 | { | ||
851 | int i; | ||
852 | /* Initiate local TCP/IP port forwardings. */ | ||
853 | for (i = 0; i < options.num_local_forwards; i++) { | ||
854 | debug("Connections to local port %d forwarded to remote address %.200s:%d", | ||
855 | options.local_forwards[i].port, | ||
856 | options.local_forwards[i].host, | ||
857 | options.local_forwards[i].host_port); | ||
858 | channel_request_local_forwarding(options.local_forwards[i].port, | ||
859 | options.local_forwards[i].host, | ||
860 | options.local_forwards[i].host_port, | ||
861 | options.gateway_ports); | ||
862 | } | ||
863 | } | ||
864 | |||
865 | extern void client_set_session_ident(int id); | ||
866 | |||
867 | void | ||
868 | client_init(int id, void *arg) | ||
869 | { | ||
870 | int len; | ||
871 | debug("client_init id %d arg %d", id, (int)arg); | ||
872 | |||
873 | if (no_shell_flag) | ||
874 | goto done; | ||
875 | |||
876 | if (tty_flag) { | ||
877 | struct winsize ws; | ||
878 | char *cp; | ||
879 | cp = getenv("TERM"); | ||
880 | if (!cp) | ||
881 | cp = ""; | ||
882 | /* Store window size in the packet. */ | ||
883 | if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0) | ||
884 | memset(&ws, 0, sizeof(ws)); | ||
885 | |||
886 | channel_request_start(id, "pty-req", 0); | ||
887 | packet_put_cstring(cp); | ||
888 | packet_put_int(ws.ws_col); | ||
889 | packet_put_int(ws.ws_row); | ||
890 | packet_put_int(ws.ws_xpixel); | ||
891 | packet_put_int(ws.ws_ypixel); | ||
892 | packet_put_cstring(""); /* XXX: encode terminal modes */ | ||
893 | packet_send(); | ||
894 | /* XXX wait for reply */ | ||
895 | } | ||
896 | len = buffer_len(&command); | ||
897 | if (len > 0) { | ||
898 | if (len > 900) | ||
899 | len = 900; | ||
900 | debug("Sending command: %.*s", len, buffer_ptr(&command)); | ||
901 | channel_request_start(id, "exec", 0); | ||
902 | packet_put_string(buffer_ptr(&command), len); | ||
903 | packet_send(); | ||
904 | } else { | ||
905 | channel_request(id, "shell", 0); | ||
906 | } | ||
907 | /* channel_callback(id, SSH2_MSG_OPEN_CONFIGMATION, client_init, 0); */ | ||
908 | done: | ||
909 | /* register different callback, etc. XXX */ | ||
910 | client_set_session_ident(id); | ||
911 | } | ||
912 | |||
913 | int | ||
914 | ssh_session2(void) | ||
915 | { | ||
916 | int window, packetmax, id; | ||
917 | int in = dup(STDIN_FILENO); | ||
918 | int out = dup(STDOUT_FILENO); | ||
919 | int err = dup(STDERR_FILENO); | ||
920 | |||
921 | if (in < 0 || out < 0 || err < 0) | ||
922 | fatal("dump in/out/err failed"); | ||
923 | |||
924 | /* should be pre-session */ | ||
925 | init_local_fwd(); | ||
926 | |||
927 | window = 32*1024; | ||
928 | if (tty_flag) { | ||
929 | packetmax = window/8; | ||
930 | } else { | ||
931 | window *= 2; | ||
932 | packetmax = window/2; | ||
933 | } | ||
934 | |||
935 | id = channel_new( | ||
936 | "session", SSH_CHANNEL_OPENING, in, out, err, | ||
937 | window, packetmax, CHAN_EXTENDED_WRITE, xstrdup("client-session")); | ||
938 | |||
939 | |||
940 | channel_open(id); | ||
941 | channel_register_callback(id, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, client_init, (void *)0); | ||
809 | 942 | ||
810 | /* Exit with the status returned by the program on the remote side. */ | 943 | return client_loop(tty_flag, tty_flag ? options.escape_char : -1); |
811 | exit(exit_status); | ||
812 | } | 944 | } |
diff --git a/sshconnect.c b/sshconnect.c index d64c0e2c0..2f9496090 100644 --- a/sshconnect.c +++ b/sshconnect.c | |||
@@ -5,27 +5,30 @@ | |||
5 | * Created: Sat Mar 18 22:15:47 1995 ylo | 5 | * Created: Sat Mar 18 22:15:47 1995 ylo |
6 | * Code to connect to a remote host, and to perform the client side of the | 6 | * Code to connect to a remote host, and to perform the client side of the |
7 | * login (authentication) dialog. | 7 | * login (authentication) dialog. |
8 | * | ||
9 | * SSH2 support added by Markus Friedl. | ||
8 | */ | 10 | */ |
9 | 11 | ||
10 | #include "includes.h" | 12 | #include "includes.h" |
11 | RCSID("$OpenBSD: sshconnect.c,v 1.58 2000/03/23 22:15:33 markus Exp $"); | 13 | RCSID("$OpenBSD: sshconnect.c,v 1.61 2000/04/04 21:37:27 markus Exp $"); |
12 | 14 | ||
13 | #ifdef HAVE_OPENSSL | 15 | #ifdef HAVE_OPENSSL |
16 | #include <openssl/bn.h> | ||
14 | #include <openssl/rsa.h> | 17 | #include <openssl/rsa.h> |
15 | #include <openssl/dsa.h> | 18 | #include <openssl/dsa.h> |
16 | #include <openssl/md5.h> | 19 | #include <openssl/md5.h> |
17 | #include <openssl/bn.h> | ||
18 | #endif | 20 | #endif |
19 | #ifdef HAVE_SSL | 21 | #ifdef HAVE_SSL |
22 | #include <ssl/bn.h> | ||
20 | #include <ssl/rsa.h> | 23 | #include <ssl/rsa.h> |
21 | #include <ssl/dsa.h> | 24 | #include <ssl/dsa.h> |
22 | #include <ssl/md5.h> | 25 | #include <ssl/md5.h> |
23 | #include <ssl/bn.h> | ||
24 | #endif | 26 | #endif |
25 | 27 | ||
26 | #include "xmalloc.h" | 28 | #include "xmalloc.h" |
27 | #include "rsa.h" | 29 | #include "rsa.h" |
28 | #include "ssh.h" | 30 | #include "ssh.h" |
31 | #include "buffer.h" | ||
29 | #include "packet.h" | 32 | #include "packet.h" |
30 | #include "authfd.h" | 33 | #include "authfd.h" |
31 | #include "cipher.h" | 34 | #include "cipher.h" |
@@ -33,7 +36,14 @@ RCSID("$OpenBSD: sshconnect.c,v 1.58 2000/03/23 22:15:33 markus Exp $"); | |||
33 | #include "uidswap.h" | 36 | #include "uidswap.h" |
34 | #include "compat.h" | 37 | #include "compat.h" |
35 | #include "readconf.h" | 38 | #include "readconf.h" |
39 | |||
40 | #include "bufaux.h" | ||
41 | |||
42 | #include "ssh2.h" | ||
43 | #include "kex.h" | ||
44 | #include "myproposal.h" | ||
36 | #include "key.h" | 45 | #include "key.h" |
46 | #include "dsa.h" | ||
37 | #include "hostfile.h" | 47 | #include "hostfile.h" |
38 | 48 | ||
39 | /* Session id for the current session. */ | 49 | /* Session id for the current session. */ |
@@ -42,6 +52,9 @@ unsigned char session_id[16]; | |||
42 | /* authentications supported by server */ | 52 | /* authentications supported by server */ |
43 | unsigned int supported_authentications; | 53 | unsigned int supported_authentications; |
44 | 54 | ||
55 | static char *client_version_string = NULL; | ||
56 | static char *server_version_string = NULL; | ||
57 | |||
45 | extern Options options; | 58 | extern Options options; |
46 | extern char *__progname; | 59 | extern char *__progname; |
47 | 60 | ||
@@ -957,6 +970,21 @@ try_password_authentication(char *prompt) | |||
957 | return 0; | 970 | return 0; |
958 | } | 971 | } |
959 | 972 | ||
973 | char * | ||
974 | chop(char *s) | ||
975 | { | ||
976 | char *t = s; | ||
977 | while (*t) { | ||
978 | if(*t == '\n' || *t == '\r') { | ||
979 | *t = '\0'; | ||
980 | return s; | ||
981 | } | ||
982 | t++; | ||
983 | } | ||
984 | return s; | ||
985 | |||
986 | } | ||
987 | |||
960 | /* | 988 | /* |
961 | * Waits for the server identification string, and sends our own | 989 | * Waits for the server identification string, and sends our own |
962 | * identification string. | 990 | * identification string. |
@@ -979,7 +1007,7 @@ ssh_exchange_identification() | |||
979 | if (buf[i] == '\r') { | 1007 | if (buf[i] == '\r') { |
980 | buf[i] = '\n'; | 1008 | buf[i] = '\n'; |
981 | buf[i + 1] = 0; | 1009 | buf[i + 1] = 0; |
982 | break; | 1010 | continue; /**XXX wait for \n */ |
983 | } | 1011 | } |
984 | if (buf[i] == '\n') { | 1012 | if (buf[i] == '\n') { |
985 | buf[i + 1] = 0; | 1013 | buf[i + 1] = 0; |
@@ -987,17 +1015,21 @@ ssh_exchange_identification() | |||
987 | } | 1015 | } |
988 | } | 1016 | } |
989 | buf[sizeof(buf) - 1] = 0; | 1017 | buf[sizeof(buf) - 1] = 0; |
1018 | server_version_string = xstrdup(buf); | ||
990 | 1019 | ||
991 | /* | 1020 | /* |
992 | * Check that the versions match. In future this might accept | 1021 | * Check that the versions match. In future this might accept |
993 | * several versions and set appropriate flags to handle them. | 1022 | * several versions and set appropriate flags to handle them. |
994 | */ | 1023 | */ |
995 | if (sscanf(buf, "SSH-%d.%d-%[^\n]\n", &remote_major, &remote_minor, | 1024 | if (sscanf(server_version_string, "SSH-%d.%d-%[^\n]\n", |
996 | remote_version) != 3) | 1025 | &remote_major, &remote_minor, remote_version) != 3) |
997 | fatal("Bad remote protocol version identification: '%.100s'", buf); | 1026 | fatal("Bad remote protocol version identification: '%.100s'", buf); |
998 | debug("Remote protocol version %d.%d, remote software version %.100s", | 1027 | debug("Remote protocol version %d.%d, remote software version %.100s", |
999 | remote_major, remote_minor, remote_version); | 1028 | remote_major, remote_minor, remote_version); |
1000 | 1029 | ||
1030 | /*** XXX option for disabling 2.0 or 1.5 */ | ||
1031 | compat_datafellows(remote_version); | ||
1032 | |||
1001 | /* Check if the remote protocol version is too old. */ | 1033 | /* Check if the remote protocol version is too old. */ |
1002 | if (remote_major == 1 && remote_minor < 3) | 1034 | if (remote_major == 1 && remote_minor < 3) |
1003 | fatal("Remote machine has too old SSH software version."); | 1035 | fatal("Remote machine has too old SSH software version."); |
@@ -1010,6 +1042,10 @@ ssh_exchange_identification() | |||
1010 | options.forward_agent = 0; | 1042 | options.forward_agent = 0; |
1011 | } | 1043 | } |
1012 | } | 1044 | } |
1045 | if ((remote_major == 2 && remote_minor == 0) || | ||
1046 | (remote_major == 1 && remote_minor == 99)) { | ||
1047 | enable_compat20(); | ||
1048 | } | ||
1013 | #if 0 | 1049 | #if 0 |
1014 | /* | 1050 | /* |
1015 | * Removed for now, to permit compatibility with latter versions. The | 1051 | * Removed for now, to permit compatibility with latter versions. The |
@@ -1020,16 +1056,19 @@ ssh_exchange_identification() | |||
1020 | fatal("Protocol major versions differ: %d vs. %d", | 1056 | fatal("Protocol major versions differ: %d vs. %d", |
1021 | PROTOCOL_MAJOR, remote_major); | 1057 | PROTOCOL_MAJOR, remote_major); |
1022 | #endif | 1058 | #endif |
1023 | |||
1024 | /* Send our own protocol version identification. */ | 1059 | /* Send our own protocol version identification. */ |
1025 | snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", | 1060 | snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s\n", |
1026 | PROTOCOL_MAJOR, PROTOCOL_MINOR, SSH_VERSION); | 1061 | compat20 ? 2 : PROTOCOL_MAJOR, |
1062 | compat20 ? 0 : PROTOCOL_MINOR, | ||
1063 | SSH_VERSION); | ||
1027 | if (atomicio(write, connection_out, buf, strlen(buf)) != strlen(buf)) | 1064 | if (atomicio(write, connection_out, buf, strlen(buf)) != strlen(buf)) |
1028 | fatal("write: %.100s", strerror(errno)); | 1065 | fatal("write: %.100s", strerror(errno)); |
1066 | client_version_string = xstrdup(buf); | ||
1067 | chop(client_version_string); | ||
1068 | chop(server_version_string); | ||
1069 | debug("Local version string %.100s", client_version_string); | ||
1029 | } | 1070 | } |
1030 | 1071 | ||
1031 | int ssh_cipher_default = SSH_CIPHER_3DES; | ||
1032 | |||
1033 | int | 1072 | int |
1034 | read_yes_or_no(const char *prompt, int defval) | 1073 | read_yes_or_no(const char *prompt, int defval) |
1035 | { | 1074 | { |
@@ -1283,6 +1322,278 @@ check_rsa_host_key(char *host, struct sockaddr *hostaddr, RSA *host_key) | |||
1283 | } | 1322 | } |
1284 | 1323 | ||
1285 | /* | 1324 | /* |
1325 | * SSH2 key exchange | ||
1326 | */ | ||
1327 | void | ||
1328 | ssh_kex2(char *host, struct sockaddr *hostaddr) | ||
1329 | { | ||
1330 | Kex *kex; | ||
1331 | char *cprop[PROPOSAL_MAX]; | ||
1332 | char *sprop[PROPOSAL_MAX]; | ||
1333 | Buffer *client_kexinit; | ||
1334 | Buffer *server_kexinit; | ||
1335 | int payload_len, dlen; | ||
1336 | unsigned int klen, kout; | ||
1337 | char *ptr; | ||
1338 | char *signature = NULL; | ||
1339 | unsigned int slen; | ||
1340 | char *server_host_key_blob = NULL; | ||
1341 | Key *server_host_key; | ||
1342 | unsigned int sbloblen; | ||
1343 | DH *dh; | ||
1344 | BIGNUM *dh_server_pub = 0; | ||
1345 | BIGNUM *shared_secret = 0; | ||
1346 | int i; | ||
1347 | unsigned char *kbuf; | ||
1348 | unsigned char *hash; | ||
1349 | |||
1350 | /* KEXINIT */ | ||
1351 | |||
1352 | debug("Sending KEX init."); | ||
1353 | if (options.cipher == SSH_CIPHER_ARCFOUR || | ||
1354 | options.cipher == SSH_CIPHER_3DES_CBC || | ||
1355 | options.cipher == SSH_CIPHER_CAST128_CBC || | ||
1356 | options.cipher == SSH_CIPHER_BLOWFISH_CBC) { | ||
1357 | myproposal[PROPOSAL_ENC_ALGS_CTOS] = cipher_name(options.cipher); | ||
1358 | myproposal[PROPOSAL_ENC_ALGS_STOC] = cipher_name(options.cipher); | ||
1359 | } | ||
1360 | if (options.compression) { | ||
1361 | myproposal[PROPOSAL_COMP_ALGS_CTOS] = "zlib"; | ||
1362 | myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib"; | ||
1363 | } else { | ||
1364 | myproposal[PROPOSAL_COMP_ALGS_CTOS] = "none"; | ||
1365 | myproposal[PROPOSAL_COMP_ALGS_STOC] = "none"; | ||
1366 | } | ||
1367 | for (i = 0; i < PROPOSAL_MAX; i++) | ||
1368 | cprop[i] = xstrdup(myproposal[i]); | ||
1369 | |||
1370 | client_kexinit = kex_init(cprop); | ||
1371 | packet_start(SSH2_MSG_KEXINIT); | ||
1372 | packet_put_raw(buffer_ptr(client_kexinit), buffer_len(client_kexinit)); | ||
1373 | packet_send(); | ||
1374 | packet_write_wait(); | ||
1375 | |||
1376 | debug("done"); | ||
1377 | |||
1378 | packet_read_expect(&payload_len, SSH2_MSG_KEXINIT); | ||
1379 | |||
1380 | /* save payload for session_id */ | ||
1381 | server_kexinit = xmalloc(sizeof(*server_kexinit)); | ||
1382 | buffer_init(server_kexinit); | ||
1383 | ptr = packet_get_raw(&payload_len); | ||
1384 | buffer_append(server_kexinit, ptr, payload_len); | ||
1385 | |||
1386 | /* skip cookie */ | ||
1387 | for (i = 0; i < 16; i++) | ||
1388 | (void) packet_get_char(); | ||
1389 | /* kex init proposal strings */ | ||
1390 | for (i = 0; i < PROPOSAL_MAX; i++) { | ||
1391 | sprop[i] = packet_get_string(NULL); | ||
1392 | debug("got kexinit string: %s", sprop[i]); | ||
1393 | } | ||
1394 | i = (int) packet_get_char(); | ||
1395 | debug("first kex follow == %d", i); | ||
1396 | i = packet_get_int(); | ||
1397 | debug("reserved == %d", i); | ||
1398 | |||
1399 | debug("done read kexinit"); | ||
1400 | kex = kex_choose_conf(cprop, sprop, 0); | ||
1401 | |||
1402 | /* KEXDH */ | ||
1403 | |||
1404 | debug("Sending SSH2_MSG_KEXDH_INIT."); | ||
1405 | |||
1406 | /* generate and send 'e', client DH public key */ | ||
1407 | dh = new_dh_group1(); | ||
1408 | packet_start(SSH2_MSG_KEXDH_INIT); | ||
1409 | packet_put_bignum2(dh->pub_key); | ||
1410 | packet_send(); | ||
1411 | packet_write_wait(); | ||
1412 | |||
1413 | #ifdef DEBUG_KEXDH | ||
1414 | fprintf(stderr, "\np= "); | ||
1415 | bignum_print(dh->p); | ||
1416 | fprintf(stderr, "\ng= "); | ||
1417 | bignum_print(dh->g); | ||
1418 | fprintf(stderr, "\npub= "); | ||
1419 | bignum_print(dh->pub_key); | ||
1420 | fprintf(stderr, "\n"); | ||
1421 | DHparams_print_fp(stderr, dh); | ||
1422 | #endif | ||
1423 | |||
1424 | debug("Wait SSH2_MSG_KEXDH_REPLY."); | ||
1425 | |||
1426 | packet_read_expect(&payload_len, SSH2_MSG_KEXDH_REPLY); | ||
1427 | |||
1428 | debug("Got SSH2_MSG_KEXDH_REPLY."); | ||
1429 | |||
1430 | /* key, cert */ | ||
1431 | server_host_key_blob = packet_get_string(&sbloblen); | ||
1432 | server_host_key = dsa_serverkey_from_blob(server_host_key_blob, sbloblen); | ||
1433 | if (server_host_key == NULL) | ||
1434 | fatal("cannot decode server_host_key_blob"); | ||
1435 | |||
1436 | check_host_key(host, hostaddr, server_host_key); | ||
1437 | |||
1438 | /* DH paramter f, server public DH key */ | ||
1439 | dh_server_pub = BN_new(); | ||
1440 | if (dh_server_pub == NULL) | ||
1441 | fatal("dh_server_pub == NULL"); | ||
1442 | packet_get_bignum2(dh_server_pub, &dlen); | ||
1443 | |||
1444 | #ifdef DEBUG_KEXDH | ||
1445 | fprintf(stderr, "\ndh_server_pub= "); | ||
1446 | bignum_print(dh_server_pub); | ||
1447 | fprintf(stderr, "\n"); | ||
1448 | debug("bits %d", BN_num_bits(dh_server_pub)); | ||
1449 | #endif | ||
1450 | |||
1451 | /* signed H */ | ||
1452 | signature = packet_get_string(&slen); | ||
1453 | |||
1454 | klen = DH_size(dh); | ||
1455 | kbuf = xmalloc(klen); | ||
1456 | kout = DH_compute_key(kbuf, dh_server_pub, dh); | ||
1457 | #ifdef DEBUG_KEXDH | ||
1458 | debug("shared secret: len %d/%d", klen, kout); | ||
1459 | fprintf(stderr, "shared secret == "); | ||
1460 | for (i = 0; i< kout; i++) | ||
1461 | fprintf(stderr, "%02x", (kbuf[i])&0xff); | ||
1462 | fprintf(stderr, "\n"); | ||
1463 | #endif | ||
1464 | shared_secret = BN_new(); | ||
1465 | |||
1466 | BN_bin2bn(kbuf, kout, shared_secret); | ||
1467 | memset(kbuf, 0, klen); | ||
1468 | xfree(kbuf); | ||
1469 | |||
1470 | /* calc and verify H */ | ||
1471 | hash = kex_hash( | ||
1472 | client_version_string, | ||
1473 | server_version_string, | ||
1474 | buffer_ptr(client_kexinit), buffer_len(client_kexinit), | ||
1475 | buffer_ptr(server_kexinit), buffer_len(server_kexinit), | ||
1476 | server_host_key_blob, sbloblen, | ||
1477 | dh->pub_key, | ||
1478 | dh_server_pub, | ||
1479 | shared_secret | ||
1480 | ); | ||
1481 | buffer_free(client_kexinit); | ||
1482 | buffer_free(server_kexinit); | ||
1483 | xfree(client_kexinit); | ||
1484 | xfree(server_kexinit); | ||
1485 | #ifdef DEBUG_KEXDH | ||
1486 | fprintf(stderr, "hash == "); | ||
1487 | for (i = 0; i< 20; i++) | ||
1488 | fprintf(stderr, "%02x", (hash[i])&0xff); | ||
1489 | fprintf(stderr, "\n"); | ||
1490 | #endif | ||
1491 | dsa_verify(server_host_key, (unsigned char *)signature, slen, hash, 20); | ||
1492 | key_free(server_host_key); | ||
1493 | |||
1494 | kex_derive_keys(kex, hash, shared_secret); | ||
1495 | packet_set_kex(kex); | ||
1496 | |||
1497 | /* have keys, free DH */ | ||
1498 | DH_free(dh); | ||
1499 | |||
1500 | debug("Wait SSH2_MSG_NEWKEYS."); | ||
1501 | packet_read_expect(&payload_len, SSH2_MSG_NEWKEYS); | ||
1502 | debug("GOT SSH2_MSG_NEWKEYS."); | ||
1503 | |||
1504 | debug("send SSH2_MSG_NEWKEYS."); | ||
1505 | packet_start(SSH2_MSG_NEWKEYS); | ||
1506 | packet_send(); | ||
1507 | packet_write_wait(); | ||
1508 | debug("done: send SSH2_MSG_NEWKEYS."); | ||
1509 | |||
1510 | /* send 1st encrypted/maced/compressed message */ | ||
1511 | packet_start(SSH2_MSG_IGNORE); | ||
1512 | packet_put_cstring("markus"); | ||
1513 | packet_send(); | ||
1514 | packet_write_wait(); | ||
1515 | |||
1516 | debug("done: KEX2."); | ||
1517 | } | ||
1518 | /* | ||
1519 | * Authenticate user | ||
1520 | */ | ||
1521 | void | ||
1522 | ssh_userauth2(int host_key_valid, RSA *own_host_key, | ||
1523 | uid_t original_real_uid, char *host) | ||
1524 | { | ||
1525 | int type; | ||
1526 | int plen; | ||
1527 | unsigned int dlen; | ||
1528 | int partial; | ||
1529 | struct passwd *pw; | ||
1530 | char *server_user, *local_user; | ||
1531 | char *auths; | ||
1532 | char *password; | ||
1533 | char *service = "ssh-connection"; // service name | ||
1534 | |||
1535 | debug("send SSH2_MSG_SERVICE_REQUEST"); | ||
1536 | packet_start(SSH2_MSG_SERVICE_REQUEST); | ||
1537 | packet_put_cstring("ssh-userauth"); | ||
1538 | packet_send(); | ||
1539 | packet_write_wait(); | ||
1540 | |||
1541 | type = packet_read(&plen); | ||
1542 | if (type != SSH2_MSG_SERVICE_ACCEPT) { | ||
1543 | fatal("denied SSH2_MSG_SERVICE_ACCEPT: %d", type); | ||
1544 | } | ||
1545 | /* payload empty for ssh-2.0.13 ?? */ | ||
1546 | /* reply = packet_get_string(&payload_len); */ | ||
1547 | debug("got SSH2_MSG_SERVICE_ACCEPT"); | ||
1548 | |||
1549 | /*XX COMMONCODE: */ | ||
1550 | /* Get local user name. Use it as server user if no user name was given. */ | ||
1551 | pw = getpwuid(original_real_uid); | ||
1552 | if (!pw) | ||
1553 | fatal("User id %d not found from user database.", original_real_uid); | ||
1554 | local_user = xstrdup(pw->pw_name); | ||
1555 | server_user = options.user ? options.user : local_user; | ||
1556 | |||
1557 | /* INITIAL request for auth */ | ||
1558 | packet_start(SSH2_MSG_USERAUTH_REQUEST); | ||
1559 | packet_put_cstring(server_user); | ||
1560 | packet_put_cstring(service); | ||
1561 | packet_put_cstring("none"); | ||
1562 | packet_send(); | ||
1563 | packet_write_wait(); | ||
1564 | |||
1565 | for (;;) { | ||
1566 | type = packet_read(&plen); | ||
1567 | if (type == SSH2_MSG_USERAUTH_SUCCESS) | ||
1568 | break; | ||
1569 | if (type != SSH2_MSG_USERAUTH_FAILURE) | ||
1570 | fatal("access denied: %d", type); | ||
1571 | /* SSH2_MSG_USERAUTH_FAILURE means: try again */ | ||
1572 | auths = packet_get_string(&dlen); | ||
1573 | debug("authentications that can continue: %s", auths); | ||
1574 | partial = packet_get_char(); | ||
1575 | if (partial) | ||
1576 | debug("partial success"); | ||
1577 | if (strstr(auths, "password") == NULL) | ||
1578 | fatal("passwd auth not supported: %s", auths); | ||
1579 | xfree(auths); | ||
1580 | /* try passwd */ | ||
1581 | password = read_passphrase("password: ", 0); | ||
1582 | packet_start(SSH2_MSG_USERAUTH_REQUEST); | ||
1583 | packet_put_cstring(server_user); | ||
1584 | packet_put_cstring(service); | ||
1585 | packet_put_cstring("password"); | ||
1586 | packet_put_char(0); | ||
1587 | packet_put_cstring(password); | ||
1588 | memset(password, 0, strlen(password)); | ||
1589 | xfree(password); | ||
1590 | packet_send(); | ||
1591 | packet_write_wait(); | ||
1592 | } | ||
1593 | debug("ssh-userauth2 successfull"); | ||
1594 | } | ||
1595 | |||
1596 | /* | ||
1286 | * SSH1 key exchange | 1597 | * SSH1 key exchange |
1287 | */ | 1598 | */ |
1288 | void | 1599 | void |
@@ -1293,6 +1604,7 @@ ssh_kex(char *host, struct sockaddr *hostaddr) | |||
1293 | RSA *host_key; | 1604 | RSA *host_key; |
1294 | RSA *public_key; | 1605 | RSA *public_key; |
1295 | int bits, rbits; | 1606 | int bits, rbits; |
1607 | int ssh_cipher_default = SSH_CIPHER_3DES; | ||
1296 | unsigned char session_key[SSH_SESSION_KEY_LENGTH]; | 1608 | unsigned char session_key[SSH_SESSION_KEY_LENGTH]; |
1297 | unsigned char cookie[8]; | 1609 | unsigned char cookie[8]; |
1298 | unsigned int supported_ciphers; | 1610 | unsigned int supported_ciphers; |
@@ -1427,7 +1739,7 @@ ssh_kex(char *host, struct sockaddr *hostaddr) | |||
1427 | RSA_free(host_key); | 1739 | RSA_free(host_key); |
1428 | 1740 | ||
1429 | if (options.cipher == SSH_CIPHER_NOT_SET) { | 1741 | if (options.cipher == SSH_CIPHER_NOT_SET) { |
1430 | if (cipher_mask() & supported_ciphers & (1 << ssh_cipher_default)) | 1742 | if (cipher_mask1() & supported_ciphers & (1 << ssh_cipher_default)) |
1431 | options.cipher = ssh_cipher_default; | 1743 | options.cipher = ssh_cipher_default; |
1432 | else { | 1744 | else { |
1433 | debug("Cipher %s not supported, using %.100s instead.", | 1745 | debug("Cipher %s not supported, using %.100s instead.", |
@@ -1640,12 +1952,16 @@ ssh_login(int host_key_valid, RSA *own_host_key, const char *orighost, | |||
1640 | /* Put the connection into non-blocking mode. */ | 1952 | /* Put the connection into non-blocking mode. */ |
1641 | packet_set_nonblocking(); | 1953 | packet_set_nonblocking(); |
1642 | 1954 | ||
1643 | supported_authentications = 0; | ||
1644 | /* key exchange */ | 1955 | /* key exchange */ |
1645 | ssh_kex(host, hostaddr); | ||
1646 | if (supported_authentications == 0) | ||
1647 | fatal("supported_authentications == 0."); | ||
1648 | |||
1649 | /* authenticate user */ | 1956 | /* authenticate user */ |
1650 | ssh_userauth(host_key_valid, own_host_key, original_real_uid, host); | 1957 | if (compat20) { |
1958 | ssh_kex2(host, hostaddr); | ||
1959 | ssh_userauth2(host_key_valid, own_host_key, original_real_uid, host); | ||
1960 | } else { | ||
1961 | supported_authentications = 0; | ||
1962 | ssh_kex(host, hostaddr); | ||
1963 | if (supported_authentications == 0) | ||
1964 | fatal("supported_authentications == 0."); | ||
1965 | ssh_userauth(host_key_valid, own_host_key, original_real_uid, host); | ||
1966 | } | ||
1651 | } | 1967 | } |
@@ -11,7 +11,7 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include "includes.h" | 13 | #include "includes.h" |
14 | RCSID("$OpenBSD: sshd.c,v 1.96 2000/03/28 21:15:45 markus Exp $"); | 14 | RCSID("$OpenBSD: sshd.c,v 1.97 2000/04/04 21:37:27 markus Exp $"); |
15 | 15 | ||
16 | #include "xmalloc.h" | 16 | #include "xmalloc.h" |
17 | #include "rsa.h" | 17 | #include "rsa.h" |
@@ -911,7 +911,7 @@ do_ssh1_kex() | |||
911 | packet_put_int(SSH_PROTOFLAG_HOST_IN_FWD_OPEN); | 911 | packet_put_int(SSH_PROTOFLAG_HOST_IN_FWD_OPEN); |
912 | 912 | ||
913 | /* Declare which ciphers we support. */ | 913 | /* Declare which ciphers we support. */ |
914 | packet_put_int(cipher_mask()); | 914 | packet_put_int(cipher_mask1()); |
915 | 915 | ||
916 | /* Declare supported authentication types. */ | 916 | /* Declare supported authentication types. */ |
917 | auth_mask = 0; | 917 | auth_mask = 0; |