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

Collapse All | Expand All

(-)a/channels.c (-127 / +256 lines)
Lines 82-87 Link Here
82
#include "key.h"
82
#include "key.h"
83
#include "authfd.h"
83
#include "authfd.h"
84
#include "pathnames.h"
84
#include "pathnames.h"
85
#include "match.h"
85
86
86
/* -- agent forwarding */
87
/* -- agent forwarding */
87
#define	NUM_SOCKS	10
88
#define	NUM_SOCKS	10
Lines 97-102 Link Here
97
/* Maximum number of fake X11 displays to try. */
98
/* Maximum number of fake X11 displays to try. */
98
#define MAX_DISPLAYS  1000
99
#define MAX_DISPLAYS  1000
99
100
101
/* Per-channel callback for pre/post select() actions */
102
typedef void chan_fn(struct ssh *, Channel *c,
103
    fd_set *readset, fd_set *writeset);
104
100
/*
105
/*
101
 * Data structure for storing which hosts are permitted for forward requests.
106
 * Data structure for storing which hosts are permitted for forward requests.
102
 * The local sides of any remote forwards are stored in this array to prevent
107
 * The local sides of any remote forwards are stored in this array to prevent
Lines 115-122 typedef struct { Link Here
115
	Channel *downstream;		/* Downstream mux*/
120
	Channel *downstream;		/* Downstream mux*/
