diff options
Diffstat (limited to 'packet.c')
-rw-r--r-- | packet.c | 181 |
1 files changed, 114 insertions, 67 deletions
@@ -15,7 +15,7 @@ | |||
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include "includes.h" | 17 | #include "includes.h" |
18 | RCSID("$Id: packet.c,v 1.5 1999/11/24 13:26:22 damien Exp $"); | 18 | RCSID("$Id: packet.c,v 1.6 1999/11/25 00:54:59 damien Exp $"); |
19 | 19 | ||
20 | #include "xmalloc.h" | 20 | #include "xmalloc.h" |
21 | #include "buffer.h" | 21 | #include "buffer.h" |
@@ -29,15 +29,19 @@ RCSID("$Id: packet.c,v 1.5 1999/11/24 13:26:22 damien Exp $"); | |||
29 | #include "compress.h" | 29 | #include "compress.h" |
30 | #include "deattack.h" | 30 | #include "deattack.h" |
31 | 31 | ||
32 | /* This variable contains the file descriptors used for communicating with | 32 | /* |
33 | the other side. connection_in is used for reading; connection_out | 33 | * This variable contains the file descriptors used for communicating with |
34 | for writing. These can be the same descriptor, in which case it is | 34 | * the other side. connection_in is used for reading; connection_out for |
35 | assumed to be a socket. */ | 35 | * writing. These can be the same descriptor, in which case it is assumed to |
36 | * be a socket. | ||
37 | */ | ||
36 | static int connection_in = -1; | 38 | static int connection_in = -1; |
37 | static int connection_out = -1; | 39 | static int connection_out = -1; |
38 | 40 | ||
39 | /* Cipher type. This value is only used to determine whether to pad the | 41 | /* |
40 | packets with zeroes or random data. */ | 42 | * Cipher type. This value is only used to determine whether to pad the |
43 | * packets with zeroes or random data. | ||
44 | */ | ||
41 | static int cipher_type = SSH_CIPHER_NONE; | 45 | static int cipher_type = SSH_CIPHER_NONE; |
42 | 46 | ||
43 | /* Protocol flags for the remote side. */ | 47 | /* Protocol flags for the remote side. */ |
@@ -76,8 +80,10 @@ static int initialized = 0; | |||
76 | /* Set to true if the connection is interactive. */ | 80 | /* Set to true if the connection is interactive. */ |
77 | static int interactive_mode = 0; | 81 | static int interactive_mode = 0; |
78 | 82 | ||
79 | /* Sets the descriptors used for communication. Disables encryption until | 83 | /* |
80 | packet_set_encryption_key is called. */ | 84 | * Sets the descriptors used for communication. Disables encryption until |
85 | * packet_set_encryption_key is called. | ||
86 | */ | ||
81 | 87 | ||
82 | void | 88 | void |
83 | packet_set_connection(int fd_in, int fd_out) | 89 | packet_set_connection(int fd_in, int fd_out) |
@@ -171,8 +177,10 @@ packet_get_protocol_flags() | |||
171 | return remote_protocol_flags; | 177 | return remote_protocol_flags; |
172 | } | 178 | } |
173 | 179 | ||
174 | /* Starts packet compression from the next packet on in both directions. | 180 | /* |
175 | Level is compression level 1 (fastest) - 9 (slow, best) as in gzip. */ | 181 | * Starts packet compression from the next packet on in both directions. |
182 | * Level is compression level 1 (fastest) - 9 (slow, best) as in gzip. | ||
183 | */ | ||
176 | 184 | ||
177 | void | 185 | void |
178 | packet_start_compression(int level) | 186 | packet_start_compression(int level) |
@@ -184,8 +192,10 @@ packet_start_compression(int level) | |||
184 | buffer_compress_init(level); | 192 | buffer_compress_init(level); |
185 | } | 193 | } |
186 | 194 | ||
187 | /* Encrypts the given number of bytes, copying from src to dest. | 195 | /* |
188 | bytes is known to be a multiple of 8. */ | 196 | * Encrypts the given number of bytes, copying from src to dest. bytes is |
197 | * known to be a multiple of 8. | ||
198 | */ | ||
189 | 199 | ||
190 | void | 200 | void |
191 | packet_encrypt(CipherContext * cc, void *dest, void *src, | 201 | packet_encrypt(CipherContext * cc, void *dest, void *src, |
@@ -194,8 +204,10 @@ packet_encrypt(CipherContext * cc, void *dest, void *src, | |||
194 | cipher_encrypt(cc, dest, src, bytes); | 204 | cipher_encrypt(cc, dest, src, bytes); |
195 | } | 205 | } |
196 | 206 | ||
197 | /* Decrypts the given number of bytes, copying from src to dest. | 207 | /* |
198 | bytes is known to be a multiple of 8. */ | 208 | * Decrypts the given number of bytes, copying from src to dest. bytes is |
209 | * known to be a multiple of 8. | ||
210 | */ | ||
199 | 211 | ||
200 | void | 212 | void |
201 | packet_decrypt(CipherContext * cc, void *dest, void *src, | 213 | packet_decrypt(CipherContext * cc, void *dest, void *src, |
@@ -206,8 +218,10 @@ packet_decrypt(CipherContext * cc, void *dest, void *src, | |||
206 | if ((bytes % 8) != 0) | 218 | if ((bytes % 8) != 0) |
207 | fatal("packet_decrypt: bad ciphertext length %d", bytes); | 219 | fatal("packet_decrypt: bad ciphertext length %d", bytes); |
208 | 220 | ||
209 | /* Cryptographic attack detector for ssh - Modifications for packet.c | 221 | /* |
210 | (C)1998 CORE-SDI, Buenos Aires Argentina Ariel Futoransky(futo@core-sdi.com) */ | 222 | * Cryptographic attack detector for ssh - Modifications for packet.c |
223 | * (C)1998 CORE-SDI, Buenos Aires Argentina Ariel Futoransky(futo@core-sdi.com) | ||
224 | */ | ||
211 | 225 | ||
212 | switch (cc->type) { | 226 | switch (cc->type) { |
213 | case SSH_CIPHER_NONE: | 227 | case SSH_CIPHER_NONE: |
@@ -224,9 +238,11 @@ packet_decrypt(CipherContext * cc, void *dest, void *src, | |||
224 | cipher_decrypt(cc, dest, src, bytes); | 238 | cipher_decrypt(cc, dest, src, bytes); |
225 | } | 239 | } |
226 | 240 | ||
227 | /* Causes any further packets to be encrypted using the given key. The same | 241 | /* |
228 | key is used for both sending and reception. However, both directions | 242 | * Causes any further packets to be encrypted using the given key. The same |
229 | are encrypted independently of each other. */ | 243 | * key is used for both sending and reception. However, both directions are |
244 | * encrypted independently of each other. | ||
245 | */ | ||
230 | 246 | ||
231 | void | 247 | void |
232 | packet_set_encryption_key(const unsigned char *key, unsigned int keylen, | 248 | packet_set_encryption_key(const unsigned char *key, unsigned int keylen, |
@@ -283,8 +299,10 @@ packet_put_bignum(BIGNUM * value) | |||
283 | buffer_put_bignum(&outgoing_packet, value); | 299 | buffer_put_bignum(&outgoing_packet, value); |
284 | } | 300 | } |
285 | 301 | ||
286 | /* Finalizes and sends the packet. If the encryption key has been set, | 302 | /* |
287 | encrypts the packet before sending. */ | 303 | * Finalizes and sends the packet. If the encryption key has been set, |
304 | * encrypts the packet before sending. | ||
305 | */ | ||
288 | 306 | ||
289 | void | 307 | void |
290 | packet_send() | 308 | packet_send() |
@@ -294,8 +312,10 @@ packet_send() | |||
294 | unsigned int checksum; | 312 | unsigned int checksum; |
295 | u_int32_t rand = 0; | 313 | u_int32_t rand = 0; |
296 | 314 | ||
297 | /* If using packet compression, compress the payload of the | 315 | /* |
298 | outgoing packet. */ | 316 | * If using packet compression, compress the payload of the outgoing |
317 | * packet. | ||
318 | */ | ||
299 | if (packet_compression) { | 319 | if (packet_compression) { |
300 | buffer_clear(&compression_buffer); | 320 | buffer_clear(&compression_buffer); |
301 | /* Skip padding. */ | 321 | /* Skip padding. */ |
@@ -348,14 +368,18 @@ packet_send() | |||
348 | 368 | ||
349 | buffer_clear(&outgoing_packet); | 369 | buffer_clear(&outgoing_packet); |
350 | 370 | ||
351 | /* Note that the packet is now only buffered in output. It won\'t | 371 | /* |
352 | be actually sent until packet_write_wait or packet_write_poll | 372 | * Note that the packet is now only buffered in output. It won\'t be |
353 | is called. */ | 373 | * actually sent until packet_write_wait or packet_write_poll is |
374 | * called. | ||
375 | */ | ||
354 | } | 376 | } |
355 | 377 | ||
356 | /* Waits until a packet has been received, and returns its type. Note that | 378 | /* |
357 | no other data is processed until this returns, so this function should | 379 | * Waits until a packet has been received, and returns its type. Note that |
358 | not be used during the interactive session. */ | 380 | * no other data is processed until this returns, so this function should not |
381 | * be used during the interactive session. | ||
382 | */ | ||
359 | 383 | ||
360 | int | 384 | int |
361 | packet_read(int *payload_len_ptr) | 385 | packet_read(int *payload_len_ptr) |
@@ -379,12 +403,16 @@ packet_read(int *payload_len_ptr) | |||
379 | /* If we got a packet, return it. */ | 403 | /* If we got a packet, return it. */ |
380 | if (type != SSH_MSG_NONE) | 404 | if (type != SSH_MSG_NONE) |
381 | return type; | 405 | return type; |
382 | /* Otherwise, wait for some data to arrive, add it to the | 406 | /* |
383 | buffer, and try again. */ | 407 | * Otherwise, wait for some data to arrive, add it to the |
408 | * buffer, and try again. | ||
409 | */ | ||
384 | FD_ZERO(&set); | 410 | FD_ZERO(&set); |
385 | FD_SET(connection_in, &set); | 411 | FD_SET(connection_in, &set); |
412 | |||
386 | /* Wait for some data to arrive. */ | 413 | /* Wait for some data to arrive. */ |
387 | select(connection_in + 1, &set, NULL, NULL, NULL); | 414 | select(connection_in + 1, &set, NULL, NULL, NULL); |
415 | |||
388 | /* Read data from the socket. */ | 416 | /* Read data from the socket. */ |
389 | len = read(connection_in, buf, sizeof(buf)); | 417 | len = read(connection_in, buf, sizeof(buf)); |
390 | if (len == 0) | 418 | if (len == 0) |
@@ -397,8 +425,10 @@ packet_read(int *payload_len_ptr) | |||
397 | /* NOTREACHED */ | 425 | /* NOTREACHED */ |
398 | } | 426 | } |
399 | 427 | ||
400 | /* Waits until a packet has been received, verifies that its type matches | 428 | /* |
401 | that given, and gives a fatal error and exits if there is a mismatch. */ | 429 | * Waits until a packet has been received, verifies that its type matches |
430 | * that given, and gives a fatal error and exits if there is a mismatch. | ||
431 | */ | ||
402 | 432 | ||
403 | void | 433 | void |
404 | packet_read_expect(int *payload_len_ptr, int expected_type) | 434 | packet_read_expect(int *payload_len_ptr, int expected_type) |
@@ -516,8 +546,10 @@ restart: | |||
516 | return (unsigned char) buf[0]; | 546 | return (unsigned char) buf[0]; |
517 | } | 547 | } |
518 | 548 | ||
519 | /* Buffers the given amount of input characters. This is intended to be | 549 | /* |
520 | used together with packet_read_poll. */ | 550 | * Buffers the given amount of input characters. This is intended to be used |
551 | * together with packet_read_poll. | ||
552 | */ | ||
521 | 553 | ||
522 | void | 554 | void |
523 | packet_process_incoming(const char *buf, unsigned int len) | 555 | packet_process_incoming(const char *buf, unsigned int len) |
@@ -543,8 +575,10 @@ packet_get_int() | |||
543 | return buffer_get_int(&incoming_packet); | 575 | return buffer_get_int(&incoming_packet); |
544 | } | 576 | } |
545 | 577 | ||
546 | /* Returns an arbitrary precision integer from the packet data. The integer | 578 | /* |
547 | must have been initialized before this call. */ | 579 | * Returns an arbitrary precision integer from the packet data. The integer |
580 | * must have been initialized before this call. | ||
581 | */ | ||
548 | 582 | ||
549 | void | 583 | void |
550 | packet_get_bignum(BIGNUM * value, int *length_ptr) | 584 | packet_get_bignum(BIGNUM * value, int *length_ptr) |
@@ -552,25 +586,27 @@ packet_get_bignum(BIGNUM * value, int *length_ptr) | |||
552 | *length_ptr = buffer_get_bignum(&incoming_packet, value); | 586 | *length_ptr = buffer_get_bignum(&incoming_packet, value); |
553 | } | 587 | } |
554 | 588 | ||
555 | /* Returns a string from the packet data. The string is allocated using | 589 | /* |
556 | xmalloc; it is the responsibility of the calling program to free it when | 590 | * Returns a string from the packet data. The string is allocated using |
557 | no longer needed. The length_ptr argument may be NULL, or point to an | 591 | * xmalloc; it is the responsibility of the calling program to free it when |
558 | integer into which the length of the string is stored. */ | 592 | * no longer needed. The length_ptr argument may be NULL, or point to an |
593 | * integer into which the length of the string is stored. | ||
594 | */ | ||
559 | 595 | ||
560 | char | 596 | char * |
561 | * | ||
562 | packet_get_string(unsigned int *length_ptr) | 597 | packet_get_string(unsigned int *length_ptr) |
563 | { | 598 | { |
564 | return buffer_get_string(&incoming_packet, length_ptr); | 599 | return buffer_get_string(&incoming_packet, length_ptr); |
565 | } | 600 | } |
566 | 601 | ||
567 | /* Sends a diagnostic message from the server to the client. This message | 602 | /* |
568 | can be sent at any time (but not while constructing another message). | 603 | * Sends a diagnostic message from the server to the client. This message |
569 | The message is printed immediately, but only if the client is being | 604 | * can be sent at any time (but not while constructing another message). The |
570 | executed in verbose mode. These messages are primarily intended to | 605 | * message is printed immediately, but only if the client is being executed |
571 | ease debugging authentication problems. The length of the formatted | 606 | * in verbose mode. These messages are primarily intended to ease debugging |
572 | message must not exceed 1024 bytes. This will automatically call | 607 | * authentication problems. The length of the formatted message must not |
573 | packet_write_wait. */ | 608 | * exceed 1024 bytes. This will automatically call packet_write_wait. |
609 | */ | ||
574 | 610 | ||
575 | void | 611 | void |
576 | packet_send_debug(const char *fmt,...) | 612 | packet_send_debug(const char *fmt,...) |
@@ -588,10 +624,12 @@ packet_send_debug(const char *fmt,...) | |||
588 | packet_write_wait(); | 624 | packet_write_wait(); |
589 | } | 625 | } |
590 | 626 | ||
591 | /* Logs the error plus constructs and sends a disconnect | 627 | /* |
592 | packet, closes the connection, and exits. This function never returns. | 628 | * Logs the error plus constructs and sends a disconnect packet, closes the |
593 | The error message should not contain a newline. The length of the | 629 | * connection, and exits. This function never returns. The error message |
594 | formatted message must not exceed 1024 bytes. */ | 630 | * should not contain a newline. The length of the formatted message must |
631 | * not exceed 1024 bytes. | ||
632 | */ | ||
595 | 633 | ||
596 | void | 634 | void |
597 | packet_disconnect(const char *fmt,...) | 635 | packet_disconnect(const char *fmt,...) |
@@ -603,8 +641,10 @@ packet_disconnect(const char *fmt,...) | |||
603 | fatal("packet_disconnect called recursively."); | 641 | fatal("packet_disconnect called recursively."); |
604 | disconnecting = 1; | 642 | disconnecting = 1; |
605 | 643 | ||
606 | /* Format the message. Note that the caller must make sure the | 644 | /* |
607 | message is of limited size. */ | 645 | * Format the message. Note that the caller must make sure the |
646 | * message is of limited size. | ||
647 | */ | ||
608 | va_start(args, fmt); | 648 | va_start(args, fmt); |
609 | vsnprintf(buf, sizeof(buf), fmt, args); | 649 | vsnprintf(buf, sizeof(buf), fmt, args); |
610 | va_end(args); | 650 | va_end(args); |
@@ -625,8 +665,7 @@ packet_disconnect(const char *fmt,...) | |||
625 | fatal("Disconnecting: %.100s", buf); | 665 | fatal("Disconnecting: %.100s", buf); |
626 | } | 666 | } |
627 | 667 | ||
628 | /* Checks if there is any buffered output, and tries to write some of the | 668 | /* Checks if there is any buffered output, and tries to write some of the output. */ |
629 | output. */ | ||
630 | 669 | ||
631 | void | 670 | void |
632 | packet_write_poll() | 671 | packet_write_poll() |
@@ -644,8 +683,10 @@ packet_write_poll() | |||
644 | } | 683 | } |
645 | } | 684 | } |
646 | 685 | ||
647 | /* Calls packet_write_poll repeatedly until all pending output data has | 686 | /* |
648 | been written. */ | 687 | * Calls packet_write_poll repeatedly until all pending output data has been |
688 | * written. | ||
689 | */ | ||
649 | 690 | ||
650 | void | 691 | void |
651 | packet_write_wait() | 692 | packet_write_wait() |
@@ -689,8 +730,10 @@ packet_set_interactive(int interactive, int keepalives) | |||
689 | /* Record that we are in interactive mode. */ | 730 | /* Record that we are in interactive mode. */ |
690 | interactive_mode = interactive; | 731 | interactive_mode = interactive; |
691 | 732 | ||
692 | /* Only set socket options if using a socket (as indicated by the | 733 | /* |
693 | descriptors being the same). */ | 734 | * Only set socket options if using a socket (as indicated by the |
735 | * descriptors being the same). | ||
736 | */ | ||
694 | if (connection_in != connection_out) | 737 | if (connection_in != connection_out) |
695 | return; | 738 | return; |
696 | 739 | ||
@@ -701,8 +744,10 @@ packet_set_interactive(int interactive, int keepalives) | |||
701 | error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); | 744 | error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); |
702 | } | 745 | } |
703 | if (interactive) { | 746 | if (interactive) { |
704 | /* Set IP options for an interactive connection. Use | 747 | /* |
705 | IPTOS_LOWDELAY and TCP_NODELAY. */ | 748 | * Set IP options for an interactive connection. Use |
749 | * IPTOS_LOWDELAY and TCP_NODELAY. | ||
750 | */ | ||
706 | int lowdelay = IPTOS_LOWDELAY; | 751 | int lowdelay = IPTOS_LOWDELAY; |
707 | if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, (void *) &lowdelay, | 752 | if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, (void *) &lowdelay, |
708 | sizeof(lowdelay)) < 0) | 753 | sizeof(lowdelay)) < 0) |
@@ -711,8 +756,10 @@ packet_set_interactive(int interactive, int keepalives) | |||
711 | sizeof(on)) < 0) | 756 | sizeof(on)) < 0) |
712 | error("setsockopt TCP_NODELAY: %.100s", strerror(errno)); | 757 | error("setsockopt TCP_NODELAY: %.100s", strerror(errno)); |
713 | } else { | 758 | } else { |
714 | /* Set IP options for a non-interactive connection. Use | 759 | /* |
715 | IPTOS_THROUGHPUT. */ | 760 | * Set IP options for a non-interactive connection. Use |
761 | * IPTOS_THROUGHPUT. | ||
762 | */ | ||
716 | int throughput = IPTOS_THROUGHPUT; | 763 | int throughput = IPTOS_THROUGHPUT; |
717 | if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, (void *) &throughput, | 764 | if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, (void *) &throughput, |
718 | sizeof(throughput)) < 0) | 765 | sizeof(throughput)) < 0) |