Search code examples
c++network-programmingsslwinsocktunnel

How to implement an SSL tunnel through a transparent proxy?


I have read the SSL TUNNELING INTERNET-DRAFT of December 1995 and set up an HTTP transparent proxy that works perfectly with unencrypted traffic.

Having read the above, as well as googled my brains out, the accepted method to create a tunnel for secure traffic through a proxy seems to be:

connect to the requested host, then have the proxy send an "HTTP 200..." confirmation message back to the client, then from that point on simply pass all further data traffic between client and server.

When I try this, however, the client (Chrome browser) responds to the "HTTP 200..." message with three wingdings characters which I forward to the remote host. At this point there is no response back and the connection fails.

Here is the code I am using for this, after having connected to the host:

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

Can anyone spot the error of my ways?


Solution

  • Your code is much more complicated than necessary. Just read into a char array, save the length returned, and write that many bytes from the same array, in a loop until recv() returns zero. 4 lines of code including two for the braces. Don't try to assemble the entire incoming message, just relay whatever comes in as it comes. Otherwise you are just adding latency, and programming errors. Get rid of all the strXXX() calls altogether.