diff options
Diffstat (limited to 'packet.c')
-rw-r--r-- | packet.c | 60 |
1 files changed, 28 insertions, 32 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: packet.c,v 1.269 2017/12/18 23:13:42 djm Exp $ */ | 1 | /* $OpenBSD: packet.c,v 1.277 2018/07/16 03:09:13 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -61,10 +61,19 @@ | |||
61 | #include <signal.h> | 61 | #include <signal.h> |
62 | #include <time.h> | 62 | #include <time.h> |
63 | 63 | ||
64 | #include <zlib.h> | 64 | /* |
65 | * Explicitly include OpenSSL before zlib as some versions of OpenSSL have | ||
66 | * "free_func" in their headers, which zlib typedefs. | ||
67 | */ | ||
68 | #ifdef WITH_OPENSSL | ||
69 | # include <openssl/bn.h> | ||
70 | # include <openssl/evp.h> | ||
71 | # ifdef OPENSSL_HAS_ECC | ||
72 | # include <openssl/ec.h> | ||
73 | # endif | ||
74 | #endif | ||
65 | 75 | ||
66 | #include "buffer.h" /* typedefs XXX */ | 76 | #include <zlib.h> |
67 | #include "key.h" /* typedefs XXX */ | ||
68 | 77 | ||
69 | #include "xmalloc.h" | 78 | #include "xmalloc.h" |
70 | #include "crc32.h" | 79 | #include "crc32.h" |
@@ -147,12 +156,6 @@ struct session_state { | |||
147 | int compression_in_failures; | 156 | int compression_in_failures; |
148 | int compression_out_failures; | 157 | int compression_out_failures; |
149 | 158 | ||
150 | /* | ||
151 | * Flag indicating whether packet compression/decompression is | ||
152 | * enabled. | ||
153 | */ | ||
154 | int packet_compression; | ||
155 | |||
156 | /* default maximum packet size */ | 159 | /* default maximum packet size */ |
157 | u_int max_packet_size; | 160 | u_int max_packet_size; |
158 | 161 | ||
@@ -418,13 +421,16 @@ ssh_packet_start_discard(struct ssh *ssh, struct sshenc *enc, | |||
418 | int | 421 | int |
419 | ssh_packet_connection_is_on_socket(struct ssh *ssh) | 422 | ssh_packet_connection_is_on_socket(struct ssh *ssh) |
420 | { | 423 | { |
421 | struct session_state *state = ssh->state; | 424 | struct session_state *state; |
422 | struct sockaddr_storage from, to; | 425 | struct sockaddr_storage from, to; |
423 | socklen_t fromlen, tolen; | 426 | socklen_t fromlen, tolen; |
424 | 427 | ||
425 | if (state->connection_in == -1 || state->connection_out == -1) | 428 | if (ssh == NULL || ssh->state == NULL) |
426 | return 0; | 429 | return 0; |
427 | 430 | ||
431 | state = ssh->state; | ||
432 | if (state->connection_in == -1 || state->connection_out == -1) | ||
433 | return 0; | ||
428 | /* filedescriptors in and out are the same, so it's a socket */ | 434 | /* filedescriptors in and out are the same, so it's a socket */ |
429 | if (state->connection_in == state->connection_out) | 435 | if (state->connection_in == state->connection_out) |
430 | return 1; | 436 | return 1; |
@@ -508,11 +514,12 @@ ssh_packet_get_connection_out(struct ssh *ssh) | |||
508 | const char * | 514 | const char * |
509 | ssh_remote_ipaddr(struct ssh *ssh) | 515 | ssh_remote_ipaddr(struct ssh *ssh) |
510 | { | 516 | { |
511 | const int sock = ssh->state->connection_in; | 517 | int sock; |
512 | 518 | ||
513 | /* Check whether we have cached the ipaddr. */ | 519 | /* Check whether we have cached the ipaddr. */ |
514 | if (ssh->remote_ipaddr == NULL) { | 520 | if (ssh->remote_ipaddr == NULL) { |
515 | if (ssh_packet_connection_is_on_socket(ssh)) { | 521 | if (ssh_packet_connection_is_on_socket(ssh)) { |
522 | sock = ssh->state->connection_in; | ||
516 | ssh->remote_ipaddr = get_peer_ipaddr(sock); | 523 | ssh->remote_ipaddr = get_peer_ipaddr(sock); |
517 | ssh->remote_port = get_peer_port(sock); | 524 | ssh->remote_port = get_peer_port(sock); |
518 | ssh->local_ipaddr = get_local_ipaddr(sock); | 525 | ssh->local_ipaddr = get_local_ipaddr(sock); |
@@ -597,7 +604,7 @@ ssh_packet_close_internal(struct ssh *ssh, int do_close) | |||
597 | state->newkeys[mode] = NULL; | 604 | state->newkeys[mode] = NULL; |
598 | ssh_clear_newkeys(ssh, mode); /* next keys */ | 605 | ssh_clear_newkeys(ssh, mode); /* next keys */ |
599 | } | 606 | } |
600 | /* comression state is in shared mem, so we can only release it once */ | 607 | /* compression state is in shared mem, so we can only release it once */ |
601 | if (do_close && state->compression_buffer) { | 608 | if (do_close && state->compression_buffer) { |
602 | sshbuf_free(state->compression_buffer); | 609 | sshbuf_free(state->compression_buffer); |
603 | if (state->compression_out_started) { | 610 | if (state->compression_out_started) { |
@@ -627,6 +634,8 @@ ssh_packet_close_internal(struct ssh *ssh, int do_close) | |||
627 | cipher_free(state->receive_context); | 634 | cipher_free(state->receive_context); |
628 | state->send_context = state->receive_context = NULL; | 635 | state->send_context = state->receive_context = NULL; |
629 | if (do_close) { | 636 | if (do_close) { |
637 | free(ssh->local_ipaddr); | ||
638 | ssh->local_ipaddr = NULL; | ||
630 | free(ssh->remote_ipaddr); | 639 | free(ssh->remote_ipaddr); |
631 | ssh->remote_ipaddr = NULL; | 640 | ssh->remote_ipaddr = NULL; |
632 | free(ssh->state); | 641 | free(ssh->state); |
@@ -713,21 +722,6 @@ start_compression_in(struct ssh *ssh) | |||
713 | return 0; | 722 | return 0; |
714 | } | 723 | } |
715 | 724 | ||
716 | int | ||
717 | ssh_packet_start_compression(struct ssh *ssh, int level) | ||
718 | { | ||
719 | int r; | ||
720 | |||
721 | if (ssh->state->packet_compression) | ||
722 | return SSH_ERR_INTERNAL_ERROR; | ||
723 | ssh->state->packet_compression = 1; | ||
724 | if ((r = ssh_packet_init_compression(ssh)) != 0 || | ||
725 | (r = start_compression_in(ssh)) != 0 || | ||
726 | (r = start_compression_out(ssh, level)) != 0) | ||
727 | return r; | ||
728 | return 0; | ||
729 | } | ||
730 | |||
731 | /* XXX remove need for separate compression buffer */ | 725 | /* XXX remove need for separate compression buffer */ |
732 | static int | 726 | static int |
733 | compress_buffer(struct ssh *ssh, struct sshbuf *in, struct sshbuf *out) | 727 | compress_buffer(struct ssh *ssh, struct sshbuf *in, struct sshbuf *out) |
@@ -965,7 +959,7 @@ ssh_packet_need_rekeying(struct ssh *ssh, u_int outbound_packet_len) | |||
965 | state->p_read.packets > MAX_PACKETS) | 959 | state->p_read.packets > MAX_PACKETS) |
966 | return 1; | 960 | return 1; |
967 | 961 | ||
968 | /* Rekey after (cipher-specific) maxiumum blocks */ | 962 | /* Rekey after (cipher-specific) maximum blocks */ |
969 | out_blocks = ROUNDUP(outbound_packet_len, | 963 | out_blocks = ROUNDUP(outbound_packet_len, |
970 | state->newkeys[MODE_OUT]->enc.block_size); | 964 | state->newkeys[MODE_OUT]->enc.block_size); |
971 | return (state->max_blocks_out && | 965 | return (state->max_blocks_out && |
@@ -1338,8 +1332,10 @@ ssh_packet_read_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) | |||
1338 | NULL, NULL, timeoutp)) >= 0) | 1332 | NULL, NULL, timeoutp)) >= 0) |
1339 | break; | 1333 | break; |
1340 | if (errno != EAGAIN && errno != EINTR && | 1334 | if (errno != EAGAIN && errno != EINTR && |
1341 | errno != EWOULDBLOCK) | 1335 | errno != EWOULDBLOCK) { |
1342 | break; | 1336 | r = SSH_ERR_SYSTEM_ERROR; |
1337 | goto out; | ||
1338 | } | ||
1343 | if (state->packet_timeout_ms == -1) | 1339 | if (state->packet_timeout_ms == -1) |
1344 | continue; | 1340 | continue; |
1345 | ms_subtract_diff(&start, &ms_remain); | 1341 | ms_subtract_diff(&start, &ms_remain); |