2010-06-18 60 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 | 
|  | -----------> |  | 
|  |    +-----+ 
+------+