View | Details | Raw Unified | Return to bug 2038 | Differences between
and this patch

Collapse All | Expand All

(-)a/auth-options.c (+45 lines)
Lines 81-86 auth_clear_options(void) Link Here
81
	}
81
	}
82
	forced_tun_device = -1;
82
	forced_tun_device = -1;
83
	channel_clear_permitted_opens();
83
	channel_clear_permitted_opens();
84
	channel_clear_permitted_remote_opens();
84
}
85
}
85
86
86
/*
87
/*
Lines 350-355 auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) Link Here
350
			free(patterns);
351
			free(patterns);
351
			goto next_option;
352
			goto next_option;
352
		}
353
		}
354
		cp = "permitremoteopen=\"";
355
		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
356
			char *p;
357
			int port;
358
			char *patterns = xmalloc(strlen(opts) + 1);
359
360
			opts += strlen(cp);
361
			i = 0;
362
			while (*opts) {
363
				if (*opts == '"')
364
					break;
365
				if (*opts == '\\' && opts[1] == '"') {
366
					opts += 2;
367
					patterns[i++] = '"';
368
					continue;
369
				}
370
				patterns[i++] = *opts++;
371
			}
372
			if (!*opts) {
373
				debug("%.100s, line %lu: missing end quote",
374
				    file, linenum);
375
				auth_debug_add("%.100s, line %lu: missing "
376
				    "end quote", file, linenum);
377
				free(patterns);
378
				goto bad_option;
379
			}
380
			patterns[i] = '\0';
381
			opts++;
382
			p = patterns;
383
			if (p == NULL || (port = permitopen_port(p)) < 0) {
384
				debug("%.100s, line %lu: Bad permitremoteopen "
385
				     "port <%.100s>", file, linenum, p ? p : 
386
				      "");
387
				auth_debug_add("%.100s, line %lu: "
388
						"Bad permitremoteopen port", 
389
						file, linenum);
390
				free(patterns);
391
				goto bad_option;
392
			}
393
			if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0)
394
				channel_add_permitted_remote_opens(port);
395
			free(patterns);
396
			goto next_option;
397
		}
353
		cp = "tunnel=\"";
398
		cp = "tunnel=\"";
354
		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
399
		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
355
			char *tun = NULL;
400
			char *tun = NULL;
(-)a/channels.c (+108 lines)
Lines 115-129 typedef struct { Link Here
115
115
116
/* List of all permitted host/port pairs to connect by the user. */
116
/* List of all permitted host/port pairs to connect by the user. */
117
static ForwardPermission *permitted_opens = NULL;
117
static ForwardPermission *permitted_opens = NULL;
118
static ForwardPermission *permitted_remote_opens = NULL;
118
119
119
/* List of all permitted host/port pairs to connect by the admin. */
120
/* List of all permitted host/port pairs to connect by the admin. */
120
static ForwardPermission *permitted_adm_opens = NULL;
121
static ForwardPermission *permitted_adm_opens = NULL;
122
static ForwardPermission *permitted_adm_remote_opens = NULL;
121
123
122
/* Number of permitted host/port pairs in the array permitted by the user. */
124
/* Number of permitted host/port pairs in the array permitted by the user. */
123
static int num_permitted_opens = 0;
125
static int num_permitted_opens = 0;
126
static int num_permitted_remote_opens = 0;
124
127
125
/* Number of permitted host/port pair in the array permitted by the admin. */
128
/* Number of permitted host/port pair in the array permitted by the admin. */
126
static int num_adm_permitted_opens = 0;
129
static int num_adm_permitted_opens = 0;
130
static int num_adm_permitted_remote_opens = 0;
127
131
128
/* special-case port number meaning allow any port */
132
/* special-case port number meaning allow any port */
129
#define FWD_PERMIT_ANY_PORT	0
133
#define FWD_PERMIT_ANY_PORT	0
Lines 134-139 static int num_adm_permitted_opens = 0; Link Here
134
 * anything after logging in anyway.
138
 * anything after logging in anyway.
135
 */
139
 */
136
static int all_opens_permitted = 0;
140
static int all_opens_permitted = 0;
141
static int all_remote_opens_permitted = 0;
137
142
138
143
139
/* -- X11 forwarding */
144
/* -- X11 forwarding */
Lines 3124-3129 channel_permit_all_opens(void) Link Here
3124
	if (num_permitted_opens == 0)
