//This is called when requests are routed through router to this endpoint //For ssl requests private static void HandleClient(TransparentProxyEndPoint endPoint, TcpClient tcpClient) { Stream clientStream = tcpClient.GetStream(); CustomBinaryReader clientStreamReader = null; StreamWriter clientStreamWriter = null; X509Certificate2 certificate = null; if (endPoint.EnableSsl) { var sslStream = new SslStream(clientStream, true); //if(endPoint.UseServerNameIndication) //{ // //implement in future once SNI supported by SSL stream // certificate = CertManager.CreateCertificate(endPoint.GenericCertificateName); //} //else certificate = CertManager.CreateCertificate(endPoint.GenericCertificateName); try { //Successfully managed to authenticate the client using the fake certificate sslStream.AuthenticateAsServer(certificate, false, SslProtocols.Tls, false); clientStreamReader = new CustomBinaryReader(sslStream, Encoding.ASCII); clientStreamWriter = new StreamWriter(sslStream); //HTTPS server created - we can now decrypt the client's traffic } catch (Exception) { if (sslStream != null) sslStream.Dispose(); Dispose(tcpClient, sslStream, clientStreamReader, clientStreamWriter, null); return; } clientStream = sslStream; } else { clientStreamReader = new CustomBinaryReader(clientStream, Encoding.ASCII); } var httpCmd = clientStreamReader.ReadLine(); //Now create the request HandleHttpSessionRequest(tcpClient, httpCmd, clientStream, clientStreamReader, clientStreamWriter, true); }
public void StartProxy() { ProxyServer.BeforeRequest += OnRequest; ProxyServer.BeforeResponse += OnResponse; //Exclude Https addresses you don't want to proxy //Usefull for clients that use certificate pinning //for example dropbox.com var explicitEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, 8000, true){ ExcludedHttpsHostNameRegex = new List<string>() { "dropbox.com" } }; //An explicit endpoint is where the client knows about the existance of a proxy //So client sends request in a proxy friendly manner ProxyServer.AddEndPoint(explicitEndPoint); ProxyServer.Start(); //Transparent endpoint is usefull for reverse proxying (client is not aware of the existance of proxy) //A transparent endpoint usually requires a network router port forwarding HTTP(S) packets to this endpoint //Currently do not support Server Name Indication (It is not currently supported by SslStream class) //That means that the transparent endpoint will always provide the same Generic Certificate to all HTTPS requests //In this example only google.com will work for HTTPS requests //Other sites will receive a certificate mismatch warning on browser //Please read about it before asking questions! var transparentEndPoint = new TransparentProxyEndPoint(IPAddress.Any, 8001, true) { GenericCertificateName = "google.com" }; ProxyServer.AddEndPoint(transparentEndPoint); foreach (var endPoint in ProxyServer.ProxyEndPoints) Console.WriteLine("Listening on '{0}' endpoint at Ip {1} and port: {2} ", endPoint.GetType().Name, endPoint.IpAddress, endPoint.Port); //You can also add/remove end points after proxy has been started ProxyServer.RemoveEndPoint(transparentEndPoint); //Only explicit proxies can be set as system proxy! ProxyServer.SetAsSystemHttpProxy(explicitEndPoint); ProxyServer.SetAsSystemHttpsProxy(explicitEndPoint); }