예제 #1
0
파일: Socks.cs 프로젝트: orf53975/PeaRoxy
        public static void Handle(byte[] firstResponse, ProxyClient client)
        {
            if (!client.Controller.IsSocksSupported || !IsSocks(firstResponse))
            {
                client.Close();
                return;
            }

            // Responding with socks protocol
            byte clientVersion = firstResponse[0];

            if (clientVersion == 5)
            {
                byte[] clientSupportedAuths = new byte[firstResponse[1]];
                Array.Copy(firstResponse, 2, clientSupportedAuths, 0, firstResponse[1]);
                byte[] serverResponse = new byte[2];
                if (clientSupportedAuths.Length == 0)
                {
                    client.Close(
                        "No authentication method found.",
                        null,
                        ErrorRenderer.HttpHeaderCode.C417ExpectationFailed);
                    return;
                }

                serverResponse[0] = clientVersion;

                // -------------Selecting authentication type
                byte serverSelectedAuth = 255;
                foreach (byte item in clientSupportedAuths)
                {
                    if (item == 0)
                    {
                        serverSelectedAuth = 0;
                    }
                }

                serverResponse[1] = serverSelectedAuth;
                client.Write(serverResponse);
                client.IsReceivingStarted = false;

                // -------------Doing authentication
                if (serverSelectedAuth == 255)
                {
                    client.Close(
                        "SOCKS Connection only accept clients with no authentication information.",
                        null,
                        ErrorRenderer.HttpHeaderCode.C417ExpectationFailed);
                    return;
                }

                // -------------Establishing connection
                byte[] response = new byte[client.UnderlyingSocket.ReceiveBufferSize];
                client.UnderlyingSocket.ReceiveTimeout = client.NoDataTimeOut;
                client.UnderlyingSocket.BeginReceive(
                    response,
                    0,
                    response.Length,
                    SocketFlags.None,
                    delegate(IAsyncResult ar)
                {
                    try
                    {
                        int bytes = client.UnderlyingSocket.EndReceive(ar);
                        Array.Resize(ref response, bytes);

                        if (response == null || response.Length == 0)
                        {
                            client.Close(
                                "No request received. Connection Timeout.",
                                null,
                                ErrorRenderer.HttpHeaderCode.C417ExpectationFailed);
                            return;
                        }

                        if (response[0] != clientVersion)
                        {
                            client.Close(
                                "Unknown SOCKS version, Expected " + clientVersion,
                                null,
                                ErrorRenderer.HttpHeaderCode.C417ExpectationFailed);
                            return;
                        }

                        byte clientConnectionType      = response[1];
                        byte clientAddressType         = response[3];
                        string clientConnectionAddress = null;
                        byte[] clientUnformatedConnectionAddress;
                        ushort clientConnectionPort = 0;
                        byte serverAresponse        = 0;
                        if (clientConnectionType != 1)
                        {
                            serverAresponse = 7;
                        }

                        switch (clientAddressType)
                        {
                        case 1:
                            clientUnformatedConnectionAddress = new byte[4];
                            Array.Copy(response, 4, clientUnformatedConnectionAddress, 0, 4);
                            clientConnectionAddress =
                                new IPAddress(clientUnformatedConnectionAddress).ToString();
                            clientConnectionPort = (ushort)((ushort)(response[8] * 256) + response[9]);
                            break;

                        case 3:
                            clientUnformatedConnectionAddress = new byte[response[4]];
                            Array.Copy(response, 5, clientUnformatedConnectionAddress, 0, response[4]);
                            clientConnectionAddress =
                                Encoding.ASCII.GetString(clientUnformatedConnectionAddress);
                            clientConnectionPort =
                                (ushort)
                                ((ushort)(response[5 + response[4]] * 256) + response[5 + response[4] + 1]);
                            break;

                        case 4:
                            clientUnformatedConnectionAddress = new byte[16];
                            Array.Copy(response, 4, clientUnformatedConnectionAddress, 0, 16);
                            clientConnectionAddress =
                                new IPAddress(clientUnformatedConnectionAddress).ToString();
                            clientConnectionPort = (ushort)((ushort)(response[20] * 256) + response[21]);
                            break;

                        default:
                            serverAresponse = 8;
                            break;
                        }

                        serverResponse    = new byte[3 + (response.Length - 3)];
                        serverResponse[0] = clientVersion;
                        serverResponse[1] = serverAresponse;
                        serverResponse[2] = 0;
                        serverResponse[3] = 3;
                        Array.Copy(response, 3, serverResponse, 3, response.Length - 3);
                        client.RequestAddress = "socks://" + clientConnectionAddress + ":"
                                                + clientConnectionPort;
                        client.Write(serverResponse);
                        client.IsReceivingStarted = false;
                        if (serverAresponse != 0)
                        {
                            client.Close(
                                "Response Error, Code: " + serverAresponse,
                                null,
                                ErrorRenderer.HttpHeaderCode.C417ExpectationFailed,
                                true);
                            return;
                        }

                        firstResponse = new byte[0];
                        DirectHandle(client, clientConnectionAddress, clientConnectionPort, firstResponse);
                    }
                    catch (Exception e)
                    {
                        client.Close(e.Message, e.StackTrace);
                    }
                },
                    response);
            }
            else if (clientVersion == 4)
            {
                try
                {
                    byte clientConnectionType = firstResponse[1];
                    byte serverAresponse      = 90;
                    if (clientConnectionType != 1)
                    {
                        serverAresponse = 91;
                    }

                    ushort clientConnectionPort = (ushort)((ushort)(firstResponse[2] * 256) + firstResponse[3]);
                    byte[] clientUnformatedConnectionAddress = new byte[4];
                    Array.Copy(firstResponse, 4, clientUnformatedConnectionAddress, 0, 4);
                    string clientConnectionAddress = new IPAddress(clientUnformatedConnectionAddress).ToString();
                    if (clientConnectionAddress.StartsWith("0.0.0.") && !clientConnectionAddress.EndsWith(".0"))
                    {
                        int domainStart = 0, domainEnd = 0;
                        for (int i = 8; i < firstResponse.Length; i++)
                        {
                            if (firstResponse[i] == 0)
                            {
                                if (domainStart == 0)
                                {
                                    domainStart = i + 1;
                                }
                                else if (domainEnd == 0)
                                {
                                    domainEnd = i;
                                }
                            }
                        }

                        if (domainEnd != 0 && domainStart != 0)
                        {
                            clientConnectionAddress = Encoding.ASCII.GetString(
                                firstResponse,
                                domainStart,
                                domainEnd - domainStart);
                        }
                        else
                        {
                            serverAresponse = 91;
                        }
                    }

                    byte[] serverResponse = new byte[8];
                    serverResponse[0] = 0;
                    serverResponse[1] = serverAresponse;
                    Array.Copy(firstResponse, 2, serverResponse, 2, 2); // PORT
                    Array.Copy(firstResponse, 4, serverResponse, 4, 4); // IP
                    client.RequestAddress = "socks://" + clientConnectionAddress + ":" + clientConnectionPort;
                    client.Write(serverResponse);
                    client.IsReceivingStarted = false;
                    if (serverAresponse != 90)
                    {
                        client.Close(
                            "Response Error, Code: " + serverAresponse,
                            null,
                            ErrorRenderer.HttpHeaderCode.C417ExpectationFailed,
                            true);
                        return;
                    }

                    firstResponse = new byte[0];
                    DirectHandle(client, clientConnectionAddress, clientConnectionPort, firstResponse);
                }
                catch (Exception e)
                {
                    client.Close(e.Message, e.StackTrace);
                }
            }
        }