2016-12-28 21 views
0

正常:瀏覽器發送到我的代理:「CONNECT ... \ r \ n \ r \ n」,代理髮送「200 OK \ r \ n \ r \ n」,瀏覽器發送加密的請求,代理調用SSL_accept(套接字)。好。openssl接受連接使用我的緩衝區

問題:瀏覽器發送到我的代理服務器:「CONNECT ... \ r \ n \ r \ n」+下一個加密的請求。代理髮送「200 OK \ r \ n \ r \ n」,調用SSL_accept(套接字)返回SSL_ERROR_SSL或SSL_ERROR_SYSCALL,因爲代理讀取加密請求的緩衝區部分。

解決方案:

  1. 使用的recv(襪子,BUF,BUFFER_SIZE,MSG_PEEK)和recv(襪子,BUF,used_size,0)。問題:所有數據將被讀取,或池()中的無限信號。

  2. 如何調用SSL_accept()使用我的緩衝區加密數據的一部分?

  3. 任何解決方案?

+1

解決方案是修復越野車客戶端。在嘗試協商TLS之前,客戶端必須等待代理建立連接併發送「200 ok ...」。客戶的代碼被破壞了。 –

+0

不要在空白行後面讀取任何內容,即使這意味着您必須一次讀取一個字節:性能在這裏並不重要。並確保在建立上行連接之前不發送200 OK。 – EJP

+1

@SamVarshavchik該錯誤在代理端。客戶端可以在收到'200'回覆之前發送數據。這在[CONNECT'規範]的[第3.3節「數據管道」](https://tools.ietf.org/html/draft-luotonen-web-proxy-tunneling-01#section-3.3) https://tools.ietf.org/html/draft-luotonen-web-proxy-tunneling-01)。代理不應該首先調用'SSL_accept()',因爲它不是TLS握手的目標。它應該將原始數據原樣傳遞給下一臺服務器。 –

回答

1

問題是與你的代理,而不是客戶端。

CONNECT specification的3.3節:

3.3。數據流水線

在接收到「建立200連接」(或任何其他成功或錯誤代碼)之前,客戶端發送一些用於服務器的數據是合法的。這允許在與代理請求相同的TCP數據包中發送用於遠程服務器的任何握手數據時,減少延遲並提高效率。這允許代理在建立到遠程服務器的連接後立即轉發數據,而不需要等待客戶端的兩個往返時間(發送200到客戶端;等待來自客戶端的下一個數據包)。

這意味着代理服務器不能認爲從 客戶端套接字描述符讀取只會返回代理請求。)相反,代理請求之後可能有任何數量的不透明數據必須在連接建立後轉發給服務器。但是,如果到遠程服務器的連接失敗,或者代理服務器不允許連接,則遠程服務器的數據將被代理丟棄。

真正的錯誤是,HTTP代理不應被調用SSL_accept()開始說起,因爲它是不是客戶端的TLS握手的目標。被請求的服務器是目標,因此只有它可以正確響應握手。您的代理不得迴應握手。這很可能會導致客戶端的失敗(特別是如果客戶正確地完成工作來驗證響應不是來自中間人)。

您的代理必須建立正常加密連接到所請求的服務器,然後通過任何原始數據,爲來回。您的代理不是客戶端/服務器加密會話的參與者,它僅僅是促進客戶端和服務器之間的數據交換的傳遞,僅此而已。

不要試圖以任何方式解釋客戶端或服務器的數據,它不是你的數據來處理。在初始CONNECT請求之後的所有內容都是不透明到代理並且必須按原樣轉發。你不知道如何,也不能對客戶端和服務器如何相互通信做出任何假設。

+0

所有的都是真的,但代理mitm。 – MikelSV

相關問題