fixunix
Tags Register FAQ Members List Social Groups Calendar Search Today's Posts Mark Forums Read

[PATCH] controlling remote port forwarding over control path - openssh

This is a discussion on [PATCH] controlling remote port forwarding over control path - openssh ; --===============0234808608== Content-Type: multipart/signed; boundary="nextPart1582234.e5pSDGogY4"; protocol="application/pgp-signature"; micalg=pgp-sha1 Content-Transfer-Encoding: 7bit --nextPart1582234.e5pSDGogY4 Content-Type: multipart/mixed; boundary="Boundary-01=_vrJKC0d+bgNBy7e" Content-Transfer-Encoding: 7bit Content-Disposition: inline --Boundary-01=_vrJKC0d+bgNBy7e Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline Hi, the attached patch implements adding and canceling of remote port forwardings by communicating with a ...


Fix Unix > Tools > openssh > [PATCH] controlling remote port forwarding over control path

Reply
 
LinkBack Tools
  #1  
Old 10-08-2007, 12:43 AM
Junior Member
 
Join Date: Sep 2009
Posts: 0
Default [PATCH] controlling remote port forwarding over control path

--===============0234808608==
Content-Type: multipart/signed; boundary="nextPart1582234.e5pSDGogY4";
protocol="application/pgp-signature"; micalg=pgp-sha1
Content-Transfer-Encoding: 7bit

--nextPart1582234.e5pSDGogY4
Content-Type: multipart/mixed;
boundary="Boundary-01=_vrJKC0d+bgNBy7e"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

--Boundary-01=_vrJKC0d+bgNBy7e
Content-Type: text/plain;
charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

Hi,

the attached patch implements adding and canceling of remote port
forwardings by communicating with a running ssh client via a control
socket.

Thus, one can do this:

ssh -MNfS ~/.ssh/ctl remotehost

and then:

ssh -S ~/.ssh/ctl -O add-rforward 2000:forward:80 localhost

to add a new remote forwarding or

ssh -S ~/.ssh/ctl -O cancel-rforward localhost:2000 localhost

to remove it.

The patch is against openssh-SNAP-20050302 so the new fine tuned=20
forwarding code is already contained.


While working on the patch a few questions/inconveniences have emerged:

1) why is mux_command in ssh.c not part of Options?

2) the current implementation allows -O to occur only once. So, to add=20
or remove multiple channels ssh has to be called multiple times. Would=20
it make sense to extend the code to allow it to occur multiple times?

ssh -S ~/.ssh/ctl \
-O add-rforward 2000:forward:80 \
-O add-rforward 2001:forward:80 \
localhost

3) permitted_opens in channels.c is a real problem. The current code=20
allocates a new element from the end of this array while adding a new=20
forwarding. But when the forwarding is cancelled the element is not=20
really freed. It is marked somehow to be not in use but the current=20
code cannot reuse it.

4) again permitted_opens. channel_request_rforward_cancel() identifies=20
the local side of a forwarding only by=20
permitted_opens[i].host_to_connect and permitted_opens[i].listen_port.=20
Since a forwarding is really a quadruple this looks a little fragile to=20
me. In fact you can try to remove a forwarding by specifying only a=20
port number

ssh -S ~/.ssh/ctl -O cancel-rforward 2000 localhost

This matches an element of permitted_opens and resets it but it does not=20
match an open channel at the server side. So the listening socket is=20
not closed. Now when someone tries to connect to that port the server=20
forwards the connection to the client. Here it does not match an=20
element of permitted_opens. Hence

WARNING: Server requests forwarding for unknown listen_port 2000

is printed and the connection is closed.

I have not yet changed this behaviour because it is the same code that=20
is used when adding or canceling forwardings with the ssh command line=20
("~C", then "-R2000:forward:80", then "~C", then "-KR2000" yields the=20
same result). But I think it's rather a bug than a feature.

Doesn't it make more sense to represent forwardings as quadruples=20
(remotehost, remoteport, localhost, localport) also at the client side?

5) I think I have to implement -O add-lforward and -O cancel-lforward,=20
too.

6) Also -O list-forwards would be useful, wouldn't it?

Torsten

--Boundary-01=_vrJKC0d+bgNBy7e
Content-Type: text/x-diff;
charset="us-ascii";
name="openssh.patch"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="openssh.patch"

