- djm@cvs.openbsd.org 2012/12/02 20:46:11
     [auth-options.c channels.c servconf.c servconf.h serverloop.c session.c]
     [sshd_config.5]
     make AllowTcpForwarding accept "local" and "remote" in addition to its
     current "yes"/"no" to allow the server to specify whether just local or
     remote TCP forwarding is enabled. ok markus@
diff --git a/serverloop.c b/serverloop.c
index 741c5be..14e60c6 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: serverloop.c,v 1.162 2012/06/20 04:42:58 djm Exp $ */
+/* $OpenBSD: serverloop.c,v 1.163 2012/12/02 20:46:11 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -950,7 +950,7 @@
 static Channel *
 server_request_direct_tcpip(void)
 {
-	Channel *c;
+	Channel *c = NULL;
 	char *target, *originator;
 	u_short target_port, originator_port;
 
@@ -963,9 +963,16 @@
 	debug("server_request_direct_tcpip: originator %s port %d, target %s "
 	    "port %d", originator, originator_port, target, target_port);
 
-	/* XXX check permission */
-	c = channel_connect_to(target, target_port,
-	    "direct-tcpip", "direct-tcpip");
+	/* XXX fine grained permissions */
+	if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0 &&
+	    !no_port_forwarding_flag) {
+		c = channel_connect_to(target, target_port,
+		    "direct-tcpip", "direct-tcpip");
+	} else {
+		logit("refused local port forward: "
+		    "originator %s port %d, target %s port %d",
+		    originator, originator_port, target, target_port);
+	}
 
 	xfree(originator);
 	xfree(target);
@@ -1126,7 +1133,7 @@
 		    listen_address, listen_port);
 
 		/* check permissions */
-		if (!options.allow_tcp_forwarding ||
+		if ((options.allow_tcp_forwarding & FORWARD_REMOTE) == 0 ||
 		    no_port_forwarding_flag ||
 		    (!want_reply && listen_port == 0)
 #ifndef NO_IPPORT_RESERVED_CONCEPT