Blame SOURCES/openssh-7.3p1-x11-max-displays.patch

3e8b5b
diff -up openssh-7.4p1/channels.c.x11max openssh-7.4p1/channels.c
3e8b5b
--- openssh-7.4p1/channels.c.x11max	2016-12-23 15:46:32.071506625 +0100
3e8b5b
+++ openssh-7.4p1/channels.c	2016-12-23 15:46:32.139506636 +0100
3e8b5b
@@ -152,8 +152,8 @@ static int all_opens_permitted = 0;
3e8b5b
 #define FWD_PERMIT_ANY_HOST	"*"
3e8b5b
 
3e8b5b
 /* -- X11 forwarding */
3e8b5b
-/* Maximum number of fake X11 displays to try. */
3e8b5b
-#define MAX_DISPLAYS  1000
3e8b5b
+/* Minimum port number for X11 forwarding */
3e8b5b
+#define X11_PORT_MIN 6000
3e8b5b
 
3e8b5b
 /* Per-channel callback for pre/post select() actions */
3e8b5b
 typedef void chan_fn(struct ssh *, Channel *c,
3e8b5b
@@ -4228,7 +4228,7 @@ channel_send_window_changes(void)
3e8b5b
  */
3e8b5b
 int
3e8b5b
 x11_create_display_inet(struct ssh *ssh, int x11_display_offset,
3e8b5b
-    int x11_use_localhost, int single_connection,
3e8b5b
+    int x11_use_localhost, int x11_max_displays, int single_connection,
3e8b5b
     u_int *display_numberp, int **chanids)
3e8b5b
 {
3e8b5b
 	Channel *nc = NULL;
3e8b5b
@@ -4240,10 +4241,15 @@ x11_create_display_inet(int x11_display_
3e8b5b
 	if (chanids == NULL)
3e8b5b
 		return -1;
3e8b5b
 
3e8b5b
+	/* Try to bind ports starting at 6000+X11DisplayOffset */
3e8b5b
+	x11_max_displays = x11_max_displays + x11_display_offset;
3e8b5b
+
3e8b5b
 	for (display_number = x11_display_offset;
3e8b5b
-	    display_number < MAX_DISPLAYS;
3e8b5b
+	    display_number < x11_max_displays;
3e8b5b
 	    display_number++) {
3e8b5b
-		port = 6000 + display_number;
3e8b5b
+		port = X11_PORT_MIN + display_number;
3e8b5b
+		if (port < X11_PORT_MIN) /* overflow */
3e8b5b
+			break;
3e8b5b
 		memset(&hints, 0, sizeof(hints));
3e8b5b
 		hints.ai_family = ssh->chanctxt->IPv4or6;
3e8b5b
 		hints.ai_flags = x11_use_localhost ? 0: AI_PASSIVE;
3e8b5b
@@ -4295,7 +4301,7 @@ x11_create_display_inet(int x11_display_
3e8b5b
 		if (num_socks > 0)
3e8b5b
 			break;
3e8b5b
 	}
3e8b5b
-	if (display_number >= MAX_DISPLAYS) {
3e8b5b
+	if (display_number >= x11_max_displays || port < X11_PORT_MIN ) {
3e8b5b
 		error("Failed to allocate internet-domain X11 display socket.");
3e8b5b
 		return -1;
3e8b5b
 	}
3e8b5b
@@ -4441,7 +4447,7 @@ x11_connect_display(void)
3e8b5b
 	memset(&hints, 0, sizeof(hints));
3e8b5b
 	hints.ai_family = ssh->chanctxt->IPv4or6;
3e8b5b
 	hints.ai_socktype = SOCK_STREAM;
3e8b5b
-	snprintf(strport, sizeof strport, "%u", 6000 + display_number);
3e8b5b
+	snprintf(strport, sizeof strport, "%u", X11_PORT_MIN + display_number);
3e8b5b
 	if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) {
3e8b5b
 		error("%.100s: unknown host. (%s)", buf,
3e8b5b
 		ssh_gai_strerror(gaierr));
3e8b5b
@@ -4457,7 +4463,7 @@ x11_connect_display(void)
3e8b5b
 		/* Connect it to the display. */
3e8b5b
 		if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
3e8b5b
 			debug2("connect %.100s port %u: %.100s", buf,
3e8b5b
-			    6000 + display_number, strerror(errno));
3e8b5b
+			    X11_PORT_MIN + display_number, strerror(errno));
3e8b5b
 			close(sock);
3e8b5b
 			continue;
3e8b5b
 		}
3e8b5b
@@ -4466,8 +4472,8 @@ x11_connect_display(void)
3e8b5b
 	}
3e8b5b
 	freeaddrinfo(aitop);
3e8b5b
 	if (!ai) {
3e8b5b
-		error("connect %.100s port %u: %.100s", buf,
3e8b5b
-		    6000 + display_number, strerror(errno));
3e8b5b
+		error("connect %.100s port %u: %.100s", buf,
3e8b5b
+		    X11_PORT_MIN + display_number, strerror(errno));
3e8b5b
 		return -1;
3e8b5b
 	}
3e8b5b
 	set_nodelay(sock);
3e8b5b
diff -up openssh-7.4p1/channels.h.x11max openssh-7.4p1/channels.h
3e8b5b
--- openssh-7.4p1/channels.h.x11max	2016-12-19 05:59:41.000000000 +0100
3e8b5b
+++ openssh-7.4p1/channels.h	2016-12-23 15:46:32.139506636 +0100
3e8b5b
@@ -293,7 +293,7 @@ int	 permitopen_port(const char *);
3e8b5b
 
3e8b5b
 void	 channel_set_x11_refuse_time(struct ssh *, u_int);
3e8b5b
 int	 x11_connect_display(struct ssh *);
3e8b5b
-int	 x11_create_display_inet(struct ssh *, int, int, int, u_int *, int **);
3e8b5b
+int	 x11_create_display_inet(struct ssh *, int, int, int, int, u_int *, int **);
3e8b5b
 void	 x11_request_forwarding_with_spoofing(struct ssh *, int,
3e8b5b
 	    const char *, const char *, const char *, int);
3e8b5b
 
3e8b5b
diff -up openssh-7.4p1/servconf.c.x11max openssh-7.4p1/servconf.c
3e8b5b
--- openssh-7.4p1/servconf.c.x11max	2016-12-23 15:46:32.133506635 +0100
3e8b5b
+++ openssh-7.4p1/servconf.c	2016-12-23 15:47:27.320519121 +0100
3e8b5b
@@ -95,6 +95,7 @@ initialize_server_options(ServerOptions
3e8b5b
 	options->print_lastlog = -1;
3e8b5b
 	options->x11_forwarding = -1;
3e8b5b
 	options->x11_display_offset = -1;
3e8b5b
+	options->x11_max_displays = -1;
3e8b5b
 	options->x11_use_localhost = -1;
3e8b5b
 	options->permit_tty = -1;
3e8b5b
 	options->permit_user_rc = -1;
3e8b5b
@@ -243,6 +244,8 @@ fill_default_server_options(ServerOption
3e8b5b
 		options->x11_forwarding = 0;
3e8b5b
 	if (options->x11_display_offset == -1)
3e8b5b
 		options->x11_display_offset = 10;
3e8b5b
+	if (options->x11_max_displays == -1)
3e8b5b
+		options->x11_max_displays = DEFAULT_MAX_DISPLAYS;
3e8b5b
 	if (options->x11_use_localhost == -1)
3e8b5b
 		options->x11_use_localhost = 1;
3e8b5b
 	if (options->xauth_location == NULL)
3e8b5b
@@ -419,7 +422,7 @@ typedef enum {
3e8b5b
 	sPasswordAuthentication, sKbdInteractiveAuthentication,
3e8b5b
 	sListenAddress, sAddressFamily,
3e8b5b
 	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
3e8b5b
-	sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
3e8b5b
+	sX11Forwarding, sX11DisplayOffset, sX11MaxDisplays, sX11UseLocalhost,
3e8b5b
 	sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive,
3e8b5b
 	sPermitUserEnvironment, sAllowTcpForwarding, sCompression,
3e8b5b
 	sRekeyLimit, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
3e8b5b
@@ -540,6 +543,7 @@ static struct {
3e8b5b
 	{ "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
3e8b5b
 	{ "x11forwarding", sX11Forwarding, SSHCFG_ALL },
3e8b5b
 	{ "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
3e8b5b
+	{ "x11maxdisplays", sX11MaxDisplays, SSHCFG_ALL },
3e8b5b
 	{ "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
3e8b5b
 	{ "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
3e8b5b
 	{ "strictmodes", sStrictModes, SSHCFG_GLOBAL },
3e8b5b
@@ -1316,6 +1320,10 @@ process_server_config_line(ServerOptions
3e8b5b
 			*intptr = value;
3e8b5b
 		break;
3e8b5b
 
3e8b5b
+	case sX11MaxDisplays:
3e8b5b
+		intptr = &options->x11_max_displays;
3e8b5b
+		goto parse_int;
3e8b5b
+
3e8b5b
 	case sX11UseLocalhost:
3e8b5b
 		intptr = &options->x11_use_localhost;
3e8b5b
 		goto parse_flag;
3e8b5b
@@ -2063,6 +2071,7 @@ copy_set_server_options(ServerOptions *d
3e8b5b
 	M_CP_INTOPT(fwd_opts.streamlocal_bind_unlink);
3e8b5b
 	M_CP_INTOPT(x11_display_offset);
3e8b5b
 	M_CP_INTOPT(x11_forwarding);
3e8b5b
+	M_CP_INTOPT(x11_max_displays);
3e8b5b
 	M_CP_INTOPT(x11_use_localhost);
3e8b5b
 	M_CP_INTOPT(permit_tty);
3e8b5b
 	M_CP_INTOPT(permit_user_rc);
3e8b5b
@@ -2315,6 +2324,7 @@ dump_config(ServerOptions *o)
3e8b5b
 #endif
3e8b5b
 	dump_cfg_int(sLoginGraceTime, o->login_grace_time);
3e8b5b
 	dump_cfg_int(sX11DisplayOffset, o->x11_display_offset);
3e8b5b
+	dump_cfg_int(sX11MaxDisplays, o->x11_max_displays);
3e8b5b
 	dump_cfg_int(sMaxAuthTries, o->max_authtries);
3e8b5b
 	dump_cfg_int(sMaxSessions, o->max_sessions);
3e8b5b
 	dump_cfg_int(sClientAliveInterval, o->client_alive_interval);
3e8b5b
diff -up openssh-7.4p1/servconf.h.x11max openssh-7.4p1/servconf.h
3e8b5b
--- openssh-7.4p1/servconf.h.x11max	2016-12-23 15:46:32.133506635 +0100
3e8b5b
+++ openssh-7.4p1/servconf.h	2016-12-23 15:46:32.140506636 +0100
3e8b5b
@@ -55,6 +55,7 @@
3e8b5b
 
3e8b5b
 #define DEFAULT_AUTH_FAIL_MAX	6	/* Default for MaxAuthTries */
3e8b5b
 #define DEFAULT_SESSIONS_MAX	10	/* Default for MaxSessions */
3e8b5b
+#define DEFAULT_MAX_DISPLAYS	1000 /* Maximum number of fake X11 displays to try. */
3e8b5b
 
3e8b5b
 /* Magic name for internal sftp-server */
3e8b5b
 #define INTERNAL_SFTP_NAME	"internal-sftp"
3e8b5b
@@ -85,6 +86,7 @@ typedef struct {
3e8b5b
 	int     x11_forwarding;	/* If true, permit inet (spoofing) X11 fwd. */
3e8b5b
 	int     x11_display_offset;	/* What DISPLAY number to start
3e8b5b
 					 * searching at */
3e8b5b
+	int 	x11_max_displays; /* Number of displays to search */
3e8b5b
 	int     x11_use_localhost;	/* If true, use localhost for fake X11 server. */
3e8b5b
 	char   *xauth_location;	/* Location of xauth program */
3e8b5b
 	int	permit_tty;	/* If false, deny pty allocation */
3e8b5b
diff -up openssh-7.4p1/session.c.x11max openssh-7.4p1/session.c
3e8b5b
--- openssh-7.4p1/session.c.x11max	2016-12-23 15:46:32.136506636 +0100
3e8b5b
+++ openssh-7.4p1/session.c	2016-12-23 15:46:32.141506636 +0100
3e8b5b
@@ -2518,8 +2518,9 @@ session_setup_x11fwd(Session *s)
3e8b5b
 		return 0;
3e8b5b
 	}
3e8b5b
	if (x11_create_display_inet(ssh, options.x11_display_offset,
3e8b5b
-	    options.x11_use_localhost, s->single_connection,
3e8b5b
-	    &s->display_number, &s->x11_chanids) == -1) {
3e8b5b
+	    options.x11_use_localhost, options.x11_max_displays,
3e8b5b
+	    s->single_connection, &s->display_number,
3e8b5b
+	    &s->x11_chanids) == -1) {
3e8b5b
 		debug("x11_create_display_inet failed.");
3e8b5b
 		return 0;
3e8b5b
 	}
3e8b5b
diff -up openssh-7.4p1/sshd_config.5.x11max openssh-7.4p1/sshd_config.5
3e8b5b
--- openssh-7.4p1/sshd_config.5.x11max	2016-12-23 15:46:32.134506635 +0100
3e8b5b
+++ openssh-7.4p1/sshd_config.5	2016-12-23 15:46:32.141506636 +0100
3e8b5b
@@ -1133,6 +1133,7 @@ Available keywords are
3e8b5b
 .Cm StreamLocalBindUnlink ,
3e8b5b
 .Cm TrustedUserCAKeys ,
3e8b5b
 .Cm X11DisplayOffset ,
3e8b5b
+.Cm X11MaxDisplays ,
3e8b5b
 .Cm X11Forwarding
3e8b5b
 and
3e8b5b
 .Cm X11UseLocalHost .
3e8b5b
@@ -1566,6 +1567,12 @@ Specifies the first display number avail
3e8b5b
 X11 forwarding.
3e8b5b
 This prevents sshd from interfering with real X11 servers.
3e8b5b
 The default is 10.
3e8b5b
+.It Cm X11MaxDisplays
3e8b5b
+Specifies the maximum number of displays available for
3e8b5b
+.Xr sshd 8 Ns 's
3e8b5b
+X11 forwarding.
3e8b5b
+This prevents sshd from exhausting local ports.
3e8b5b
+The default is 1000.
3e8b5b
 .It Cm X11Forwarding
3e8b5b
 Specifies whether X11 forwarding is permitted.
3e8b5b
 The argument must be