Example #1
0
        /// <summary>
        /// Creates a new instance of the object.
        /// </summary>
        /// <param name="settings">Tor settings.</param>
        /// <param name="torSocks5EndPoint">Valid Tor end point.</param>
        public TorProcessManager(TorSettings settings, EndPoint torSocks5EndPoint)
        {
            TorSocks5EndPoint = torSocks5EndPoint;
            TorProcess        = null;
            Settings          = settings;
            TorSocks5Client   = new TorSocks5Client(torSocks5EndPoint);

            IoHelpers.EnsureContainingDirectoryExists(Settings.LogFilePath);
        }
Example #2
0
        /// <summary>
        /// Creates a new instance of the object.
        /// </summary>
        /// <param name="settings">Tor settings.</param>
        /// <param name="torSocks5EndPoint">Valid Tor end point.</param>
        public TorProcessManager(TorSettings settings, EndPoint torSocks5EndPoint)
        {
            TorSocks5EndPoint = torSocks5EndPoint;
            _monitorState     = StateNotStarted;
            Stop            = new CancellationTokenSource();
            TorProcess      = null;
            Settings        = settings;
            TorSocks5Client = new TorSocks5Client(torSocks5EndPoint);

            IoHelpers.EnsureContainingDirectoryExists(Settings.LogFilePath);
        }
Example #3
0
        /// <param name="torSocks5EndPoint">Opt out Tor with null.</param>
        public static async Task <bool> IsTorRunningAsync(EndPoint torSocks5EndPoint)
        {
            using var client = new TorSocks5Client(torSocks5EndPoint);
            try
            {
                await client.ConnectAsync().ConfigureAwait(false);

                await client.HandshakeAsync().ConfigureAwait(false);
            }
            catch (ConnectionException)
            {
                return(false);
            }
            return(true);
        }
        public async Task ThrowsProperExceptionsAsync()
        {
            var manager = new TorSocks5Manager(SharedFixture.TorSock5EndPoint);
            await Assert.ThrowsAsync <TorSocks5FailureResponseException>(async()
                                                                         => await manager.ReverseResolveAsync(IPAddress.Parse("0.64.147.228"), isolateStream: false));

            await Assert.ThrowsAsync <TorSocks5FailureResponseException>(async()
                                                                         =>
            {
                TorSocks5Client c1 = null;
                try
                {
                    c1 = await manager.EstablishTcpConnectionAsync(new IPEndPoint(IPAddress.Parse("192.64.147.228"), 302), false);
                }
                finally
                {
                    c1?.Dispose();
                }
            });
        }
        public async Task CanConnectDomainAndIpAsync()
        {
            var manager = new TorSocks5Manager(SharedFixture.TorSock5EndPoint);

            TorSocks5Client c1 = null;
            TorSocks5Client c2 = null;

            try
            {
                c1 = await manager.EstablishTcpConnectionAsync(new IPEndPoint(IPAddress.Parse("192.64.147.228"), 80));

                c2 = await manager.EstablishTcpConnectionAsync("google.com", 443);

                c2 = await manager.EstablishTcpConnectionAsync("facebookcorewwwi.onion", 443);
            }
            finally
            {
                c1?.Dispose();
                c2?.Dispose();
            }
        }
Example #6
0
        /// <summary>
        /// Installs Tor if it is not installed, then it starts Tor.
        /// </summary>
        /// <param name="ensureRunning">
        /// If <c>false</c>, Tor is started but no attempt to verify that it actually runs is made.
        /// <para>If <c>true</c>, we start Tor and attempt to connect to it to verify it is running (at most 25 attempts).</para>
        /// </param>
        public async Task <bool> StartAsync(bool ensureRunning)
        {
            try
            {
                // Is Tor already running? Either our Tor process from previous Wasabi Wallet run or possibly user's own Tor.
                bool isAlreadyRunning = await TorSocks5Client.IsTorRunningAsync().ConfigureAwait(false);

                if (isAlreadyRunning)
                {
                    string msg = TorSocks5EndPoint is IPEndPoint endpoint
                                                ? $"Tor is already running on {endpoint.Address}:{endpoint.Port}."
                                                : "Tor is already running.";
                    Logger.LogInfo(msg);
                    return(true);
                }

                // Install Tor if it is not installed and verify Tor is not tampered with (using hash/checksum).
                bool verified = await new TorInstallator(Settings).VerifyInstallationAsync().ConfigureAwait(false);

                if (!verified)
                {
                    Logger.LogInfo("Failed to verify Tor installation.");
                    return(false);
                }

                string torArguments = Settings.GetCmdArguments(TorSocks5EndPoint) + $" --Log \"notice file {Settings.LogFilePath}\"";

                var startInfo = new ProcessStartInfo
                {
                    FileName               = Settings.TorBinaryFilePath,
                    Arguments              = torArguments,
                    UseShellExecute        = false,
                    CreateNoWindow         = true,
                    RedirectStandardOutput = true,
                    WorkingDirectory       = Settings.TorDir
                };

                if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    var env = startInfo.EnvironmentVariables;

                    env["LD_LIBRARY_PATH"] = !env.ContainsKey("LD_LIBRARY_PATH") || string.IsNullOrEmpty(env["LD_LIBRARY_PATH"])
                                                ? Settings.TorBinaryDir
                                                : Settings.TorBinaryDir + Path.PathSeparator + env["LD_LIBRARY_PATH"];

                    Logger.LogDebug($"Environment variable 'LD_LIBRARY_PATH' set to: '{env["LD_LIBRARY_PATH"]}'.");
                }

                TorProcess = new ProcessAsync(startInfo);

                Logger.LogInfo($"Starting Tor process ...");
                TorProcess.Start();

                if (ensureRunning)
                {
                    int i = 0;
                    while (true)
                    {
                        i++;

                        bool isRunning = await TorSocks5Client.IsTorRunningAsync().ConfigureAwait(false);

                        if (isRunning)
                        {
                            break;
                        }

                        const int MaxAttempts = 25;

                        if (i >= MaxAttempts)
                        {
                            Logger.LogError($"All {MaxAttempts} attempts to connect to Tor failed.");
                            return(false);
                        }

                        // Wait 250 milliseconds between attempts.
                        await Task.Delay(250).ConfigureAwait(false);
                    }

                    Logger.LogInfo("Tor is running.");
                    return(true);
                }
            }
            catch (Exception ex)
            {
                Logger.LogError("Could not automatically start Tor. Try running Tor manually.", ex);
            }

            return(false);
        }