- markus@cvs.openbsd.org 2011/09/10 22:26:34
     [channels.c channels.h clientloop.c ssh.1]
     support cancellation of local/dynamic forwardings from ~C commandline;
     ok & feedback djm@
diff --git a/clientloop.c b/clientloop.c
index c19b01f..1339521 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: clientloop.c,v 1.236 2011/06/22 22:08:42 djm Exp $ */
+/* $OpenBSD: clientloop.c,v 1.237 2011/09/10 22:26:34 markus Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -839,9 +839,8 @@
 {
 	void (*handler)(int);
 	char *s, *cmd, *cancel_host;
-	int delete = 0;
-	int local = 0, remote = 0, dynamic = 0;
-	int cancel_port;
+	int delete = 0, local = 0, remote = 0, dynamic = 0;
+	int cancel_port, ok;
 	Forward fwd;
 
 	bzero(&fwd, sizeof(fwd));
@@ -867,8 +866,12 @@
 		    "Request remote forward");
 		logit("      -D[bind_address:]port                  "
 		    "Request dynamic forward");
+		logit("      -KL[bind_address:]port                 "
+		    "Cancel local forward");
 		logit("      -KR[bind_address:]port                 "
 		    "Cancel remote forward");
+		logit("      -KD[bind_address:]port                 "
+		    "Cancel dynamic forward");
 		if (!options.permit_local_command)
 			goto out;
 		logit("      !args                                  "
@@ -897,11 +900,7 @@
 		goto out;
 	}
 
-	if ((local || dynamic) && delete) {
-		logit("Not supported.");
-		goto out;
-	}
-	if (remote && delete && !compat20) {
+	if (delete && !compat20) {
 		logit("Not supported for SSH protocol version 1.");
 		goto out;
 	}
@@ -924,7 +923,21 @@
 			logit("Bad forwarding close port");
 			goto out;
 		}
-		channel_request_rforward_cancel(cancel_host, cancel_port);
+		if (remote)
+			ok = channel_request_rforward_cancel(cancel_host,
+			    cancel_port) == 0;
+		else if (dynamic)
+                	ok = channel_cancel_lport_listener(cancel_host,
+			    cancel_port, 0, options.gateway_ports) > 0;
+		else
+                	ok = channel_cancel_lport_listener(cancel_host,
+			    cancel_port, CHANNEL_CANCEL_PORT_STATIC,
+			    options.gateway_ports) > 0;
+		if (!ok) {
+			logit("Unkown port forwarding.");
+			goto out;
+		}
+		logit("Canceled forwarding.");
 	} else {
 		if (!parse_forward(&fwd, s, dynamic, remote)) {
 			logit("Bad forwarding specification.");
@@ -945,7 +958,6 @@
 				goto out;
 			}
 		}
-
 		logit("Forwarding port.");
 	}