2012-03-06 9 views
3

私はSSL TUNNELING INTERNET-DRAFT of December 1995を読んで、暗号化されていないトラフィックに完全に対応するHTTP透過プロキシを設定しました。トランスペアレントプロキシ経由でSSLトンネルを実装する方法は?

は、上記を読んで、だけでなく、私の脳をGoogleで検索したので、プロキシ経由でセキュアなトラフィック用のトンネルを作成するために用いられる方法は、のようだ:

、プロキシが送ってきた、要求されたホストへの接続します"HTTP 200 ..."という確認メッセージがクライアントに返され、その時点からクライアントとサーバー間のそれ以上のすべてのデータトラフィックが単純に渡されます。

私はこれを試すと、クライアント(Chromeブラウザ)が "HTTP 200 ..."メッセージに3つのwingdings文字で応答し、リモートホストに転送します。この時点では応答は返っておらず、接続は失敗します。ここで

は、私がホストに接続された後、これを使用していたコードは次のとおりです。

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リクエストでは動作しますが、バイナリデータでは失敗します)。 –

答えて

3

コードは必要以上に複雑です。 char配列を読み込んで、返された長さを保存し、recv()がゼロを返すまでループ内で同じ配列からそのバイト数を書き込んでください。中括弧の2行を含む4行のコード。着信メッセージ全体を組み立てようとしないでください。到着したものはそのまま中継してください。それ以外の場合は、待ち時間とプログラミングエラーを追加するだけです。すべてのstrXXX()呼び出しを一掃してください。

+0

元々私はそれをやっていましたが、何も起こっていないときにクライアントからどんな種類のデータが来たのかを見たいと思っていました。クライアント 'hello'は、3つ以上の文字で構成されている必要があります。 –

+0

@PhilipLangfordバイナリデータをASCIIとして扱うことは何も役に立たないでしょう。同様に、それらを「ウィングディング」と呼ぶことは無駄です。バイトの実際の値は何ですか? – EJP

+0

私はあなたの助言を取り、転送を簡略化し、バイト交換を見ることができます。しかし、私のロジックは、リモートホストがその要求を決して果たさない無限ループを引き起こします。 擬似コード: '(recv from client> 0) { ホストに送信; while(recv from host> 0) クライアントに送信します。 } –

2

私はあなたのトラフィックがASCII NUL文字が含まれていないという仮定をしなければならないと思う:

  strcat(cdata, buff); 
     } 

     total = 0; 
     bytes = strlen(cdata); 

ASCII NUL sがストリーム内に存在する場合、これらは失敗します。

+0

良い点。私はこれを使ってstd :: stringを使っていくつかのサイクルを節約しましたが、ネットワーク操作はおそらくその効果を無効にします。 –

+0

'std :: string'も' 0x00'バイトをうまく扱えません。バイナリデータは_binary_であり、文字列クラスを使用して処理することはできません。 EJPの答えは、私が行ったより良いアプローチを示唆しています。データをまったく解釈しようとしません。 – sarnold

関連する問題