private volatile bool _disposedValue = false;         // To detect redundant calls

        protected virtual void Dispose(bool disposing)
        {
            if (!_disposedValue)
            {
                if (disposing)
                {
                    Interlocked.CompareExchange(ref _running, 2, 1);                     // If running, make it stopping.

                    if (TorSocks5EndPoint == null)
                    {
                        Interlocked.Exchange(ref _running, 3);
                    }

                    Stop?.Cancel();
                    while (IsStopping)
                    {
                        Task.Delay(50).GetAwaiter().GetResult();                         // DO NOT MAKE IT ASYNC (.NET Core threading brainfart)
                    }
                    Stop?.Dispose();
                    TorProcess?.Dispose();
                }

                _disposedValue = true;
            }
        }
        public void SetupTest()
        {
            var desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);

            // You should set here the path to your Tor browser exe. Mine was installed on my desktop because of that I'm using the below path.
            var torBinaryPath = string.Concat(desktopPath, @"\Tor Browser\Browser\firefox.exe");
            var process       = new Process();

            TorProcess = process;
            TorProcess.StartInfo.FileName    = torBinaryPath;
            TorProcess.StartInfo.Arguments   = "-n";
            TorProcess.StartInfo.WindowStyle = ProcessWindowStyle.Maximized;
            TorProcess.Start();

            var profile = new FirefoxProfile();

            profile.SetPreference("network.proxy.type", 1);
            profile.SetPreference("network.proxy.socks", "127.0.0.1");
            profile.SetPreference("network.proxy.socks_port", 9150);
            var firefoxOptions = new FirefoxOptions
            {
                Profile = profile
            };

            Driver = new FirefoxDriver(firefoxOptions);
            Wait   = new WebDriverWait(Driver, TimeSpan.FromSeconds(60));
        }
        public void GenerateHashPassword(SecureString password)
        {
            using (var insecurePassword = password.Insecure())
            {
                var torProcessStartInfo = new ProcessStartInfo(GetTorFileName())
                {
                    Arguments              = $"--hash-password {password}",
                    UseShellExecute        = false,
                    CreateNoWindow         = true,
                    RedirectStandardOutput = true,
                };

                try
                {
                    TorProcess = Process.Start(torProcessStartInfo);

                    var    sOut   = TorProcess.StandardOutput;
                    var    raw    = sOut.ReadToEnd();
                    var    lines  = raw.Split(Environment.NewLine);
                    string result = string.Empty;


                    logger.LogInformation(GetTorFileName());


                    //  If it's multi-line use the last non-empty line.
                    //  We don't want to pull in potential warnings.
                    if (lines.Length > 1)
                    {
                        var rlines = lines.Reverse();
                        foreach (var line in rlines)
                        {
                            if (!string.IsNullOrWhiteSpace(line))
                            {
                                result = Regex.Replace(line, Environment.NewLine, string.Empty);
                                logger.LogInformation($"Hopefully password line: {line}");
                                break;
                            }
                        }
                    }

                    if (!TorProcess.HasExited)
                    {
                        TorProcess.Kill();
                    }

                    sOut.Close();
                    TorProcess.Close();
                    TorProcess = null;

                    hashedPassword = Regex.Match(result, "16:[0-9A-F]+")?.Value ?? string.Empty;
                }
                catch (Exception ex)
                {
                    logger.LogWarning(ex.Message);
                }
            }
        }
Esempio n. 4
0
        public async Task StopAsync()
        {
            Interlocked.CompareExchange(ref _running, 2, 1);             // If running, make it stopping.

            if (TorSocks5EndPoint is null)
            {
                Interlocked.Exchange(ref _running, 3);
            }

            Stop?.Cancel();
            while (Interlocked.CompareExchange(ref _running, 3, 0) == 2)
            {
                await Task.Delay(50);
            }
            Stop?.Dispose();
            Stop = null;
            TorProcess?.Dispose();
            TorProcess = null;
        }
