|
Lines 77-82
Link Here
|
| 77 |
#include "key.h" |
77 |
#include "key.h" |
| 78 |
#include "authfd.h" |
78 |
#include "authfd.h" |
| 79 |
#include "pathnames.h" |
79 |
#include "pathnames.h" |
|
|
80 |
#include "match.h" |
| 80 |
|
81 |
|
| 81 |
/* -- channel core */ |
82 |
/* -- channel core */ |
| 82 |
|
83 |
|
|
Lines 109-115
Link Here
|
| 109 |
*/ |
110 |
*/ |
| 110 |
typedef struct { |
111 |
typedef struct { |
| 111 |
char *host_to_connect; /* Connect to 'host'. */ |
112 |
char *host_to_connect; /* Connect to 'host'. */ |
| 112 |
u_short port_to_connect; /* Connect to 'port'. */ |
113 |
u_short min_port_to_connect; /* Connect to 'port' (minimum). */ |
|
|
114 |
u_short max_port_to_connect; /* Connect to 'port' (maximum). */ |
| 113 |
u_short listen_port; /* Remote side should listen port number. */ |
115 |
u_short listen_port; /* Remote side should listen port number. */ |
| 114 |
} ForwardPermission; |
116 |
} ForwardPermission; |
| 115 |
|
117 |
|
|
Lines 2906-2912
Link Here
|
| 2906 |
permitted_opens = xrealloc(permitted_opens, |
2908 |
permitted_opens = xrealloc(permitted_opens, |
| 2907 |
num_permitted_opens + 1, sizeof(*permitted_opens)); |
2909 |
num_permitted_opens + 1, sizeof(*permitted_opens)); |
| 2908 |
permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host_to_connect); |
2910 |
permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host_to_connect); |
| 2909 |
permitted_opens[num_permitted_opens].port_to_connect = port_to_connect; |
2911 |
permitted_opens[num_permitted_opens].min_port_to_connect = port_to_connect; |
|
|
2912 |
permitted_opens[num_permitted_opens].max_port_to_connect = port_to_connect; |
| 2910 |
permitted_opens[num_permitted_opens].listen_port = listen_port; |
2913 |
permitted_opens[num_permitted_opens].listen_port = listen_port; |
| 2911 |
num_permitted_opens++; |
2914 |
num_permitted_opens++; |
| 2912 |
} |
2915 |
} |
|
Lines 2942-2948
Link Here
|
| 2942 |
packet_send(); |
2945 |
packet_send(); |
| 2943 |
|
2946 |
|
| 2944 |
permitted_opens[i].listen_port = 0; |
2947 |
permitted_opens[i].listen_port = 0; |
| 2945 |
permitted_opens[i].port_to_connect = 0; |
2948 |
permitted_opens[i].min_port_to_connect = 0; |
|
|
2949 |
permitted_opens[i].max_port_to_connect = 0; |
| 2946 |
xfree(permitted_opens[i].host_to_connect); |
2950 |
xfree(permitted_opens[i].host_to_connect); |
| 2947 |
permitted_opens[i].host_to_connect = NULL; |
2951 |
permitted_opens[i].host_to_connect = NULL; |
| 2948 |
} |
2952 |
} |
|
Lines 3000-3028
Link Here
|
| 3000 |
} |
3004 |
} |
| 3001 |
|
3005 |
|
| 3002 |
void |
3006 |
void |
| 3003 |
channel_add_permitted_opens(char *host, int port) |
3007 |
channel_add_permitted_opens(char *host, int min_port, int max_port) |
| 3004 |
{ |
3008 |
{ |
| 3005 |
debug("allow port forwarding to host %s port %d", host, port); |
3009 |
if (min_port == max_port) { |
|
|
3010 |
debug("allow port forwarding to host %s port %d", host, min_port); |
| 3011 |
} else { |
| 3012 |
if (min_port > max_port) { |
| 3013 |
// xor swap the ports |
| 3014 |
min_port ^= max_port; |
| 3015 |
max_port ^= min_port; |
| 3016 |
min_port ^= max_port; |
| 3017 |
} |
| 3018 |
debug("allow port forwarding to host %s ports %d through %d", host, min_port, max_port); |
| 3019 |
} |
| 3006 |
|
3020 |
|
| 3007 |
permitted_opens = xrealloc(permitted_opens, |
3021 |
permitted_opens = xrealloc(permitted_opens, |
| 3008 |
num_permitted_opens + 1, sizeof(*permitted_opens)); |
3022 |
num_permitted_opens + 1, sizeof(*permitted_opens)); |
| 3009 |
permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host); |
3023 |
permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host); |
| 3010 |
permitted_opens[num_permitted_opens].port_to_connect = port; |
3024 |
permitted_opens[num_permitted_opens].min_port_to_connect = min_port; |
|
|
3025 |
permitted_opens[num_permitted_opens].min_port_to_connect = max_port; |
| 3011 |
num_permitted_opens++; |
3026 |
num_permitted_opens++; |
| 3012 |
|
3027 |
|
| 3013 |
all_opens_permitted = 0; |
3028 |
all_opens_permitted = 0; |
| 3014 |
} |
3029 |
} |
| 3015 |
|
3030 |
|
| 3016 |
int |
3031 |
int |
| 3017 |
channel_add_adm_permitted_opens(char *host, int port) |
3032 |
channel_add_adm_permitted_opens(char *host, int min_port, int max_port) |
| 3018 |
{ |
3033 |
{ |
| 3019 |
debug("config allows port forwarding to host %s port %d", host, port); |
3034 |
if (min_port == max_port) { |
|
|
3035 |
debug("config allows port forwarding to host %s port %d", host, min_port); |
| 3036 |
} else { |
| 3037 |
if (min_port > max_port) { |
| 3038 |
// xor swap the ports |
| 3039 |
min_port ^= max_port; |
| 3040 |
max_port ^= min_port; |
| 3041 |
min_port ^= max_port; |
| 3042 |
} |
| 3043 |
debug("config allows port forwarding to host %s ports %d through %d", host, min_port, max_port); |
| 3044 |
} |
| 3020 |
|
3045 |
|
| 3021 |
permitted_adm_opens = xrealloc(permitted_adm_opens, |
3046 |
permitted_adm_opens = xrealloc(permitted_adm_opens, |
| 3022 |
num_adm_permitted_opens + 1, sizeof(*permitted_adm_opens)); |
3047 |
num_adm_permitted_opens + 1, sizeof(*permitted_adm_opens)); |
| 3023 |
permitted_adm_opens[num_adm_permitted_opens].host_to_connect |
3048 |
permitted_adm_opens[num_adm_permitted_opens].host_to_connect |
| 3024 |
= xstrdup(host); |
3049 |
= xstrdup(host); |
| 3025 |
permitted_adm_opens[num_adm_permitted_opens].port_to_connect = port; |
3050 |
permitted_adm_opens[num_adm_permitted_opens].min_port_to_connect = min_port; |
|
|
3051 |
permitted_adm_opens[num_adm_permitted_opens].max_port_to_connect = max_port; |
| 3026 |
return ++num_adm_permitted_opens; |
3052 |
return ++num_adm_permitted_opens; |
| 3027 |
} |
3053 |
} |
| 3028 |
|
3054 |
|
|
Lines 3067-3075
Link Here
|
| 3067 |
return; |
3093 |
return; |
| 3068 |
} |
3094 |
} |
| 3069 |
for (i = 0; i < num_adm_permitted_opens; i++) |
3095 |
for (i = 0; i < num_adm_permitted_opens; i++) |
| 3070 |
if (permitted_adm_opens[i].host_to_connect != NULL) |
3096 |
if (permitted_adm_opens[i].host_to_connect != NULL) { |
| 3071 |
printf(" %s:%d", permitted_adm_opens[i].host_to_connect, |
3097 |
if (permitted_adm_opens[i].min_port_to_connect == |
| 3072 |
permitted_adm_opens[i].port_to_connect); |
3098 |
permitted_adm_opens[i].max_port_to_connect) { |
|
|
3099 |
printf(" %s:%d", permitted_adm_opens[i].host_to_connect, |
| 3100 |
permitted_adm_opens[i].min_port_to_connect); |
| 3101 |
} else { |
| 3102 |
printf(" %s:%d-%d", permitted_adm_opens[i].host_to_connect, |
| 3103 |
permitted_adm_opens[i].min_port_to_connect, |
| 3104 |
permitted_adm_opens[i].max_port_to_connect); |
| 3105 |
} |
| 3106 |
} |
| 3073 |
printf("\n"); |
3107 |
printf("\n"); |
| 3074 |
} |
3108 |
} |
| 3075 |
|
3109 |
|
|
Lines 3090-3095
Link Here
|
| 3090 |
error("connect_next: getnameinfo failed"); |
3124 |
error("connect_next: getnameinfo failed"); |
| 3091 |
continue; |
3125 |
continue; |
| 3092 |
} |
3126 |
} |
|
|
3127 |
if (channel_is_connect_to_permitted(cctx) == 0) |
| 3128 |
continue; |
| 3093 |
if ((sock = socket(cctx->ai->ai_family, cctx->ai->ai_socktype, |
3129 |
if ((sock = socket(cctx->ai->ai_family, cctx->ai->ai_socktype, |
| 3094 |
cctx->ai->ai_protocol)) == -1) { |
3130 |
cctx->ai->ai_protocol)) == -1) { |
| 3095 |
if (cctx->ai->ai_next == NULL) |
3131 |
if (cctx->ai->ai_next == NULL) |
|
Lines 3178-3184
Link Here
|
| 3178 |
permitted_opens[i].listen_port == listen_port) { |
3214 |
permitted_opens[i].listen_port == listen_port) { |
| 3179 |
return connect_to( |
3215 |
return connect_to( |
| 3180 |
permitted_opens[i].host_to_connect, |
3216 |
permitted_opens[i].host_to_connect, |
| 3181 |
permitted_opens[i].port_to_connect, ctype, rname); |
3217 |
permitted_opens[i].min_port_to_connect, ctype, rname); |
| 3182 |
} |
3218 |
} |
| 3183 |
} |
3219 |
} |
| 3184 |
error("WARNING: Server requests forwarding for unknown listen_port %d", |
3220 |
error("WARNING: Server requests forwarding for unknown listen_port %d", |
|
Lines 3186-3222
Link Here
|
| 3186 |
return NULL; |
3222 |
return NULL; |
| 3187 |
} |
3223 |
} |
| 3188 |
|
3224 |
|
| 3189 |
/* Check if connecting to that port is permitted and connect. */ |
3225 |
/* Check if connecting to that port is permitted */ |
| 3190 |
Channel * |
3226 |
int |
| 3191 |
channel_connect_to(const char *host, u_short port, char *ctype, char *rname) |
3227 |
channel_is_connect_to_permitted(const struct channel_connect *cctx) |
| 3192 |
{ |
3228 |
{ |
| 3193 |
int i, permit, permit_adm = 1; |
3229 |
int r, i, permit, permit_adm = 1; |
|
|
3230 |
char ipaddr[128]; // probably overkill size-wise |
| 3231 |
|
| 3232 |
/* Get an ip address string for match_host_and_ip */ |
| 3233 |
inet_ntop(cctx->ai->ai_family, &((const struct sockaddr_in *)cctx->ai->ai_addr)->sin_addr, ipaddr, cctx->ai->ai_addrlen); |
| 3234 |
|
| 3235 |
debug2("checking with ip %.100s for %.100s", ipaddr, cctx->host); |
| 3194 |
|
3236 |
|
| 3195 |
permit = all_opens_permitted; |
3237 |
permit = all_opens_permitted; |
| 3196 |
if (!permit) { |
3238 |
if (!permit) { |
| 3197 |
for (i = 0; i < num_permitted_opens; i++) |
3239 |
for (i = 0; i < num_permitted_opens; i++) { |
|
|
3240 |
debug2("checking ports %d => %d <= %d", permitted_opens[i].min_port_to_connect, cctx->port, permitted_opens[i].max_port_to_connect); |
| 3198 |
if (permitted_opens[i].host_to_connect != NULL && |
3241 |
if (permitted_opens[i].host_to_connect != NULL && |
| 3199 |
permitted_opens[i].port_to_connect == port && |
3242 |
permitted_opens[i].min_port_to_connect <= cctx->port && |
| 3200 |
strcmp(permitted_opens[i].host_to_connect, host) == 0) |
3243 |
permitted_opens[i].max_port_to_connect >= cctx->port) { |
| 3201 |
permit = 1; |
3244 |
debug2("checking %.100s, %.100s, %.100s", cctx->host, ipaddr, permitted_opens[i].host_to_connect); |
|
|
3245 |
r = match_host_and_ip(cctx->host, ipaddr, permitted_opens[i].host_to_connect); |
| 3246 |
if (r == -1) { /* negated match - this attempt is blocked */ |
| 3247 |
debug2("denied %.100s:%d by %.100s:%d-%d", cctx->host, cctx->port, |
| 3248 |
permitted_opens[i].host_to_connect, |
| 3249 |
permitted_opens[i].min_port_to_connect, |
| 3250 |
permitted_opens[i].max_port_to_connect); |
| 3251 |
permit = 0; |
| 3252 |
break; |
| 3253 |
} else if (r == 1) { |
| 3254 |
debug2("permited %.100s:%d by %.100s:%d-%d", cctx->host, cctx->port, |
| 3255 |
permitted_opens[i].host_to_connect, |
| 3256 |
permitted_opens[i].min_port_to_connect, |
| 3257 |
permitted_opens[i].max_port_to_connect); |
| 3258 |
permit = 1; |
| 3259 |
} |
| 3260 |
} |
| 3261 |
} |
| 3202 |
} |
3262 |
} |
| 3203 |
|
3263 |
|
| 3204 |
if (num_adm_permitted_opens > 0) { |
3264 |
if (num_adm_permitted_opens > 0) { |
| 3205 |
permit_adm = 0; |
3265 |
permit_adm = 0; |
| 3206 |
for (i = 0; i < num_adm_permitted_opens; i++) |
3266 |
for (i = 0; i < num_adm_permitted_opens; i++) { |
| 3207 |
if (permitted_adm_opens[i].host_to_connect != NULL && |
3267 |
if (permitted_adm_opens[i].host_to_connect != NULL && |
| 3208 |
permitted_adm_opens[i].port_to_connect == port && |
3268 |
permitted_adm_opens[i].min_port_to_connect <= cctx->port && |
| 3209 |
strcmp(permitted_adm_opens[i].host_to_connect, host) |
3269 |
permitted_adm_opens[i].max_port_to_connect >= cctx->port) { |
| 3210 |
== 0) |
3270 |
debug2("checking %.100s, %.100s, %.100s", cctx->host, ipaddr, permitted_adm_opens[i].host_to_connect); |
| 3211 |
permit_adm = 1; |
3271 |
r = match_host_and_ip(cctx->host, ipaddr, permitted_adm_opens[i].host_to_connect); |
|
|
3272 |
if (r == -1) { /* negated match - this attempt is blocked */ |
| 3273 |
debug2("server config denied %.100s:%d by %.100s:%d-%d", cctx->host, cctx->port, |
| 3274 |
permitted_adm_opens[i].host_to_connect, |
| 3275 |
permitted_adm_opens[i].min_port_to_connect, |
| 3276 |
permitted_adm_opens[i].max_port_to_connect); |
| 3277 |
permit_adm = 0; |
| 3278 |
break; |
| 3279 |
} else if (r == 1) { |
| 3280 |
debug2("server config permited %.100s:%d by %.100s:%d-%d", cctx->host, cctx->port, |
| 3281 |
permitted_adm_opens[i].host_to_connect, |
| 3282 |
permitted_adm_opens[i].min_port_to_connect, |
| 3283 |
permitted_adm_opens[i].max_port_to_connect); |
| 3284 |
permit_adm = 1; |
| 3285 |
} |
| 3286 |
} |
| 3287 |
} |
| 3212 |
} |
3288 |
} |
| 3213 |
|
3289 |
|
| 3214 |
if (!permit || !permit_adm) { |
3290 |
if (!permit || !permit_adm) { |
| 3215 |
logit("Received request to connect to host %.100s port %d, " |
3291 |
logit("Received request to connect to host %.100s port %d, " |
| 3216 |
"but the request was denied.", host, port); |
3292 |
"but the request was denied.", cctx->host, cctx->port); |
| 3217 |
return NULL; |
3293 |
return 0; |
| 3218 |
} |
3294 |
} |
| 3219 |
return connect_to(host, port, ctype, rname); |
3295 |
return 1; |
|
|
3296 |
} |
| 3297 |
/* Check if connecting to that port is permitted and connect. */ |
| 3298 |
Channel * |
| 3299 |
channel_connect_to(const char *host, u_short port, char *ctype, char *rname) |
| 3300 |
{ |
| 3301 |
return connect_to(host, port, ctype, rname); /* XXX replace calls to channel_connect_to */ |
| 3220 |
} |
3302 |
} |
| 3221 |
|
3303 |
|
| 3222 |
void |
3304 |
void |