summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/forwarding.dox162
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
*/