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