Sophie

Sophie

distrib > Fedora > 18 > i386 > by-pkgid > ee8fafc31a7ba3ce3ae4499cedf4e1bc > files > 92

libssh-devel-0.5.5-1.fc18.i686.rpm

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.3.1"/>
<title>libssh: Chapter 7: Forwarding connections (tunnel)</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td style="padding-left: 0.5em;">
   <div id="projectname">libssh
   &#160;<span id="projectnumber">0.5.5</span>
   </div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.3.1 -->
  <div id="navrow1" class="tabs">
    <ul class="tablist">
      <li><a href="index.html"><span>Main&#160;Page</span></a></li>
      <li class="current"><a href="pages.html"><span>Related&#160;Pages</span></a></li>
      <li><a href="modules.html"><span>Modules</span></a></li>
      <li><a href="annotated.html"><span>Data&#160;Structures</span></a></li>
      <li><a href="files.html"><span>Files</span></a></li>
    </ul>
  </div>
<div id="nav-path" class="navpath">
  <ul>
<li class="navelem"><a class="el" href="index.html">index</a></li><li class="navelem"><a class="el" href="libssh_tutorial.html">The Tutorial</a></li>  </ul>
</div>
</div><!-- top -->
<div class="header">
  <div class="headertitle">
<div class="title">Chapter 7: Forwarding connections (tunnel) </div>  </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><h1><a class="anchor" id="forwarding_connections"></a>
Forwarding connections</h1>
<p>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. SSH also allows X11 tunnels.</p>
<h2><a class="anchor" id="forwarding_direct"></a>
Direct port forwarding</h2>
<p>Direct port forwarding is from client to server. The client opens a tunnel, and forwards whatever data to the server. Then, the server connects to an end point. The end point can reside on another machine or on the SSH server itself.</p>
<p>Example of use of direct port forwarding: </p>
<pre class="fragment">Mail client application   Google Mail
         |                    ^
     5555 (arbitrary)         |
         |                143 (IMAP2)
         V                    |
    SSH client   =====&gt;   SSH server 

Legend:
--P--&gt;: port connexion through port P
=====&gt;: SSH tunnel
</pre><p> A mail client connects to port 5555 of a client. An encrypted tunnel is established to the server. The server connects to port 143 of Google Mail (the end point). Now the local mail client can retreive mail.</p>
<h2><a class="anchor" id="forwarding_reverse"></a>
Reverse port forwarding</h2>
<p>The reverse forwarding is slightly different. It goes from server to client, even though the client has the initiative of establishing the tunnel. Once the tunnel is established, the server will listen on a port. Whenever a connection to this port is made, the server forwards the data to the client.</p>
<p>Example of use of reverse port forwarding: </p>
<pre class="fragment"> Local mail server    Mail client application
         ^                     |
         |               5555 (arbitrary)
     143 (IMAP2)               |
         |                     V
    SSH client   &lt;=====   SSH server

Legend:
--P--&gt;: port connexion through port P
=====&gt;: SSH tunnel
</pre><p> In this example, the SSH client establishes the tunnel, but it is used to forward the connections established at the server to the client.</p>
<h2><a class="anchor" id="forwarding_x11"></a>
X11 tunnels</h2>
<p>X11 tunnels allow a remote application to display locally.</p>
<p>Example of use of X11 tunnels: </p>
<pre class="fragment">   Local display     Graphical application
   (X11 server)          (X11 client)
         ^                     |
         |                     V
    SSH client   &lt;=====   SSH server

