Пример #1
0
        /// <summary>
        ///     Initializes a new instance of the <see cref="ProxyClient" /> class.
        /// </summary>
        /// <param name="client">
        ///     The underlaying Net.Sockets.Socket
        /// </param>
        /// <param name="parent">
        ///     The parent ProxyController class
        /// </param>
        public ProxyClient(Socket client, ProxyController parent)
        {
            this.SmartRequestBuffer              = new byte[0];
            this.SmartResponseBuffer             = new byte[0];
            this.lastSendingSpeedCalculationTime = this.lastReceivingSpeedCalculationTime = Environment.TickCount;
            this.oldSentBytes = this.oldReceivedBytes = this.ReceivedBytes = this.SentBytes = 0;
            if (client != null && client.ProtocolType == ProtocolType.Tcp)
            {
                this.RequestType = RequestTypes.Tcp;
            }
            else if (client != null && client.ProtocolType == ProtocolType.Udp)
            {
                this.RequestType = RequestTypes.Udp;
            }

            this.Status                 = StatusCodes.Connected;
            this.LastError              = string.Empty;
            this.NoDataTimeOut          = 60;
            this.IsSmartForwarderEnable = parent.SmartPear.ForwarderHttpEnable || parent.SmartPear.ForwarderHttpsEnable ||
                                          parent.SmartPear.ForwarderSocksEnable;
            this.SendPacketSize    = 1024;
            this.ReceivePacketSize = 8192;
            this.IsClosed          = false;
            this.Controller        = parent;
            this.UnderlyingSocket  = client;
            if (this.UnderlyingSocket != null)
            {
                this.UnderlyingSocket.Blocking = false;
                this.UnderlyingSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.DontFragment, true);
            }
        }
Пример #2
0
 /// <summary>
 ///     Initializes a new instance of the <see cref="DnsResolver" /> class.
 /// </summary>
 /// <param name="parent">
 ///     The parent proxy controller class to forward DNS requests.
 /// </param>
 public DnsResolver(ProxyController parent)
 {
     this.parent = parent;
     this.DnsResolverServerIp     = IPAddress.Parse("8.8.4.4");
     this.DnsResolverSupported    = true;
     this.DnsResolverUdpSupported = true;
 }