116
} ForwardPermission;
121
} ForwardPermission;
117
122
118
typedef void chan_fn(struct ssh *, Channel *c,
123
/*
119
    fd_set *readset, fd_set *writeset);
124
 * Stores the forwarding permission state for a single direction (local or
125
 * remote).
126
 */
127
struct fwdperms {
128
	/*
129
	 * List of all local permitted host/port pairs to connect by the
130
	 * user.
131
	 */
132
	u_int num_permitted_opens;
133
	ForwardPermission *permitted_opens;
134
135
	/*
136
	 * List of all permitted host/port pairs to connect by the
137
	 * admin.
138
	 */
139
	u_int num_adm_permitted_opens;
140
	ForwardPermission *permitted_adm_opens;
141
142
	/*
143
	 * If this is true, all opens are permitted.  This is the case on
144
	 * the server on which we have to trust the client anyway, and the
145
	 * user could do anything after logging in anyway.
146
	 */
147
	int all_opens_permitted;
148
};
120
149
121
/* Master structure for channels state */
150
/* Master structure for channels state */
122
struct ssh_channels {
151
struct ssh_channels {
Lines 149-179 struct ssh_channels { Link Here
149
	chan_fn **channel_post;
178
	chan_fn **channel_post;
150
179
151
	/* -- tcp forwarding */
180
	/* -- tcp forwarding */
152
181
	struct fwdperms fpms_local;
153
	/* List of all permitted host/port pairs to connect by the user. */
182
	struct fwdperms fpms_remote;
154
	ForwardPermission *permitted_opens;
155
156
	/* List of all permitted host/port pairs to connect by the admin. */
157
	ForwardPermission *permitted_adm_opens;
158
159
	/*
160
	 * Number of permitted host/port pairs in the array permitted by
161
	 * the user.
162
	 */
163
	u_int num_permitted_opens;
164
165
	/*
166
	 * Number of permitted host/port pair in the array permitted by
167
	 * the admin.
168
	 */
169
	u_int num_adm_permitted_opens;
170
171
	/*
172
	 * If this is true, all opens are permitted.  This is the case on
173
	 * the server on which we have to trust the client anyway, and the
174
	 * user could do anything after logging in anyway.
175
	 */
176
	int all_opens_permitted;
177
183
178
	/* -- X11 forwarding */
184
	/* -- X11 forwarding */
179
185
Lines 456-497 fwd_perm_clear(ForwardPermission *fp) Link Here
456
	bzero(fp, sizeof(*fp));
462
	bzero(fp, sizeof(*fp));
457
}
463
}
458
464
459
enum { FWDPERM_USER, FWDPERM_ADMIN };
465
/* Returns an printable name for the specified forwarding permission list */
466
static const char *
467
fwd_ident(int who, int where)
468
{
469
	if (who == FORWARD_ADM) {
470
		if (where == FORWARD_LOCAL)
471
			return "admin local";
472
		else if (where == FORWARD_REMOTE)
473
			return "admin remote";
474
	} else if (who == FORWARD_USER) {
475
		if (where == FORWARD_LOCAL)
476
			return "user local";
477
		else if (where == FORWARD_REMOTE)
478
			return "user remote";
479
	}
480
	fatal("Unknown forward permission list %d/%d", who, where);
481
}
460
482
483
/* Returns the forwarding permission list for the specified direction */
484
struct fwdperms *
485
fwdperms_get(struct ssh *ssh, int where)
486
{
487
	struct ssh_channels *sc = ssh->chanctxt;
488
489
	switch (where) {
490
	case FORWARD_LOCAL:
491
		return &sc->fpms_local;
492
		break;
493
	case FORWARD_REMOTE:
494
		return &sc->fpms_remote;
495
		break;
496
	default:
497
		fatal("%s: invalid forwarding direction %d", __func__, where);
498
	}
499
}
500
501
/* Reutrns pointers to the specified forwarding list and its element count */
502
static void
503
fwdperms_get_array(struct ssh *ssh, int who, int where,
504
    ForwardPermission ***fppp, u_int **nfppp)
505
{
506
	struct fwdperms *fpms = fwdperms_get(ssh, where);
507
508
	switch (who) {
509
	case FORWARD_USER:
510
		*fppp = &fpms->permitted_opens;
511
		*nfppp = &fpms->num_permitted_opens;
512
		break;
513
	case FORWARD_ADM:
514
		*fppp = &fpms->permitted_adm_opens;
515
		*nfppp = &fpms->num_adm_permitted_opens;
516
		break;
517
	default:
518
		fatal("%s: invalid forwarding client %d", __func__, who);
519
	}
520
}
521
522
/* Adds an entry to the spcified forwarding list */
461
static int
523
static int
462
fwd_perm_list_add(struct ssh *ssh, int which,
524
fwdperms_add(struct ssh *ssh, int who, int where,
463
    const char *host_to_connect, int port_to_connect,
525
    const char *host_to_connect, int port_to_connect,
464
    const char *listen_host, const char *listen_path, int listen_port,
526
    const char *listen_host, const char *listen_path, int listen_port,
465
    Channel *downstream)
527
    Channel *downstream)
466
{
528
{
467
	ForwardPermission **fpl;
529
	ForwardPermission **fpp;
468
	u_int n, *nfpl;
530
	u_int n, *nfpp;
469
531
470
	switch (which) {
532
	fwdperms_get_array(ssh, who, where, &fpp, &nfpp);
471
	case FWDPERM_USER:
472
		fpl = &ssh->chanctxt->permitted_opens;
473
		nfpl = &ssh->chanctxt->num_permitted_opens;
474
		break;
475
	case FWDPERM_ADMIN:
476
		fpl = &ssh->chanctxt->permitted_adm_opens;
477
		nfpl = &ssh->chanctxt->num_adm_permitted_opens;
478
		break;
479
	default:
480
		fatal("%s: invalid list %d", __func__, which);
481
	}
482
533
483
	if (*nfpl >= INT_MAX)
534
	if (*nfpp >= INT_MAX)
484
		fatal("%s: overflow", __func__);
535
		fatal("%s: %s overflow", __func__, fwd_ident(who, where));
485
536
486
	*fpl = xrecallocarray(*fpl, *nfpl, *nfpl + 1, sizeof(**fpl));
537
	*fpp = xrecallocarray(*fpp, *nfpp, *nfpp + 1, sizeof(**fpp));
487
	n = (*nfpl)++;
538
	n = (*nfpp)++;
488
#define MAYBE_DUP(s) ((s == NULL) ? NULL : xstrdup(s))
539
#define MAYBE_DUP(s) ((s == NULL) ? NULL : xstrdup(s))
489
	(*fpl)[n].host_to_connect = MAYBE_DUP(host_to_connect);
540
	(*fpp)[n].host_to_connect = MAYBE_DUP(host_to_connect);
490
	(*fpl)[n].port_to_connect = port_to_connect;
541
	(*fpp)[n].port_to_connect = port_to_connect;
491
	(*fpl)[n].listen_host = MAYBE_DUP(listen_host);
542
	(*fpp)[n].listen_host = MAYBE_DUP(listen_host);
492
	(*fpl)[n].listen_path = MAYBE_DUP(listen_path);
543
	(*fpp)[n].listen_path = MAYBE_DUP(listen_path);
493
	(*fpl)[n].listen_port = listen_port;
544
	(*fpp)[n].listen_port = listen_port;
494
	(*fpl)[n].downstream = downstream;
545
	(*fpp)[n].downstream = downstream;
495
#undef MAYBE_DUP
546
#undef MAYBE_DUP
496
	return (int)n;
547
	return (int)n;
497
}
548
}
Lines 500-511 static void Link Here
500
mux_remove_remote_forwardings(struct ssh *ssh, Channel *c)
551
mux_remove_remote_forwardings(struct ssh *ssh, Channel *c)
501
{
552
{
502
	struct ssh_channels *sc = ssh->chanctxt;
553
	struct ssh_channels *sc = ssh->chanctxt;
554
	struct fwdperms *fpms = &sc->fpms_local;
503
	ForwardPermission *fp;
555
	ForwardPermission *fp;
504
	int r;
556
	int r;
505
	u_int i;
557
	u_int i;
506
558
507
	for (i = 0; i < sc->num_permitted_opens; i++) {
559
	for (i = 0; i < fpms->num_permitted_opens; i++) {
508
		fp = &sc->permitted_opens[i];
560
		fp = &fpms->permitted_opens[i];
509
		if (fp->downstream != c)
561
		if (fp->downstream != c)
510
			continue;
562
			continue;
511
563
Lines 2729-2735 channel_proxy_downstream(struct ssh *ssh, Channel *downstream) Link Here
2729
			goto out;
2781
			goto out;
2730
		}
2782
		}
2731
		/* Record that connection to this host/port is permitted. */
2783
		/* Record that connection to this host/port is permitted. */
2732
		fwd_perm_list_add(ssh, FWDPERM_USER, "<mux>", -1,
2784
		fwdperms_add(ssh, FORWARD_USER, FORWARD_LOCAL, "<mux>", -1,
2733
		    listen_host, NULL, (int)listen_port, downstream);
2785
		    listen_host, NULL, (int)listen_port, downstream);
2734
		listen_host = NULL;
2786
		listen_host = NULL;
2735
		break;
2787
		break;
Lines 3637-3647 channel_setup_local_fwd_listener(struct ssh *ssh, Link Here
3637
	}
3689
	}
3638
}
3690
}
3639
3691
3692
/* Matches a remote forwarding permission against a requested forwarding */
3693
static int
3694
remote_open_match(ForwardPermission *allowed_open, struct Forward *fwd)
3695
{
3696
	int ret;
3697
	char *lhost;
3698
3699
	/* XXX add ACLs for streamlocal */
3700
	if (fwd->listen_path != NULL)
3701
		return 1;
3702
3703
	if (fwd->listen_host == NULL || allowed_open->listen_host == NULL)
3704
		return 0;
3705
3706
	if (allowed_open->listen_port != FWD_PERMIT_ANY_PORT &&
3707
	    allowed_open->listen_port != fwd->listen_port)
3708
		return 0;
3709
3710
	/* Match hostnames case-insensitively */
3711
	lhost = xstrdup(fwd->listen_host);
3712
	lowercase(lhost);
3713
	ret = match_pattern(lhost, allowed_open->listen_host);
3714
	free(lhost);
3715
3716
	return ret;
3717
}
3718
3719
/* Checks whether a requested remote forwarding is permitted */
3720
static int
3721
check_rfwd_permission(struct ssh *ssh, struct Forward *fwd)
3722
{
3723
	struct ssh_channels *sc = ssh->chanctxt;
3724
	struct fwdperms *fpms = &sc->fpms_remote;
3725
	u_int i, permit, permit_adm = 1;
3726
	ForwardPermission *fp;
3727
3728
	/* XXX apply GatewayPorts override before checking? */
3729
3730
	permit = fpms->all_opens_permitted;
3731
	if (!permit) {
3732
		for (i = 0; i < fpms->num_permitted_opens; i++) {
3733
			fp = &fpms->permitted_opens[i];
3734
			if (remote_open_match(fp, fwd)) {
3735
				permit = 1;
3736
				break;
3737
			}
3738
		}
3739
	}
3740
3741
	if (fpms->num_adm_permitted_opens > 0) {
3742
		permit_adm = 0;
3743
		for (i = 0; i < fpms->num_adm_permitted_opens; i++) {
3744
			fp = &fpms->permitted_adm_opens[i];
3745
			if (remote_open_match(fp, fwd)) {
3746
				permit_adm = 1;
3747
				break;
3748
			}
3749
		}
3750
	}
3751
3752
	return permit && permit_adm;
3753
}
3754
3640
/* protocol v2 remote port fwd, used by sshd */
3755
/* protocol v2 remote port fwd, used by sshd */
3641
int
3756
int
3642
channel_setup_remote_fwd_listener(struct ssh *ssh, struct Forward *fwd,
3757
channel_setup_remote_fwd_listener(struct ssh *ssh, struct Forward *fwd,
3643
    int *allocated_listen_port, struct ForwardOptions *fwd_opts)
3758
    int *allocated_listen_port, struct ForwardOptions *fwd_opts)
3644
{
3759
{
3760
	if (!check_rfwd_permission(ssh, fwd)) {
3761
		packet_send_debug("port forwarding refused");
3762
		return 0;
3763
	}
3645
	if (fwd->listen_path != NULL) {
3764
	if (fwd->listen_path != NULL) {
3646
		return channel_setup_fwd_listener_streamlocal(ssh,
3765
		return channel_setup_fwd_listener_streamlocal(ssh,
3647
		    SSH_CHANNEL_RUNIX_LISTENER, fwd, fwd_opts);
3766
		    SSH_CHANNEL_RUNIX_LISTENER, fwd, fwd_opts);
Lines 3724-3730 channel_request_remote_forwarding(struct ssh *ssh, struct Forward *fwd) Link Here
3724
				listen_host = xstrdup(fwd->listen_host);
3843
				listen_host = xstrdup(fwd->listen_host);
3725
			listen_port = fwd->listen_port;
3844
			listen_port = fwd->listen_port;
3726
		}
3845
		}
3727
		idx = fwd_perm_list_add(ssh, FWDPERM_USER,
3846
		idx = fwdperms_add(ssh, FORWARD_USER, FORWARD_LOCAL,
3728
		    host_to_connect, port_to_connect,
3847
		    host_to_connect, port_to_connect,
3729
		    listen_host, listen_path, listen_port, NULL);
3848
		    listen_host, listen_path, listen_port, NULL);
3730
	}
3849
	}
Lines 3797-3808 channel_request_rforward_cancel_tcpip(struct ssh *ssh, Link Here
3797
    const char *host, u_short port)
3916
    const char *host, u_short port)
