LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   C coding: Hacking ssh: dynamic local port forwarding implementation? (http://www.linuxquestions.org/questions/programming-9/c-coding-hacking-ssh-dynamic-local-port-forwarding-implementation-786608/)

Web31337 02-03-2010 03:48 AM

C coding: Hacking ssh: dynamic local port forwarding implementation?
 
From this thread I've decided to try add a feature of removing local port forwardings in ssh.
Here are some very ugly and not-yet working hacks what I made so far:

* Patch for channels.c
* Patch for channels.h
* Patch for clientloop.c

Apply these to sources of 5.3p1( http://ftp.arcane-networks.fr/pub/Op...h-5.3p1.tar.gz ), MD5 13563dbf61f36ca9a1e4254260131041
I was clearly expecting this to work without any troubles-everything seem to be logically correct, but I made a programming mistake somewhere: don't know where, maybe you will point me to this?
Many sites say there is a WAY AROUND with -D param(starting socks proxy as a tunnel-generator), added since 5.2, but I don't need that way around. I need a way through. I use exact ports for exact services and if I want to change it runtime I'd like to have ability to do so.
If you have other ideas or points instead of coding this, please share them here & here(original question).

Here is what I get so far when I run rebuilt ./ssh -vvv root@fs:
Code:

<snip>
root@fs:~#
ssh> -L10222:127.0.0.1:80
debug3: channel_setup_fwd_listener: type 2 wildcard 0 addr NULL
debug1: Local forwarding listening on 127.0.0.1 port 10222.
debug2: fd 7 setting O_NONBLOCK
debug3: fd 7 is O_NONBLOCK
debug1: channel 1: new [port listener]
socket: Address family not supported by protocol
Forwarding port.
debug3: Wrote 48 bytes for a total of 2821

root@fs:~#
ssh> -KL10222
debug3: Attempting to remove local forwarding... /* added by me in patch */
debug3: Total channels: 10 /* added by me in patch */
Segmentation fault

Anyone who is interested to help, please post back. Right now I still have no solution for this. Probably I'll put it somewhere out of sight for a while if noone will reply today. This is one of my first programming experiments under linux so I don't know many things. Thanks for help.

Web31337 02-03-2010 05:48 AM

Wait... looks like I fixed it. The problem was with line 2660 of a patched channels.c: if we comment host it works.
Code:

/*strcmp(c->path, host) == 0 &&*/
more details and complete fix a bit later.
I can't really guarantee this is going to work without memory leaks: I am not sure it really frees everything but it's made as in same rport function.
here is what it issues now(running ./ssh -vvv root@fs, port 80 on fs is nginx webserver):
Code:

<debug output skipped>
root@fs:~#
ssh> -L10222:127.0.0.1:80
debug3: channel_setup_fwd_listener: type 2 wildcard 0 addr NULL
debug1: Local forwarding listening on 127.0.0.1 port 10222.
debug2: fd 7 setting O_NONBLOCK
debug3: fd 7 is O_NONBLOCK
debug1: channel 1: new [port listener]
socket: Address family not supported by protocol
Forwarding port.
debug3: Wrote 48 bytes for a total of 2917

Testing forwarding to nginx with nc and simple request, manually entered:
Code:

afkhaxor@srvr:~$ nc 127.0.0.1 10222
GET / HTTP/1.0
Host: fs

HTTP/1.1 200 OK
Server: nginx
Date: Wed, 03 Feb 2010 10:42:51 GMT
Content-Type: text/html; charset=utf-8
Connection: close

<html>
<head><title>Index of /</title></head>
<body bgcolor="white">
<h1>Index of /</h1><hr><pre><a href="../">../</a>
<a href="test.py">test.py</a>                                            10-Oct-2009 13:41                2866
</pre><hr></body>
</html>

Dropping port 10222 forward:
Code:

<debug output from forwarding skipped>
root@fs:~#
ssh> -KL10222
debug3: Attempting to remove local forwarding...
debug3: Total channels: 10
debug2: channel_cancel_lport_listener: close channel 1
debug1: channel 1: free: port listener, nchannels 2
debug3: channel 1: status: The following connections are open:
  #0 client-session (t4 r0 i0/0 o0/0 fd 4/5 cfd -1)

debug3: channel 1: close_fds r 7 w 7 e -1 c -1

And ensuring port is gone:
Code:

afkhaxor@srvr:~$ nc 127.0.0.1 10222
(UNKNOWN) [127.0.0.1] 10222 (?) : Connection refused

Port is not listened anymore. I can also request yet another forwarding on the same port after I cancelled it again and it works.
No segfaults now.
I'll post full patches a bit later here and in original question when I will finally get that to work.
--upd:
It also works well with cancellation of forwarding 10222 to 127.0.0.1:80 and reforwarding it then to 192.0.32.10:80 (example.org IP) and correctly addresses traffic to example.org after it.

Web31337 02-03-2010 07:05 AM

Patch released
 
So, after some tests it looks like I did that.
By using option -KL while running you can remove local tunnel now. By using -L again you can forward freed port to another destination.
Grab patches for 5.3p1 sources(this must only be applied to 5.3p1 version from official OpenSSH site, other versions may not work): http://stat.web31337.org/etc/openssh-patch/

Direct links for files:
* channels.c.patch
* channels.h.patch
* clientloop.c.patch
* MD5 sum | SHA1 sum

Apply patches for each file:
Code:

if you fetched patches already with wget:
$ patch channels.c channels.c.patch
or if you want to apply it directly:
$ curl http://stat.web31337.org/etc/openssh-patch/channels.c.patch | patch channels.c

Please notice the solution is NOT for production-stable environment. It most probably will also fail on removing local tunnels with specifying bind address. It has not been tested against multi-interfaces. Future help with adding this is most welcome! Probably, I won't release it soon but I'll dig into it later.
WARNING: I do not guarantee this solution will work 100% for you, as well as I do not guarantee it won't cause any damage(physical or virtual). USE AT YOUR OWN RISK!

I don't also guarantee this solution is unique, but still, googling a bit does not give me anything but -D parameter as a way around. I see no way to remove tunnel while connected. That's why I tried to implement it myself.


All times are GMT -5. The time now is 02:36 PM.