View | Details | Raw Unified | Return to bug 2716
Collapse All | Expand All

(-)a/auth-options.c (+56 lines)
Lines 82-87 auth_clear_options(void) Link Here
82
	authorized_principals = NULL;
82
	authorized_principals = NULL;
83
	forced_tun_device = -1;
83
	forced_tun_device = -1;
84
	channel_clear_permitted_opens();
84
	channel_clear_permitted_opens();
85
	channel_clear_permitted_listens();
85
}
86
}
86
87
87
/*
88
/*
Lines 383-388 auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) Link Here
383
			free(patterns);
384
			free(patterns);
384
			goto next_option;
385
			goto next_option;
385
		}
386
		}
387
		cp = "permitlisten=\"";
388
		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
389
			char *host, *p;
390
			int port;
391
			char *patterns = xmalloc(strlen(opts) + 1);
392
393
			opts += strlen(cp);
394
			i = 0;
395
			while (*opts) {
396
				if (*opts == '"')
397
					break;
398
				if (*opts == '\\' && opts[1] == '"') {
399
					opts += 2;
400
					patterns[i++] = '"';
401
					continue;
402
				}
403
				patterns[i++] = *opts++;
404
			}
405
			if (!*opts) {
406
				debug("%.100s, line %lu: missing end quote",
407
				    file, linenum);
408
				auth_debug_add("%.100s, line %lu: missing "
409
				    "end quote", file, linenum);
410
				free(patterns);
411
				goto bad_option;
412
			}
413
			patterns[i] = '\0';
414
			opts++;
415
			p = patterns;
416
			/* XXX - add streamlocal support */
417
			host = hpdelim(&p);
418
			if (host == NULL || strlen(host) >= NI_MAXHOST) {
419
				debug("%.100s, line %lu: Bad permitlisten "
420
				    "specification <%.100s>", file, linenum,
421
				    patterns);
422
				auth_debug_add("%.100s, line %lu: "
423
				    "Bad permitlisten specification", file,
424
				    linenum);
425
				free(patterns);
426
				goto bad_option;
427
			}
428
			host = cleanhostname(host);
429
			if (p == NULL || (port = permitopen_port(p)) < 0) {
430
				debug("%.100s, line %lu: Bad permitlisten port "
431
				    "<%.100s>", file, linenum, p ? p : "");
432
				auth_debug_add("%.100s, line %lu: "
433
				    "Bad permitopen port", file, linenum);
434
				free(patterns);
435
				goto bad_option;
436
			}
437
			if ((options.allow_tcp_forwarding & FORWARD_REMOTE) != 0)
438
				channel_add_permitted_listens(host, port);
439
			free(patterns);
440
			goto next_option;
441
		}
386
		cp = "tunnel=\"";
442
		cp = "tunnel=\"";
387
		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
443
		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
388
			char *tun = NULL;
444
			char *tun = NULL;
(-)a/channels.c (+66 lines)
Lines 129-140 static ForwardPermission *permitted_opens = NULL; Link Here
129
/* List of all permitted host/port pairs to connect by the admin. */
129
/* List of all permitted host/port pairs to connect by the admin. */
130
static ForwardPermission *permitted_adm_opens = NULL;
130
static ForwardPermission *permitted_adm_opens = NULL;
131
131
132
/* List of all permitted remote host/port pairs to connect by the user. */
133
static ForwardPermission *permitted_listens = NULL;
134
132
/* Number of permitted host/port pairs in the array permitted by the user. */
135
/* Number of permitted host/port pairs in the array permitted by the user. */
133
static int num_permitted_opens = 0;
136
static int num_permitted_opens = 0;
134
137
135
/* Number of permitted host/port pair in the array permitted by the admin. */
138
/* Number of permitted host/port pair in the array permitted by the admin. */
136
static int num_adm_permitted_opens = 0;
139
static int num_adm_permitted_opens = 0;
137
140
141
/* Number of permitted remote host/port pairs. */
142
static int num_permitted_listens = 0;
143
138
/* special-case port number meaning allow any port */
144
/* special-case port number meaning allow any port */
139
#define FWD_PERMIT_ANY_PORT	0
145
#define FWD_PERMIT_ANY_PORT	0
140
146
Lines 148-153 static int num_adm_permitted_opens = 0; Link Here
148
 */
154
 */
149
static int all_opens_permitted = 0;
155
static int all_opens_permitted = 0;
150
156
157
/**
158
 * If this is true, all remote opens are permitted.
159
 */
160
static int all_listens_permitted = 0;
151
161
152
/* -- X11 forwarding */
162
/* -- X11 forwarding */
153
163
Lines 3503-3508 channel_add_permitted_opens(char *host, int port) Link Here
3503
	all_opens_permitted = 0;
3513
	all_opens_permitted = 0;