diff -Naur openssh/clientloop.c openssh.new/clientloop.c
=2D-- openssh/clientloop.c 2005-03-01 11:24:33.000000000 +0100
+++ openssh.new/clientloop.c 2005-03-04 15:45:19.950645565 +0100
@@ -551,6 +551,21 @@
xfree(cctx);
}
=20
+static inline int
+client_process_control_answer( Buffer *m, int allowed, int client_fd )
+{
+ buffer_clear(m);
+ buffer_put_int(m, allowed);
+ buffer_put_int(m, getpid());
+ if (ssh_msg_send(client_fd, /* version */1, m) =3D=3D -1) {
+ error("%s: client msg_send failed", __func__);
+ close(client_fd);
+ buffer_free(m);
+ return -1;
+ }
+ return 0;
+}
+
static void
client_process_control(fd_set * readset)
{
@@ -564,6 +579,7 @@
u_int len, env_len, command, flags;
uid_t euid;
gid_t egid;
+ char *command_arg;
=20
/*
* Accept connection on control socket
@@ -611,6 +627,7 @@
allowed =3D 1;
command =3D buffer_get_int(&m);
flags =3D buffer_get_int(&m);
+ command_arg=3Dbuffer_get_string(&m, 0);
=20
buffer_clear(&m);
=20
@@ -630,14 +647,49 @@
/* FALLTHROUGH */=09
case SSHMUX_COMMAND_ALIVE_CHECK:
/* Reply for SSHMUX_COMMAND_TERMINATE and ALIVE_CHECK */
=2D buffer_clear(&m);
=2D buffer_put_int(&m, allowed);
=2D buffer_put_int(&m, getpid());
=2D if (ssh_msg_send(client_fd, /* version */1, &m) =3D=3D -1) {
=2D error("%s: client msg_send failed", __func__);
=2D close(client_fd);
=2D buffer_free(&m);
+ if( client_process_control_answer(&m, allowed, client_fd) )
+ return;
+ buffer_free(&m);
+ close(client_fd);
+ return;
+ case SSHMUX_COMMAND_RFADD:
+ debug2("%s: RFADD: %s", __func__, command_arg);
+ if( client_process_control_answer(&m, allowed, client_fd) )
+ return;
+ {
+ Forward fwd;
+ if (parse_forward(&fwd, command_arg))
+ channel_request_remote_forwarding
+ (fwd.listen_host, fwd.listen_port,
+ fwd.connect_host, fwd.connect_port);
+ else
+ logit("Bad forwarding specification.");
+ }
+ buffer_free(&m);
+ close(client_fd);
+ return;
+ case SSHMUX_COMMAND_RFCANCEL:
+ debug2("%s: RFCANCEL: %s", __func__, command_arg);
+ if( client_process_control_answer(&m, allowed, client_fd) )
return;
+ {
+ int cancel_port =3D 0;
+ char *cancel_host =3D hpdelim(&command_arg);
+ if (command_arg !=3D NULL) {
+ cancel_port =3D a2port(command_arg);
+ cancel_host =3D cleanhostname(cancel_host);
+ } else {
+ cancel_port =3D a2port(cancel_host);
+ cancel_host =3D NULL;
+ }
+ if (cancel_port =3D=3D 0) {
+ logit("Bad forwarding close port");
+ buffer_free(&m);
+ close(client_fd);
+ return;
+ }
+ channel_request_rforward_cancel(cancel_host,
+ cancel_port);
}
buffer_free(&m);
close(client_fd);
@@ -650,15 +702,8 @@
}
=20
/* Reply for SSHMUX_COMMAND_OPEN */
=2D buffer_clear(&m);
=2D buffer_put_int(&m, allowed);
=2D buffer_put_int(&m, getpid());
=2D if (ssh_msg_send(client_fd, /* version */1, &m) =3D=3D -1) {
=2D error("%s: client msg_send failed", __func__);
=2D close(client_fd);
=2D buffer_free(&m);
+ if( client_process_control_answer(&m, allowed, client_fd) )
return;
=2D }
=20
if (!allowed) {
error("Refused control connection");
diff -Naur openssh/clientloop.h openssh.new/clientloop.h
=2D-- openssh/clientloop.h 2004-11-07 10:06:19.000000000 +0100
+++ openssh.new/clientloop.h 2005-03-04 14:18:24.368906053 +0100
@@ -45,6 +45,8 @@
#define SSHMUX_COMMAND_OPEN 1 /* Open new connection */
#define SSHMUX_COMMAND_ALIVE_CHECK 2 /* Check master is alive */
#define SSHMUX_COMMAND_TERMINATE 3 /* Ask master to exit */
+#define SSHMUX_COMMAND_RFADD 4 /* Add remote forward */
+#define SSHMUX_COMMAND_RFCANCEL 5 /* Cancel remote forward */
=20
#define SSHMUX_FLAG_TTY (1) /* Request tty on open */
#define SSHMUX_FLAG_SUBSYS (1<<1) /* Subsystem request on open */
diff -Naur openssh/ssh.c openssh.new/ssh.c
=2D-- openssh/ssh.c 2005-03-01 11:24:34.000000000 +0100
+++ openssh.new/ssh.c 2005-03-04 15:43:08.122712179 +0100
@@ -146,6 +146,7 @@
=20
/* Multiplexing control command */
static u_int mux_command =3D SSHMUX_COMMAND_OPEN;
+static char *mux_command_arg=3D"";
=20
/* Only used in control client mode */
volatile sig_atomic_t control_client_terminate =3D 0;
@@ -279,7 +280,13 @@
mux_command =3D SSHMUX_COMMAND_ALIVE_CHECK;
else if (strcmp(optarg, "exit") =3D=3D 0)
mux_command =3D SSHMUX_COMMAND_TERMINATE;
=2D else
+ else if (strcmp(optarg, "add-rforward") =3D=3D 0) {
+ mux_command =3D SSHMUX_COMMAND_RFADD;
+ mux_command_arg=3Dav[optind++];
+ } else if (strcmp(optarg, "cancel-rforward") =3D=3D 0) {
+ mux_command =3D SSHMUX_COMMAND_RFCANCEL;
+ mux_command_arg=3Dav[optind++];
+ } else
fatal("Invalid multiplex command.");
break;
case 'P': /* deprecated */
@@ -1326,6 +1333,7 @@
/* Send our command to server */
buffer_put_int(&m, mux_command);
buffer_put_int(&m, flags);
+ buffer_put_cstring(&m, mux_command_arg);
if (ssh_msg_send(sock, /* version */1, &m) =3D=3D -1)
fatal("%s: msg_send", __func__);
buffer_clear(&m);
@@ -1349,6 +1357,12 @@
case SSHMUX_COMMAND_TERMINATE:
fprintf(stderr, "Exit request sent.\r\n");
exit(0);
+ case SSHMUX_COMMAND_RFADD:
+ fprintf(stderr, "Add request sent.\r\n");
+ exit(0);
+ case SSHMUX_COMMAND_RFCANCEL:
+ fprintf(stderr, "Cancel request sent.\r\n");
+ exit(0);
case SSHMUX_COMMAND_OPEN:
/* continue below */
break;

--Boundary-01=_vrJKC0d+bgNBy7e--

--nextPart1582234.e5pSDGogY4
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.5 (GNU/Linux)

iD8DBQBCKJrzwicyCTir8T4RAv1RAJwKUlqCXK9q++mf3V0Puu vcirCCBgCfTv59
9GR8AxYaeLWTgqgCUUZ3J9M=
=TdKG
-----END PGP SIGNATURE-----

--nextPart1582234.e5pSDGogY4--


--===============0234808608==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
http://www.mindrot.org/mailman/listi...enssh-unix-dev

--===============0234808608==--

Reply With Quote
Reply

Tools


Similar Threads
Thread Thread Starter Forum Replies Last Post
Warning: remote port forwarding failed for listen port 4043 unix SSH 1 10-10-2007 05:00 AM
External port forwarding control mechanism unix openssh 0 10-08-2007 01:08 AM
Re: [PATCH] controlling remote port forwarding over control path unix openssh 0 10-08-2007 12:43 AM
Re: [PATCH] controlling remote port forwarding over control path unix openssh 0 10-08-2007 12:43 AM
Re: [PATCH] controlling remote port forwarding over control path unix openssh 0 10-08-2007 12:43 AM


All times are GMT. The time now is 08:35 AM.