2012-03-06 95 views
3

我已閱讀SSL TUNNELING INTERNET-DRAFT of December 1995並設置了一個HTTP透明代理,可與未加密的流量完美協作。如何通過透明代理實現SSL隧道?

看了上面的,還有GOOGLE了我的腦袋,被接受的方法是通過代理來創建安全流量的隧道似乎是:

連接請求的主機,然後讓代理髮送「HTTP 200 ...」確認消息返回給客戶端,然後從這一點簡單地傳遞客戶端和服務器之間所有進一步的數據流量。然而,當我嘗試這樣做時,客戶端(Chrome瀏覽器)使用三個wingdings字符來響應「HTTP 200 ...」消息,這些字符將轉發給遠程主機。此時沒有迴應,連接失敗。

這裏是我使用這個代碼,具有連接到主機後:

if((*request=='C')&&(*(request+1)=='O')&&(*(request+2)=='N')&&(*(request+3)=='N')) 
{ 

    int recvLen; 

    send(output,htok,strlen(htok),0); //htok looks like "HTTP/1.0 200 Connection Established\nProxy-Agent: this_proxy\r\n\r\n" 

    std::memset(buff,0,bSize); 
    int total; 
     int bytes; 
     int n; 
     char cdata[MAXDATA]; 
     while ((recvLen = recv(output, buff, bSize-1,0)) > 0) //recving from client - here we get wingdings 
     { 
      memset(cdata,0, MAXDATA); 
      strcat(cdata, buff); 
      while(recvLen>=bSize-1)//just in case buff is too small 
      { 
       std::memset(buff,0,bSize); 
       recvLen=recv(output,buff,bSize-1,0); 
       strcat(cdata, buff); 
      } 

      total = 0; 
      bytes = strlen(cdata);      
      cout << cdata << endl;//how I see the wingdings 
      while (total < strlen(cdata)) 
      {  
       n = send(requestSock, cdata + total, bytes,0);//forwarding to remote host 
       if(n == SOCKET_ERROR) 
       { 
        cout << "secure sending error" << endl; 
        break; 
       } 
       total += n; 
       bytes -= n; 
      } 

      std::memset(buff,0,bSize); 
      recvLen=recv(requestSock, buff, bSize,0);//get reply from remote host 
      if (recvLen > 0) 
      { 
       do 
       { 
        cout<<"Thread "<<threadid<<" [Connection:Secure]: "<<recvLen<<endl; 


        send(output, buff, recvLen,0);//forward all to client 

        recvLen= recv(requestSock, buff, bSize,0); 

        if(0==recvLen || SOCKET_ERROR==recvLen)   
        { 
         cout<<"finished secure receiving or socket error"<<endl; 
         break; 
        } 

       }while(true); 
      } 
         }//end while, loop checks again for client data 

任何人能發現我的方式錯誤?

+0

send()調用可以發送少於recvLen,並且您忽略這個事實。另一個問題是將SSL中的二進制數據作爲文本處理(您的代碼可以用於文本HTTP請求,但無論如何都會以二進制數據失敗)。 – 2012-03-06 07:02:44

回答

3

您的代碼比必要的複雜得多。只需讀入char數組,保存返回的長度,然後在同一個數組中寫入多個字節,直到recv()返回零。 4行代碼包括兩個大括號。不要嘗試收集整個傳入的消息,只是傳遞任何進來的消息。否則,你只是增加延遲和編程錯誤。擺脫所有的strXXX()調用。

+0

最初我是這麼做的,但後來想看看什麼時候沒有發生什麼樣的數據來自客戶端。一個客戶端'你好'應該包含超過3個wingding chars ... – 2012-03-06 02:53:19

+0

@PhilipLangford將二進制數據作爲ASCII處理並不會告訴你任何有用的東西。同樣,稱他們爲'wingdings'是徒勞的。什麼是字節的實際值? – EJP 2012-03-06 03:02:14

+0

我接受了您的建議並簡化了傳輸,現在可以看到字節交換,但是,我的邏輯導致遠程主機無法完成其請求的無限循環。 僞代碼: 'while(recv from client> 0) { 發送給主機; while(recv from host> 0) send to client; } – 2012-03-06 18:06:26

2

我不認爲你應該作一個假設,交通不包含ASCII字符NUL

  strcat(cdata, buff); 
     } 

     total = 0; 
     bytes = strlen(cdata); 

如果有ASCII NUL S上的數據流中,這些都將失敗。

+0

好點。我這樣做是通過使用std :: string來保存幾個週期,但網絡操作可能會使這種效應無效。 – 2012-03-06 02:47:11

+0

'std :: string'也不好處理'0x00'字節。二進制數據是_binary_,不能使用字符串類來處理。 EJP的回答表明比我更好的方法 - 根本不要試圖解釋數據。 – sarnold 2012-03-06 08:45:52