diff options
Diffstat (limited to 'channels.c')
-rw-r--r-- | channels.c | 252 |
1 files changed, 187 insertions, 65 deletions
diff --git a/channels.c b/channels.c index 24d4a9f42..f6e9b4d8c 100644 --- a/channels.c +++ b/channels.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: channels.c,v 1.311 2011/06/22 22:08:42 djm Exp $ */ | 1 | /* $OpenBSD: channels.c,v 1.315 2011/09/23 07:45:05 markus 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 |
@@ -125,6 +125,9 @@ static int num_permitted_opens = 0; | |||
125 | /* Number of permitted host/port pair in the array permitted by the admin. */ | 125 | /* Number of permitted host/port pair in the array permitted by the admin. */ |
126 | static int num_adm_permitted_opens = 0; | 126 | static int num_adm_permitted_opens = 0; |
127 | 127 | ||
128 | /* special-case port number meaning allow any port */ | ||
129 | #define FWD_PERMIT_ANY_PORT 0 | ||
130 | |||
128 | /* | 131 | /* |
129 | * If this is true, all opens are permitted. This is the case on the server | 132 | * If this is true, all opens are permitted. This is the case on the server |
130 | * on which we have to trust the client anyway, and the user could do | 133 | * on which we have to trust the client anyway, and the user could do |
@@ -302,6 +305,8 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd, | |||
302 | buffer_init(&c->output); | 305 | buffer_init(&c->output); |
303 | buffer_init(&c->extended); | 306 | buffer_init(&c->extended); |
304 | c->path = NULL; | 307 | c->path = NULL; |
308 | c->listening_addr = NULL; | ||
309 | c->listening_port = 0; | ||
305 | c->ostate = CHAN_OUTPUT_OPEN; | 310 | c->ostate = CHAN_OUTPUT_OPEN; |
306 | c->istate = CHAN_INPUT_OPEN; | 311 | c->istate = CHAN_INPUT_OPEN; |
307 | c->flags = 0; | 312 | c->flags = 0; |
@@ -411,6 +416,10 @@ channel_free(Channel *c) | |||
411 | xfree(c->path); | 416 | xfree(c->path); |
412 | c->path = NULL; | 417 | c->path = NULL; |
413 | } | 418 | } |
419 | if (c->listening_addr) { | ||
420 | xfree(c->listening_addr); | ||
421 | c->listening_addr = NULL; | ||
422 | } | ||
414 | while ((cc = TAILQ_FIRST(&c->status_confirms)) != NULL) { | 423 | while ((cc = TAILQ_FIRST(&c->status_confirms)) != NULL) { |
415 | if (cc->abandon_cb != NULL) | 424 | if (cc->abandon_cb != NULL) |
416 | cc->abandon_cb(c, cc->ctx); | 425 | cc->abandon_cb(c, cc->ctx); |
@@ -2634,6 +2643,46 @@ channel_set_af(int af) | |||
2634 | IPv4or6 = af; | 2643 | IPv4or6 = af; |
2635 | } | 2644 | } |
2636 | 2645 | ||
2646 | |||
2647 | /* | ||
2648 | * Determine whether or not a port forward listens to loopback, the | ||
2649 | * specified address or wildcard. On the client, a specified bind | ||
2650 | * address will always override gateway_ports. On the server, a | ||
2651 | * gateway_ports of 1 (``yes'') will override the client's specification | ||
2652 | * and force a wildcard bind, whereas a value of 2 (``clientspecified'') | ||
2653 | * will bind to whatever address the client asked for. | ||
2654 | * | ||
2655 | * Special-case listen_addrs are: | ||
2656 | * | ||
2657 | * "0.0.0.0" -> wildcard v4/v6 if SSH_OLD_FORWARD_ADDR | ||
2658 | * "" (empty string), "*" -> wildcard v4/v6 | ||
2659 | * "localhost" -> loopback v4/v6 | ||
2660 | */ | ||
2661 | static const char * | ||
2662 | channel_fwd_bind_addr(const char *listen_addr, int *wildcardp, | ||
2663 | int is_client, int gateway_ports) | ||
2664 | { | ||
2665 | const char *addr = NULL; | ||
2666 | int wildcard = 0; | ||
2667 | |||
2668 | if (listen_addr == NULL) { | ||
2669 | /* No address specified: default to gateway_ports setting */ | ||
2670 | if (gateway_ports) | ||
2671 | wildcard = 1; | ||
2672 | } else if (gateway_ports || is_client) { | ||
2673 | if (((datafellows & SSH_OLD_FORWARD_ADDR) && | ||
2674 | strcmp(listen_addr, "0.0.0.0") == 0 && is_client == 0) || | ||
2675 | *listen_addr == '\0' || strcmp(listen_addr, "*") == 0 || | ||
2676 | (!is_client && gateway_ports == 1)) | ||
2677 | wildcard = 1; | ||
2678 | else if (strcmp(listen_addr, "localhost") != 0) | ||
2679 | addr = listen_addr; | ||
2680 | } | ||
2681 | if (wildcardp != NULL) | ||
2682 | *wildcardp = wildcard; | ||
2683 | return addr; | ||
2684 | } | ||
2685 | |||
2637 | static int | 2686 | static int |
2638 | channel_setup_fwd_listener(int type, const char *listen_addr, | 2687 | channel_setup_fwd_listener(int type, const char *listen_addr, |
2639 | u_short listen_port, int *allocated_listen_port, | 2688 | u_short listen_port, int *allocated_listen_port, |
@@ -2659,36 +2708,9 @@ channel_setup_fwd_listener(int type, const char *listen_addr, | |||
2659 | return 0; | 2708 | return 0; |
2660 | } | 2709 | } |
2661 | 2710 | ||
2662 | /* | 2711 | /* Determine the bind address, cf. channel_fwd_bind_addr() comment */ |
2663 | * Determine whether or not a port forward listens to loopback, | 2712 | addr = channel_fwd_bind_addr(listen_addr, &wildcard, |
2664 | * specified address or wildcard. On the client, a specified bind | 2713 | is_client, gateway_ports); |
2665 | * address will always override gateway_ports. On the server, a | ||
2666 | * gateway_ports of 1 (``yes'') will override the client's | ||
2667 | * specification and force a wildcard bind, whereas a value of 2 | ||
2668 | * (``clientspecified'') will bind to whatever address the client | ||
2669 | * asked for. | ||
2670 | * | ||
2671 | * Special-case listen_addrs are: | ||
2672 | * | ||
2673 | * "0.0.0.0" -> wildcard v4/v6 if SSH_OLD_FORWARD_ADDR | ||
2674 | * "" (empty string), "*" -> wildcard v4/v6 | ||
2675 | * "localhost" -> loopback v4/v6 | ||
2676 | */ | ||
2677 | addr = NULL; | ||
2678 | if (listen_addr == NULL) { | ||
2679 | /* No address specified: default to gateway_ports setting */ | ||
2680 | if (gateway_ports) | ||
2681 | wildcard = 1; | ||
2682 | } else if (gateway_ports || is_client) { | ||
2683 | if (((datafellows & SSH_OLD_FORWARD_ADDR) && | ||
2684 | strcmp(listen_addr, "0.0.0.0") == 0 && is_client == 0) || | ||
2685 | *listen_addr == '\0' || strcmp(listen_addr, "*") == 0 || | ||
2686 | (!is_client && gateway_ports == 1)) | ||
2687 | wildcard = 1; | ||
2688 | else if (strcmp(listen_addr, "localhost") != 0) | ||
2689 | addr = listen_addr; | ||
2690 | } | ||
2691 | |||
2692 | debug3("channel_setup_fwd_listener: type %d wildcard %d addr %s", | 2714 | debug3("channel_setup_fwd_listener: type %d wildcard %d addr %s", |
2693 | type, wildcard, (addr == NULL) ? "NULL" : addr); | 2715 | type, wildcard, (addr == NULL) ? "NULL" : addr); |
2694 | 2716 | ||
@@ -2792,7 +2814,12 @@ channel_setup_fwd_listener(int type, const char *listen_addr, | |||
2792 | 0, "port listener", 1); | 2814 | 0, "port listener", 1); |
2793 | c->path = xstrdup(host); | 2815 | c->path = xstrdup(host); |
2794 | c->host_port = port_to_connect; | 2816 | c->host_port = port_to_connect; |
2795 | c->listening_port = listen_port; | 2817 | c->listening_addr = addr == NULL ? NULL : xstrdup(addr); |
2818 | if (listen_port == 0 && allocated_listen_port != NULL && | ||
2819 | !(datafellows & SSH_BUG_DYNAMIC_RPORT)) | ||
2820 | c->listening_port = *allocated_listen_port; | ||
2821 | else | ||
2822 | c->listening_port = listen_port; | ||
2796 | success = 1; | 2823 | success = 1; |
2797 | } | 2824 | } |
2798 | if (success == 0) | 2825 | if (success == 0) |
@@ -2810,9 +2837,44 @@ channel_cancel_rport_listener(const char *host, u_short port) | |||
2810 | 2837 | ||
2811 | for (i = 0; i < channels_alloc; i++) { | 2838 | for (i = 0; i < channels_alloc; i++) { |
2812 | Channel *c = channels[i]; | 2839 | Channel *c = channels[i]; |
2840 | if (c == NULL || c->type != SSH_CHANNEL_RPORT_LISTENER) | ||
2841 | continue; | ||
2842 | if (strcmp(c->path, host) == 0 && c->listening_port == port) { | ||
2843 | debug2("%s: close channel %d", __func__, i); | ||
2844 | channel_free(c); | ||
2845 | found = 1; | ||
2846 | } | ||
2847 | } | ||
2848 | |||
2849 | return (found); | ||
2850 | } | ||
2851 | |||
2852 | int | ||
2853 | channel_cancel_lport_listener(const char *lhost, u_short lport, | ||
2854 | int cport, int gateway_ports) | ||
2855 | { | ||
2856 | u_int i; | ||
2857 | int found = 0; | ||
2858 | const char *addr = channel_fwd_bind_addr(lhost, NULL, 1, gateway_ports); | ||
2813 | 2859 | ||
2814 | if (c != NULL && c->type == SSH_CHANNEL_RPORT_LISTENER && | 2860 | for (i = 0; i < channels_alloc; i++) { |
2815 | strcmp(c->path, host) == 0 && c->listening_port == port) { | 2861 | Channel *c = channels[i]; |
2862 | if (c == NULL || c->type != SSH_CHANNEL_PORT_LISTENER) | ||
2863 | continue; | ||
2864 | if (c->listening_port != lport) | ||
2865 | continue; | ||
2866 | if (cport == CHANNEL_CANCEL_PORT_STATIC) { | ||
2867 | /* skip dynamic forwardings */ | ||
2868 | if (c->host_port == 0) | ||
2869 | continue; | ||
2870 | } else { | ||
2871 | if (c->host_port != cport) | ||
2872 | continue; | ||
2873 | } | ||
2874 | if ((c->listening_addr == NULL && addr != NULL) || | ||
2875 | (c->listening_addr != NULL && addr == NULL)) | ||
2876 | continue; | ||
2877 | if (addr == NULL || strcmp(c->listening_addr, addr) == 0) { | ||
2816 | debug2("%s: close channel %d", __func__, i); | 2878 | debug2("%s: close channel %d", __func__, i); |
2817 | channel_free(c); | 2879 | channel_free(c); |
2818 | found = 1; | 2880 | found = 1; |
@@ -2843,37 +2905,44 @@ channel_setup_remote_fwd_listener(const char *listen_address, | |||
2843 | } | 2905 | } |
2844 | 2906 | ||
2845 | /* | 2907 | /* |
2908 | * Translate the requested rfwd listen host to something usable for | ||
2909 | * this server. | ||
2910 | */ | ||
2911 | static const char * | ||
2912 | channel_rfwd_bind_host(const char *listen_host) | ||
2913 | { | ||
2914 | if (listen_host == NULL) { | ||
2915 | if (datafellows & SSH_BUG_RFWD_ADDR) | ||
2916 | return "127.0.0.1"; | ||
2917 | else | ||
2918 | return "localhost"; | ||
2919 | } else if (*listen_host == '\0' || strcmp(listen_host, "*") == 0) { | ||
2920 | if (datafellows & SSH_BUG_RFWD_ADDR) | ||
2921 | return "0.0.0.0"; | ||
2922 | else | ||
2923 | return ""; | ||
2924 | } else | ||
2925 | return listen_host; | ||
2926 | } | ||
2927 | |||
2928 | /* | ||
2846 | * Initiate forwarding of connections to port "port" on remote host through | 2929 | * Initiate forwarding of connections to port "port" on remote host through |
2847 | * the secure channel to host:port from local side. | 2930 | * the secure channel to host:port from local side. |
2931 | * Returns handle (index) for updating the dynamic listen port with | ||
2932 | * channel_update_permitted_opens(). | ||
2848 | */ | 2933 | */ |
2849 | |||
2850 | int | 2934 | int |
2851 | channel_request_remote_forwarding(const char *listen_host, u_short listen_port, | 2935 | channel_request_remote_forwarding(const char *listen_host, u_short listen_port, |
2852 | const char *host_to_connect, u_short port_to_connect) | 2936 | const char *host_to_connect, u_short port_to_connect) |
2853 | { | 2937 | { |
2854 | int type, success = 0; | 2938 | int type, success = 0, idx = -1; |
2855 | 2939 | ||
2856 | /* Send the forward request to the remote side. */ | 2940 | /* Send the forward request to the remote side. */ |
2857 | if (compat20) { | 2941 | if (compat20) { |
2858 | const char *address_to_bind; | ||
2859 | if (listen_host == NULL) { | ||
2860 | if (datafellows & SSH_BUG_RFWD_ADDR) | ||
2861 | address_to_bind = "127.0.0.1"; | ||
2862 | else | ||
2863 | address_to_bind = "localhost"; | ||
2864 | } else if (*listen_host == '\0' || | ||
2865 | strcmp(listen_host, "*") == 0) { | ||
2866 | if (datafellows & SSH_BUG_RFWD_ADDR) | ||
2867 | address_to_bind = "0.0.0.0"; | ||
2868 | else | ||
2869 | address_to_bind = ""; | ||
2870 | } else | ||
2871 | address_to_bind = listen_host; | ||
2872 | |||
2873 | packet_start(SSH2_MSG_GLOBAL_REQUEST); | 2942 | packet_start(SSH2_MSG_GLOBAL_REQUEST); |
2874 | packet_put_cstring("tcpip-forward"); | 2943 | packet_put_cstring("tcpip-forward"); |
2875 | packet_put_char(1); /* boolean: want reply */ | 2944 | packet_put_char(1); /* boolean: want reply */ |
2876 | packet_put_cstring(address_to_bind); | 2945 | packet_put_cstring(channel_rfwd_bind_host(listen_host)); |
2877 | packet_put_int(listen_port); | 2946 | packet_put_int(listen_port); |
2878 | packet_send(); | 2947 | packet_send(); |
2879 | packet_write_wait(); | 2948 | packet_write_wait(); |
@@ -2905,25 +2974,25 @@ channel_request_remote_forwarding(const char *listen_host, u_short listen_port, | |||
2905 | /* Record that connection to this host/port is permitted. */ | 2974 | /* Record that connection to this host/port is permitted. */ |
2906 | permitted_opens = xrealloc(permitted_opens, | 2975 | permitted_opens = xrealloc(permitted_opens, |
2907 | num_permitted_opens + 1, sizeof(*permitted_opens)); | 2976 | num_permitted_opens + 1, sizeof(*permitted_opens)); |
2908 | permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host_to_connect); | 2977 | idx = num_permitted_opens++; |
2909 | permitted_opens[num_permitted_opens].port_to_connect = port_to_connect; | 2978 | permitted_opens[idx].host_to_connect = xstrdup(host_to_connect); |
2910 | permitted_opens[num_permitted_opens].listen_port = listen_port; | 2979 | permitted_opens[idx].port_to_connect = port_to_connect; |
2911 | num_permitted_opens++; | 2980 | permitted_opens[idx].listen_port = listen_port; |
2912 | } | 2981 | } |
2913 | return (success ? 0 : -1); | 2982 | return (idx); |
2914 | } | 2983 | } |
2915 | 2984 | ||
2916 | /* | 2985 | /* |
2917 | * Request cancellation of remote forwarding of connection host:port from | 2986 | * Request cancellation of remote forwarding of connection host:port from |
2918 | * local side. | 2987 | * local side. |
2919 | */ | 2988 | */ |
2920 | void | 2989 | int |
2921 | channel_request_rforward_cancel(const char *host, u_short port) | 2990 | channel_request_rforward_cancel(const char *host, u_short port) |
2922 | { | 2991 | { |
2923 | int i; | 2992 | int i; |
2924 | 2993 | ||
2925 | if (!compat20) | 2994 | if (!compat20) |
2926 | return; | 2995 | return -1; |
2927 | 2996 | ||
2928 | for (i = 0; i < num_permitted_opens; i++) { | 2997 | for (i = 0; i < num_permitted_opens; i++) { |
2929 | if (permitted_opens[i].host_to_connect != NULL && | 2998 | if (permitted_opens[i].host_to_connect != NULL && |
@@ -2932,12 +3001,12 @@ channel_request_rforward_cancel(const char *host, u_short port) | |||
2932 | } | 3001 | } |
2933 | if (i >= num_permitted_opens) { | 3002 | if (i >= num_permitted_opens) { |
2934 | debug("%s: requested forward not found", __func__); | 3003 | debug("%s: requested forward not found", __func__); |
2935 | return; | 3004 | return -1; |
2936 | } | 3005 | } |
2937 | packet_start(SSH2_MSG_GLOBAL_REQUEST); | 3006 | packet_start(SSH2_MSG_GLOBAL_REQUEST); |
2938 | packet_put_cstring("cancel-tcpip-forward"); | 3007 | packet_put_cstring("cancel-tcpip-forward"); |
2939 | packet_put_char(0); | 3008 | packet_put_char(0); |
2940 | packet_put_cstring(host == NULL ? "" : host); | 3009 | packet_put_cstring(channel_rfwd_bind_host(host)); |
2941 | packet_put_int(port); | 3010 | packet_put_int(port); |
2942 | packet_send(); | 3011 | packet_send(); |
2943 | 3012 | ||
@@ -2945,6 +3014,8 @@ channel_request_rforward_cancel(const char *host, u_short port) | |||
2945 | permitted_opens[i].port_to_connect = 0; | 3014 | permitted_opens[i].port_to_connect = 0; |
2946 | xfree(permitted_opens[i].host_to_connect); | 3015 | xfree(permitted_opens[i].host_to_connect); |
2947 | permitted_opens[i].host_to_connect = NULL; | 3016 | permitted_opens[i].host_to_connect = NULL; |
3017 | |||
3018 | return 0; | ||
2948 | } | 3019 | } |
2949 | 3020 | ||
2950 | /* | 3021 | /* |
@@ -3013,6 +3084,35 @@ channel_add_permitted_opens(char *host, int port) | |||
3013 | all_opens_permitted = 0; | 3084 | all_opens_permitted = 0; |
3014 | } | 3085 | } |
3015 | 3086 | ||
3087 | /* | ||
3088 | * Update the listen port for a dynamic remote forward, after | ||
3089 | * the actual 'newport' has been allocated. If 'newport' < 0 is | ||
3090 | * passed then they entry will be invalidated. | ||
3091 | */ | ||
3092 | void | ||
3093 | channel_update_permitted_opens(int idx, int newport) | ||
3094 | { | ||
3095 | if (idx < 0 || idx >= num_permitted_opens) { | ||
3096 | debug("channel_update_permitted_opens: index out of range:" | ||
3097 | " %d num_permitted_opens %d", idx, num_permitted_opens); | ||
3098 | return; | ||
3099 | } | ||
3100 | debug("%s allowed port %d for forwarding to host %s port %d", | ||
3101 | newport > 0 ? "Updating" : "Removing", | ||
3102 | newport, | ||
3103 | permitted_opens[idx].host_to_connect, | ||
3104 | permitted_opens[idx].port_to_connect); | ||
3105 | if (newport >= 0) { | ||
3106 | permitted_opens[idx].listen_port = | ||
3107 | (datafellows & SSH_BUG_DYNAMIC_RPORT) ? 0 : newport; | ||
3108 | } else { | ||
3109 | permitted_opens[idx].listen_port = 0; | ||
3110 | permitted_opens[idx].port_to_connect = 0; | ||
3111 | xfree(permitted_opens[idx].host_to_connect); | ||
3112 | permitted_opens[idx].host_to_connect = NULL; | ||
3113 | } | ||
3114 | } | ||
3115 | |||
3016 | int | 3116 | int |
3017 | channel_add_adm_permitted_opens(char *host, int port) | 3117 | channel_add_adm_permitted_opens(char *host, int port) |
3018 | { | 3118 | { |
@@ -3073,6 +3173,28 @@ channel_print_adm_permitted_opens(void) | |||
3073 | printf("\n"); | 3173 | printf("\n"); |
3074 | } | 3174 | } |
3075 | 3175 | ||
3176 | /* returns port number, FWD_PERMIT_ANY_PORT or -1 on error */ | ||
3177 | int | ||
3178 | permitopen_port(const char *p) | ||
3179 | { | ||
3180 | int port; | ||
3181 | |||
3182 | if (strcmp(p, "*") == 0) | ||
3183 | return FWD_PERMIT_ANY_PORT; | ||
3184 | if ((port = a2port(p)) > 0) | ||
3185 | return port; | ||
3186 | return -1; | ||
3187 | } | ||
3188 | |||
3189 | static int | ||
3190 | port_match(u_short allowedport, u_short requestedport) | ||
3191 | { | ||
3192 | if (allowedport == FWD_PERMIT_ANY_PORT || | ||
3193 | allowedport == requestedport) | ||
3194 | return 1; | ||
3195 | return 0; | ||
3196 | } | ||
3197 | |||
3076 | /* Try to start non-blocking connect to next host in cctx list */ | 3198 | /* Try to start non-blocking connect to next host in cctx list */ |
3077 | static int | 3199 | static int |
3078 | connect_next(struct channel_connect *cctx) | 3200 | connect_next(struct channel_connect *cctx) |
@@ -3175,7 +3297,7 @@ channel_connect_by_listen_address(u_short listen_port, char *ctype, char *rname) | |||
3175 | 3297 | ||
3176 | for (i = 0; i < num_permitted_opens; i++) { | 3298 | for (i = 0; i < num_permitted_opens; i++) { |
3177 | if (permitted_opens[i].host_to_connect != NULL && | 3299 | if (permitted_opens[i].host_to_connect != NULL && |
3178 | permitted_opens[i].listen_port == listen_port) { | 3300 | port_match(permitted_opens[i].listen_port, listen_port)) { |
3179 | return connect_to( | 3301 | return connect_to( |
3180 | permitted_opens[i].host_to_connect, | 3302 | permitted_opens[i].host_to_connect, |
3181 | permitted_opens[i].port_to_connect, ctype, rname); | 3303 | permitted_opens[i].port_to_connect, ctype, rname); |
@@ -3196,7 +3318,7 @@ channel_connect_to(const char *host, u_short port, char *ctype, char *rname) | |||
3196 | if (!permit) { | 3318 | if (!permit) { |
3197 | for (i = 0; i < num_permitted_opens; i++) | 3319 | for (i = 0; i < num_permitted_opens; i++) |
3198 | if (permitted_opens[i].host_to_connect != NULL && | 3320 | if (permitted_opens[i].host_to_connect != NULL && |
3199 | permitted_opens[i].port_to_connect == port && | 3321 | port_match(permitted_opens[i].port_to_connect, port) && |
3200 | strcmp(permitted_opens[i].host_to_connect, host) == 0) | 3322 | strcmp(permitted_opens[i].host_to_connect, host) == 0) |
3201 | permit = 1; | 3323 | permit = 1; |
3202 | } | 3324 | } |
@@ -3205,7 +3327,7 @@ channel_connect_to(const char *host, u_short port, char *ctype, char *rname) | |||
3205 | permit_adm = 0; | 3327 | permit_adm = 0; |
3206 | for (i = 0; i < num_adm_permitted_opens; i++) | 3328 | for (i = 0; i < num_adm_permitted_opens; i++) |
3207 | if (permitted_adm_opens[i].host_to_connect != NULL && | 3329 | if (permitted_adm_opens[i].host_to_connect != NULL && |
3208 | permitted_adm_opens[i].port_to_connect == port && | 3330 | port_match(permitted_adm_opens[i].port_to_connect, port) && |
3209 | strcmp(permitted_adm_opens[i].host_to_connect, host) | 3331 | strcmp(permitted_adm_opens[i].host_to_connect, host) |
3210 | == 0) | 3332 | == 0) |
3211 | permit_adm = 1; | 3333 | permit_adm = 1; |