OpenSSH contract development / patch
Devin Nate
devin.nate at QHRtech.com
Fri May 5 03:55:47 AEST 2017
Sorry to double post. I see the mailing list does not prefer attachments.
permitgwport patch inline here, and changes behavior to require permitopen in an authorized_keys file, otherwise no ports may be opened (default deny).
Thanks,
Devin
permitgwports-and-permitopen-mandatory-openssh-7.2p2.patch
--- auth-options.c.orig 2016-05-02 11:25:41.420811342 -0600
+++ auth-options.c 2016-05-02 13:06:23.149347634 -0600
@@ -81,6 +81,7 @@
authorized_principals = NULL;
forced_tun_device = -1;
channel_clear_permitted_opens();
+ channel_clear_permitted_gatewayports();
}
/*
@@ -326,6 +327,51 @@
/* deny access */
return 0;
}
+ cp = "permitgwport=\"";
+ if (strncasecmp(opts, cp, strlen(cp)) == 0) {
+ char *p;
+ int port;
+ char *patterns = xmalloc(strlen(opts) + 1);
+
+ opts += strlen(cp);
+ i = 0;
+ while (*opts) {
+ if (*opts == '"')
+ break;
+ if (*opts == '\\' && opts[1] == '"') {
+ opts += 2;
+ patterns[i++] = '"';
+ continue;
+ }
+ patterns[i++] = *opts++;
+ }
+ if (!*opts) {
+ debug("%.100s, line %lu: missing end quote",
+ file, linenum);
+ auth_debug_add("%.100s, line %lu: missing "
+ "end quote", file, linenum);
+ free(patterns);
+ goto bad_option;
+ }
+ patterns[i] = '\0';
+ opts++;
+ p = patterns;
+ port = a2port(p);
+ if (port <= 0 || port >= 65536) {
+ debug("%.100s, line %lu: Bad permitgwport "
+ "specification <%.100s>", file, linenum,
+ patterns);
+ auth_debug_add("%.100s, line %lu: "
+ "Bad permitgwport specification", file,
+ linenum);
+ free(patterns);
+ goto bad_option;
+ }
+ if ((options.allow_tcp_forwarding & FORWARD_REMOTE) != 0)
+ channel_add_permitted_gatewayports(port);
+ free(patterns);
+ goto next_option;
+ }
cp = "permitopen=\"";
if (strncasecmp(opts, cp, strlen(cp)) == 0) {
char *host, *p;
--- channels.c.orig 2016-05-02 11:18:46.095511183 -0600
+++ channels.c 2016-05-03 16:50:46.033883347 -0600
@@ -135,6 +135,12 @@
/* Number of permitted host/port pair in the array permitted by the admin. */
static int num_adm_permitted_opens = 0;
+/* List of all permitted ports allowed to be gateway ports by the user */
+static int *permitted_gatewayports = NULL;
+
+/* Number of permitted ports allowed to be gateway ports by the user */
+static int num_permitted_gatewayports = 0;
+
/* special-case port number meaning allow any port */
#define FWD_PERMIT_ANY_PORT 0
@@ -3303,6 +3309,24 @@
return 1;
}
+int
+gatewayport_permit(int requestedport)
+{
+ int i, permit = 0;
+ for (i = 0; i < num_permitted_gatewayports; i++) {
+ if (permitted_gatewayports[i] == requestedport) {
+ permit = 1;
+ break;
+ }
+ }
+ if (!permit) {
+ logit("Received request for gateway port %d, "
+ "but the request was denied.", requestedport);
+ return 0;
+ }
+ return 1;
+}
+
/*
* Note that in the listen host/port case
* we don't support FWD_PERMIT_ANY_PORT and
@@ -3482,8 +3506,8 @@
void
channel_permit_all_opens(void)
{
- if (num_permitted_opens == 0)
- all_opens_permitted = 1;
+ /* always require explicit permitopens */
+ all_opens_permitted = 0;
}
void
@@ -3503,6 +3527,16 @@
all_opens_permitted = 0;
}
+void
+channel_add_permitted_gatewayports(int port)
+{
+ debug("allow gatewayport %d", port);
+ permitted_gatewayports = xreallocarray(permitted_gatewayports,
+ num_permitted_gatewayports + 1, sizeof(*permitted_gatewayports));
+ permitted_gatewayports[num_permitted_gatewayports] = port;
+ num_permitted_gatewayports++;
+}
+
/*
* Update the listen port for a dynamic remote forward, after
* the actual 'newport' has been allocated. If 'newport' < 0 is
@@ -3577,6 +3611,14 @@
}
void
+channel_clear_permitted_gatewayports(void)
+{
+ free(permitted_gatewayports);
+ permitted_gatewayports = NULL;
+ num_permitted_gatewayports = 0;
+}
+
+void
channel_clear_adm_permitted_opens(void)
{
int i;
--- channels.h.orig 2016-05-02 11:27:24.917708255 -0600
+++ channels.h 2016-05-02 18:55:21.789555565 -0600
@@ -261,10 +261,12 @@
void channel_set_af(int af);
void channel_permit_all_opens(void);
void channel_add_permitted_opens(char *, int);
+void channel_add_permitted_gatewayports(int);
int channel_add_adm_permitted_opens(char *, int);
void channel_disable_adm_local_opens(void);
void channel_update_permitted_opens(int, int);
void channel_clear_permitted_opens(void);
+void channel_clear_permitted_gatewayports(void);
void channel_clear_adm_permitted_opens(void);
void channel_print_adm_permitted_opens(void);
int channel_input_port_forward_request(int, struct ForwardOptions *);
@@ -281,6 +283,7 @@
int channel_cancel_rport_listener(struct Forward *);
int channel_cancel_lport_listener(struct Forward *, int, struct ForwardOptions *);
int permitopen_port(const char *);
+int gatewayport_permit(int);
/* x11 forwarding */
--- serverloop.c.orig 2016-05-02 17:15:09.745831104 -0600
+++ serverloop.c 2016-05-03 16:52:02.181666652 -0600
@@ -1240,6 +1240,7 @@
if ((options.allow_tcp_forwarding & FORWARD_REMOTE) == 0 ||
no_port_forwarding_flag ||
(!want_reply && fwd.listen_port == 0)
+ || !gatewayport_permit(fwd.listen_port)
#ifndef NO_IPPORT_RESERVED_CONCEPT
|| (fwd.listen_port != 0 && fwd.listen_port < IPPORT_RESERVED &&
pw->pw_uid != 0)
More information about the openssh-unix-dev
mailing list