Пример #3
0
        /// <summary>
        ///     Render the error message on the specified Proxy Client
        /// </summary>
        /// <param name="client">
        ///     The client.
        /// </param>
        /// <param name="title">
        ///     The title.
        /// </param>
        /// <param name="message">
        ///     The message.
        /// </param>
        /// <param name="code">
        ///     The HTTP code.
        /// </param>
        /// <param name="sslStream">
        ///     The SSL stream if any.
        /// </param>
        /// <returns>
        ///     <see cref="bool" /> showing if the process ended successfully.
        /// </returns>
        public bool RenderError(
            ProxyClient client,
            string title,
            string message,
            HttpHeaderCode code = HttpHeaderCode.C500ServerError,
            SslStream sslStream = null)
        {
            try
            {
                if (client.RequestAddress == string.Empty)
                {
                    return(false);
                }

                Uri url;
                if (!Uri.TryCreate(client.RequestAddress, UriKind.Absolute, out url))
                {
                    return(false);
                }

                bool https = false;
                if (url.Scheme.Equals("HTTP", StringComparison.OrdinalIgnoreCase))
                {
                    if (!this.EnableOnHttp)
                    {
                        return(false);
                    }
                }
                else if (url.Scheme.Equals("HTTPS", StringComparison.OrdinalIgnoreCase) ||
                         url.Scheme.Equals("SOCKS", StringComparison.OrdinalIgnoreCase))
                {
                    if (!((this.EnableOnPort80 && url.Port == 80) || (this.EnableOnPort443 && url.Port == 443)))
                    {
                        return(false);
                    }

                    https = url.Port == 443;
                }
                else
                {
                    return(false);
                }

                if (client.IsReceivingStarted || !client.IsSendingStarted)
                {
                    return(false);
                }

                string html = Resources.HTTPErrorTemplate;
                html = html.Replace("%VERSION", Assembly.GetEntryAssembly().GetName().Version.ToString());
                html = html.Replace("%TITLE", title);
                html = html.Replace("%MESSAGE", Common.ConvertToHtmlEntities(message));
                string conString = "Not Connected";
                if (client.Controller.ActiveServer != null)
                {
                    conString = client.Controller.ActiveServer.ToString();
                }

                List <string> args = new List <string>();
                if (client.Controller.SmartPear.ForwarderHttpEnable)
                {
                    args.Add("P:HTTP");
                }

                if (client.Controller.SmartPear.ForwarderHttpsEnable)
                {
                    args.Add("P:HTTPS");
                }

                if (client.Controller.SmartPear.ForwarderSocksEnable && client.Controller.SmartPear.ForwarderHttpsEnable)
                {
                    args.Add("P:SOCKS");
                }

                if (args.Count > 0)
                {
                    conString = args.Aggregate(conString + " (", (current, arg) => current + (" " + arg + "; ")) + ")";
                }

                html = html.Replace("%CONSTRING", conString);

                string statusCode;
                switch (code)
                {
                case HttpHeaderCode.C200Ok:
                    statusCode = "200 OK";
                    break;

                case HttpHeaderCode.C501NotImplemented:
                    statusCode = "501 Not Implemented";
                    break;

                case HttpHeaderCode.C502BadGateway:
                    statusCode = "502 Bad Gateway";
                    break;

                case HttpHeaderCode.C504GatewayTimeout:
                    statusCode = "504 Gateway Timeout";
                    break;

                case HttpHeaderCode.C417ExpectationFailed:
                    statusCode = "417 Expectation Failed";
                    break;

                case HttpHeaderCode.C404NotFound:
                    statusCode = "404 Not Found";
                    break;

                default:
                    statusCode = "500 Internal Server Error";
                    break;
                }

                const string NewLineSep = "\r\n";
                string       header     = "HTTP/1.1 " + statusCode + NewLineSep + "Server: PeaRoxy Error Renderer" + NewLineSep
                                          + "Content-Length: " + html.Length + NewLineSep + "Connection: close" + NewLineSep
                                          + "Content-Type: text/html;" + NewLineSep + NewLineSep;
                byte[] db = Encoding.ASCII.GetBytes(header + html);

                if (!Common.IsSocketConnected(client.UnderlyingSocket))
                {
                    return(false);
                }

                if (https)
                {
                    string certAddress = url.DnsSafeHost;
                    if (!Common.IsIpAddress(certAddress))
                    {
                        if (string.IsNullOrEmpty(certAddress))
                        {
                            return(false);
                        }
                    }

                    certAddress = GetCertForDomain(certAddress);
                    if (string.IsNullOrEmpty(certAddress))
                    {
                        return(false);
                    }

                    try
                    {
                        X509Certificate certificate = new X509Certificate2(certAddress, string.Empty);
                        if (sslStream == null)
                        {
                            client.UnderlyingSocket.Blocking = true;
                            Stream stream = new NetworkStream(client.UnderlyingSocket);
                            sslStream = new SslStream(stream)
                            {
                                ReadTimeout = 30 * 1000, WriteTimeout = 30 * 1000
                            };
                            sslStream.AuthenticateAsServer(certificate);
                        }

                        sslStream.BeginWrite(
                            db,
                            0,
                            db.Length,
                            delegate(IAsyncResult ar)
                        {
                            try
                            {
                                sslStream.EndWrite(ar);
                                sslStream.Flush();
                                sslStream.Close();
                                client.UnderlyingSocket.Close();
                            }
                            catch (Exception)
                            {
                            }
                        },
                            null);
                    }
                    catch
                    {
                    }
                }
                else
                {
                    client.UnderlyingSocket.BeginSend(
                        db,
                        0,
                        db.Length,
                        SocketFlags.None,
                        delegate(IAsyncResult ar)
                    {
                        try
                        {
                            client.UnderlyingSocket.EndSend(ar);
                            client.UnderlyingSocket.Close();
                        }
                        catch (Exception)
                        {
                        }
                    },
                        null);
                }

                return(true);
            }
            catch (Exception e)
            {
                ProxyController.LogIt(e.Message + " - " + e.StackTrace);
            }

            return(false);
        }