Esempio n. 5
0
        private volatile bool _disposedValue = false;         // To detect redundant calls

        protected virtual void Dispose(bool disposing)
        {
            if (!_disposedValue)
            {
                if (disposing)
                {
                    if (IsRunning)
                    {
                        Interlocked.Exchange(ref _running, 2);
                    }
                    Stop?.Cancel();
                    while (IsStopping)
                    {
                        Task.Delay(50).GetAwaiter().GetResult();                         // DO NOT MAKE IT ASYNC (.NET Core threading brainfart)
                    }
                    Stop?.Dispose();
                    TorProcess?.Dispose();
                }

                _disposedValue = true;
            }
        }
Esempio n. 6
0
        public async Task StopAsync()
        {
            _disposed = true;

            if (TorControlClient is TorControlClient torControlClient)
            {
                // Even though terminating the TCP connection with Tor would shut down Tor,
                // the spec is quite clear:
                // > As of Tor 0.2.5.2-alpha, Tor does not wait a while for circuits to
                // > close when shutting down because of an exiting controller. If you
                // > want to ensure a clean shutdown--and you should!--then send "SIGNAL
                // > SHUTDOWN" and wait for the Tor process to close.)
                if (Settings.TerminateOnExit)
                {
                    await torControlClient.SignalShutdownAsync().ConfigureAwait(false);
                }

                // Leads to Tor termination because we sent TAKEOWNERSHIP command.
                await torControlClient.DisposeAsync().ConfigureAwait(false);
            }

            // Dispose Tor process resources (does not stop/kill Tor process).
            TorProcess?.Dispose();
        }
 public void TeardownTest()
 {
     Driver.Quit();
     TorProcess.Kill();
 }
Esempio n. 8
0
        static void Main(string[] args)
        {
            try
            {
                using (var tp = new TorProcess())
                {
                    tp.Start(
                        behavior: TorProcess.StartBehavior.ReturnExisting,
                        windowStyle: System.Diagnostics.ProcessWindowStyle.Minimized);
                    if (tp.InitWait(
                            retrySleep: TimeSpan.FromSeconds(3),
                            maxWait: TimeSpan.FromMinutes(2)))
                    {
                        string       html = null;
                        const string url  = "https://check.torproject.org/";
                        using (var client = new WebClient())
                        {
                            client.Proxy = new SocksWebProxy();
                            html         = client.DownloadString(url);
                        }
                        var doc = new HtmlAgilityPack.HtmlDocument();
                        doc.LoadHtml(html);
                        var       nodes = doc.DocumentNode.SelectNodes("//p/strong");
                        IPAddress ip;
                        foreach (var node in nodes)
                        {
                            if (IPAddress.TryParse(node.InnerText, out ip))
                            {
                                Console.WriteLine(":::::::::::::::::::::");
                                if (html.Contains("Congratulations. This browser is configured to use Tor."))
                                {
                                    Console.WriteLine("Connected through Tor with IP: " + ip.ToString());
                                }
                                else
                                {
                                    Console.Write("Not connected through Tor with IP: " + ip.ToString());
                                }
                                Console.WriteLine(":::::::::::::::::::::");
                                return;
                            }
                        }
                        Console.WriteLine(":::::::::::::::::::::");
                        Console.Write("IP not found");
                        Console.WriteLine(":::::::::::::::::::::");
                    }
                    else
                    {
                        Console.WriteLine("Can not confirm if tor is running");
                    }
                }
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex.Message);
            }
            finally
            {
#if DEBUG
                Console.WriteLine("Press enter to continue...");
                Console.ReadLine();
#endif
            }
        }
        /// <summary>
        /// Starts Tor process if it is not running already.
        /// </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)
        {
            ThrowIfDisposed();

            try
            {
                // Is Tor already running? Either our Tor process from previous Wasabi Wallet run or possibly user's own Tor.
                bool isAlreadyRunning = await TcpConnectionFactory.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);
                }

                string torArguments = Settings.GetCmdArguments(TorSocks5EndPoint);

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

                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(startInfo);

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

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

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

                        if (isRunning)
                        {
                            break;
                        }

                        if (TorProcess.HasExited)
                        {
                            Logger.LogError("Tor process failed to start!");
                            return(false);
                        }

                        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);
        }