3798
{
3917
{
3799
	struct ssh_channels *sc = ssh->chanctxt;
3918
	struct ssh_channels *sc = ssh->chanctxt;
3919
	struct fwdperms *fpms = &sc->fpms_local;
3800
	int r;
3920
	int r;
3801
	u_int i;
3921
	u_int i;
3802
	ForwardPermission *fp;
3922
	ForwardPermission *fp;
3803
3923
3804
	for (i = 0; i < sc->num_permitted_opens; i++) {
3924
	for (i = 0; i < fpms->num_permitted_opens; i++) {
3805
		fp = &sc->permitted_opens[i];
3925
		fp = &fpms->permitted_opens[i];
3806
		if (open_listen_match_tcpip(fp, host, port, 0))
3926
		if (open_listen_match_tcpip(fp, host, port, 0))
3807
			break;
3927
			break;
3808
		fp = NULL;
3928
		fp = NULL;
Lines 3832-3843 static int Link Here
3832
channel_request_rforward_cancel_streamlocal(struct ssh *ssh, const char *path)
3952
channel_request_rforward_cancel_streamlocal(struct ssh *ssh, const char *path)
3833
{
3953
{
3834
	struct ssh_channels *sc = ssh->chanctxt;
3954
	struct ssh_channels *sc = ssh->chanctxt;
3955
	struct fwdperms *fpms = &sc->fpms_local;
3835
	int r;
3956
	int r;
3836
	u_int i;
3957
	u_int i;
3837
	ForwardPermission *fp;
3958
	ForwardPermission *fp;
3838
3959
3839
	for (i = 0; i < sc->num_permitted_opens; i++) {
3960
	for (i = 0; i < fpms->num_permitted_opens; i++) {
3840
		fp = &sc->permitted_opens[i];
3961
		fp = &fpms->permitted_opens[i];
3841
		if (open_listen_match_streamlocal(fp, path))
3962
		if (open_listen_match_streamlocal(fp, path))
3842
			break;
3963
			break;
3843
		fp = NULL;
3964
		fp = NULL;
Lines 3881-3900 channel_request_rforward_cancel(struct ssh *ssh, struct Forward *fwd) Link Here
3881
 * anyway, and the server has no way to know but to trust the client anyway.
4002
 * anyway, and the server has no way to know but to trust the client anyway.
3882
 */
4003
 */
3883
void
4004
void
3884
channel_permit_all_opens(struct ssh *ssh)
4005
channel_permit_all_opens(struct ssh *ssh, int where)
3885
{
4006
{
3886
	if (ssh->chanctxt->num_permitted_opens == 0)
4007
	struct fwdperms *fpms = fwdperms_get(ssh, where);
3887
		ssh->chanctxt->all_opens_permitted = 1;
4008
4009
	if (fpms->num_permitted_opens == 0)
4010
		fpms->all_opens_permitted = 1;
4011
}
4012
4013
/*
4014
 * Permit the specified host/port for forwarding.
4015
 */
4016
void
4017
channel_add_permitted_open(struct ssh *ssh, int who, int where,
4018
    char *host, int port)
4019
{
4020
	int local = where == FORWARD_LOCAL;
4021
	struct fwdperms *fpms = fwdperms_get(ssh, where);
4022
4023
	debug("allow %s forwarding to host %s port %d",
4024
	    fwd_ident(who, where), host, port);
4025
	/*
4026
	 * Remote forwards set listen_host/port, local forwards set
4027
	 * host/port_to_connect.
4028
	 */
4029
	fwdperms_add(ssh, who, where,
4030
	    local ? host : 0, local ? port : 0,
4031
	    local ? NULL : host, NULL, local ? 0 : port, NULL);
4032
	fpms->all_opens_permitted = 0;
4033
}
4034
4035
/*
4036
 * Administratively disable forwarding.
4037
 */
4038
void
4039
channel_disable_adm_opens(struct ssh *ssh, int where)
4040
{
4041
	channel_clear_permitted_opens(ssh, FORWARD_ADM, where);
4042
	fwdperms_add(ssh, FORWARD_ADM, where,
4043
	    NULL, 0, NULL, NULL, 0, NULL);
3888
}
4044
}
3889
4045
4046
/*
4047
 * Clear a list of permitted opens.
4048
 */
3890
void
4049
void
3891
channel_add_permitted_opens(struct ssh *ssh, char *host, int port)
4050
channel_clear_permitted_opens(struct ssh *ssh, int who, int where)
3892
{
4051
{
3893
	struct ssh_channels *sc = ssh->chanctxt;
4052
	ForwardPermission **fpp;
4053
	u_int *nfpp;
3894
4054
3895
	debug("allow port forwarding to host %s port %d", host, port);
4055
	fwdperms_get_array(ssh, who, where, &fpp, &nfpp);
3896
	fwd_perm_list_add(ssh, FWDPERM_USER, host, port, NULL, NULL, 0, NULL);
4056
	*fpp = xrecallocarray(*fpp, *nfpp, 0, sizeof(**fpp));
3897
	sc->all_opens_permitted = 0;
4057
	*nfpp = 0;
3898
}
4058
}
3899
4059
3900
/*
4060
/*
Lines 3905-3965 channel_add_permitted_opens(struct ssh *ssh, char *host, int port) Link Here
3905
void
4065
void
3906
channel_update_permitted_opens(struct ssh *ssh, int idx, int newport)
4066
channel_update_permitted_opens(struct ssh *ssh, int idx, int newport)
3907
{
4067
{
3908
	struct ssh_channels *sc = ssh->chanctxt;
4068
	struct fwdperms *fpms = &ssh->chanctxt->fpms_local;
3909
4069
3910
	if (idx < 0 || (u_int)idx >= sc->num_permitted_opens) {
4070
	if (idx < 0 || (u_int)idx >= fpms->num_permitted_opens) {
3911
		debug("%s: index out of range: %d num_permitted_opens %d",
4071
		debug("%s: index out of range: %d num_permitted_opens %d",
3912
		    __func__, idx, sc->num_permitted_opens);
4072
		    __func__, idx, fpms->num_permitted_opens);
3913
		return;
4073
		return;
3914
	}
4074
	}
3915
	debug("%s allowed port %d for forwarding to host %s port %d",
4075
	debug("%s allowed port %d for forwarding to host %s port %d",
3916
	    newport > 0 ? "Updating" : "Removing",
4076
	    newport > 0 ? "Updating" : "Removing",
3917
	    newport,
4077
	    newport,
3918
	    sc->permitted_opens[idx].host_to_connect,
4078
	    fpms->permitted_opens[idx].host_to_connect,
3919
	    sc->permitted_opens[idx].port_to_connect);
4079
	    fpms->permitted_opens[idx].port_to_connect);
3920
	if (newport <= 0)
4080
	if (newport <= 0)
3921
		fwd_perm_clear(&sc->permitted_opens[idx]);
4081
		fwd_perm_clear(&fpms->permitted_opens[idx]);
3922
	else {
4082
	else {
3923
		sc->permitted_opens[idx].listen_port =
4083
		fpms->permitted_opens[idx].listen_port =
3924
		    (datafellows & SSH_BUG_DYNAMIC_RPORT) ? 0 : newport;
4084
		    (datafellows & SSH_BUG_DYNAMIC_RPORT) ? 0 : newport;
3925
	}
4085
	}
3926
}
4086
}
3927
4087
3928
int
3929
channel_add_adm_permitted_opens(struct ssh *ssh, char *host, int port)
3930
{
3931
	debug("config allows port forwarding to host %s port %d", host, port);
3932
	return fwd_perm_list_add(ssh, FWDPERM_ADMIN, host, port,
3933
	    NULL, NULL, 0, NULL);
3934
}
3935
3936
void
3937
channel_disable_adm_local_opens(struct ssh *ssh)
3938
{
3939
	channel_clear_adm_permitted_opens(ssh);
3940
	fwd_perm_list_add(ssh, FWDPERM_ADMIN, NULL, 0, NULL, NULL, 0, NULL);
3941
}
3942
3943
void
3944
channel_clear_permitted_opens(struct ssh *ssh)
3945
{
3946
	struct ssh_channels *sc = ssh->chanctxt;
3947
3948
	sc->permitted_opens = xrecallocarray(sc->permitted_opens,
3949
	    sc->num_permitted_opens, 0, sizeof(*sc->permitted_opens));
3950
	sc->num_permitted_opens = 0;
3951
}
3952
3953
void
3954
channel_clear_adm_permitted_opens(struct ssh *ssh)
3955
{
3956
	struct ssh_channels *sc = ssh->chanctxt;
3957
3958
	sc->permitted_adm_opens = xrecallocarray(sc->permitted_adm_opens,
3959
	    sc->num_adm_permitted_opens, 0, sizeof(*sc->permitted_adm_opens));
3960
	sc->num_adm_permitted_opens = 0;
3961
}
3962
3963
/* returns port number, FWD_PERMIT_ANY_PORT or -1 on error */
4088
/* returns port number, FWD_PERMIT_ANY_PORT or -1 on error */
3964
int
4089
int
3965
permitopen_port(const char *p)
4090
permitopen_port(const char *p)
Lines 4148-4158 channel_connect_by_listen_address(struct ssh *ssh, const char *listen_host, Link Here
4148
    u_short listen_port, char *ctype, char *rname)
4273
    u_short listen_port, char *ctype, char *rname)
4149
{
4274
{
4150
	struct ssh_channels *sc = ssh->chanctxt;
4275
	struct ssh_channels *sc = ssh->chanctxt;
4276
	struct fwdperms *fpms = &sc->fpms_local;
4151
	u_int i;
4277
	u_int i;
4152
	ForwardPermission *fp;
4278
	ForwardPermission *fp;
4153
4279
4154
	for (i = 0; i < sc->num_permitted_opens; i++) {
4280
	for (i = 0; i < fpms->num_permitted_opens; i++) {
4155
		fp = &sc->permitted_opens[i];
4281
		fp = &fpms->permitted_opens[i];
4156
		if (open_listen_match_tcpip(fp, listen_host, listen_port, 1)) {
4282
		if (open_listen_match_tcpip(fp, listen_host, listen_port, 1)) {
4157
			if (fp->downstream)
4283
			if (fp->downstream)
4158
				return fp->downstream;
4284
				return fp->downstream;
Lines 4174-4184 channel_connect_by_listen_path(struct ssh *ssh, const char *path, Link Here
4174
    char *ctype, char *rname)
4300
    char *ctype, char *rname)
4175
{
4301
{
4176
	struct ssh_channels *sc = ssh->chanctxt;
4302
	struct ssh_channels *sc = ssh->chanctxt;
4303
	struct fwdperms *fpms = &sc->fpms_local;
4177
	u_int i;
4304
	u_int i;
4178
	ForwardPermission *fp;
4305
	ForwardPermission *fp;
4179
4306
4180
	for (i = 0; i < sc->num_permitted_opens; i++) {
4307
	for (i = 0; i < fpms->num_permitted_opens; i++) {
4181
		fp = &sc->permitted_opens[i];
4308
		fp = &fpms->permitted_opens[i];
4182
		if (open_listen_match_streamlocal(fp, path)) {
4309
		if (open_listen_match_streamlocal(fp, path)) {
4183
			return connect_to(ssh,
4310
			return connect_to(ssh,
4184
			    fp->host_to_connect, fp->port_to_connect,
4311
			    fp->host_to_connect, fp->port_to_connect,
Lines 4196-4211 channel_connect_to_port(struct ssh *ssh, const char *host, u_short port, Link Here
4196
    char *ctype, char *rname, int *reason, const char **errmsg)
4323
    char *ctype, char *rname, int *reason, const char **errmsg)
4197
{
4324
{
4198
	struct ssh_channels *sc = ssh->chanctxt;
4325
	struct ssh_channels *sc = ssh->chanctxt;
4326
	struct fwdperms *fpms = &sc->fpms_local;
4199
	struct channel_connect cctx;
4327
	struct channel_connect cctx;
4200
	Channel *c;
4328
	Channel *c;
4201
	u_int i, permit, permit_adm = 1;
4329
	u_int i, permit, permit_adm = 1;
4202
	int sock;
4330
	int sock;
4203
	ForwardPermission *fp;
4331
	ForwardPermission *fp;
4204
4332
4205
	permit = sc->all_opens_permitted;
4333
	permit = fpms->all_opens_permitted;
4206
	if (!permit) {
4334
	if (!permit) {
4207
		for (i = 0; i < sc->num_permitted_opens; i++) {
4335
		for (i = 0; i < fpms->num_permitted_opens; i++) {
4208
			fp = &sc->permitted_opens[i];
4336
			fp = &fpms->permitted_opens[i];
4209
			if (open_match(fp, host, port)) {
4337
			if (open_match(fp, host, port)) {
4210
				permit = 1;
4338
				permit = 1;
4211
				break;
4339
				break;
Lines 4213-4222 channel_connect_to_port(struct ssh *ssh, const char *host, u_short port, Link Here
4213
		}
4341
		}
4214
	}
4342
	}
4215
4343
4216
	if (sc->num_adm_permitted_opens > 0) {
4344
	if (fpms->num_adm_permitted_opens > 0) {
4217
		permit_adm = 0;
4345
		permit_adm = 0;
4218
		for (i = 0; i < sc->num_adm_permitted_opens; i++) {
4346
		for (i = 0; i < fpms->num_adm_permitted_opens; i++) {
4219
			fp = &sc->permitted_adm_opens[i];
4347
			fp = &fpms->permitted_adm_opens[i];
4220
			if (open_match(fp, host, port)) {
4348
			if (open_match(fp, host, port)) {
4221
				permit_adm = 1;
4349
				permit_adm = 1;
4222
				break;
4350
				break;
Lines 4255-4267 channel_connect_to_path(struct ssh *ssh, const char *path, Link Here
4255
    char *ctype, char *rname)
4383
    char *ctype, char *rname)
4256
{
4384
{
4257
	struct ssh_channels *sc = ssh->chanctxt;
4385
	struct ssh_channels *sc = ssh->chanctxt;
4386
	struct fwdperms *fpms = &sc->fpms_local;
4258
	u_int i, permit, permit_adm = 1;
4387
	u_int i, permit, permit_adm = 1;
4259
	ForwardPermission *fp;
4388
	ForwardPermission *fp;
4260
4389
4261
	permit = sc->all_opens_permitted;
4390
	permit = fpms->all_opens_permitted;
4262
	if (!permit) {
4391
	if (!permit) {
4263
		for (i = 0; i < sc->num_permitted_opens; i++) {
4392
		for (i = 0; i < fpms->num_permitted_opens; i++) {
4264
			fp = &sc->permitted_opens[i];
4393
			fp = &fpms->permitted_opens[i];
4265
			if (open_match(fp, path, PORT_STREAMLOCAL)) {
4394
			if (open_match(fp, path, PORT_STREAMLOCAL)) {
4266
				permit = 1;
4395
				permit = 1;
4267
				break;
4396
				break;
Lines 4269-4278 channel_connect_to_path(struct ssh *ssh, const char *path, Link Here
4269
		}
4398
		}
4270
	}
4399
	}
4271
4400
4272
	if (sc->num_adm_permitted_opens > 0) {
4401
	if (fpms->num_adm_permitted_opens > 0) {
4273
		permit_adm = 0;
4402
		permit_adm = 0;
4274
		for (i = 0; i < sc->num_adm_permitted_opens; i++) {
4403
		for (i = 0; i < fpms->num_adm_permitted_opens; i++) {
4275
			fp = &sc->permitted_adm_opens[i];
4404
			fp = &fpms->permitted_adm_opens[i];
4276
			if (open_match(fp, path, PORT_STREAMLOCAL)) {
4405
			if (open_match(fp, path, PORT_STREAMLOCAL)) {
4277
				permit_adm = 1;
4406
				permit_adm = 1;
4278
				break;
4407
				break;
(-)a/channels.h (-9 / +13 lines)
Lines 63-68 Link Here
63
63
64
#define CHANNEL_CANCEL_PORT_STATIC	-1
64
#define CHANNEL_CANCEL_PORT_STATIC	-1
65
65
66
/* TCP forwarding */
67
#define FORWARD_DENY		0
68
#define FORWARD_REMOTE		(1)
69
#define FORWARD_LOCAL		(1<<1)
70
#define FORWARD_ALLOW		(FORWARD_REMOTE|FORWARD_LOCAL)
71
72
#define FORWARD_ADM		0x100
73
#define FORWARD_USER		0x101
74
66
struct ssh;
75
struct ssh;
67
struct Channel;
76
struct Channel;
68
typedef struct Channel Channel;
77
typedef struct Channel Channel;
Lines 283-298 int channel_find_open(struct ssh *); Link Here
283
struct Forward;
292
struct Forward;
284
struct ForwardOptions;
293
struct ForwardOptions;
285
void	 channel_set_af(struct ssh *, int af);
294
void	 channel_set_af(struct ssh *, int af);
286
void     channel_permit_all_opens(struct ssh *);
295
void     channel_permit_all_opens(struct ssh *, int);
287
void	 channel_add_permitted_opens(struct ssh *, char *, int);
296
void	 channel_add_permitted_open(struct ssh *, int, int, char *, int);
288
int	 channel_add_adm_permitted_opens(struct ssh *, char *, int);
297
void	 channel_clear_permitted_opens(struct ssh *, int, int);
289
void	 channel_copy_adm_permitted_opens(struct ssh *,
298
void	 channel_disable_adm_opens(struct ssh *, int);
290
	    const struct fwd_perm_list *);
291
void	 channel_disable_adm_local_opens(struct ssh *);
292
void	 channel_update_permitted_opens(struct ssh *, int, int);
299
void	 channel_update_permitted_opens(struct ssh *, int, int);
293
void	 channel_clear_permitted_opens(struct ssh *);
294
void	 channel_clear_adm_permitted_opens(struct ssh *);
295
void 	 channel_print_adm_permitted_opens(struct ssh *);
296
Channel	*channel_connect_to_port(struct ssh *, const char *, u_short,
300
Channel	*channel_connect_to_port(struct ssh *, const char *, u_short,
297
	    char *, char *, int *, const char **);
301
	    char *, char *, int *, const char **);
298
Channel *channel_connect_to_path(struct ssh *, const char *, char *, char *);
302
Channel *channel_connect_to_path(struct ssh *, const char *, char *, char *);
(-)a/regress/forward-control.sh (-9 / +54 lines)
Lines 67-73 check_rfwd() { Link Here
67
	_message=$2
67
	_message=$2
68
	rm -f $READY
68
	rm -f $READY
69
	${SSH} -F $OBJ/ssh_proxy \
69
	${SSH} -F $OBJ/ssh_proxy \
70
	    -R$RFWD_PORT:127.0.0.1:$PORT \
70
	    -R127.0.0.1:$RFWD_PORT:127.0.0.1:$PORT \
71
	    -o ExitOnForwardFailure=yes \
71
	    -o ExitOnForwardFailure=yes \
72
	    -n host exec sh -c \'"sleep 60 & echo \$! > $READY ; wait "\' \
72
	    -n host exec sh -c \'"sleep 60 & echo \$! > $READY ; wait "\' \
73
	    >/dev/null 2>&1 &
73
	    >/dev/null 2>&1 &
Lines 100-107 cp ${OBJ}/authorized_keys_${USER} ${OBJ}/authorized_keys_${USER}.bak Link Here
100
check_lfwd Y "default configuration"
100
check_lfwd Y "default configuration"
101
check_rfwd Y "default configuration"
101
check_rfwd Y "default configuration"
102
102
103
# Usage: all_tests yes|local|remote|no Y|N Y|N Y|N Y|N Y|N Y|N
103
# Usage: lperm_tests yes|local|remote|no Y|N Y|N Y|N Y|N Y|N Y|N
104
all_tests() {
104
lperm_tests() {
105
	_tcpfwd=$1
105
	_tcpfwd=$1
106
	_plain_lfwd=$2
106
	_plain_lfwd=$2
107
	_plain_rfwd=$3
107
	_plain_rfwd=$3
Lines 113-124 all_tests() { Link Here
113
	_goodfwd=127.0.0.1:${PORT}
113
	_goodfwd=127.0.0.1:${PORT}
114
	cp ${OBJ}/authorized_keys_${USER}.bak  ${OBJ}/authorized_keys_${USER}
114
	cp ${OBJ}/authorized_keys_${USER}.bak  ${OBJ}/authorized_keys_${USER}
115
	_prefix="AllowTcpForwarding=$_tcpfwd"
115
	_prefix="AllowTcpForwarding=$_tcpfwd"
116
116
	# No PermitOpen
117
	# No PermitOpen
117
	( cat ${OBJ}/sshd_proxy.bak ;
118
	( cat ${OBJ}/sshd_proxy.bak ;
118
	  echo "AllowTcpForwarding $_tcpfwd" ) \
119
	  echo "AllowTcpForwarding $_tcpfwd" ) \
119
	    > ${OBJ}/sshd_proxy
120
	    > ${OBJ}/sshd_proxy
120
	check_lfwd $_plain_lfwd "$_prefix"
121
	check_lfwd $_plain_lfwd "$_prefix"
121
	check_rfwd $_plain_rfwd "$_prefix"
122
	check_rfwd $_plain_rfwd "$_prefix"
123
122
	# PermitOpen via sshd_config that doesn't match
124
	# PermitOpen via sshd_config that doesn't match
123
	( cat ${OBJ}/sshd_proxy.bak ;
125
	( cat ${OBJ}/sshd_proxy.bak ;
124
	  echo "AllowTcpForwarding $_tcpfwd" ;
126
	  echo "AllowTcpForwarding $_tcpfwd" ;
Lines 131-136 all_tests() { Link Here
131
	  echo "AllowTcpForwarding $_tcpfwd" ;
133
	  echo "AllowTcpForwarding $_tcpfwd" ;
132
	  echo "PermitOpen $_badfwd $_goodfwd" ) \
134
	  echo "PermitOpen $_badfwd $_goodfwd" ) \
133
	    > ${OBJ}/sshd_proxy
135
	    > ${OBJ}/sshd_proxy
136
	check_lfwd $_plain_lfwd "$_prefix, PermitOpen"
137
	check_rfwd $_plain_rfwd "$_prefix, PermitOpen"
138
139
	# permitopen keys option.
134
	# NB. permitopen via authorized_keys should have same
140
	# NB. permitopen via authorized_keys should have same
135
	# success/fail as via sshd_config
141
	# success/fail as via sshd_config
136
	# permitopen via authorized_keys that doesn't match
142
	# permitopen via authorized_keys that doesn't match
Lines 151-156 all_tests() { Link Here
151
	    > ${OBJ}/sshd_proxy
157
	    > ${OBJ}/sshd_proxy
152
	check_lfwd $_permit_lfwd "$_prefix, permitopen"
158
	check_lfwd $_permit_lfwd "$_prefix, permitopen"
153
	check_rfwd $_permit_rfwd "$_prefix, permitopen"
159
	check_rfwd $_permit_rfwd "$_prefix, permitopen"
160
154
	# Check port-forwarding flags in authorized_keys.
161
	# Check port-forwarding flags in authorized_keys.
155
	# These two should refuse all.
162
	# These two should refuse all.
156
	sed "s/^/no-port-forwarding /" \
163
	sed "s/^/no-port-forwarding /" \
Lines 180-188 all_tests() { Link Here
180
	check_rfwd $_plain_rfwd "$_prefix, restrict,port-forwarding"
187
	check_rfwd $_plain_rfwd "$_prefix, restrict,port-forwarding"
181
}
188
}
182
189
183
#                      no-permitopen mismatch-permitopen match-permitopen
190
#          permit-open      none          mismatch         match
184
#   AllowTcpForwarding  local remote        local remote     local remote
191
#   AllowTcpForwarding  local remote    local remote    local remote
185
all_tests          yes      Y      Y            N      Y         Y      Y
192
lperm_tests     yes     Y     Y         N     Y         Y     Y
186
all_tests        local      Y      N            N      N         Y      N
193
lperm_tests   local     Y     N         N     N         Y     N
187
all_tests       remote      N      Y            N      Y         N      Y
194
lperm_tests  remote     N     Y         N     Y         N     Y
188
all_tests           no      N      N            N      N         N      N
195
lperm_tests      no     N     N         N     N         N     N
196
197
# Usage: rperm_tests yes|local|remote|no Y|N Y|N Y|N Y|N Y|N Y|N
198
rperm_tests() {
199
	_tcpfwd=$1
200
	_plain_lfwd=$2
201
	_plain_rfwd=$3
202
	_nopermit_lfwd=$4
203
	_nopermit_rfwd=$5
204
	_permit_lfwd=$6
205
	_permit_rfwd=$7
206
	_badfwd=127.0.0.1:22
207
	_goodfwd=127.0.0.1:${RFWD_PORT}
208
	cp ${OBJ}/authorized_keys_${USER}.bak  ${OBJ}/authorized_keys_${USER}
209
	_prefix="AllowTcpForwarding=$_tcpfwd"
210
211
	# PermitRemoteOpen via sshd_config that doesn't match
212
	( cat ${OBJ}/sshd_proxy.bak ;
213
	  echo "AllowTcpForwarding $_tcpfwd" ;
214
	  echo "PermitRemoteOpen $_badfwd" ) \
215
	    > ${OBJ}/sshd_proxy
216
	check_lfwd $_nopermit_lfwd "$_prefix, !PermitRemoteOpen"
217
	check_rfwd $_nopermit_rfwd "$_prefix, !PermitRemoteOpen"
218
	# PermitRemoteOpen via sshd_config that does match
219
	( cat ${OBJ}/sshd_proxy.bak ;
220
	  echo "AllowTcpForwarding $_tcpfwd" ;
221
	  echo "PermitRemoteOpen $_badfwd $_goodfwd" ) \
222
	    > ${OBJ}/sshd_proxy
223
	check_lfwd $_plain_lfwd "$_prefix, PermitRemoteOpen"
224
	check_rfwd $_plain_rfwd "$_prefix, PermitRemoteOpen"
225
}
226
227
#   permit-remote-open      none          mismatch         match
228
#   AllowTcpForwarding  local remote    local remote    local remote
229
rperm_tests     yes     Y     Y         Y     N         Y     Y
230
rperm_tests   local     Y     N         Y     N         Y     N
231
rperm_tests  remote     N     Y         N     N         N     Y
232
rperm_tests      no     N     N         N     N         N     N
233
(-)a/regress/test-exec.sh (-1 / +4 lines)
Lines 375-381 fail () Link Here
375
	save_debug_log "FAIL: $@"
375
	save_debug_log "FAIL: $@"
376
	RESULT=1
376
	RESULT=1
377
	echo "$@"
377
	echo "$@"
378
378
	if test "x$TEST_SSH_FATAL_FAILURES" != "x" ; then
379
		cleanup
380
		exit $RESULT
381
	fi
379
}
382
}
380
383
381
fatal ()
384
fatal ()
(-)a/servconf.c (-47 / +89 lines)
Lines 160-165 initialize_server_options(ServerOptions *options) Link Here
160
	options->num_accept_env = 0;
160
	options->num_accept_env = 0;
161
	options->permit_tun = -1;
161
	options->permit_tun = -1;
162
	options->permitted_opens = NULL;
162
	options->permitted_opens = NULL;
163
	options->permitted_remote_opens = NULL;
163
	options->adm_forced_command = NULL;
164
	options->adm_forced_command = NULL;
164
	options->chroot_directory = NULL;
165
	options->chroot_directory = NULL;
165
	options->authorized_keys_command = NULL;
166
	options->authorized_keys_command = NULL;
Lines 462-468 typedef enum { Link Here
462
	sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
463
	sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
463
	sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
464
	sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
464
	sAcceptEnv, sPermitTunnel,
465
	sAcceptEnv, sPermitTunnel,
465
	sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
466
	sMatch, sPermitOpen, sPermitRemoteOpen, sForceCommand, sChrootDirectory,
466
	sUsePrivilegeSeparation, sAllowAgentForwarding,
467
	sUsePrivilegeSeparation, sAllowAgentForwarding,
467
	sHostCertificate,
468
	sHostCertificate,
468
	sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
469
	sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
Lines 597-602 static struct { Link Here
597
	{ "permituserrc", sPermitUserRC, SSHCFG_ALL },
598
	{ "permituserrc", sPermitUserRC, SSHCFG_ALL },
598
	{ "match", sMatch, SSHCFG_ALL },
599
	{ "match", sMatch, SSHCFG_ALL },
599
	{ "permitopen", sPermitOpen, SSHCFG_ALL },
600
	{ "permitopen", sPermitOpen, SSHCFG_ALL },
601
	{ "permitremoteopen", sPermitRemoteOpen, SSHCFG_ALL },
600
	{ "forcecommand", sForceCommand, SSHCFG_ALL },
602
	{ "forcecommand", sForceCommand, SSHCFG_ALL },
601
	{ "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
603
	{ "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
602
	{ "hostcertificate", sHostCertificate, SSHCFG_GLOBAL },
604
	{ "hostcertificate", sHostCertificate, SSHCFG_GLOBAL },
Lines 632-637 static struct { Link Here
632
	{ -1, NULL }
634
	{ -1, NULL }
633
};
635
};
634
636
637
/* Returns an opcode name from its number */
638
639
static const char *
640
lookup_opcode_name(ServerOpCodes code)
641
{
642
	u_int i;
643
644
	for (i = 0; keywords[i].name != NULL; i++)
645
		if (keywords[i].opcode == code)
646
			return(keywords[i].name);
647
	return "UNKNOWN";
648
}
649
650
635
/*
651
/*
636
 * Returns the number of the token pointed to by cp or sBadOption.
652
 * Returns the number of the token pointed to by cp or sBadOption.
637
 */
653
 */
Lines 814-856 process_queued_listen_addrs(ServerOptions *options) Link Here
814
}
830
}
815
831
816
/*
832
/*
817
 * Inform channels layer of permitopen options from configuration.
833
 * Inform channels layer of permitopen options for a single forwarding
834
 * direction (local/remote).
818
 */
835
 */
819
void
836
static void
820
process_permitopen(struct ssh *ssh, ServerOptions *options)
837
process_permitopen_list(struct ssh *ssh, ServerOpCodes opcode,
838
    char **opens, u_int num_opens)
821
{
839
{
822
	u_int i;
840
	u_int i;
823
	int port;
841
	int port;
824
	char *host, *arg, *oarg;
842
	char *host, *arg, *oarg;
843
	int where = opcode == sPermitOpen ? FORWARD_LOCAL : FORWARD_REMOTE;
844
	const char *what = lookup_opcode_name(opcode);
825
845
826
	channel_clear_adm_permitted_opens(ssh);
846
	channel_clear_permitted_opens(ssh, FORWARD_ADM, where);
827
	if (options->num_permitted_opens == 0)
847
	if (num_opens == 0)
828
		return; /* permit any */
848
		return; /* permit any */
829
849
830
	/* handle keywords: "any" / "none" */
850
	/* handle keywords: "any" / "none" */
831
	if (options->num_permitted_opens == 1 &&
851
	if (num_opens == 1 && strcmp(opens[0], "any") == 0)
832
	    strcmp(options->permitted_opens[0], "any") == 0)
833
		return;
852
		return;
834
	if (options->num_permitted_opens == 1 &&
853
	if (num_opens == 1 && strcmp(opens[0], "none") == 0) {
835
	    strcmp(options->permitted_opens[0], "none") == 0) {
854
		channel_disable_adm_opens(ssh, where);
836
		channel_disable_adm_local_opens(ssh);
837
		return;
855
		return;
838
	}
856
	}
839
	/* Otherwise treat it as a list of permitted host:port */
857
	/* Otherwise treat it as a list of permitted host:port */
840
	for (i = 0; i < options->num_permitted_opens; i++) {
858
	for (i = 0; i < num_opens; i++) {
841
		oarg = arg = xstrdup(options->permitted_opens[i]);
859
		oarg = arg = xstrdup(opens[i]);
842
		host = hpdelim(&arg);
860
		host = hpdelim(&arg);
843
		if (host == NULL)
861
		if (host == NULL)
844
			fatal("%s: missing host in PermitOpen", __func__);
862
			fatal("%s: missing host in %s", __func__, what);
845
		host = cleanhostname(host);
863
		host = cleanhostname(host);
846
		if (arg == NULL || ((port = permitopen_port(arg)) < 0))
864
		if (arg == NULL || ((port = permitopen_port(arg)) < 0))
847
			fatal("%s: bad port number in PermitOpen", __func__);
865
			fatal("%s: bad port number in %s", __func__, what);
848
		/* Send it to channels layer */
866
		/* Send it to channels layer */
849
		channel_add_adm_permitted_opens(ssh, host, port);
867
		channel_add_permitted_open(ssh, FORWARD_ADM,
868
		    where, host, port);
850
		free(oarg);
869
		free(oarg);
851
	}
870
	}
852
}
871
}
853
872
873
/*
874
 * Inform channels layer of permitopen options from configuration.
875
 */
876
void
877
process_permitopen(struct ssh *ssh, ServerOptions *options)
878
{
879
	process_permitopen_list(ssh, sPermitOpen,
880
	    options->permitted_opens, options->num_permitted_opens);
881
	process_permitopen_list(ssh, sPermitRemoteOpen,
882
	    options->permitted_remote_opens,
883
	    options->num_permitted_remote_opens);
884
}
885
854
struct connection_info *
886
struct connection_info *
855
get_connection_info(int populate, int use_dns)
887
get_connection_info(int populate, int use_dns)
856
{
888
{
Lines 1144-1155 process_server_config_line(ServerOptions *options, char *line, Link Here
1144
    const char *filename, int linenum, int *activep,
1176
    const char *filename, int linenum, int *activep,
1145
    struct connection_info *connectinfo)
1177
    struct connection_info *connectinfo)
1146
{
1178
{
1147
	char *cp, **charptr, *arg, *arg2, *p;
1179
	char *cp, ***chararrayptr, **charptr, *arg, *arg2, *p;
1148
	int cmdline = 0, *intptr, value, value2, n, port;
1180
	int cmdline = 0, *intptr, value, value2, n, port;
1149
	SyslogFacility *log_facility_ptr;
1181
	SyslogFacility *log_facility_ptr;
1150
	LogLevel *log_level_ptr;
1182
	LogLevel *log_level_ptr;
1151
	ServerOpCodes opcode;
1183
	ServerOpCodes opcode;
1152
	u_int i, flags = 0;
1184
	u_int i, *uintptr, uvalue, flags = 0;
1153
	size_t len;
1185
	size_t len;
1154
	long long val64;
1186
	long long val64;
1155
	const struct multistate *multistate_ptr;
1187
	const struct multistate *multistate_ptr;
Lines 1799-1834 process_server_config_line(ServerOptions *options, char *line, Link Here
1799
		*activep = value;
1831
		*activep = value;
1800
		break;
1832
		break;
1801
1833
1834
	case sPermitRemoteOpen:
1802
	case sPermitOpen:
1835
	case sPermitOpen:
1836
		if (opcode == sPermitRemoteOpen) {
1837
			uintptr = &options->num_permitted_remote_opens;
1838
			chararrayptr = &options->permitted_remote_opens;
1839
		} else {
1840
			uintptr = &options->num_permitted_opens;
1841
			chararrayptr = &options->permitted_opens;
1842
		}
1803
		arg = strdelim(&cp);
1843
		arg = strdelim(&cp);
1804
		if (!arg || *arg == '\0')
1844
		if (!arg || *arg == '\0')
1805
			fatal("%s line %d: missing PermitOpen specification",
1845
			fatal("%s line %d: missing %s specification",
1806
			    filename, linenum);
1846
			    filename, linenum, lookup_opcode_name(opcode));
1807
		value = options->num_permitted_opens;	/* modified later */
1847
		uvalue = *uintptr;	/* modified later */
1808
		if (strcmp(arg, "any") == 0 || strcmp(arg, "none") == 0) {
1848
		if (strcmp(arg, "any") == 0 || strcmp(arg, "none") == 0) {
1809
			if (*activep && value == 0) {
1849
			if (*activep && uvalue == 0) {
1810
				options->num_permitted_opens = 1;
1850
				*uintptr = 1;
1811
				options->permitted_opens = xcalloc(1,
1851
				*chararrayptr = xcalloc(1,
1812
				    sizeof(*options->permitted_opens));
1852
				    sizeof(**chararrayptr));
1813
				options->permitted_opens[0] = xstrdup(arg);
1853
				(*chararrayptr)[0] = xstrdup(arg);
1814
			}
1854
			}
1815
			break;
1855
			break;
1816
		}
1856
		}
1817
		for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
1857
		for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
1818
			arg2 = xstrdup(arg);
1858
			arg2 = xstrdup(arg);
1819
			p = hpdelim(&arg);
1859
			p = hpdelim(&arg);
1820
			if (p == NULL)
1860
			/* XXX support bare port number for PermitRemoteOpen */
1821
				fatal("%s line %d: missing host in PermitOpen",
1861
			if (p == NULL) {
1822
				    filename, linenum);
1862
				fatal("%s line %d: missing host in %s",
1863
				    filename, linenum,
1864
				    lookup_opcode_name(opcode));
1865
			}
1823
			p = cleanhostname(p);
1866
			p = cleanhostname(p);
1824
			if (arg == NULL || ((port = permitopen_port(arg)) < 0))
1867
			if (arg == NULL ||
1825
				fatal("%s line %d: bad port number in "
1868
			    ((port = permitopen_port(arg)) < 0)) {
1826
				    "PermitOpen", filename, linenum);
1869
				fatal("%s line %d: bad port number in %s",
1827
			if (*activep && value == 0) {
1870
				    filename, linenum,
1871
				    lookup_opcode_name(opcode));
1872
			}
1873
			if (*activep && uvalue == 0) {
1828
				array_append(filename, linenum,
1874
				array_append(filename, linenum,
1829
				    "PermitOpen",
1875
				    lookup_opcode_name(opcode),
1830
				    &options->permitted_opens,
1876
				    chararrayptr, uintptr, arg2);
1831
				    &options->num_permitted_opens, arg2);
1832
			}
1877
			}
1833
			free(arg2);
1878
			free(arg2);
1834
		}
1879
		}
Lines 2307-2323 fmt_intarg(ServerOpCodes code, int val) Link Here
2307
	}
2352
	}
2308
}
2353
}
2309
2354
2310
static const char *
2311
lookup_opcode_name(ServerOpCodes code)
2312
{
2313
	u_int i;
2314
2315
	for (i = 0; keywords[i].name != NULL; i++)
2316
		if (keywords[i].opcode == code)
2317
			return(keywords[i].name);
2318
	return "UNKNOWN";
2319
}
2320
2321
static void
2355
static void
2322
dump_cfg_int(ServerOpCodes code, int val)
2356
dump_cfg_int(ServerOpCodes code, int val)
2323
{
2357
{
Lines 2562-2565 dump_config(ServerOptions *o) Link Here
2562
			printf(" %s", o->permitted_opens[i]);
2596
			printf(" %s", o->permitted_opens[i]);
2563
	}
2597
	}
2564
	printf("\n");
2598
	printf("\n");
2599
	printf("permitremoteopen");
2600
	if (o->num_permitted_remote_opens == 0)
2601
		printf(" any");
2602
	else {
2603
		for (i = 0; i < o->num_permitted_remote_opens; i++)
2604
			printf(" %s", o->permitted_remote_opens[i]);
2605
	}
2606
	printf("\n");
2565
}
2607
}
(-)a/servconf.h (-8 / +6 lines)
Lines 32-43 Link Here
32
#define PRIVSEP_ON		1
32
#define PRIVSEP_ON		1
33
#define PRIVSEP_NOSANDBOX	2
33
#define PRIVSEP_NOSANDBOX	2
34
34
35
/* AllowTCPForwarding */
36
#define FORWARD_DENY		0
37
#define FORWARD_REMOTE		(1)
38
#define FORWARD_LOCAL		(1<<1)
39
#define FORWARD_ALLOW		(FORWARD_REMOTE|FORWARD_LOCAL)
40
41
/* PermitOpen */
35
/* PermitOpen */
42
#define PERMITOPEN_ANY		0
36
#define PERMITOPEN_ANY		0
43
#define PERMITOPEN_NONE		-2
37
#define PERMITOPEN_NONE		-2
Lines 187-194 typedef struct { Link Here
187
181
188
	int	permit_tun;
182
	int	permit_tun;
189
183
190
	char   **permitted_opens;
184
	char   **permitted_opens;	/* May also be one of PERMITOPEN_* */
191
	u_int   num_permitted_opens; /* May also be one of PERMITOPEN_* */
185
	u_int   num_permitted_opens;
186
	char   **permitted_remote_opens; /* May also be one of PERMITOPEN_* */
187
	u_int   num_permitted_remote_opens;
192
188
193
	char   *chroot_directory;
189
	char   *chroot_directory;
194
	char   *revoked_keys_file;
190
	char   *revoked_keys_file;
Lines 252-257 struct connection_info { Link Here
252
		M_CP_STRARRAYOPT(accept_env, num_accept_env); \
248
		M_CP_STRARRAYOPT(accept_env, num_accept_env); \
253
		M_CP_STRARRAYOPT(auth_methods, num_auth_methods); \
249
		M_CP_STRARRAYOPT(auth_methods, num_auth_methods); \
254
		M_CP_STRARRAYOPT(permitted_opens, num_permitted_opens); \
250
		M_CP_STRARRAYOPT(permitted_opens, num_permitted_opens); \
251
		M_CP_STRARRAYOPT(permitted_remote_opens, \
252
		    num_permitted_remote_opens); \
255
	} while (0)
253
	} while (0)
256
254
257
struct connection_info *get_connection_info(int, int);
255
struct connection_info *get_connection_info(int, int);
(-)a/session.c (-8 / +17 lines)
Lines 298-304 set_permitopen_from_authopts(struct ssh *ssh, const struct sshauthopt *opts) Link Here
298
298
299
	if ((options.allow_tcp_forwarding & FORWARD_LOCAL) == 0)
299
	if ((options.allow_tcp_forwarding & FORWARD_LOCAL) == 0)
300
		return;
300
		return;
301
	channel_clear_permitted_opens(ssh);
301
	channel_clear_permitted_opens(ssh, FORWARD_USER, FORWARD_LOCAL);
302
	for (i = 0; i < auth_opts->npermitopen; i++) {
302
	for (i = 0; i < auth_opts->npermitopen; i++) {
303
		tmp = cp = xstrdup(auth_opts->permitopen[i]);
303
		tmp = cp = xstrdup(auth_opts->permitopen[i]);
304
		/* This shouldn't fail as it has already been checked */
304
		/* This shouldn't fail as it has already been checked */
Lines 308-314 set_permitopen_from_authopts(struct ssh *ssh, const struct sshauthopt *opts) Link Here
308
		if (cp == NULL || (port = permitopen_port(cp)) < 0)
308
		if (cp == NULL || (port = permitopen_port(cp)) < 0)
309
			fatal("%s: internal error: permitopen port",
309
			fatal("%s: internal error: permitopen port",
310
			    __func__);
310
			    __func__);
311
		channel_add_permitted_opens(ssh, host, port);
311
		channel_add_permitted_open(ssh, FORWARD_USER, FORWARD_LOCAL,
312
		    host, port);
312
		free(tmp);
313
		free(tmp);
313
	}
314
	}
314
}
315
}
Lines 323-335 do_authenticated(struct ssh *ssh, Authctxt *authctxt) Link Here
323
	/* setup the channel layer */
324
	/* setup the channel layer */
324
	/* XXX - streamlocal? */
325
	/* XXX - streamlocal? */
325
	set_permitopen_from_authopts(ssh, auth_opts);
326
	set_permitopen_from_authopts(ssh, auth_opts);
327
326
	if (!auth_opts->permit_port_forwarding_flag ||
328
	if (!auth_opts->permit_port_forwarding_flag ||
327
	    options.disable_forwarding ||
329
	    options.disable_forwarding) {
328
	    (options.allow_tcp_forwarding & FORWARD_LOCAL) == 0)
330
		channel_disable_adm_opens(ssh, FORWARD_LOCAL);
329
		channel_disable_adm_local_opens(ssh);
331
		channel_disable_adm_opens(ssh, FORWARD_REMOTE);
330
	else
332
	} else {
331
		channel_permit_all_opens(ssh);
333
		if ((options.allow_tcp_forwarding & FORWARD_LOCAL) == 0)
332
334
			channel_disable_adm_opens(ssh, FORWARD_LOCAL);
335
		else
336
			channel_permit_all_opens(ssh, FORWARD_LOCAL);
337
		if ((options.allow_tcp_forwarding & FORWARD_REMOTE) == 0)
338
			channel_disable_adm_opens(ssh, FORWARD_REMOTE);
339
		else
340
			channel_permit_all_opens(ssh, FORWARD_REMOTE);
341
	}
333
	auth_debug_send();
342
	auth_debug_send();
334
343
335
	prepare_auth_info_file(authctxt->pw, authctxt->session_info);
344
	prepare_auth_info_file(authctxt->pw, authctxt->session_info);

Return to bug 2038