3129
	if (num_permitted_opens == 0)
3125
		all_opens_permitted = 1;
3130
		all_opens_permitted = 1;
3126
}
3131
}
3132
void
3133
channel_permit_all_remote_opens(void)
3134
{
3135
	if (num_permitted_remote_opens == 0)
3136
		all_remote_opens_permitted = 1;
3137
}
3138
3127
3139
3128
void
3140
void
3129
channel_add_permitted_opens(char *host, int port)
3141
channel_add_permitted_opens(char *host, int port)
Lines 3139-3144 channel_add_permitted_opens(char *host, int port) Link Here
3139
	all_opens_permitted = 0;
3151
	all_opens_permitted = 0;
3140
}
3152
}
3141
3153
3154
void
3155
channel_add_permitted_remote_opens(int port)
3156
{
3157
	debug("allow remote port forwarding %d", port);
3158
3159
	permitted_remote_opens = xrealloc(permitted_remote_opens,
3160
	    num_permitted_remote_opens + 1, sizeof(*permitted_remote_opens));
3161
	permitted_remote_opens[num_permitted_opens].listen_port = port;
3162
	num_permitted_remote_opens++;
3163
3164
	all_remote_opens_permitted = 0;
3165
}
3166
3142
/*
3167
/*
3143
 * Update the listen port for a dynamic remote forward, after
3168
 * Update the listen port for a dynamic remote forward, after
3144
 * the actual 'newport' has been allocated. If 'newport' < 0 is
3169
 * the actual 'newport' has been allocated. If 'newport' < 0 is
Lines 3181-3186 channel_add_adm_permitted_opens(char *host, int port) Link Here
3181
	return ++num_adm_permitted_opens;
3206
	return ++num_adm_permitted_opens;
3182
}
3207
}
3183
3208
3209
int
3210
channel_add_adm_permitted_remote_opens(int port)
3211
{
3212
	debug("config allows remote port forwarding,  port %d", port);
3213
3214
	permitted_adm_remote_opens = xrealloc(permitted_adm_remote_opens,
3215
	    num_adm_permitted_remote_opens + 1, sizeof(*permitted_adm_remote_opens));
3216
	permitted_adm_remote_opens[num_adm_permitted_remote_opens].listen_port = port;
3217
	return ++num_adm_permitted_remote_opens;
3218
}
3219
3220
3184
void
3221
void
3185
channel_disable_adm_local_opens(void)
3222
channel_disable_adm_local_opens(void)
3186
{
3223
{
Lines 3191-3196 channel_disable_adm_local_opens(void) Link Here
3191
}
3228
}
3192
3229
3193
void
3230
void
3231
channel_disable_adm_remote_opens(void)
3232
{
3233
	channel_clear_adm_permitted_remote_opens();
3234
	permitted_adm_remote_opens = xmalloc(sizeof(*permitted_adm_remote_opens));
3235
	permitted_adm_remote_opens[num_adm_permitted_remote_opens].host_to_connect = NULL;
3236
	num_adm_permitted_remote_opens = 1;
3237
}
3238
3239
void
3194
channel_clear_permitted_opens(void)
3240
channel_clear_permitted_opens(void)
3195
{
3241
{
3196
	int i;
3242
	int i;
Lines 3203-3208 channel_clear_permitted_opens(void) Link Here
3203
}
3249
}
3204
3250
3205
void
3251
void
3252
channel_clear_permitted_remote_opens(void)
3253
{
3254
3255
	free(permitted_remote_opens);
3256
	permitted_remote_opens = NULL;
3257
	num_permitted_remote_opens = 0;
3258
}
3259
3260
3261
void
3206
channel_clear_adm_permitted_opens(void)
3262
channel_clear_adm_permitted_opens(void)
3207
{
3263
{
3208
	int i;
3264
	int i;
Lines 3215-3220 channel_clear_adm_permitted_opens(void) Link Here
3215
}
3271
}
3216
3272
3217
void
3273
void
3274
channel_clear_adm_permitted_remote_opens(void)
3275
{
3276
	free(permitted_adm_remote_opens);
3277
	permitted_adm_remote_opens = NULL;
3278
	num_adm_permitted_remote_opens = 0;
3279
}
3280
3281
3282
void
3218
channel_print_adm_permitted_opens(void)
3283
channel_print_adm_permitted_opens(void)
3219
{
3284
{
3220
	int i;
3285
	int i;
Lines 3399-3404 channel_connect_to(const char *host, u_short port, char *ctype, char *rname) Link Here
3399
	return connect_to(host, port, ctype, rname);
3464
	return connect_to(host, port, ctype, rname);
3400
}
3465
}
3401
3466
3467
/* Check if remote port is permitted and connect. */
3468
int 
3469
channel_connect_remote_to(u_short port)
3470
{
3471
	int i, permit, permit_adm = 1;
3472
	int allowed_port = 0;
3473
3474
	permit = all_remote_opens_permitted;
3475
	if (!permit) {
3476
		for (i = 0; i < num_permitted_remote_opens; i++) {
3477
			allowed_port = permitted_remote_opens[i].listen_port;
3478
			debug("i=%d check remote permitted vs requested "
3479
					"%u vs %u", i, allowed_port, port);
3480
			if ( port_match(allowed_port, port)) {
3481
				debug2("i=%d found match remote permitted vs "
3482
						"requested %u==%u", i, allowed_port, port);
3483
				permit = 1;
3484
				break;
3485
			}
3486
		}	
3487
	}
3488
	if (num_adm_permitted_remote_opens > 0) {
3489
		permit_adm = 0;
3490
		for (i = 0; i < num_adm_permitted_remote_opens; i++)
3491
			if (port_match(allowed_port, port) ) {
3492
				/*  && strcmp(permitted_adm_remote_opens[i].host_to_connect, host) == 0) */
3493
				debug2("i=%d found match admin remote permitted vs "
3494
						"requested %u==%u", i, allowed_port, port);
3495
				permit_adm = 1;
3496
				
3497
			}
3498
	}
3499
3500
	if (!permit || !permit_adm) {
3501
		logit("Received request to forward remote port %d, "
3502
		      "but the request was denied. return %d", port, permit);
3503
		return 0;
3504
	}
3505
	return ( permit | permit_adm);
3506
}
3507
3508
3509
3402
void
3510
void
3403
channel_send_window_changes(void)
3511
channel_send_window_changes(void)
3404
{
3512
{
(-)a/channels.h (+7 lines)
Lines 256-269 int channel_find_open(void); Link Here
256
/* tcp forwarding */
256
/* tcp forwarding */
257
void	 channel_set_af(int af);
257
void	 channel_set_af(int af);
258
void     channel_permit_all_opens(void);
258
void     channel_permit_all_opens(void);
259
void     channel_permit_all_remote_opens(void);
259
void	 channel_add_permitted_opens(char *, int);
260
void	 channel_add_permitted_opens(char *, int);
261
void	 channel_add_permitted_remote_opens(int);
260
int	 channel_add_adm_permitted_opens(char *, int);
262
int	 channel_add_adm_permitted_opens(char *, int);
263
int	 channel_add_adm_permitted_remote_opens(int);
261
void	 channel_disable_adm_local_opens(void);
264
void	 channel_disable_adm_local_opens(void);
265
void	 channel_disable_adm_remote_opens(void);
262
void	 channel_update_permitted_opens(int, int);
266
void	 channel_update_permitted_opens(int, int);
263
void	 channel_clear_permitted_opens(void);
267
void	 channel_clear_permitted_opens(void);
264
void	 channel_clear_adm_permitted_opens(void);
268
void	 channel_clear_adm_permitted_opens(void);
269
void	 channel_clear_permitted_remote_opens(void);
270
void	 channel_clear_adm_permitted_remote_opens(void);
265
void 	 channel_print_adm_permitted_opens(void);
271
void 	 channel_print_adm_permitted_opens(void);
266
int      channel_input_port_forward_request(int, int);
272
int      channel_input_port_forward_request(int, int);
273
int     channel_connect_remote_to(u_short);
267
Channel	*channel_connect_to(const char *, u_short, char *, char *);
274
Channel	*channel_connect_to(const char *, u_short, char *, char *);
268
Channel	*channel_connect_stdio_fwd(const char*, u_short, int, int);
275
Channel	*channel_connect_stdio_fwd(const char*, u_short, int, int);
269
Channel	*channel_connect_by_listen_address(u_short, char *, char *);
276
Channel	*channel_connect_by_listen_address(u_short, char *, char *);
(-)a/servconf.c (-1 / +33 lines)
Lines 341-347 typedef enum { Link Here
341
	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
341
	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
342
	sClientAliveCountMax, sAuthorizedKeysFile,
342
	sClientAliveCountMax, sAuthorizedKeysFile,
343
	sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
343
	sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
344
	sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
344
	sMatch, sPermitOpen, sPermitRemoteOpen, sForceCommand, sChrootDirectory,
345
	sUsePrivilegeSeparation, sAllowAgentForwarding,
345
	sUsePrivilegeSeparation, sAllowAgentForwarding,
346
	sHostCertificate,
346
	sHostCertificate,
347
	sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
347
	sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
Lines 462-467 static struct { Link Here
462
	{ "permittty", sPermitTTY, SSHCFG_ALL },
462
	{ "permittty", sPermitTTY, SSHCFG_ALL },
463
	{ "match", sMatch, SSHCFG_ALL },
463
	{ "match", sMatch, SSHCFG_ALL },
464
	{ "permitopen", sPermitOpen, SSHCFG_ALL },
464
	{ "permitopen", sPermitOpen, SSHCFG_ALL },
465
	{ "permitremoteopen", sPermitRemoteOpen, SSHCFG_ALL },
465
	{ "forcecommand", sForceCommand, SSHCFG_ALL },
466
	{ "forcecommand", sForceCommand, SSHCFG_ALL },
466
	{ "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
467
	{ "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
467
	{ "hostcertificate", sHostCertificate, SSHCFG_GLOBAL },
468
	{ "hostcertificate", sHostCertificate, SSHCFG_GLOBAL },
Lines 1521-1526 process_server_config_line(ServerOptions *options, char *line, Link Here
1521
				    channel_add_adm_permitted_opens(p, port);
1522
				    channel_add_adm_permitted_opens(p, port);
1522
		}
1523
		}
1523
		break;
1524
		break;
1525
	case sPermitRemoteOpen:
1526
		arg = strdelim(&cp);
1527
		if (!arg || *arg == '\0')
1528
			fatal("%s line %d: missing PermitRemoteOpen "
1529
				" specification", filename, linenum);
1530
		n = options->num_permitted_remote_opens; /* modified later */
1531
		if (strcmp(arg, "any") == 0) {
1532
			if (*activep && n == -1) {
1533
				channel_clear_adm_permitted_remote_opens();
1534
				options->num_permitted_remote_opens = 0;
1535
			}
1536
			break;
1537
		}
1538
		if (strcmp(arg, "none") == 0) {
1539
			if (*activep && n == -1) {
1540
				options->num_permitted_remote_opens = 1;
1541
				channel_disable_adm_remote_opens();
1542
			}
1543
			break;
1544
		}
1545
		if (*activep && n == -1)
1546
			channel_clear_adm_permitted_remote_opens();
1547
		for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
1548
			if (arg == NULL || ((port = permitopen_port(arg)) < 0))
1549
				fatal("%s line %d: bad port number in "
1550
				      "PermitRemoteOpen", filename, linenum);
1551
			if (*activep && n == -1)
1552
				options->num_permitted_remote_opens =
1553
					channel_add_adm_permitted_remote_opens(port);
1554
		}
1555
		break;
1524
1556
1525
	case sForceCommand:
1557
	case sForceCommand:
1526
		if (cp == NULL)
1558
		if (cp == NULL)
(-)a/servconf.h (+1 lines)
Lines 168-173 typedef struct { Link Here
168
	int	permit_tun;
168
	int	permit_tun;
169
169
170
	int	num_permitted_opens;
170
	int	num_permitted_opens;
171
	int	num_permitted_remote_opens;
171
172
172
	char   *chroot_directory;
173
	char   *chroot_directory;
173
	char   *revoked_keys_file;
174
	char   *revoked_keys_file;
(-)a/serverloop.c (-4 / +11 lines)
Lines 1148-1157 server_input_global_request(int type, u_int32_t seq, void *ctxt) Link Here
1148
			success = 0;
1148
			success = 0;
1149
			packet_send_debug("Server has disabled port forwarding.");
1149
			packet_send_debug("Server has disabled port forwarding.");
1150
		} else {
1150
		} else {
1151
			/* Start listening on the port */
1151
			debug2("check permitted remote opens");
1152
			success = channel_setup_remote_fwd_listener(
1152
			if (!channel_connect_remote_to(listen_port)) {
1153
			    listen_address, listen_port,
1153
				success = 0;
1154
			    &allocated_listen_port, options.gateway_ports);
1154
				packet_send_debug("Server denied remote port forward request.");
1155
			}
1156
			else {
1157
				/* Start listening on the port */
1158
				success = channel_setup_remote_fwd_listener(
1159
						listen_address, listen_port,
1160
						&allocated_listen_port, options.gateway_ports);
1161
			}
1155
		}
1162
		}
1156
		free(listen_address);
1163
		free(listen_address);
1157
	} else if (strcmp(rtype, "cancel-tcpip-forward") == 0) {
1164
	} else if (strcmp(rtype, "cancel-tcpip-forward") == 0) {
(-)a/session.c (-2 / +6 lines)
Lines 274-283 do_authenticated(Authctxt *authctxt) Link Here
274
274
275
	/* setup the channel layer */
275
	/* setup the channel layer */
276
	if (no_port_forwarding_flag ||
276
	if (no_port_forwarding_flag ||
277
	    (options.allow_tcp_forwarding & FORWARD_LOCAL) == 0)
277
	    (options.allow_tcp_forwarding & FORWARD_LOCAL) == 0) {
278
		channel_disable_adm_local_opens();
278
		channel_disable_adm_local_opens();
279
	else
279
		channel_disable_adm_remote_opens();
280
	}
281
	else {
280
		channel_permit_all_opens();
282
		channel_permit_all_opens();
283
		channel_permit_all_remote_opens();
284
	}
281
285
282
	auth_debug_send();
286
	auth_debug_send();
283
287
(-)a/sshd.8 (+12 lines)
Lines 617-622 they must be literal domains or addresses. Link Here
617
A port specification of
617
A port specification of
618
.Cm *
618
.Cm *
619
matches any port.
619
matches any port.
620
.It Cm permitremoteopen="port"
621
Limit remote 
622
.Li ``ssh -R''
623
port forwarding such that it may only forward the specified port to the client.
624
Multiple
625
.Cm permitremoteopen
626
options may be applied separated by commas.
627
Specified port must be a single port. 
628
A port specification of
629
.Cm *
630
matches any port.
631
620
.It Cm principals="principals"
632
.It Cm principals="principals"
621
On a
633
On a
622
.Cm cert-authority
634
.Cm cert-authority
(-)a/sshd_config.5 (-1 / +17 lines)
Lines 839-844 Available keywords are Link Here
839
.Cm PasswordAuthentication ,
839
.Cm PasswordAuthentication ,
840
.Cm PermitEmptyPasswords ,
840
.Cm PermitEmptyPasswords ,
841
.Cm PermitOpen ,
841
.Cm PermitOpen ,
842
.Cm PermitRemoteOpen ,
842
.Cm PermitRootLogin ,
843
.Cm PermitRootLogin ,
843
.Cm PermitTTY ,
844
.Cm PermitTTY ,
844
.Cm PermitTunnel ,
845
.Cm PermitTunnel ,
Lines 922-927 An argument of Link Here
922
.Dq none
923
.Dq none
923
can be used to prohibit all forwarding requests.
924
can be used to prohibit all forwarding requests.
924
By default all port forwarding requests are permitted.
925
By default all port forwarding requests are permitted.
926
.It
927
.Cm PermitRemoteOpen
928
.Sm off
929
.Ar \& port
930
.Sm on
931
.El
932
.Pp
933
Multiple forwards may be specified by separating them with whitespace.
934
An argument of
935
.Dq any
936
can be used to remove all restrictions and permit any remoite forwarding 
937
requests.  An argument of
938
.Dq none
939
can be used to prohibit all forwarding requests.
940
By default all port forwarding requests are permitted.
941
925
.It Cm PermitRootLogin
942
.It Cm PermitRootLogin
926
Specifies whether root can log in using
943
Specifies whether root can log in using
927
.Xr ssh 1 .
944
.Xr ssh 1 .
928
- 

Return to bug 2038