summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarren Tucker <dtucker@zip.com.au>2004-05-24 10:18:05 +1000
committerDarren Tucker <dtucker@zip.com.au>2004-05-24 10:18:05 +1000
commite7066dfde3d4ac36038050b6027a742356f7b1f1 (patch)
treed9e6913dd07931f85936058614bb156e86ca6f7b
parente4ab1157db90ff9602940669ccfda679aa4094a0 (diff)
- djm@cvs.openbsd.org 2004/05/21 11:33:11
[channels.c channels.h clientloop.c serverloop.c ssh.1] bz #756: add support for the cancel-tcpip-forward request for the server and the client (through the ~C commandline). reported by z3p AT twistedmatrix.com; ok markus@
-rw-r--r--ChangeLog7
-rw-r--r--channels.c67
-rw-r--r--channels.h4
-rw-r--r--clientloop.c84
-rw-r--r--serverloop.c13
-rw-r--r--ssh.113
6 files changed, 153 insertions, 35 deletions
diff --git a/ChangeLog b/ChangeLog
index 91c9ce5ec..0e8f4a556 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -10,6 +10,11 @@
10 - markus@cvs.openbsd.org 2004/05/21 08:43:03 10 - markus@cvs.openbsd.org 2004/05/21 08:43:03
11 [kex.h moduli.c tildexpand.c] 11 [kex.h moduli.c tildexpand.c]
12 add prototypes for -Wall; ok djm 12 add prototypes for -Wall; ok djm
13 - djm@cvs.openbsd.org 2004/05/21 11:33:11
14 [channels.c channels.h clientloop.c serverloop.c ssh.1]
15 bz #756: add support for the cancel-tcpip-forward request for the server and
16 the client (through the ~C commandline). reported by z3p AT twistedmatrix.com;
17 ok markus@
13 18
1420040523 1920040523
15 - (djm) [sshd_config] Explain consequences of UsePAM=yes a little better in 20 - (djm) [sshd_config] Explain consequences of UsePAM=yes a little better in
@@ -1139,4 +1144,4 @@
1139 - (djm) Trim deprecated options from INSTALL. Mention UsePAM 1144 - (djm) Trim deprecated options from INSTALL. Mention UsePAM
1140 - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu 1145 - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu
1141 1146
1142$Id: ChangeLog,v 1.3361 2004/05/24 00:14:24 dtucker Exp $ 1147$Id: ChangeLog,v 1.3362 2004/05/24 00:18:05 dtucker Exp $
diff --git a/channels.c b/channels.c
index 55dc67342..2b1ce0e5c 100644
--- a/channels.c
+++ b/channels.c
@@ -39,7 +39,7 @@
39 */ 39 */
40 40
41#include "includes.h" 41#include "includes.h"
42RCSID("$OpenBSD: channels.c,v 1.201 2004/05/11 19:01:43 deraadt Exp $"); 42RCSID("$OpenBSD: channels.c,v 1.202 2004/05/21 11:33:11 djm Exp $");
43 43
44#include "ssh.h" 44#include "ssh.h"
45#include "ssh1.h" 45#include "ssh1.h"
@@ -2228,6 +2228,26 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
2228 return success; 2228 return success;
2229} 2229}
2230 2230
2231int
2232channel_cancel_rport_listener(const char *host, u_short port)
2233{
2234 int i, found = 0;
2235
2236 for(i = 0; i < channels_alloc; i++) {
2237 Channel *c = channels[i];
2238
2239 if (c != NULL && c->type == SSH_CHANNEL_RPORT_LISTENER &&
2240 strncmp(c->path, host, sizeof(c->path)) == 0 &&
2241 c->listening_port == port) {
2242 debug2("%s: close clannel %d", __func__, i);
2243 channel_free(c);
2244 found = 1;
2245 }
2246 }
2247
2248 return (found);
2249}
2250
2231/* protocol local port fwd, used by ssh (and sshd in v1) */ 2251/* protocol local port fwd, used by ssh (and sshd in v1) */
2232int 2252int
2233channel_setup_local_fwd_listener(u_short listen_port, 2253channel_setup_local_fwd_listener(u_short listen_port,
@@ -2305,6 +2325,42 @@ channel_request_remote_forwarding(u_short listen_port,
2305} 2325}
2306 2326
2307/* 2327/*
2328 * Request cancellation of remote forwarding of connection host:port from
2329 * local side.
2330 */
2331
2332void
2333channel_request_rforward_cancel(u_short port)
2334{
2335 int i;
2336 const char *address_to_bind = "0.0.0.0";
2337
2338 if (!compat20)
2339 return;
2340
2341 for (i = 0; i < num_permitted_opens; i++) {
2342 if (permitted_opens[i].host_to_connect != NULL &&
2343 permitted_opens[i].listen_port == port)
2344 break;
2345 }
2346 if (i >= num_permitted_opens) {
2347 debug("%s: requested forward not found", __func__);
2348 return;
2349 }
2350 packet_start(SSH2_MSG_GLOBAL_REQUEST);
2351 packet_put_cstring("cancel-tcpip-forward");
2352 packet_put_char(0);
2353 packet_put_cstring(address_to_bind);
2354 packet_put_int(port);
2355 packet_send();
2356
2357 permitted_opens[i].listen_port = 0;
2358 permitted_opens[i].port_to_connect = 0;
2359 free(permitted_opens[i].host_to_connect);
2360 permitted_opens[i].host_to_connect = NULL;
2361}
2362
2363/*
2308 * This is called after receiving CHANNEL_FORWARDING_REQUEST. This initates 2364 * This is called after receiving CHANNEL_FORWARDING_REQUEST. This initates
2309 * listening for the port, and sends back a success reply (or disconnect 2365 * listening for the port, and sends back a success reply (or disconnect
2310 * message if there was an error). This never returns if there was an error. 2366 * message if there was an error). This never returns if there was an error.
@@ -2373,7 +2429,8 @@ channel_clear_permitted_opens(void)
2373 int i; 2429 int i;
2374 2430
2375 for (i = 0; i < num_permitted_opens; i++) 2431 for (i = 0; i < num_permitted_opens; i++)
2376 xfree(permitted_opens[i].host_to_connect); 2432 if (permitted_opens[i].host_to_connect != NULL)
2433 xfree(permitted_opens[i].host_to_connect);
2377 num_permitted_opens = 0; 2434 num_permitted_opens = 0;
2378 2435
2379} 2436}
@@ -2441,7 +2498,8 @@ channel_connect_by_listen_address(u_short listen_port)
2441 int i; 2498 int i;
2442 2499
2443 for (i = 0; i < num_permitted_opens; i++) 2500 for (i = 0; i < num_permitted_opens; i++)
2444 if (permitted_opens[i].listen_port == listen_port) 2501 if (permitted_opens[i].host_to_connect != NULL &&
2502 permitted_opens[i].listen_port == listen_port)
2445 return connect_to( 2503 return connect_to(
2446 permitted_opens[i].host_to_connect, 2504 permitted_opens[i].host_to_connect,
2447 permitted_opens[i].port_to_connect); 2505 permitted_opens[i].port_to_connect);
@@ -2459,7 +2517,8 @@ channel_connect_to(const char *host, u_short port)
2459 permit = all_opens_permitted; 2517 permit = all_opens_permitted;
2460 if (!permit) { 2518 if (!permit) {
2461 for (i = 0; i < num_permitted_opens; i++) 2519 for (i = 0; i < num_permitted_opens; i++)
2462 if (permitted_opens[i].port_to_connect == port && 2520 if (permitted_opens[i].host_to_connect != NULL &&
2521 permitted_opens[i].port_to_connect == port &&
2463 strcmp(permitted_opens[i].host_to_connect, host) == 0) 2522 strcmp(permitted_opens[i].host_to_connect, host) == 0)
2464 permit = 1; 2523 permit = 1;
2465 2524
diff --git a/channels.h b/channels.h
index 7d981479b..0a49c55ea 100644
--- a/channels.h
+++ b/channels.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: channels.h,v 1.71 2003/09/23 20:41:11 markus Exp $ */ 1/* $OpenBSD: channels.h,v 1.72 2004/05/21 11:33:11 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -200,8 +200,10 @@ void channel_input_port_forward_request(int, int);
200int channel_connect_to(const char *, u_short); 200int channel_connect_to(const char *, u_short);
201int channel_connect_by_listen_address(u_short); 201int channel_connect_by_listen_address(u_short);
202void channel_request_remote_forwarding(u_short, const char *, u_short); 202void channel_request_remote_forwarding(u_short, const char *, u_short);
203void channel_request_rforward_cancel(u_short port);
203int channel_setup_local_fwd_listener(u_short, const char *, u_short, int); 204int channel_setup_local_fwd_listener(u_short, const char *, u_short, int);
204int channel_setup_remote_fwd_listener(const char *, u_short, int); 205int channel_setup_remote_fwd_listener(const char *, u_short, int);
206int channel_cancel_rport_listener(const char *, u_short);
205 207
206/* x11 forwarding */ 208/* x11 forwarding */
207 209
diff --git a/clientloop.c b/clientloop.c
index 9cbc1b0ce..ce627e8b8 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -59,7 +59,7 @@
59 */ 59 */
60 60
61#include "includes.h" 61#include "includes.h"
62RCSID("$OpenBSD: clientloop.c,v 1.120 2004/05/20 10:58:05 dtucker Exp $"); 62RCSID("$OpenBSD: clientloop.c,v 1.121 2004/05/21 11:33:11 djm Exp $");
63 63
64#include "ssh.h" 64#include "ssh.h"
65#include "ssh1.h" 65#include "ssh1.h"
@@ -506,6 +506,7 @@ process_cmdline(void)
506 char *s, *cmd; 506 char *s, *cmd;
507 u_short fwd_port, fwd_host_port; 507 u_short fwd_port, fwd_host_port;
508 char buf[1024], sfwd_port[6], sfwd_host_port[6]; 508 char buf[1024], sfwd_port[6], sfwd_host_port[6];
509 int delete = 0;
509 int local = 0; 510 int local = 0;
510 511
511 leave_raw_mode(); 512 leave_raw_mode();
@@ -515,44 +516,77 @@ process_cmdline(void)
515 goto out; 516 goto out;
516 while (*s && isspace(*s)) 517 while (*s && isspace(*s))
517 s++; 518 s++;
519 if (*s == '-')
520 s++; /* Skip cmdline '-', if any */
518 if (*s == '\0') 521 if (*s == '\0')
519 goto out; 522 goto out;
520 if (strlen(s) < 2 || s[0] != '-' || !(s[1] == 'L' || s[1] == 'R')) { 523
524 if (*s == '?') {
525 logit("Commands:");
526 logit(" -Lport:host:hostport Request local forward");
527 logit(" -Rport:host:hostport Request remote forward");
528 logit(" -KRhostport Cancel remote forward");
529 goto out;
530 }
531
532 if (*s == 'K') {
533 delete = 1;
534 s++;
535 }
536 if (*s != 'L' && *s != 'R') {
521 logit("Invalid command."); 537 logit("Invalid command.");
522 goto out; 538 goto out;
523 } 539 }
524 if (s[1] == 'L') 540 if (*s == 'L')
525 local = 1; 541 local = 1;
526 if (!local && !compat20) { 542 if (local && delete) {
543 logit("Not supported.");
544 goto out;
545 }
546 if ((!local || delete) && !compat20) {
527 logit("Not supported for SSH protocol version 1."); 547 logit("Not supported for SSH protocol version 1.");
528 goto out; 548 goto out;
529 } 549 }
530 s += 2; 550
551 s++;
531 while (*s && isspace(*s)) 552 while (*s && isspace(*s))
532 s++; 553 s++;
533 554
534 if (sscanf(s, "%5[0-9]:%255[^:]:%5[0-9]", 555 if (delete) {
535 sfwd_port, buf, sfwd_host_port) != 3 && 556 if (sscanf(s, "%5[0-9]", sfwd_host_port) != 1) {
536 sscanf(s, "%5[0-9]/%255[^/]/%5[0-9]", 557 logit("Bad forwarding specification.");
537 sfwd_port, buf, sfwd_host_port) != 3) { 558 goto out;
538 logit("Bad forwarding specification."); 559 }
539 goto out; 560 if ((fwd_host_port = a2port(sfwd_host_port)) == 0) {
540 } 561 logit("Bad forwarding port(s).");
541 if ((fwd_port = a2port(sfwd_port)) == 0 || 562 goto out;
542 (fwd_host_port = a2port(sfwd_host_port)) == 0) { 563 }
543 logit("Bad forwarding port(s)."); 564 channel_request_rforward_cancel(fwd_host_port);
544 goto out; 565 } else {
545 } 566 if (sscanf(s, "%5[0-9]:%255[^:]:%5[0-9]",
546 if (local) { 567 sfwd_port, buf, sfwd_host_port) != 3 &&
547 if (channel_setup_local_fwd_listener(fwd_port, buf, 568 sscanf(s, "%5[0-9]/%255[^/]/%5[0-9]",
548 fwd_host_port, options.gateway_ports) < 0) { 569 sfwd_port, buf, sfwd_host_port) != 3) {
549 logit("Port forwarding failed."); 570 logit("Bad forwarding specification.");
550 goto out; 571 goto out;
551 } 572 }
552 } else 573 if ((fwd_port = a2port(sfwd_port)) == 0 ||
553 channel_request_remote_forwarding(fwd_port, buf, 574 (fwd_host_port = a2port(sfwd_host_port)) == 0) {
554 fwd_host_port); 575 logit("Bad forwarding port(s).");
555 logit("Forwarding port."); 576 goto out;
577 }
578 if (local) {
579 if (channel_setup_local_fwd_listener(fwd_port, buf,
580 fwd_host_port, options.gateway_ports) < 0) {
581 logit("Port forwarding failed.");
582 goto out;
583 }
584 } else
585 channel_request_remote_forwarding(fwd_port, buf,
586 fwd_host_port);
587 logit("Forwarding port.");
588 }
589
556out: 590out:
557 signal(SIGINT, handler); 591 signal(SIGINT, handler);
558 enter_raw_mode(); 592 enter_raw_mode();
diff --git a/serverloop.c b/serverloop.c
index a777a048d..8d2642d5b 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -35,7 +35,7 @@
35 */ 35 */
36 36
37#include "includes.h" 37#include "includes.h"
38RCSID("$OpenBSD: serverloop.c,v 1.115 2004/01/19 21:25:15 markus Exp $"); 38RCSID("$OpenBSD: serverloop.c,v 1.116 2004/05/21 11:33:11 djm Exp $");
39 39
40#include "xmalloc.h" 40#include "xmalloc.h"
41#include "packet.h" 41#include "packet.h"
@@ -991,6 +991,17 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt)
991 listen_address, listen_port, options.gateway_ports); 991 listen_address, listen_port, options.gateway_ports);
992 } 992 }
993 xfree(listen_address); 993 xfree(listen_address);
994 } else if (strcmp(rtype, "cancel-tcpip-forward") == 0) {
995 char *cancel_address;
996 u_short cancel_port;
997
998 cancel_address = packet_get_string(NULL);
999 cancel_port = (u_short)packet_get_int();
1000 debug("%s: cancel-tcpip-forward addr %s port %d", __func__,
1001 cancel_address, cancel_port);
1002
1003 success = channel_cancel_rport_listener(cancel_address,
1004 cancel_port);
994 } 1005 }
995 if (want_reply) { 1006 if (want_reply) {
996 packet_start(success ? 1007 packet_start(success ?
diff --git a/ssh.1 b/ssh.1
index b7b126440..7da143b19 100644
--- a/ssh.1
+++ b/ssh.1
@@ -34,7 +34,7 @@
34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36.\" 36.\"
37.\" $OpenBSD: ssh.1,v 1.185 2004/05/02 11:57:52 dtucker Exp $ 37.\" $OpenBSD: ssh.1,v 1.186 2004/05/21 11:33:11 djm Exp $
38.Dd September 25, 1999 38.Dd September 25, 1999
39.Dt SSH 1 39.Dt SSH 1
40.Os 40.Os
@@ -302,11 +302,18 @@ Display a list of escape characters.
302Send a BREAK to the remote system 302Send a BREAK to the remote system
303(only useful for SSH protocol version 2 and if the peer supports it). 303(only useful for SSH protocol version 2 and if the peer supports it).
304.It Cm ~C 304.It Cm ~C
305Open command line (only useful for adding port forwardings using the 305Open command line.
306Currently this allows the addition of port forwardings using the
306.Fl L 307.Fl L
307and 308and
308.Fl R 309.Fl R
309options). 310options (see below).
311It also allows the cancellation of existing remote port-forwardings
312using
313.Fl KR Ar hostport .
314Basic help is available, using the
315.Fl ?
316option.
310.It Cm ~R 317.It Cm ~R
311Request rekeying of the connection 318Request rekeying of the connection
312(only useful for SSH protocol version 2 and if the peer supports it). 319(only useful for SSH protocol version 2 and if the peer supports it).