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) _______________________________________________ openssh-unix-dev mailing list openssh-unix-dev@xxxxxxxxxxx https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev