libssh2通道SSL BIO用法

时间:2010-06-18 13:15:16

标签: c ssl openssl libssh

我正在为自己的娱乐写一个小的ftp项目,假设能做4件事:

  1. 直接连接到ftp
  2. 使用SSL(包装器)直接连接到ftp
  3. 通过ssh隧道连接到ftp
  4. 通过ssh隧道连接到带有SSL的ftp。
  5. 我正在使用标准库1和2编写我的程序in plain C(unix,在这种情况下并不重要),使用libssh2 for 3和4以及OpenSSL for 2和4。

    我能够1-3工作,但不能4.这就是我所在的地方:

    1. 通过打开套接字来完成主机:端口,连接,写入/读取套接字。
    2. 通过打开一个socket到host:port,连接,编写“AUTH SSL”,从前一个套接字启动一个带有BIO的SSL对象 - > SSL_connect(),SSL_read(),SSL_write()。
    3. 通过打开目标和localhost之间的隧道来完成(虽然我不确定我在我的方法中使用的是localhost绑定:)
    4. 类似的东西:

      test_ssh_channel = libssh2_channel_direct_tcpip_ex(test_ssh_session, "100.100.100.100", 21, "127.0.0.1", 21);
      

      然后我写入/读取该通道(libssh2_channel_read()) - 正如我所看到的,它给出了以下流程: 纯文本 - >通过ssh发送 - >从ssh主机传送纯文本到目标。 为了3.这很好并且完成了工作。

      现在,对于4.我被卡住,因为我(试图保持简单)需要以某种方式将此频道转换为套接字。所以我看到它的方式有两个选择:

      • 一个。做一个伪套接字和每个    我需要读/写的时间,我    从频道读/写,    发送/检索到套接字,    并让SSL_connect(pseudo_socket)    与我的伪插座通信,    每次都接受什么    ssl_write发送,发送给    频道,反之亦然。

      • 湾设置一个BIO缓冲区(有    比我更多的BIO功能    包裹我的头;该    文件还没有完全    有用)并以某种方式读/写    这一点。

      理想情况下,我会选择2,因为这个原因:由于我的项目是用C语言编写的,因此在执行其他代码时保持套接字读/写会比我更喜欢复杂一点。

      然而,b。提出了一个问题:我担心握手会如何运作;特别是我担心我最终会与localhost握手,而不是与remotehost握手。

      总结一下我的问题:我可以通过渠道读取/写入SSL(在它周围放一个包装),这样4的流程就变成了:纯文本 - > SSL(明文) - >通过ssh - >从ssh主机向目标主机发送SSL(纯文本)?

      这有点长,但我希望这是可以理解的。如果没有,请告诉我,我会澄清。从谷歌搜索/搜索stackoverflow似乎是我和一个与mysql一起工作的人有同样的问题和有限的答案。

      非常感谢任何输入!

      • 詹姆斯

1 个答案:

答案 0 :(得分:2)

是的,选项2是正确的方法。使用BIO_make_bio_pair()创建BIO对,并使用SSL_set_bio()将其分配给SSL对象。

然后使用BIO_read()读取加密端SSL数据并将其写入libssh隧道,并从libssh隧道读取并使用BIO_write()写入。


<强>附录:

当您使用此方法时,您的SSL对象没有自己的文件描述符 - BIO替换文件描述符/套接字。 OpenSSL不是从文件描述符读取和写入,而是从您提供的BIO读取和写入。

BIO只是位于OpenSSL库和您自己的代码之间的接口。它们是您实现加密端SSL数据与另一端(而不是直接使用套接字的OpenSSL)的实际传输方式。

当您在BIO_read() wbio上提供的BIO上SSL_set_bio()时,您将读取加密端SSL数据,然后您必须将其发送给其他人站在自己身边(大概使用一些libssh2功能)。同样,当您从另一方(再次,从某些libssh2函数)接收加密端SSL数据时,您使用BIO_write()在您提供的BIO rbio上将其泵入SSL }。

也许这个插图会有所帮助。当您从SSL对象读取和写入时,OpenSSL将只是从底层BIO读取和写入,将数据留在那里供您稍后处理:

+------+               +-----+               +-----+
| Your | SSL_write()   | SSL | BIO_read()    | BIO |
| code | ------------> |     | <------------ |     |
|      |               |     |               |     |
|      |               |     | BIO_write()   |     |
|      |               |     | ------------> |     |
+------+               +-----+               +-----+

+------+              +-----+               +-----+
| Your | SSL_read()   | SSL | BIO_read()    | BIO |
| code | <----------- |     | <------------ |     |
|      |              |     |               |     |
|      |              |     | BIO_write()   |     |
|      |              |     | ------------> |     |
+------+              +-----+               +-----+

(但请注意,SSL_write()可能导致基础BIO的读取,反之亦然。)

如果wbio中有数据,您必须阅读并将其发送到另一方:

+------+              +-----+
| Your | BIO_read()   | BIO |
| code | <----------- |     |
|      |              +-----+
|      |                           +---------+
|      | libssh2_channel_write()   | libssh2 |
|      | ------------------------> |         | -> (... to other side)
|      |                           +---------+
+------+

相反,当有另一方提供的数据时,您应该阅读并将其传递到rbio

+------+
| Your |                          +---------+
| code | libssh2_channel_read()   | libssh2 |
|      | <----------------------- |         | -> (... from other side)
|      |                          +---------+
|      |              +-----+
|      | BIO_write()  | BIO |
|      | -----------> |     |
|      |              +-----+
+------+