- djm@cvs.openbsd.org 2010/06/25 07:14:46
     [channels.c mux.c readconf.c readconf.h ssh.h]
     bz#1327: remove hardcoded limit of 100 permitopen clauses and port
     forwards per direction; ok markus@ stevesk@
diff --git a/channels.c b/channels.c
index 0f750c4..2f2798d 100644
--- a/channels.c
+++ b/channels.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: channels.c,v 1.304 2010/05/14 23:29:23 djm Exp $ */
+/* $OpenBSD: channels.c,v 1.305 2010/06/25 07:14:45 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -114,10 +114,10 @@
 } ForwardPermission;
 
 /* List of all permitted host/port pairs to connect by the user. */
-static ForwardPermission permitted_opens[SSH_MAX_FORWARDS_PER_DIRECTION];
+static ForwardPermission *permitted_opens = NULL;
 
 /* List of all permitted host/port pairs to connect by the admin. */
-static ForwardPermission permitted_adm_opens[SSH_MAX_FORWARDS_PER_DIRECTION];
+static ForwardPermission *permitted_adm_opens = NULL;
 
 /* Number of permitted host/port pairs in the array permitted by the user. */
 static int num_permitted_opens = 0;
@@ -2838,10 +2838,6 @@
 {
 	int type, success = 0;
 
-	/* Record locally that connection to this host/port is permitted. */
-	if (num_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION)
-		fatal("channel_request_remote_forwarding: too many forwards");
-
 	/* Send the forward request to the remote side. */
 	if (compat20) {
 		const char *address_to_bind;
@@ -2891,6 +2887,9 @@
 		}
 	}
 	if (success) {
+		/* Record that connection to this host/port is permitted. */
+		permitted_opens = xrealloc(permitted_opens,
+		    num_permitted_opens + 1, sizeof(*permitted_opens));
 		permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host_to_connect);
 		permitted_opens[num_permitted_opens].port_to_connect = port_to_connect;
 		permitted_opens[num_permitted_opens].listen_port = listen_port;
@@ -2988,10 +2987,10 @@
 void
 channel_add_permitted_opens(char *host, int port)
 {
-	if (num_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION)
-		fatal("channel_add_permitted_opens: too many forwards");
 	debug("allow port forwarding to host %s port %d", host, port);
 
+	permitted_opens = xrealloc(permitted_opens,
+	    num_permitted_opens + 1, sizeof(*permitted_opens));
 	permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host);
 	permitted_opens[num_permitted_opens].port_to_connect = port;
 	num_permitted_opens++;
@@ -3002,10 +3001,10 @@
 int
 channel_add_adm_permitted_opens(char *host, int port)
 {
-	if (num_adm_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION)
-		fatal("channel_add_adm_permitted_opens: too many forwards");
 	debug("config allows port forwarding to host %s port %d", host, port);
 
+	permitted_adm_opens = xrealloc(permitted_adm_opens,
+	    num_adm_permitted_opens + 1, sizeof(*permitted_adm_opens));
 	permitted_adm_opens[num_adm_permitted_opens].host_to_connect
 	     = xstrdup(host);
 	permitted_adm_opens[num_adm_permitted_opens].port_to_connect = port;
@@ -3020,6 +3019,10 @@
 	for (i = 0; i < num_permitted_opens; i++)
 		if (permitted_opens[i].host_to_connect != NULL)
 			xfree(permitted_opens[i].host_to_connect);
+	if (num_permitted_opens > 0) {
+		xfree(permitted_opens);
+		permitted_opens = NULL;
+	}
 	num_permitted_opens = 0;
 }
 
@@ -3031,6 +3034,10 @@
 	for (i = 0; i < num_adm_permitted_opens; i++)
 		if (permitted_adm_opens[i].host_to_connect != NULL)
 			xfree(permitted_adm_opens[i].host_to_connect);
+	if (num_adm_permitted_opens > 0) {
+		xfree(permitted_adm_opens);
+		permitted_adm_opens = NULL;
+	}
 	num_adm_permitted_opens = 0;
 }