コード例 #1
0
        /// <summary>
        /// When Tor receives a "RESOLVE" SOCKS command, it initiates
        /// a remote lookup of the hostname provided as the target address in the SOCKS
        /// request.
        /// </summary>
        internal async Task <IPAddress> ResolveAsync(string host)
        {
            // https://gitweb.torproject.org/torspec.git/tree/socks-extensions.txt#n44

            host = Guard.NotNullOrEmptyOrWhitespace(nameof(host), host, true);

            if (TorSocks5EndPoint is null)
            {
                var hostAddresses = await Dns.GetHostAddressesAsync(host);

                return(hostAddresses.First());
            }

            var cmd = CmdField.Resolve;

            var dstAddr = new AddrField(host);

            var dstPort = new PortField(0);

            var resolveRequest = new TorSocks5Request(cmd, dstAddr, dstPort);
            var sendBuffer     = resolveRequest.ToBytes();

            var receiveBuffer = await SendAsync(sendBuffer);

            var resolveResponse = new TorSocks5Response();

            resolveResponse.FromBytes(receiveBuffer);

            if (resolveResponse.Rep != RepField.Succeeded)
            {
                throw new TorSocks5FailureResponseException(resolveResponse.Rep);
            }
            return(IPAddress.Parse(resolveResponse.BndAddr.DomainOrIPv4));
        }
コード例 #2
0
 public TorSocks5Request(CmdField cmd, AddrField dstAddr, PortField dstPort)
 {
     Cmd     = Guard.NotNull(nameof(cmd), cmd);
     DstAddr = Guard.NotNull(nameof(dstAddr), dstAddr);
     DstPort = Guard.NotNull(nameof(dstPort), dstPort);
     Ver     = VerField.Socks5;
     Rsv     = RsvField.X00;
     Atyp    = dstAddr.Atyp;
 }
コード例 #3
0
 public TorSocks5Response(RepField rep, AddrField bndAddr, PortField bndPort)
 {
     Rep     = Guard.NotNull(nameof(rep), rep);
     BndAddr = Guard.NotNull(nameof(bndAddr), bndAddr);
     BndPort = Guard.NotNull(nameof(bndPort), bndPort);
     Ver     = VerField.Socks5;
     Rsv     = RsvField.X00;
     Atyp    = bndAddr.Atyp;
 }
コード例 #4
0
        void ReleaseDesignerOutlets()
        {
            if (HostField != null)
            {
                HostField.Dispose();
                HostField = null;
            }

            if (MessageField != null)
            {
                MessageField.Dispose();
                MessageField = null;
            }

            if (PortField != null)
            {
                PortField.Dispose();
                PortField = null;
            }

            if (StatusField != null)
            {
                StatusField.Dispose();
                StatusField = null;
            }

            if (TargetField != null)
            {
                TargetField.Dispose();
                TargetField = null;
            }

            if (UseridField != null)
            {
                UseridField.Dispose();
                UseridField = null;
            }

            if (PasswordField != null)
            {
                PasswordField.Dispose();
                PasswordField = null;
            }
        }
コード例 #5
0
        public override void FromBytes(byte[] bytes)
        {
            Guard.NotNullOrEmpty(nameof(bytes), bytes);
            Guard.MinimumAndNotNull($"{nameof(bytes)}.{nameof(bytes.Length)}", bytes.Length, 6);

            Ver = new VerField();
            Ver.FromByte(bytes[0]);

            Cmd = new CmdField();
            Cmd.FromByte(bytes[1]);

            Rsv = new RsvField();
            Rsv.FromByte(bytes[2]);

            Atyp = new AtypField();
            Atyp.FromByte(bytes[3]);

            DstAddr = new AddrField();
            DstAddr.FromBytes(bytes.Skip(4).Take(bytes.Length - 4 - 2).ToArray());

            DstPort = new PortField();
            DstPort.FromBytes(bytes.Skip(bytes.Length - 2).ToArray());
        }
コード例 #6
0
        public static void ShowBackingValueField(
            PortField data,
            SerializedProperty property,
            bool isConnected,
            bool includeChildren,
            GUIStyle style = null, params GUILayoutOption[] options)
        {
            var portData     = data.PortData;
            var labelContent = portData.ItemName != null ? new GUIContent(portData.ItemName) : new GUIContent(property.displayName);

            switch (portData.ShowBackingValue)
            {
            case ShowBackingValue.Unconnected:
                // Display a label if port is connected
                if (isConnected)
                {
                    EditorDrawerUtils.DrawLabelField(labelContent, style, options);
                }
                // Display an editable property field if port is not connected
                else
                {
                    ReactivePortDrawer.DrawPropertyValue(data.Value, property, labelContent);
                }

                break;

            case ShowBackingValue.Never:
                // Display a label
                EditorDrawerUtils.DrawLabelField(labelContent, style, options);
                break;

            case ShowBackingValue.Always:
                // Display an editable property field
                ReactivePortDrawer.DrawPropertyValue(data.Value, property, labelContent);
                break;
            }
        }
