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