Click here to Skip to main content
15,889,909 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I am writing a proxy server and have no trouble with HTTP, but when it comes to HTTPS and SSL, I cannot get a tunnel working.

All I want to do is open a tunnel to the server so I don't have to get involved with certificates or use the SslStream.

The code uses a TcpListener to listen for requests on localhost port 444.

SSLtcplistener = new TcpListener(Local, 444);


When running the SSL request from the browser looks like:

CONNECT www.google.com:443 HTTP/1.0
User-Agent: Mozilla/4.0 (compatible; MSIE.........................
Host: www.google.com
Content-Length: 0
Proxy-Connection: Keep-Alive
Pragma: no-cache


Next I accept the connection.

Socket socket = SSLtcplistener.AcceptSocket();


and then extract the host string and port number from the SSL request and open a new socket to Google on port 433 like this:

IPEndPoint IPE = new IPEndPoint(Dns.Resolve(this.Connect).AddressList[0], this.Port);//443

this.Send = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
this.Send.Connect(IPE);


If the 'Send' socket is open, then I send this message back to the browsers:

HTTP/1.0 200 Connection Established\r\n
Proxy-agent: Netscape-Proxy/1.1\r\n\r\n


and close the browser connection expecting the browser to open another connection and to send encrypted data that I just need to relay back to the open send socket but the next request from the browsers is simply the same as the previous request and when I relay this to the Google server, I get nothing back.

I've looked at a few examples but they are in Java and use a different type of socket, so I'm a bit lost but the reason I want SSL to pass through the proxy is so that some sites can be banned.

Any help would be appreciated because I have spent a day getting nowhere.
Posted
Updated 13-Mar-10 8:58am
v2

I found the answer was to keep both the request and responce sockets open and all you need to do is open the request socket on the address and port names in the CONNECT part of the header and then to simply relay any data in the sockets from one to another.

Just now i'm having trouble with responces that don't have a content-length in the header and i'm having to use a loop counter to guess if all the data has been recived which is not easy when some connections to the server are being kept oped due to Keep-Alive being used in the request.

One trick i am using to speed things us is to check the last few bytes recived from the servers and then looking at the request file type to decide if all the data has been sent.



C#
public string GetEndOfData(byte[] ReceiveBuffer,int Rec)
      {
          byte[] Test = new byte[10];
          Test[0] = ReceiveBuffer[Rec - 10];
          Test[1] = ReceiveBuffer[Rec - 9];
          Test[2] = ReceiveBuffer[Rec - 8];
          Test[3] = ReceiveBuffer[Rec - 7];
          Test[4] = ReceiveBuffer[Rec - 6];
          Test[5] = ReceiveBuffer[Rec - 5];
          Test[6] = ReceiveBuffer[Rec - 4];
          Test[7] = ReceiveBuffer[Rec - 3];
          Test[8] = ReceiveBuffer[Rec - 2];
          Test[9] = ReceiveBuffer[Rec - 1];
          return ASCIIEncoding.ASCII.GetString(Test);
      }


public bool IsComplete(byte[] ReceiveBuffer,int Rec, string FileName)
       {
           string EndOfData = GetEndOfData(ReceiveBuffer, Rec).ToUpper();
           if (FileName.ToUpper().Trim().EndsWith(".GIF"))
           {
               if (ReceiveBuffer[Rec - 2] == 0 && ReceiveBuffer[Rec - 1] == 59)
                   return true;
           }

           else if (FileName.ToUpper().Trim().EndsWith(".JPG"))
           {
               if (ReceiveBuffer[Rec - 2] == 255 && ReceiveBuffer[Rec - 1] == 217)
                   return true;
           }
           else if (FileName.ToUpper().Trim().EndsWith(".PNG"))
           {
               if (ReceiveBuffer[Rec - 3] == 66 && ReceiveBuffer[Rec - 2] == 96 && ReceiveBuffer[Rec - 1] == 130)
                   return true;
           }
           else if (FileName.ToUpper().Trim().EndsWith(".HTM") || FileName.ToUpper().Trim().EndsWith(".HTML") || FileName.ToUpper().Trim().EndsWith(".ASP") || FileName.ToUpper().Trim().EndsWith(".ASPX"))
           {
               if (EndOfData.IndexOf("</HTML>") > -1)
                   return true;
           }
           return false;

       }


Simply closing each request socket regardless of what is in the headers works to some degree but streaming from Youtube becomes real slow and also note that YouTube adds custom headers.

my next step is to make fake cookies because i have become tired of Google knowing my every move and yes i know this has alreay been done ten times before but has any one ever made a pop up blocker for the in-line divs that gets in everyone face ?
 
Share this answer
 
Comments
Simon_Whitehead 29-Sep-10 22:49pm    
Would you mind sharing your code? I'm having nothing but trouble attempting this.. I sure would appreciate a look at your example.

I'm basically wanting to filter only URLs in an SSL request (which is what you appear to be doing..).. got any tips on just passing the rest of the SSL traffic through?

chem
Finally get the solution ,need to implement Remote Tunnel.
 
Share this answer
 
Comments
CHill60 10-Jul-13 9:25am    
Please don't post additional answers to questions that are 3 years old. This isn't a solution to the original question, it's a response to your own post - which should have been posted against your own question.
GAJERA 10-Jul-13 9:43am    
ok,will take care

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900