コード例 #7
0
        /// <summary>
        /// Tor attempts to find the canonical hostname for that IPv4 record
        /// </summary>
        internal async Task <string> ReverseResolveAsync(IPAddress iPv4)
        {
            // https://gitweb.torproject.org/torspec.git/tree/socks-extensions.txt#n55

            Guard.NotNull(nameof(iPv4), iPv4);

            if (TorSocks5EndPoint is null)             // Only Tor is iPv4 dependent
            {
                var host = await Dns.GetHostEntryAsync(iPv4);

                return(host.HostName);
            }

            Guard.Same($"{nameof(iPv4)}.{nameof(iPv4.AddressFamily)}", AddressFamily.InterNetwork, iPv4.AddressFamily);

            var cmd = CmdField.ResolvePtr;

            var dstAddr = new AddrField(iPv4.ToString());

            var dstPort = new PortField(0);

            var resolveRequest = new TorSocks5Request(cmd, dstAddr, dstPort);
            var sendBuffer     = resolveRequest.ToBytes();

            var receiveBuffer = await SendAsync(sendBuffer);

            var resolveResponse = new TorSocks5Response();

            resolveResponse.FromBytes(receiveBuffer);

            if (resolveResponse.Rep != RepField.Succeeded)
            {
                throw new TorSocks5FailureResponseException(resolveResponse.Rep);
            }
            return(resolveResponse.BndAddr.DomainOrIPv4);
        }
コード例 #8
0
        /// <param name="host">IPv4 or domain</param>
        internal async Task ConnectToDestinationAsync(string host, int port, bool isRecursiveCall = false)
        {
            host = Guard.NotNullOrEmptyOrWhitespace(nameof(host), host, true);
            Guard.MinimumAndNotNull(nameof(port), port, 0);

            if (TorSocks5EndPoint is null)
            {
                using (await AsyncLock.LockAsync().ConfigureAwait(false))
                {
                    TcpClient?.Dispose();
                    TcpClient = IPAddress.TryParse(host, out IPAddress ip) ? new TcpClient(ip.AddressFamily) : new TcpClient();
                    await TcpClient.ConnectAsync(host, port).ConfigureAwait(false);

                    Stream         = TcpClient.GetStream();
                    RemoteEndPoint = TcpClient.Client.RemoteEndPoint;
                }

                return;
            }

            var cmd = CmdField.Connect;

            var dstAddr = new AddrField(host);

            DestinationHost = dstAddr.DomainOrIPv4;

            var dstPort = new PortField(port);

            DestinationPort = dstPort.DstPort;

            var connectionRequest = new TorSocks5Request(cmd, dstAddr, dstPort);
            var sendBuffer        = connectionRequest.ToBytes();

            var receiveBuffer = await SendAsync(sendBuffer, isRecursiveCall : isRecursiveCall).ConfigureAwait(false);

            var connectionResponse = new TorSocks5Response();

            connectionResponse.FromBytes(receiveBuffer);

            if (connectionResponse.Rep != RepField.Succeeded)
            {
                // https://www.ietf.org/rfc/rfc1928.txt
                // When a reply(REP value other than X'00') indicates a failure, the
                // SOCKS server MUST terminate the TCP connection shortly after sending
                // the reply.This must be no more than 10 seconds after detecting the
                // condition that caused a failure.
                DisposeTcpClient();
                throw new TorSocks5FailureResponseException(connectionResponse.Rep);
            }

            // Do not check the Bnd. Address and Bnd. Port. because Tor does not seem to return any, ever. It returns zeros instead.
            // Generally also do not check anything but the success response, according to Socks5 RFC

            // If the reply code(REP value of X'00') indicates a success, and the
            // request was either a BIND or a CONNECT, the client may now start
            // passing data. If the selected authentication method supports
            // encapsulation for the purposes of integrity, authentication and / or
            // confidentiality, the data are encapsulated using the method-dependent
            // encapsulation.Similarly, when data arrives at the SOCKS server for
            // the client, the server MUST encapsulate the data as appropriate for
            // the authentication method in use.
        }
コード例 #9
0
        void ReleaseDesignerOutlets()
        {
            if (ServiceOptionsLabel != null)
            {
                ServiceOptionsLabel.Dispose();
                ServiceOptionsLabel = null;
            }

            if (ProtocolLabel != null)
            {
                ProtocolLabel.Dispose();
                ProtocolLabel = null;
            }

            if (RecordNameLabel != null)
            {
                RecordNameLabel.Dispose();
                RecordNameLabel = null;
            }

            if (PortField != null)
            {
                PortField.Dispose();
                PortField = null;
            }

            if (RecordNameField != null)
            {
                RecordNameField.Dispose();
                RecordNameField = null;
            }

            if (PriorityField != null)
            {
                PriorityField.Dispose();
                PriorityField = null;
            }

            if (ProtocolOptionsField != null)
            {
                ProtocolOptionsField.Dispose();
                ProtocolOptionsField = null;
            }

            if (ServiceOptionsField != null)
            {
                ServiceOptionsField.Dispose();
                ServiceOptionsField = null;
            }

            if (TargetHostField != null)
            {
                TargetHostField.Dispose();
                TargetHostField = null;
            }

            if (WeightField != null)
            {
                WeightField.Dispose();
                WeightField = null;
            }
        }