2010-06-18 70 views
1

我在写我自己的娱乐这是假设能够做的4件事小FTP项目:libssh2通道SSL BIO使用

  1. 直接连接到FTP
  2. 直接连接到一个ftp使用SSL(封装)
  3. 通过ssh隧道连接到ftp
  4. 通过ssh隧道通过SSL连接到ftp。

我在纯C写程序(UNIX,而不是它在这种情况下重要的),使用标准库1和2中,除了OpenSSL,以便进行2和4

使用libssh2 3和4

我能够拿到1-3的工作,而不是4.下面是我在哪里:

  1. 打开一个套接字服务器来完成的:端口,连接,写入/从套接字读取。
  2. 通过打开一个套接字到主机:端口,连接,写入“AUTH SSL”,从先前的套接字启动一个具有BIO的SSL对象 - SSL_connect(),SSL_read(),SSL_write()。
  3. 打开目标本地主机和之间的隧道(做虽然我不知道我使用本地主机绑定的东西在我的approac :)

类似:

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.我卡住了,因为我(试图保持简单)需要以某种方式将此通道转换为套接字。所以我看到它的方式有两种选择:

  • a。做一个伪插座,每 时间我需要读/写,我 读取通道/写, 发送/检索它插入插座, 让所以SSL_connect(pseudo_socket) 与我的假插座每一次沟通, 接受ssl_write发送的内容,发送到 通道,反之亦然。

  • 湾建立一个BIO缓冲区(有 更多的生物功能比我可以 包裹我的头; 文档还没有完全 有帮助),并以某种方式读取/写入 。

理想我会去2,出于这个原因:由于我的项目是用C语言编写,维护套接字读/写在执行其他代码将变得更复杂一点比我更喜欢。

然而,b。给出了一个问题:我很担心握手是如何工作的;特别是我担心我最终会与localhost而不是远程主机握手。

总结我的问题:我可以通过通道读取/写入SSL(放置一个包装器),以便4.的流程变为:纯文本 - > SSL(纯文本) - >通过ssh - >从SSL主机提供SSL(明文)到目标主机?

这有点长,但我希望这是可以理解的。如果没有,请让我知道,我会清理。从谷歌搜索/搜索stackoverflow它似乎是我和一个与MySQL工作的人有这个相同的问题,并有限的答案。

任何输入是非常感谢!

  • 詹姆斯

回答

2

是,选择2是正确的道路要走。使用BIO_make_bio_pair()创建一个BIO对,并使用SSL_set_bio()将它们分配给SSL对象。

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


附录:

当您使用此方法,您的SSL对象不它自己的文件描述符 - BIOS的替代文件描述符/插座。 OpenSSL不是从文件描述符中读写,而是从您提供的BIO中读取和写入。

BIO只是一个介于OpenSSL库和您自己的代码之间的接口。它们是您实现将加密端SSL数据实际发送到另一端(而不是直接使用套接字的OpenSSL)的一种方式。

当你做你提供的wbioSSL_set_bio()的BIO一个BIO_read(),你会读出加密端SSL数据,然后你必须(可能使用一些libssh2功能)发送这个到对方自己。同样,当您从另一端接收加密端SSL数据(同样,从一些libssh2函数),您可以通过在您作为rbio提供的BIO上使用BIO_write()将其泵入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 | 
|  | -----------> |  | 
|  |    +-----+ 
+------+