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