Legend:
-----&gt;: X11 connection through X11 display number
=====&gt;: SSH tunnel
</pre><p> The SSH tunnel is established by the client.</p>
<p>How to establish X11 tunnels with libssh has already been described in this tutorial.</p>
<dl class="section see"><dt>See Also</dt><dd>x11</dd></dl>
<h2><a class="anchor" id="libssh_direct"></a>
Doing direct port forwarding with libssh</h2>
<p>To do direct port forwarding, call function channel_open_forward():</p>
<ul>
<li>you need a separate channel for the tunnel as first parameter;</li>
<li>second and third parameters are the remote endpoint;</li>
<li>fourth and fifth parameters are sent to the remote server so that they can be logged on that server.</li>
</ul>
<p>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.</p>
<p>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.</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span> direct_forwarding(ssh_session session)</div>
<div class="line">{</div>
<div class="line">  ssh_channel forwarding_channel;</div>
<div class="line">  <span class="keywordtype">int</span> rc;</div>
<div class="line">  <span class="keywordtype">char</span> *http_get = <span class="stringliteral">&quot;GET / HTTP/1.1\nHost: www.google.com\n\n&quot;</span>;</div>
<div class="line">  <span class="keywordtype">int</span> nbytes, nwritten;</div>
<div class="line"></div>
<div class="line">  forwarding_channel = <a class="code" href="group__libssh__channel.html#gada8ccda7bf65165fe145d3096a252dcc" title="Allocate a new channel.">ssh_channel_new</a>(session);</div>
<div class="line">  <span class="keywordflow">if</span> (rc != SSH_OK) <span class="keywordflow">return</span> rc;</div>
<div class="line"></div>
<div class="line">  rc = channel_open_forward(forwarding_channel,</div>
<div class="line">                            <span class="stringliteral">&quot;www.google.com&quot;</span>, 80,</div>
<div class="line">                            <span class="stringliteral">&quot;localhost&quot;</span>, 5555);</div>
<div class="line">  <span class="keywordflow">if</span> (rc != SSH_OK)</div>
<div class="line">  {</div>
<div class="line">    <a class="code" href="group__libssh__channel.html#gad1417f9eae8928fed20faafe2d9dbfff" title="Close and free a channel.">ssh_channel_free</a>(forwarding_channel);</div>
<div class="line">    <span class="keywordflow">return</span> rc;</div>
<div class="line">  }</div>
<div class="line"></div>
<div class="line">  nbytes = strlen(http_get);</div>
<div class="line">  nwritten = channel_write(forwarding_channel, http_get, nbytes);</div>
<div class="line">  <span class="keywordflow">if</span> (nbytes != nwritten)</div>
<div class="line">  {</div>
<div class="line">    <a class="code" href="group__libssh__channel.html#gad1417f9eae8928fed20faafe2d9dbfff" title="Close and free a channel.">ssh_channel_free</a>(forwarding_channel);</div>
<div class="line">    <span class="keywordflow">return</span> SSH_ERROR;</div>
<div class="line">  }</div>
<div class="line"></div>
<div class="line">  ...</div>
<div class="line"></div>
<div class="line">  <a class="code" href="group__libssh__channel.html#gad1417f9eae8928fed20faafe2d9dbfff" title="Close and free a channel.">ssh_channel_free</a>(forwarding_channel);</div>
<div class="line">  <span class="keywordflow">return</span> SSH_OK;</div>
<div class="line">}</div>
</div><!-- fragment --><p>The data sent by Google can be retrieved for example with <a class="el" href="group__libssh__session.html#ga86cbf041bced56d18a2a5248c46cecb4" title="A wrapper for the select syscall.">ssh_select()</a> and <a class="el" href="group__libssh__channel.html#gac92381c4c5d4a7eab35f6e84686f033d" title="Reads data from a channel.">ssh_channel_read()</a>. 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.</p>
<h2><a class="anchor" id="libssh_reverse"></a>
Doing reverse port forwarding with libssh</h2>
<p>To do reverse port forwarding, call ssh_channel_forward_listen(), then ssh_channel_forward_accept().</p>
<p>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 &lt; 1024).</p>
<p>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:</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span> web_server(ssh_session session)</div>
<div class="line">{</div>
<div class="line">  <span class="keywordtype">int</span> rc;</div>
<div class="line">  ssh_channel channel;</div>
<div class="line">  <span class="keywordtype">char</span> buffer[256];</div>
<div class="line">  <span class="keywordtype">int</span> nbytes, nwritten;</div>
<div class="line">  <span class="keywordtype">char</span> *helloworld = <span class="stringliteral">&quot;&quot;</span></div>
<div class="line"><span class="stringliteral">&quot;HTTP/1.1 200 OK\n&quot;</span></div>
<div class="line"><span class="stringliteral">&quot;Content-Type: text/html\n&quot;</span></div>
<div class="line"><span class="stringliteral">&quot;Content-Length: 113\n&quot;</span></div>
<div class="line"><span class="stringliteral">&quot;\n&quot;</span></div>
<div class="line"><span class="stringliteral">&quot;&lt;html&gt;\n&quot;</span></div>
<div class="line"><span class="stringliteral">&quot;  &lt;head&gt;\n&quot;</span></div>
<div class="line"><span class="stringliteral">&quot;    &lt;title&gt;Hello, World!&lt;/title&gt;\n&quot;</span></div>
<div class="line"><span class="stringliteral">&quot;  &lt;/head&gt;\n&quot;</span></div>
<div class="line"><span class="stringliteral">&quot;  &lt;body&gt;\n&quot;</span></div>
<div class="line"><span class="stringliteral">&quot;    &lt;h1&gt;Hello, World!&lt;/h1&gt;\n&quot;</span></div>
<div class="line"><span class="stringliteral">&quot;  &lt;/body&gt;\n&quot;</span></div>
<div class="line"><span class="stringliteral">&quot;&lt;/html&gt;\n&quot;</span>;</div>
<div class="line"></div>
<div class="line">  rc = ssh_channel_forward_listen(session, NULL, 8080, NULL);</div>
<div class="line">  <span class="keywordflow">if</span> (rc != SSH_OK)</div>
<div class="line">  {</div>
<div class="line">    fprintf(stderr, <span class="stringliteral">&quot;Error opening remote port: %s\n&quot;</span>, <a class="code" href="group__libssh__error.html#ga9241586665bf21f823806473fc386258" title="Retrieve the error text message from the last error.">ssh_get_error</a>(session));</div>
<div class="line">    <span class="keywordflow">return</span> rc;</div>
<div class="line">  }</div>
<div class="line"></div>
<div class="line">  channel = ssh_channel_forward_accept(session, 60000);</div>
<div class="line">  <span class="keywordflow">if</span> (channel == NULL)</div>
<div class="line">  {</div>
<div class="line">    fprintf(stderr, <span class="stringliteral">&quot;Error waiting for incoming connection: %s\n&quot;</span>, <a class="code" href="group__libssh__error.html#ga9241586665bf21f823806473fc386258" title="Retrieve the error text message from the last error.">ssh_get_error</a>(session));</div>
<div class="line">    <span class="keywordflow">return</span> SSH_ERROR;</div>
<div class="line">  }</div>
<div class="line"></div>
<div class="line">  <span class="keywordflow">while</span> (1)</div>
<div class="line">  {</div>
<div class="line">    nbytes = <a class="code" href="group__libssh__channel.html#gac92381c4c5d4a7eab35f6e84686f033d" title="Reads data from a channel.">ssh_channel_read</a>(channel, buffer, <span class="keyword">sizeof</span>(buffer), 0);</div>
<div class="line">    <span class="keywordflow">if</span> (nbytes &lt; 0)</div>
<div class="line">    {</div>
<div class="line">      fprintf(stderr, <span class="stringliteral">&quot;Error reading incoming data: %s\n&quot;</span>, <a class="code" href="group__libssh__error.html#ga9241586665bf21f823806473fc386258" title="Retrieve the error text message from the last error.">ssh_get_error</a>(session));</div>
<div class="line">      <a class="code" href="group__libssh__channel.html#ga072f82fdf3e50514f747653af2c99004" title="Send an end of file on the channel.">ssh_channel_send_eof</a>(channel);</div>
<div class="line">      <a class="code" href="group__libssh__channel.html#gad1417f9eae8928fed20faafe2d9dbfff" title="Close and free a channel.">ssh_channel_free</a>(channel);</div>
<div class="line">      <span class="keywordflow">return</span> SSH_ERROR;</div>
<div class="line">    }</div>
<div class="line">    <span class="keywordflow">if</span> (strncmp(buffer, <span class="stringliteral">&quot;GET /&quot;</span>, 5)) <span class="keywordflow">continue</span>;</div>
<div class="line"></div>
<div class="line">    nbytes = strlen(helloworld);</div>
<div class="line">    nwritten = <a class="code" href="group__libssh__channel.html#ga5d658df773ba854b35ff9f905341e2fb" title="Blocking write on a channel.">ssh_channel_write</a>(channel, helloworld, nbytes);</div>
<div class="line">    <span class="keywordflow">if</span> (nwritten != nbytes)</div>
<div class="line">    {</div>
<div class="line">      fprintf(stderr, <span class="stringliteral">&quot;Error sending answer: %s\n&quot;</span>, <a class="code" href="group__libssh__error.html#ga9241586665bf21f823806473fc386258" title="Retrieve the error text message from the last error.">ssh_get_error</a>(session));</div>
<div class="line">      <a class="code" href="group__libssh__channel.html#ga072f82fdf3e50514f747653af2c99004" title="Send an end of file on the channel.">ssh_channel_send_eof</a>(channel);</div>
<div class="line">      <a class="code" href="group__libssh__channel.html#gad1417f9eae8928fed20faafe2d9dbfff" title="Close and free a channel.">ssh_channel_free</a>(channel);</div>
<div class="line">      <span class="keywordflow">return</span> SSH_ERROR;</div>
<div class="line">    }</div>
<div class="line">    printf(<span class="stringliteral">&quot;Sent answer\n&quot;</span>);</div>
<div class="line">  }</div>
<div class="line"></div>
<div class="line">  <a class="code" href="group__libssh__channel.html#ga072f82fdf3e50514f747653af2c99004" title="Send an end of file on the channel.">ssh_channel_send_eof</a>(channel);</div>
<div class="line">  <a class="code" href="group__libssh__channel.html#gad1417f9eae8928fed20faafe2d9dbfff" title="Close and free a channel.">ssh_channel_free</a>(channel);</div>
<div class="line">  <span class="keywordflow">return</span> SSH_OK;</div>
<div class="line">}</div>
</div><!-- fragment --> </div></div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.3.1
</small></address>
</body>
</html>