Пример #4
0
        internal void Accepting()
        {
            try
            {
                if (this.DnsResolverSupported && this.dnsTcpListenerSocket.Poll(0, SelectMode.SelectRead))
                {
                    ProxyClient c = new ProxyClient(this.dnsTcpListenerSocket.Accept(), this.parent)
                    {
                        ReceivePacketSize
                            =
                                this.parent
                                .ReceivePacketSize,
                        SendPacketSize
                            =
                                this.parent
                                .SendPacketSize,
                        NoDataTimeOut =
                            10,
                        RequestType =
                            ProxyClient
                            .RequestTypes
                            .Dns,
                        IsSendingStarted
                            = true,
                    };
                    lock (this.parent.ConnectedClients) this.parent.ConnectedClients.Add(c);
                    this.parent.ActiveServer.Clone().Establish(this.DnsResolverServerIp.ToString(), 53, c);
                }

                if (this.DnsResolverSupported && this.DnsResolverUdpSupported)
                {
                    if (this.dnsUdpListenerSocket == null)
                    {
                        this.dnsUdpListenerSocket = new Socket(
                            AddressFamily.InterNetwork,
                            SocketType.Dgram,
                            ProtocolType.Udp)
                        {
                            EnableBroadcast = true
                        };
                        this.dnsUdpListenerSocket.Bind(this.localDnsIp);
                    }

                    try
                    {
                        if (this.dnsUdpListenerSocket.Poll(0, SelectMode.SelectRead))
                        {
                            byte[]   globalBuffer = new byte[500];
                            EndPoint remoteEp     = new IPEndPoint(IPAddress.Any, 0);
                            int      i            = this.dnsUdpListenerSocket.ReceiveFrom(globalBuffer, ref remoteEp);
                            byte[]   buffer       = new byte[i + 2];
                            Array.Copy(globalBuffer, 0, buffer, 2, i);
                            Task.Factory.StartNew(
                                delegate
                            {
                                try
                                {
                                    buffer[0] = (byte)Math.Floor((double)i / 256);
                                    buffer[1] = (byte)(i % 256);

                                    IPAddress ip = this.parent.Ip;

                                    // Connecting to our self on same port, But TCP
                                    if (ip.Equals(IPAddress.Any))
                                    {
                                        ip = IPAddress.Loopback;
                                    }

                                    Socket tcpLinkForUdp = new Socket(
                                        AddressFamily.InterNetwork,
                                        SocketType.Stream,
                                        ProtocolType.Tcp);
                                    tcpLinkForUdp.Connect(ip, 53);

                                    tcpLinkForUdp.Send(buffer);
                                    buffer = new byte[tcpLinkForUdp.ReceiveBufferSize];
                                    i      = tcpLinkForUdp.Receive(buffer);
                                    if (i != 0)
                                    {
                                        int neededBytes = (buffer[0] * 256) + buffer[1] + 2;
                                        Array.Resize(ref buffer, Math.Max(i, neededBytes));
                                        if (i < neededBytes)
                                        {
                                            int timeout  = Environment.TickCount + 2000;
                                            int received = i;
                                            while (received < neededBytes && timeout > Environment.TickCount &&
                                                   Common.IsSocketConnected(tcpLinkForUdp))
                                            {
                                                i = tcpLinkForUdp.Receive(
                                                    buffer,
                                                    received,
                                                    buffer.Length - received,
                                                    SocketFlags.None);
                                                received += i;
                                                if (i == 0)
                                                {
                                                    break;
                                                }

                                                Thread.Sleep(16);
                                            }
                                        }
                                    }

                                    this.dnsUdpListenerSocket.SendTo(
                                        buffer,
                                        2,
                                        buffer.Length - 2,
                                        SocketFlags.None,
                                        remoteEp);
                                }
                                catch (Exception
                                       e)
                                {
                                    ProxyController.LogIt("DNS Resolver UDP Error: " + e.Message);
                                }
                            });
                        }
                    }
                    catch (Exception)
                    {
                        this.dnsUdpListenerSocket.Close();
                        this.dnsUdpListenerSocket = null;
                    }
                }
            }
            catch
            {
            }
        }
Пример #5
0
        /// <summary>
        ///     The close method which supports mentioning a message about the reason
        /// </summary>
        /// <param name="title">
        ///     The title.
        /// </param>
        /// <param name="message">
        ///     The message.
        /// </param>
        /// <param name="code">
        ///     The HTTP code.
        /// </param>
        /// <param name="async">
        ///     Indicating if the closing process should treat the client as an asynchronous client
        /// </param>
        /// <param name="sslstream">
        ///     The SSL stream if any.
        /// </param>
        public void Close(
            string title   = null,
            string message = null,
            ErrorRenderer.HttpHeaderCode code = ErrorRenderer.HttpHeaderCode.C500ServerError,
            bool async          = false,
            SslStream sslstream = null)
        {
            this.Status = StatusCodes.Closing;
            try
            {
                if (title != null)
                {
                    if (message == null)
                    {
                        message = "No more information.";
                    }

                    this.LastError = title + "\r\n" + message;
                }

                if (this.UnderlyingSocket != null)
                {
                    // Testing or not
                    if (this.LastError != string.Empty && title != null)
                    {
                        ProxyController.LogIt(title);
                    }

                    if (title == null ||
                        !this.Controller.ErrorRenderer.RenderError(this, title, message, code, sslstream))
                    {
                        if (async)
                        {
                            byte[] db = new byte[0];
                            if (this.UnderlyingSocket != null)
                            {
                                this.UnderlyingSocket.BeginSend(
                                    db,
                                    0,
                                    db.Length,
                                    SocketFlags.None,
                                    delegate(IAsyncResult ar)
                                {
                                    try
                                    {
                                        this.UnderlyingSocket.Close();         // Close request connection it-self
                                        this.UnderlyingSocket.EndSend(ar);
                                    }
                                    catch (Exception)
                                    {
                                    }
                                },
                                    null);
                            }
                        }
                        else
                        {
                            if (this.UnderlyingSocket != null)
                            {
                                this.UnderlyingSocket.Close();
                            }
                        }
                    }
                }
            }
            catch
            {
            }

            this.IsClosed = true;
            this.Controller.ClientDisconnected(this);
        }