diff options
Diffstat (limited to 'channels.c')
-rw-r--r-- | channels.c | 63 |
1 files changed, 43 insertions, 20 deletions
diff --git a/channels.c b/channels.c index 9486c1cff..a84b487e5 100644 --- a/channels.c +++ b/channels.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: channels.c,v 1.341 2015/02/06 23:21:59 millert Exp $ */ | 1 | /* $OpenBSD: channels.c,v 1.347 2015/07/01 02:26:31 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 |
@@ -161,6 +161,9 @@ static char *x11_saved_proto = NULL; | |||
161 | static char *x11_saved_data = NULL; | 161 | static char *x11_saved_data = NULL; |
162 | static u_int x11_saved_data_len = 0; | 162 | static u_int x11_saved_data_len = 0; |
163 | 163 | ||
164 | /* Deadline after which all X11 connections are refused */ | ||
165 | static u_int x11_refuse_time; | ||
166 | |||
164 | /* | 167 | /* |
165 | * Fake X11 authentication data. This is what the server will be sending us; | 168 | * Fake X11 authentication data. This is what the server will be sending us; |
166 | * we should replace any occurrences of this by the real data. | 169 | * we should replace any occurrences of this by the real data. |
@@ -306,7 +309,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd, | |||
306 | if (channels_alloc > 10000) | 309 | if (channels_alloc > 10000) |
307 | fatal("channel_new: internal error: channels_alloc %d " | 310 | fatal("channel_new: internal error: channels_alloc %d " |
308 | "too big.", channels_alloc); | 311 | "too big.", channels_alloc); |
309 | channels = xrealloc(channels, channels_alloc + 10, | 312 | channels = xreallocarray(channels, channels_alloc + 10, |
310 | sizeof(Channel *)); | 313 | sizeof(Channel *)); |
311 | channels_alloc += 10; | 314 | channels_alloc += 10; |
312 | debug2("channel: expanding %d", channels_alloc); | 315 | debug2("channel: expanding %d", channels_alloc); |
@@ -912,6 +915,13 @@ x11_open_helper(Buffer *b) | |||
912 | u_char *ucp; | 915 | u_char *ucp; |
913 | u_int proto_len, data_len; | 916 | u_int proto_len, data_len; |
914 | 917 | ||
918 | /* Is this being called after the refusal deadline? */ | ||
919 | if (x11_refuse_time != 0 && (u_int)monotime() >= x11_refuse_time) { | ||
920 | verbose("Rejected X11 connection after ForwardX11Timeout " | ||
921 | "expired"); | ||
922 | return -1; | ||
923 | } | ||
924 | |||
915 | /* Check if the fixed size part of the packet is in buffer. */ | 925 | /* Check if the fixed size part of the packet is in buffer. */ |
916 | if (buffer_len(b) < 12) | 926 | if (buffer_len(b) < 12) |
917 | return 0; | 927 | return 0; |
@@ -1483,6 +1493,12 @@ channel_set_reuseaddr(int fd) | |||
1483 | error("setsockopt SO_REUSEADDR fd %d: %s", fd, strerror(errno)); | 1493 | error("setsockopt SO_REUSEADDR fd %d: %s", fd, strerror(errno)); |
1484 | } | 1494 | } |
1485 | 1495 | ||
1496 | void | ||
1497 | channel_set_x11_refuse_time(u_int refuse_time) | ||
1498 | { | ||
1499 | x11_refuse_time = refuse_time; | ||
1500 | } | ||
1501 | |||
1486 | /* | 1502 | /* |
1487 | * This socket is listening for connections to a forwarded TCP/IP port. | 1503 | * This socket is listening for connections to a forwarded TCP/IP port. |
1488 | */ | 1504 | */ |
@@ -2192,8 +2208,8 @@ channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp, | |||
2192 | 2208 | ||
2193 | /* perhaps check sz < nalloc/2 and shrink? */ | 2209 | /* perhaps check sz < nalloc/2 and shrink? */ |
2194 | if (*readsetp == NULL || sz > *nallocp) { | 2210 | if (*readsetp == NULL || sz > *nallocp) { |
2195 | *readsetp = xrealloc(*readsetp, nfdset, sizeof(fd_mask)); | 2211 | *readsetp = xreallocarray(*readsetp, nfdset, sizeof(fd_mask)); |
2196 | *writesetp = xrealloc(*writesetp, nfdset, sizeof(fd_mask)); | 2212 | *writesetp = xreallocarray(*writesetp, nfdset, sizeof(fd_mask)); |
2197 | *nallocp = sz; | 2213 | *nallocp = sz; |
2198 | } | 2214 | } |
2199 | *maxfdp = n; | 2215 | *maxfdp = n; |
@@ -2270,7 +2286,7 @@ channel_output_poll(void) | |||
2270 | packet_put_int(c->remote_id); | 2286 | packet_put_int(c->remote_id); |
2271 | packet_put_string(data, dlen); | 2287 | packet_put_string(data, dlen); |
2272 | packet_send(); | 2288 | packet_send(); |
2273 | c->remote_window -= dlen + 4; | 2289 | c->remote_window -= dlen; |
2274 | free(data); | 2290 | free(data); |
2275 | } | 2291 | } |
2276 | continue; | 2292 | continue; |
@@ -2641,7 +2657,7 @@ channel_input_window_adjust(int type, u_int32_t seq, void *ctxt) | |||
2641 | { | 2657 | { |
2642 | Channel *c; | 2658 | Channel *c; |
2643 | int id; | 2659 | int id; |
2644 | u_int adjust; | 2660 | u_int adjust, tmp; |
2645 | 2661 | ||
2646 | if (!compat20) | 2662 | if (!compat20) |
2647 | return 0; | 2663 | return 0; |
@@ -2657,7 +2673,10 @@ channel_input_window_adjust(int type, u_int32_t seq, void *ctxt) | |||
2657 | adjust = packet_get_int(); | 2673 | adjust = packet_get_int(); |
2658 | packet_check_eom(); | 2674 | packet_check_eom(); |
2659 | debug2("channel %d: rcvd adjust %u", id, adjust); | 2675 | debug2("channel %d: rcvd adjust %u", id, adjust); |
2660 | c->remote_window += adjust; | 2676 | if ((tmp = c->remote_window + adjust) < c->remote_window) |
2677 | fatal("channel %d: adjust %u overflows remote window %u", | ||
2678 | id, adjust, c->remote_window); | ||
2679 | c->remote_window = tmp; | ||
2661 | return 0; | 2680 | return 0; |
2662 | } | 2681 | } |
2663 | 2682 | ||
@@ -2805,17 +2824,21 @@ channel_setup_fwd_listener_tcpip(int type, struct Forward *fwd, | |||
2805 | char ntop[NI_MAXHOST], strport[NI_MAXSERV]; | 2824 | char ntop[NI_MAXHOST], strport[NI_MAXSERV]; |
2806 | in_port_t *lport_p; | 2825 | in_port_t *lport_p; |
2807 | 2826 | ||
2808 | host = (type == SSH_CHANNEL_RPORT_LISTENER) ? | ||
2809 | fwd->listen_host : fwd->connect_host; | ||
2810 | is_client = (type == SSH_CHANNEL_PORT_LISTENER); | 2827 | is_client = (type == SSH_CHANNEL_PORT_LISTENER); |
2811 | 2828 | ||
2812 | if (host == NULL) { | 2829 | if (is_client && fwd->connect_path != NULL) { |
2813 | error("No forward host name."); | 2830 | host = fwd->connect_path; |
2814 | return 0; | 2831 | } else { |
2815 | } | 2832 | host = (type == SSH_CHANNEL_RPORT_LISTENER) ? |
2816 | if (strlen(host) >= NI_MAXHOST) { | 2833 | fwd->listen_host : fwd->connect_host; |
2817 | error("Forward host name too long."); | 2834 | if (host == NULL) { |
2818 | return 0; | 2835 | error("No forward host name."); |
2836 | return 0; | ||
2837 | } | ||
2838 | if (strlen(host) >= NI_MAXHOST) { | ||
2839 | error("Forward host name too long."); | ||
2840 | return 0; | ||
2841 | } | ||
2819 | } | 2842 | } |
2820 | 2843 | ||
2821 | /* Determine the bind address, cf. channel_fwd_bind_addr() comment */ | 2844 | /* Determine the bind address, cf. channel_fwd_bind_addr() comment */ |
@@ -3237,7 +3260,7 @@ channel_request_remote_forwarding(struct Forward *fwd) | |||
3237 | } | 3260 | } |
3238 | if (success) { | 3261 | if (success) { |
3239 | /* Record that connection to this host/port is permitted. */ | 3262 | /* Record that connection to this host/port is permitted. */ |
3240 | permitted_opens = xrealloc(permitted_opens, | 3263 | permitted_opens = xreallocarray(permitted_opens, |
3241 | num_permitted_opens + 1, sizeof(*permitted_opens)); | 3264 | num_permitted_opens + 1, sizeof(*permitted_opens)); |
3242 | idx = num_permitted_opens++; | 3265 | idx = num_permitted_opens++; |
3243 | if (fwd->connect_path != NULL) { | 3266 | if (fwd->connect_path != NULL) { |
@@ -3468,7 +3491,7 @@ channel_add_permitted_opens(char *host, int port) | |||
3468 | { | 3491 | { |
3469 | debug("allow port forwarding to host %s port %d", host, port); | 3492 | debug("allow port forwarding to host %s port %d", host, port); |
3470 | 3493 | ||
3471 | permitted_opens = xrealloc(permitted_opens, | 3494 | permitted_opens = xreallocarray(permitted_opens, |
3472 | num_permitted_opens + 1, sizeof(*permitted_opens)); | 3495 | num_permitted_opens + 1, sizeof(*permitted_opens)); |
3473 | permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host); | 3496 | permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host); |
3474 | permitted_opens[num_permitted_opens].port_to_connect = port; | 3497 | permitted_opens[num_permitted_opens].port_to_connect = port; |
@@ -3518,7 +3541,7 @@ channel_add_adm_permitted_opens(char *host, int port) | |||
3518 | { | 3541 | { |
3519 | debug("config allows port forwarding to host %s port %d", host, port); | 3542 | debug("config allows port forwarding to host %s port %d", host, port); |
3520 | 3543 | ||
3521 | permitted_adm_opens = xrealloc(permitted_adm_opens, | 3544 | permitted_adm_opens = xreallocarray(permitted_adm_opens, |
3522 | num_adm_permitted_opens + 1, sizeof(*permitted_adm_opens)); | 3545 | num_adm_permitted_opens + 1, sizeof(*permitted_adm_opens)); |
3523 | permitted_adm_opens[num_adm_permitted_opens].host_to_connect | 3546 | permitted_adm_opens[num_adm_permitted_opens].host_to_connect |
3524 | = xstrdup(host); | 3547 | = xstrdup(host); |
@@ -3533,7 +3556,7 @@ void | |||
3533 | channel_disable_adm_local_opens(void) | 3556 | channel_disable_adm_local_opens(void) |
3534 | { | 3557 | { |
3535 | channel_clear_adm_permitted_opens(); | 3558 | channel_clear_adm_permitted_opens(); |
3536 | permitted_adm_opens = xmalloc(sizeof(*permitted_adm_opens)); | 3559 | permitted_adm_opens = xcalloc(sizeof(*permitted_adm_opens), 1); |
3537 | permitted_adm_opens[num_adm_permitted_opens].host_to_connect = NULL; | 3560 | permitted_adm_opens[num_adm_permitted_opens].host_to_connect = NULL; |
3538 | num_adm_permitted_opens = 1; | 3561 | num_adm_permitted_opens = 1; |
3539 | } | 3562 | } |