예제 #1
0
        internal void ClientDisconnected(ProxyClient client)
        {
            lock (this.routingClients)
                for (int i = 0; i < this.routingClients.Count; i++)
                {
                    if (this.routingClients[i].ParentClient == null ||
                        this.routingClients[i].ParentClient.Equals(client))
                    {
                        this.routingClients.RemoveAt(i);
                        i--;
                    }
                }

            lock (this.ConnectedClients)
                if (this.ConnectedClients.Contains(client))
                {
                    this.ConnectedClients.Remove(client);
                }
        }
예제 #2
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);
        }
예제 #3
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
            {
            }
        }