3504
}
3514
}
3505
3515
3516
void
3517
channel_add_permitted_listens(char *host, int port)
3518
{
3519
	debug("allow remote port forwarding to host %s port %d", host, port);
3520
3521
	permitted_listens = xreallocarray(permitted_listens,
3522
        num_permitted_listens + 1, sizeof(*permitted_listens));
3523
	permitted_listens[num_permitted_listens].host_to_connect = xstrdup(host);
3524
	permitted_listens[num_permitted_listens].port_to_connect = port;
3525
	permitted_listens[num_permitted_listens].listen_host = NULL;
3526
	permitted_listens[num_permitted_listens].listen_path = NULL;
3527
	permitted_listens[num_permitted_listens].listen_port = 0;
3528
	num_permitted_listens++;
3529
3530
	all_listens_permitted = 0;
3531
}
3532
3506
/*
3533
/*
3507
 * Update the listen port for a dynamic remote forward, after
3534
 * Update the listen port for a dynamic remote forward, after
3508
 * the actual 'newport' has been allocated. If 'newport' < 0 is
3535
 * the actual 'newport' has been allocated. If 'newport' < 0 is
Lines 3592-3597 channel_clear_adm_permitted_opens(void) Link Here
3592
}
3619
}
3593
3620
3594
void
3621
void
3622
channel_clear_permitted_listens(void)
3623
{
3624
    int i;
3625
3626
    for (i = 0; i < num_permitted_listens; i++) {
3627
        free(permitted_listens[i].host_to_connect);
3628
        free(permitted_listens[i].listen_host);
3629
        free(permitted_listens[i].listen_path);
3630
    }
3631
    free(permitted_listens);
3632
    permitted_listens = NULL;
3633
    num_permitted_listens = 0;
3634
}
3635
3636
void
3595
channel_print_adm_permitted_opens(void)
3637
channel_print_adm_permitted_opens(void)
3596
{
3638
{
3597
	int i;
3639
	int i;
Lines 3885-3890 channel_connect_to_path(const char *path, char *ctype, char *rname) Link Here
3885
	return connect_to(path, PORT_STREAMLOCAL, ctype, rname);
3927
	return connect_to(path, PORT_STREAMLOCAL, ctype, rname);
3886
}
3928
}
3887
3929
3930
/* Check if connecting to that port is permitted and connect. */
3931
int
3932
channel_connect_check_permitted_listens(const char *host, u_short port)
3933
{
3934
    int i, permit = 1;
3935
3936
    permit = all_listens_permitted;
3937
    if (!permit) {
3938
        for (i = 0; i < num_permitted_listens; i++)
3939
            if (open_match(&permitted_listens[i], host, port)) {
3940
                permit = 1;
3941
                break;
3942
            }
3943
    }
3944
3945
    if (!permit) {
3946
        logit("Received request for remote forward to host %.100s port %d, "
3947
                      "but the request was denied.", host, port);
3948
        return -1;
3949
    }
3950
3951
    return 0;
3952
}
3953
3888
void
3954
void
3889
channel_send_window_changes(void)
3955
channel_send_window_changes(void)
3890
{
3956
{
(-)a/channels.h (+3 lines)
Lines 267-281 struct ForwardOptions; Link Here
267
void	 channel_set_af(int af);
267
void	 channel_set_af(int af);
268
void     channel_permit_all_opens(void);
268
void     channel_permit_all_opens(void);
269
void	 channel_add_permitted_opens(char *, int);
269
void	 channel_add_permitted_opens(char *, int);
270
void	 channel_add_permitted_listens(char *, int);
270
int	 channel_add_adm_permitted_opens(char *, int);
271
int	 channel_add_adm_permitted_opens(char *, int);
271
void	 channel_disable_adm_local_opens(void);
272
void	 channel_disable_adm_local_opens(void);
272
void	 channel_update_permitted_opens(int, int);
273
void	 channel_update_permitted_opens(int, int);
273
void	 channel_clear_permitted_opens(void);
274
void	 channel_clear_permitted_opens(void);
274
void	 channel_clear_adm_permitted_opens(void);
275
void	 channel_clear_adm_permitted_opens(void);
276
void	 channel_clear_permitted_listens(void);
275
void 	 channel_print_adm_permitted_opens(void);
277
void 	 channel_print_adm_permitted_opens(void);
276
Channel	*channel_connect_to_port(const char *, u_short, char *, char *, int *,
278
Channel	*channel_connect_to_port(const char *, u_short, char *, char *, int *,
277
	     const char **);
279
	     const char **);
278
Channel *channel_connect_to_path(const char *, char *, char *);
280
Channel *channel_connect_to_path(const char *, char *, char *);
281
int channel_connect_check_permitted_listens(const char *host, u_short port);
279
Channel	*channel_connect_stdio_fwd(const char*, u_short, int, int);
282
Channel	*channel_connect_stdio_fwd(const char*, u_short, int, int);
280
Channel	*channel_connect_by_listen_address(const char *, u_short,
283
Channel	*channel_connect_by_listen_address(const char *, u_short,
281
	     char *, char *);
284
	     char *, char *);
(-)a/serverloop.c (-3 / +3 lines)
Lines 729-739 server_input_global_request(int type, u_int32_t seq, void *ctxt) Link Here
729
		    fwd.listen_host, fwd.listen_port);
729
		    fwd.listen_host, fwd.listen_port);
730
730
731
		/* check permissions */
731
		/* check permissions */
732
		if ((options.allow_tcp_forwarding & FORWARD_REMOTE) == 0 ||
732
		if (channel_connect_check_permitted_listens(fwd.listen_host, fwd.listen_port) < 0 &&
733
		    ((options.allow_tcp_forwarding & FORWARD_REMOTE) == 0 ||
733
		    no_port_forwarding_flag || options.disable_forwarding ||
734
		    no_port_forwarding_flag || options.disable_forwarding ||
734
		    (!want_reply && fwd.listen_port == 0) ||
735
		    (!want_reply && fwd.listen_port == 0) ||
735
		    (fwd.listen_port != 0 &&
736
		    (fwd.listen_port != 0 &&
736
		     !bind_permitted(fwd.listen_port, pw->pw_uid))) {
737
		     !bind_permitted(fwd.listen_port, pw->pw_uid)))) {
737
			success = 0;
738
			success = 0;
738
			packet_send_debug("Server has disabled port forwarding.");
739
			packet_send_debug("Server has disabled port forwarding.");
739
		} else {
740
		} else {
740
- 

Return to bug 2716