diff options
-rw-r--r-- | doc/forwarding.dox | 162 |
1 files changed, 160 insertions, 2 deletions
diff --git a/doc/forwarding.dox b/doc/forwarding.dox index f6a2869e..5acf1f1b 100644 --- a/doc/forwarding.dox +++ b/doc/forwarding.dox @@ -5,7 +5,7 @@ Port forwarding comes in SSH protocol in two different flavours: direct or reverse port forwarding. Direct port forwarding is also named local port forwardind, and reverse port forwarding is also called -remote port forwarding. +remote port forwarding. SSH also allows X11 tunnels. @@ -58,6 +58,164 @@ In this example, the SSH client establishes the tunnel, but it is used to forward the connections established at the server to the client. -*** To be written *** + +@subsection forwarding_x11 X11 tunnels + +X11 tunnels allow a remote application to display locally. + +Example of use of X11 tunnels: +@verbatim + Local display Graphical application + (X11 server) (X11 client) + ^ | + | V + SSH client <===== SSH server + +Legend: +----->: X11 connection through X11 display number +=====>: SSH tunnel +@endverbatim +The SSH tunnel is established by the client. + +How to establish X11 tunnels with libssh has already been described in +this tutorial. + +@see x11 + + +@subsection libssh_direct Doing direct port forwarding with libssh + +To do direct port forwarding, call function channel_open_forward(): + - you need a separate channel for the tunnel as first parameter; + - second and third parameters are the remote endpoint; + - fourth and fifth parameters are sent to the remote server + so that they can be logged on that server. + +If you don't plan to forward the data you will receive to any local port, +just put fake values like "localhost" and 5555 as your local host and port. + +The example below shows how to open a direct channel that would be +used to retrieve google's home page from the remote SSH server. + +@code +int direct_forwarding(ssh_session session) +{ + ssh_channel forwarding_channel; + int rc; + char *http_get = "GET / HTTP/1.1\nHost: www.google.com\n\n"; + int nbytes, nwritten; + + forwarding_channel = ssh_channel_new(session); + if (rc != SSH_OK) return rc; + + rc = channel_open_forward(forwarding_channel, + "www.google.com", 80, + "localhost", 5555); + if (rc != SSH_OK) + { + ssh_channel_free(forwarding_channel); + return rc; + } + + nbytes = strlen(http_get); + nwritten = channel_write(forwarding_channel, http_get, nbytes); + if (nbytes != nwritten) + { + ssh_channel_free(forwarding_channel); + return SSH_ERROR; + } + + ... + + ssh_channel_free(forwarding_channel); + return SSH_OK; +} +@endcode + +The data sent by Google can be retrieved for example with ssh_select() +and ssh_channel_read(). Goggle's home page can then be displayed on the +local SSH client, saved into a local file, made available on a local port, +or whatever use you have for it. + + +@subsection libssh_reverse Doing reverse port forwarding with libssh + +To do reverse port forwarding, call ssh_channel_forward_listen(), +then ssh_channel_forward_accept(). + +When you call ssh_channel_forward_listen(), you can let the remote server +chose the non-priviledged port it should listen to. Otherwise, you can chose +your own priviledged or non-priviledged port. Beware that you should have +administrative priviledges on the remote server to open a priviledged port +(port number < 1024). + +Below is an example of a very rough web server waiting for connections on port +8080 of remote SSH server. The incoming connections are passed to the +local libssh application, which handles them: + +@code +int web_server(ssh_session session) +{ + int rc; + ssh_channel channel; + char buffer[256]; + int nbytes, nwritten; + char *helloworld = "" +"HTTP/1.1 200 OK\n" +"Content-Type: text/html\n" +"Content-Length: 113\n" +"\n" +"<html>\n" +" <head>\n" +" <title>Hello, World!</title>\n" +" </head>\n" +" <body>\n" +" <h1>Hello, World!</h1>\n" +" </body>\n" +"</html>\n"; + + rc = ssh_channel_forward_listen(session, NULL, 8080, NULL); + if (rc != SSH_OK) + { + fprintf(stderr, "Error opening remote port: %s\n", ssh_get_error(session)); + return rc; + } + + channel = ssh_channel_forward_accept(session, 60000); + if (channel == NULL) + { + fprintf(stderr, "Error waiting for incoming connection: %s\n", ssh_get_error(session)); + return SSH_ERROR; + } + + while (1) + { + nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0); + if (nbytes < 0) + { + fprintf(stderr, "Error reading incoming data: %s\n", ssh_get_error(session)); + ssh_channel_send_eof(channel); + ssh_channel_free(channel); + return SSH_ERROR; + } + if (strncmp(buffer, "GET /", 5)) continue; + + nbytes = strlen(helloworld); + nwritten = ssh_channel_write(channel, helloworld, nbytes); + if (nwritten != nbytes) + { + fprintf(stderr, "Error sending answer: %s\n", ssh_get_error(session)); + ssh_channel_send_eof(channel); + ssh_channel_free(channel); + return SSH_ERROR; + } + printf("Sent answer\n"); + } + + ssh_channel_send_eof(channel); + ssh_channel_free(channel); + return SSH_OK; +} +@endcode */ |