diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | channels.c | 67 | ||||
-rw-r--r-- | channels.h | 4 | ||||
-rw-r--r-- | clientloop.c | 84 | ||||
-rw-r--r-- | serverloop.c | 13 | ||||
-rw-r--r-- | ssh.1 | 13 |
6 files changed, 153 insertions, 35 deletions
@@ -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 | ||
14 | 20040523 | 19 | 20040523 |
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" |
42 | RCSID("$OpenBSD: channels.c,v 1.201 2004/05/11 19:01:43 deraadt Exp $"); | 42 | RCSID("$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 | ||
2231 | int | ||
2232 | channel_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) */ |
2232 | int | 2252 | int |
2233 | channel_setup_local_fwd_listener(u_short listen_port, | 2253 | channel_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 | |||
2332 | void | ||
2333 | channel_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); | |||
200 | int channel_connect_to(const char *, u_short); | 200 | int channel_connect_to(const char *, u_short); |
201 | int channel_connect_by_listen_address(u_short); | 201 | int channel_connect_by_listen_address(u_short); |
202 | void channel_request_remote_forwarding(u_short, const char *, u_short); | 202 | void channel_request_remote_forwarding(u_short, const char *, u_short); |
203 | void channel_request_rforward_cancel(u_short port); | ||
203 | int channel_setup_local_fwd_listener(u_short, const char *, u_short, int); | 204 | int channel_setup_local_fwd_listener(u_short, const char *, u_short, int); |
204 | int channel_setup_remote_fwd_listener(const char *, u_short, int); | 205 | int channel_setup_remote_fwd_listener(const char *, u_short, int); |
206 | int 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" |
62 | RCSID("$OpenBSD: clientloop.c,v 1.120 2004/05/20 10:58:05 dtucker Exp $"); | 62 | RCSID("$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 | |||
556 | out: | 590 | out: |
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" |
38 | RCSID("$OpenBSD: serverloop.c,v 1.115 2004/01/19 21:25:15 markus Exp $"); | 38 | RCSID("$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 ? |
@@ -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. | |||
302 | Send a BREAK to the remote system | 302 | Send 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 |
305 | Open command line (only useful for adding port forwardings using the | 305 | Open command line. |
306 | Currently this allows the addition of port forwardings using the | ||
306 | .Fl L | 307 | .Fl L |
307 | and | 308 | and |
308 | .Fl R | 309 | .Fl R |
309 | options). | 310 | options (see below). |
311 | It also allows the cancellation of existing remote port-forwardings | ||
312 | using | ||
313 | .Fl KR Ar hostport . | ||
314 | Basic help is available, using the | ||
315 | .Fl ? | ||
316 | option. | ||
310 | .It Cm ~R | 317 | .It Cm ~R |
311 | Request rekeying of the connection | 318 | Request 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). |