private async Task SetupTorAsync(ClientInteraction interaction, ConnectionSettingsBase settings, string torPath) { var tor = settings as ITorConnectionSettings; if (tor == null) { throw new ConfigException("TOR Settings not properly configured"); } _Disposables.Add(await tor.SetupAsync(interaction, torPath).ConfigureAwait(false)); }
private async Task SetupTorAsync(ClientInteraction interaction, ConnectionSettingsBase settings, string torPath) { var tor = settings as ITorConnectionSettings; if (tor == null) { return; } _Disposables.Add(await tor.SetupAsync(interaction, torPath).ConfigureAwait(false)); }
/// <summary>Invokes the interaction synchronously.</summary> /// <param name="clientSession">The client Session.</param> /// <param name="interaction">The interaction.</param> public static void InvokeInteraction( this ClientSession clientSession, ClientInteraction interaction, int duration = AwaitInteractionDuration) { clientSession.AwaitReady(() => clientSession.InvokeInteractionAsync(interaction), session => session.State == ClientSessionState.Ready, false, AwaitInteractionDuration); }
public async Task ConfigureAsync(TumblerConfiguration conf, ClientInteraction interaction) { try { await ConfigureAsyncCore(conf, interaction).ConfigureAwait(false); } catch { Dispose(); throw; } }
private async Task SetupTorAsync(ClientInteraction interaction, ConnectionSettingsBase settings, string torPath) { var tor = settings as ITorConnectionSettings; if (tor == null) { throw new ConfigException("TOR Settings not properly configured"); } try { var torSettings = await tor.SetupAsync(interaction, torPath).ConfigureAwait(false); _Disposables.Add(torSettings); } catch (ConfigException cex) { throw new PrivacyProtocolConfigException(PrivacyProtocolType.Tor, cex); } }
public async Task <IDisposable> SetupAsync(ClientInteraction interaction, string torPath) { var autoConfig = Proxy.Address.Equals(IPAddress.Parse("127.0.0.1")); if (!await TestConnectionAsync(Proxy).ConfigureAwait(false)) { if (torPath != null && autoConfig) { var args = $"-socksport {Proxy.Port}"; await interaction.AskConnectToTorAsync(torPath, args).ConfigureAwait(false); try { var processInfo = new ProcessStartInfo(torPath) { Arguments = args, UseShellExecute = false, CreateNoWindow = true, RedirectStandardOutput = false }; var process = new ProcessDisposable(Process.Start(processInfo)); try { await SetupAsync(interaction, null).ConfigureAwait(false); } catch { process.Dispose(); throw; } return(process); } catch (Exception ex) { Logs.Configuration.LogError($"Failed to start Tor, please verify your configuration settings \"torpath\": {ex.Message}"); } } throw new ConfigException($"Unable to connect to SOCKS {Proxy.Address}:{Proxy.Port}"); } return(NullDisposable.Instance); }
/// <summary>Invokes the interaction synchronously.</summary> /// <param name="clientSession">The client Session.</param> /// <param name="interaction">The interaction.</param> public static void InvokeInteraction(this ClientSession clientSession, ClientInteraction interaction) { clientSession.AwaitReady(() => clientSession.InvokeInteractionAsync(interaction)); }
async Task ConfigureAsyncCore(TumblerConfiguration conf, ClientInteraction interaction) { Cooperative = conf.Cooperative; ClassicTumblerParameters = conf.ClassicTumblerParameters.Clone(); Network = conf.Network; LocalEndpoint = conf.Listen; RPCClient rpcClient = null; try { rpcClient = conf.RPC.ConfigureRPCClient(conf.Network); } catch { throw new ConfigException("Please, fix rpc settings in " + conf.ConfigurationFile); } bool torConfigured = false; if (conf.TorSettings != null) { Exception error = null; try { _Resources.Add(await conf.TorSettings.SetupAsync(interaction, conf.TorPath).ConfigureAwait(false)); Logs.Configuration.LogInformation("Successfully authenticated to Tor"); var torRSA = Path.Combine(conf.DataDir, "Tor.rsa"); TorPrivateKey = null; if (File.Exists(torRSA)) { TorPrivateKey = File.ReadAllText(torRSA, Encoding.UTF8); } TorConnection = conf.TorSettings.CreateTorClient2(); _Resources.Add(TorConnection); await TorConnection.ConnectAsync().ConfigureAwait(false); await TorConnection.AuthenticateAsync().ConfigureAwait(false); var result = await TorConnection.RegisterHiddenServiceAsync(conf.Listen, conf.TorSettings.VirtualPort, TorPrivateKey).ConfigureAwait(false); if (TorPrivateKey == null) { File.WriteAllText(torRSA, result.PrivateKey, Encoding.UTF8); Logs.Configuration.LogWarning($"Tor RSA private key generated to {torRSA}"); } var tumblerUri = new TumblerUrlBuilder { Port = result.HiddenServiceUri.Port, Host = result.HiddenServiceUri.Host }; TumblerUris.Add(tumblerUri); TorUri = tumblerUri.GetRoutableUri(false); ClassicTumblerParameters.ExpectedAddress = TorUri.AbsoluteUri; Logs.Configuration.LogInformation($"Tor configured on {result.HiddenServiceUri}"); torConfigured = true; } catch (ConfigException ex) { error = ex; } catch (TorException ex) { error = ex; } catch (ClientInteractionException) { } if (error != null) { Logs.Configuration.LogWarning("Error while configuring Tor hidden service: " + error.Message); } } if (!torConfigured) { Logs.Configuration.LogWarning("The tumbler is not configured as a Tor Hidden service"); } var tumlerKeyData = LoadRSAKeyData(conf.DataDir, "Tumbler.pem", conf.NoRSAProof); var voucherKeyData = LoadRSAKeyData(conf.DataDir, "Voucher.pem", conf.NoRSAProof); ClassicTumblerParameters.ServerKey = tumlerKeyData.Item2; ClassicTumblerParameters.VoucherKey = voucherKeyData.Item2; TumblerKey = tumlerKeyData.Item1; VoucherKey = voucherKeyData.Item1; if (!conf.TorMandatory) { var httpUri = new TumblerUrlBuilder() { Host = LocalEndpoint.Address.ToString(), Port = LocalEndpoint.Port, }; TumblerUris.Add(httpUri); if (String.IsNullOrEmpty(ClassicTumblerParameters.ExpectedAddress)) { ClassicTumblerParameters.ExpectedAddress = httpUri.GetRoutableUri(false).AbsoluteUri; } } ClassicTumblerParametersHash = ClassicTumblerParameters.GetHash(); var configurationHash = ClassicTumblerParameters.GetHash(); foreach (var uri in TumblerUris) { uri.ConfigurationHash = configurationHash; } Logs.Configuration.LogInformation(""); Logs.Configuration.LogInformation($"--------------------------------"); Logs.Configuration.LogInformation($"Shareable URIs of the running tumbler are:"); foreach (var uri in TumblerUris) { Logs.Configuration.LogInformation(uri.ToString()); } Logs.Configuration.LogInformation($"--------------------------------"); Logs.Configuration.LogInformation(""); var dbreeze = new DBreezeRepository(Path.Combine(conf.DataDir, "db2")); Repository = dbreeze; _Resources.Add(dbreeze); Tracker = new Tracker(dbreeze, Network); Services = ExternalServices.CreateFromRPCClient(rpcClient, dbreeze, Tracker, true); }
public async Task ConfigureAsync(TumblerClientConfigurationBase configuration, ClientInteraction interaction) { interaction = interaction ?? new AcceptAllClientInteraction(); Network = configuration.Network; TumblerServer = configuration.TumblerServer; BobSettings = configuration.BobConnectionSettings; AliceSettings = configuration.AliceConnectionSettings; AllowInsecure = configuration.AllowInsecure; if (this.TumblerServer.IsOnion) { await SetupTorAsync(interaction, configuration.TorPath).ConfigureAwait(false); } else if (configuration.TorMandatory) { throw new ConfigException("The tumbler server should use TOR"); } Cooperative = configuration.Cooperative; Repository = configuration.DBreezeRepository; _Disposables.Add(Repository); Tracker = configuration.Tracker; Services = configuration.Services; DestinationWallet = configuration.DestinationWallet; TumblerParameters = Repository.Get <ClassicTumbler.ClassicTumblerParameters>("Configuration", TumblerServer.ToString()); if (TumblerParameters != null && TumblerParameters.GetHash() != configuration.TumblerServer.ConfigurationHash) { TumblerParameters = null; } if (!configuration.OnlyMonitor) { var client = CreateTumblerClient(0); if (TumblerParameters == null) { Logs.Configuration.LogInformation("Downloading tumbler information of " + configuration.TumblerServer.ToString()); var parameters = Retry(3, () => client.GetTumblerParameters()); if (parameters == null) { throw new ConfigException("Unable to download tumbler's parameters"); } if (parameters.GetHash() != configuration.TumblerServer.ConfigurationHash) { throw new ConfigException("The tumbler returned an invalid configuration"); } var standardCycles = new StandardCycles(configuration.Network); var standardCycle = standardCycles.GetStandardCycle(parameters); if (parameters.ExpectedAddress != TumblerServer.GetRoutableUri(false).AbsoluteUri) { throw new ConfigException("This tumbler has parameters used for an unexpected uri"); } Logs.Configuration.LogInformation("Checking RSA key proof and standardness of the settings..."); if (standardCycle == null || !parameters.IsStandard()) { Logs.Configuration.LogWarning("This tumbler has non standard parameters"); if (!AllowInsecure) { throw new ConfigException("This tumbler has non standard parameters"); } standardCycle = null; } await interaction.ConfirmParametersAsync(parameters, standardCycle).ConfigureAwait(false); Repository.UpdateOrInsert("Configuration", TumblerServer.ToString(), parameters, (o, n) => n); TumblerParameters = parameters; Logs.Configuration.LogInformation("Tumbler parameters saved"); } Logs.Configuration.LogInformation($"Using tumbler {TumblerServer.ToString()}"); } }
public async Task <IDisposable> SetupAsync(ClientInteraction interaction, string torPath) { var autoConfig = string.IsNullOrEmpty(Password) && String.IsNullOrEmpty(CookieFile) && Server.Address.Equals(IPAddress.Parse("127.0.0.1")); var connectResult = await TryConnectAsync().ConfigureAwait(false); if (connectResult == TorConnectionSettings.ConnectionTest.SocketError) { if (torPath != null && autoConfig) { var args = $"-controlport {Server.Port} -cookieauthentication 1"; await interaction.AskConnectToTorAsync(torPath, args).ConfigureAwait(false); try { var processInfo = new ProcessStartInfo(torPath) { Arguments = args, UseShellExecute = false, CreateNoWindow = true, RedirectStandardOutput = false }; var process = new ProcessDisposable(Process.Start(processInfo)); try { await SetupAsync(interaction, null).ConfigureAwait(false); } catch { process.Dispose(); throw; } return(process); } catch (Exception ex) { Logs.Configuration.LogError($"Failed to start Tor, please verify your configuration settings \"torpath\": {ex.Message}"); } } throw new ConfigException("Unable to connect to tor control port"); } else if (connectResult == TorConnectionSettings.ConnectionTest.Success) { return(NullDisposable.Instance); } else if (!autoConfig && connectResult == TorConnectionSettings.ConnectionTest.AuthError) { throw new ConfigException("Unable to authenticate tor control port"); } if (autoConfig) { AutoDetectCookieFile(); } connectResult = await TryConnectAsync().ConfigureAwait(false); if (connectResult != TorConnectionSettings.ConnectionTest.Success) { throw new ConfigException("Unable to authenticate tor control port"); } return(NullDisposable.Instance); }
async Task ConfigureAsyncCore(TumblerConfiguration conf, ClientInteraction interaction) { Cooperative = conf.Cooperative; ClassicTumblerParameters = conf.ClassicTumblerParameters.Clone(); Network = conf.Network; LocalEndpoint = conf.Listen; bool torConfigured = false; if (conf.TorSettings != null) { Exception error = null; try { _Resources.Add(await conf.TorSettings.SetupAsync(interaction, conf.TorPath).ConfigureAwait(false)); Logs.Configuration.LogInformation("Successfully authenticated to Tor"); var torRSA = Path.Combine(conf.DataDir, "Tor.rsa"); string privateKey = null; if (File.Exists(torRSA)) { privateKey = File.ReadAllText(torRSA, Encoding.UTF8); } TorConnection = conf.TorSettings.CreateTorClient2(); _Resources.Add(TorConnection); await TorConnection.ConnectAsync().ConfigureAwait(false); await TorConnection.AuthenticateAsync().ConfigureAwait(false); var result = await TorConnection.RegisterHiddenServiceAsync(conf.Listen, conf.TorSettings.VirtualPort, privateKey).ConfigureAwait(false); if (privateKey == null) { File.WriteAllText(torRSA, result.PrivateKey, Encoding.UTF8); Logs.Configuration.LogWarning($"Tor RSA private key generated to {torRSA}"); } var tumblerUri = new TumblerUrlBuilder(); tumblerUri.Port = result.HiddenServiceUri.Port; tumblerUri.Host = result.HiddenServiceUri.Host; TumblerUris.Add(tumblerUri); TorUri = tumblerUri.RoutableUri; Logs.Configuration.LogInformation($"Tor configured on {result.HiddenServiceUri}"); torConfigured = true; } catch (ConfigException ex) { error = ex; } catch (TorException ex) { error = ex; } catch (ClientInteractionException) { } if (error != null) { Logs.Configuration.LogWarning("Error while configuring Tor hidden service: " + error.Message); } } if (!torConfigured) { Logs.Configuration.LogWarning("The tumbler is not configured as a Tor Hidden service"); } var rsaFile = Path.Combine(conf.DataDir, "Tumbler.pem"); if (!File.Exists(rsaFile)) { Logs.Configuration.LogWarning("RSA private key not found, please backup it. Creating..."); TumblerKey = new RsaKey(); File.WriteAllBytes(rsaFile, TumblerKey.ToBytes()); Logs.Configuration.LogInformation("RSA key saved (" + rsaFile + ")"); } else { Logs.Configuration.LogInformation("RSA private key found (" + rsaFile + ")"); TumblerKey = new RsaKey(File.ReadAllBytes(rsaFile)); } var voucherFile = Path.Combine(conf.DataDir, "Voucher.pem"); if (!File.Exists(voucherFile)) { Logs.Configuration.LogWarning("Creation of Voucher Key"); VoucherKey = new RsaKey(); File.WriteAllBytes(voucherFile, VoucherKey.ToBytes()); Logs.Configuration.LogInformation("RSA key saved (" + voucherFile + ")"); } else { Logs.Configuration.LogInformation("Voucher key found (" + voucherFile + ")"); VoucherKey = new RsaKey(File.ReadAllBytes(voucherFile)); } ClassicTumblerParameters.ServerKey = TumblerKey.PubKey; ClassicTumblerParameters.VoucherKey = VoucherKey.PubKey; ClassicTumblerParametersHash = ClassicTumblerParameters.GetHash(); if (conf.AllowInsecure) { TumblerUris.Add(new TumblerUrlBuilder() { Host = LocalEndpoint.Address.ToString(), Port = LocalEndpoint.Port, }); } var configurationHash = ClassicTumblerParameters.GetHash(); foreach (var uri in TumblerUris) { uri.ConfigurationHash = configurationHash; } Logs.Configuration.LogInformation(""); Logs.Configuration.LogInformation($"--------------------------------"); Logs.Configuration.LogInformation($"Shareable URIs of the running tumbler are:"); foreach (var uri in TumblerUris) { Logs.Configuration.LogInformation(uri.ToString()); } Logs.Configuration.LogInformation($"--------------------------------"); Logs.Configuration.LogInformation(""); Repository = conf.DBreezeRepository; _Resources.Add(Repository); Tracker = conf.Tracker; Services = conf.Services; }
public static async Task <TumblerClientRuntime> FromConfigurationAsync(TumblerClientConfigurationBase configuration, ClientInteraction interaction) { TumblerClientRuntime runtime = new TumblerClientRuntime(); try { await runtime.ConfigureAsync(configuration, interaction).ConfigureAwait(false); } catch { runtime.Dispose(); throw; } return(runtime); }
public async Task ConfigureAsync(TumblerClientConfigurationBase configuration, TumblerProtocolType tumblerProtocol, ClientInteraction interaction = null, bool connectionTest = false) { interaction = interaction ?? new AcceptAllClientInteraction(); Network = configuration.Network; // if connectiontest then just test the connection, don't care about anything else // todo: refactor it in NTumbleBit for proper connectionTest, it's hacking if (connectionTest) { TumblerServer = configuration.TumblerServer; BobSettings = configuration.BobConnectionSettings; AliceSettings = configuration.AliceConnectionSettings; AllowInsecure = configuration.AllowInsecure; if (this.TumblerServer.IsOnion) { await SetupTorAsync(interaction, configuration.TorPath).ConfigureAwait(false); } else if (configuration.TorMandatory) { throw new ConfigException("The tumbler server should use TOR"); } var client = CreateTumblerClient(0, tumblerProtocol, connectTimeout: TimeSpan.FromSeconds(15)); TumblerParameters = Retry(1, () => client.GetTumblerParameters()); if (TumblerParameters == null) { throw new ConfigException("Unable to download tumbler's parameters"); } return; } Repository = configuration.DBreezeRepository; _Disposables.Add(Repository); Tracker = configuration.Tracker; Services = configuration.Services; if (!configuration.OnlyMonitor) { DataDir = configuration.DataDir; TumblerServer = configuration.TumblerServer; BobSettings = configuration.BobConnectionSettings; AliceSettings = configuration.AliceConnectionSettings; AllowInsecure = configuration.AllowInsecure; if (this.TumblerServer.IsOnion) { await SetupTorAsync(interaction, configuration.TorPath).ConfigureAwait(false); } else if (configuration.TorMandatory) { throw new ConfigException("The tumbler server should use TOR"); } Cooperative = configuration.Cooperative; DestinationWallet = configuration.DestinationWallet; try { TumblerParameters = Repository.Get <ClassicTumblerParameters>("Configuration", configuration.TumblerServer.ToString()); } catch { TumblerParameters = null; } if (TumblerParameters != null && TumblerParameters.GetHash() != configuration.TumblerServer.ConfigurationHash) { TumblerParameters = null; } var client = CreateTumblerClient(0, tumblerProtocol); Logs.Configuration.LogInformation("Downloading tumbler information of " + configuration.TumblerServer.ToString()); var parameters = Retry(3, () => client.GetTumblerParameters()); if (parameters == null) { throw new ConfigException("Unable to download tumbler's parameters"); } if (parameters.GetHash() != configuration.TumblerServer.ConfigurationHash) { throw new ConfigException("The tumbler returned an invalid configuration"); } var standardCycles = new StandardCycles(configuration.Network); var standardCycle = standardCycles.GetStandardCycle(parameters); if (parameters.ExpectedAddress != TumblerServer.GetRoutableUri(false).AbsoluteUri) { throw new ConfigException("This tumbler has parameters used for an unexpected uri"); } Logs.Configuration.LogInformation("Checking RSA key proof and standardness of the settings..."); try { if (standardCycle == null || !parameters.IsStandard()) { Logs.Configuration.LogWarning("This tumbler has non standard parameters"); if (!AllowInsecure) { throw new ConfigException("This tumbler has non standard parameters"); } standardCycle = null; } } catch (Exception e) { Console.WriteLine("Exception checking tumbler parameters: " + e); } await interaction.ConfirmParametersAsync(parameters, standardCycle).ConfigureAwait(false); if (TumblerParameters == null) { Repository.UpdateOrInsert("Configuration", TumblerServer.ToString(), parameters, (o, n) => n); TumblerParameters = parameters; Logs.Configuration.LogInformation("Tumbler parameters saved"); } Logs.Configuration.LogInformation($"Using tumbler {TumblerServer.ToString()}"); } }
public async Task ConfigureAsync(TumblerClientConfigurationBase configuration, ClientInteraction interaction = null, bool connectionTest = false) { interaction = interaction ?? new AcceptAllClientInteraction(); Network = configuration.Network;
public static async Task <TumblerClientRuntime> FromConfigurationAsync(TumblerClientConfiguration configuration, ClientInteraction interaction) { TumblerClientRuntime runtime = new TumblerClientRuntime(); try { await runtime.ConfigureAsync(configuration, interaction).ConfigureAwait(false); } catch (Exception ex) { var message = ex.Message; runtime.Dispose(); throw; } return(runtime); }
public static TumblerClientRuntime FromConfiguration(TumblerClientConfigurationBase configuration, ClientInteraction interaction = null, bool connectionTest = false) { return(FromConfigurationAsync(configuration, interaction, connectionTest).GetAwaiter().GetResult()); }
public async Task ConfigureAsync(TumblerClientConfiguration configuration, ClientInteraction interaction) { interaction = interaction ?? new AcceptAllClientInteraction(); Network = configuration.Network; TumblerServer = configuration.TumblerServer; BobSettings = configuration.BobConnectionSettings; AliceSettings = configuration.AliceConnectionSettings; AllowInsecure = configuration.AllowInsecure; await SetupTorAsync(interaction, configuration.TorPath).ConfigureAwait(false); RPCClient rpc = null; try { rpc = configuration.RPCArgs.ConfigureRPCClient(configuration.Network); } catch { throw new ConfigException("Please, fix rpc settings in " + configuration.ConfigurationFile); } var dbreeze = new DBreezeRepository(Path.Combine(configuration.DataDir, "db2")); Cooperative = configuration.Cooperative; Repository = dbreeze; _Disposables.Add(dbreeze); Tracker = new Tracker(dbreeze, Network); Services = ExternalServices.CreateFromRPCClient(rpc, dbreeze, Tracker); if (configuration.OutputWallet.RootKey != null && configuration.OutputWallet.KeyPath != null) { DestinationWallet = new ClientDestinationWallet(configuration.OutputWallet.RootKey, configuration.OutputWallet.KeyPath, dbreeze, configuration.Network); } else if (configuration.OutputWallet.RPCArgs != null) { try { DestinationWallet = new RPCDestinationWallet(configuration.OutputWallet.RPCArgs.ConfigureRPCClient(Network)); } catch { throw new ConfigException("Please, fix outputwallet rpc settings in " + configuration.ConfigurationFile); } } else { throw new ConfigException("Missing configuration for outputwallet"); } TumblerParameters = dbreeze.Get <ClassicTumbler.ClassicTumblerParameters>("Configuration", configuration.TumblerServer.Uri.AbsoluteUri); if (TumblerParameters != null && TumblerParameters.GetHash() != configuration.TumblerServer.ConfigurationHash) { TumblerParameters = null; } if (!configuration.OnlyMonitor) { var client = CreateTumblerClient(0); if (TumblerParameters == null) { Logs.Configuration.LogInformation("Downloading tumbler information of " + configuration.TumblerServer.Uri.AbsoluteUri); var parameters = Retry(3, () => client.GetTumblerParameters()); if (parameters == null) { throw new ConfigException("Unable to download tumbler's parameters"); } if (parameters.GetHash() != configuration.TumblerServer.ConfigurationHash) { throw new ConfigException("The tumbler returned an invalid configuration"); } var standardCycles = new StandardCycles(configuration.Network); var standardCycle = standardCycles.GetStandardCycle(parameters); if (standardCycle == null || !parameters.IsStandard()) { Logs.Configuration.LogWarning("This tumbler has non standard parameters"); if (!AllowInsecure) { throw new ConfigException("This tumbler has non standard parameters"); } standardCycle = null; } await interaction.ConfirmParametersAsync(parameters, standardCycle).ConfigureAwait(false); Repository.UpdateOrInsert("Configuration", TumblerServer.Uri.AbsoluteUri, parameters, (o, n) => n); TumblerParameters = parameters; Logs.Configuration.LogInformation("Tumbler parameters saved"); } Logs.Configuration.LogInformation($"Using tumbler {TumblerServer.Uri.AbsoluteUri}"); } }
private void OnArriveAtClient(ClientInteraction client) { client.TryStartTransaction(); }
public static TumblerRuntime FromConfiguration(TumblerConfiguration conf, ClientInteraction interaction) { return(FromConfigurationAsync(conf, interaction).GetAwaiter().GetResult()); }
private async Task SetupTorAsync(ClientInteraction interaction, string torPath) { await SetupTorAsync(interaction, AliceSettings, torPath).ConfigureAwait(false); await SetupTorAsync(interaction, BobSettings, torPath).ConfigureAwait(false); }
public static async Task <TumblerRuntime> FromConfigurationAsync(TumblerConfiguration conf, ClientInteraction interaction) { if (conf == null) { throw new ArgumentNullException("conf"); } TumblerRuntime runtime = new TumblerRuntime(); await runtime.ConfigureAsync(conf, interaction).ConfigureAwait(false); return(runtime); }
public static async Task <TumblerClientRuntime> FromConfigurationAsync(TumblerClientConfigurationBase configuration, ClientInteraction interaction = null, bool connectionTest = false) { TumblerClientRuntime runtime = new TumblerClientRuntime(); try { await runtime.ConfigureAsync(configuration, interaction, connectionTest).ConfigureAwait(false); } catch (Exception e) { Console.WriteLine("Exception during runtime configuration: " + e); runtime?.Dispose(); throw; } return(runtime); }
async Task ConfigureAsyncCore(TumblerConfiguration conf, ClientInteraction interaction) { Cooperative = conf.Cooperative; ClassicTumblerParameters = conf.ClassicTumblerParameters.Clone(); Network = conf.Network; LocalEndpoint = conf.Listen; TumblerProtocol = conf.TumblerProtocol; bool torConfigured = false; if (conf.TorSettings != null) { Exception error = null; try { _Resources.Add(await conf.TorSettings.SetupAsync(interaction, conf.TorPath).ConfigureAwait(false)); Logs.Configuration.LogInformation("Successfully authenticated to Tor"); var torRSA = Path.Combine(conf.DataDir, "Tor.rsa"); TorPrivateKey = null; if (File.Exists(torRSA)) { TorPrivateKey = File.ReadAllText(torRSA, Encoding.UTF8); } TorConnection = conf.TorSettings.CreateTorClient2(); _Resources.Add(TorConnection); await TorConnection.ConnectAsync().ConfigureAwait(false); await TorConnection.AuthenticateAsync().ConfigureAwait(false); var result = await TorConnection.RegisterHiddenServiceAsync(conf.Listen, conf.TorSettings.VirtualPort, TorPrivateKey).ConfigureAwait(false); if (TorPrivateKey == null) { File.WriteAllText(torRSA, result.PrivateKey, Encoding.UTF8); Logs.Configuration.LogWarning($"Tor RSA private key generated to {torRSA}"); } var tumblerUri = new TumblerUrlBuilder { Host = result.HiddenServiceUri.Host, Port = result.HiddenServiceUri.Port }; TumblerUris.Add(tumblerUri); TorUri = tumblerUri.GetRoutableUri(false); ClassicTumblerParameters.ExpectedAddress = TorUri.AbsoluteUri; Logs.Configuration.LogInformation($"Tor configured on {result.HiddenServiceUri}"); torConfigured = true; } catch (ConfigException ex) { error = ex; } catch (TorException ex) { error = ex; } catch (ClientInteractionException) { } if (error != null) { Logs.Configuration.LogWarning("Error while configuring Tor hidden service: " + error.Message); } } if (!torConfigured) { Logs.Configuration.LogWarning("The tumbler is not configured as a Tor Hidden service"); } var tumlerKeyData = LoadRSAKeyData(conf.DataDir, "Tumbler.pem", conf.NoRSAProof); var voucherKeyData = LoadRSAKeyData(conf.DataDir, "Voucher.pem", conf.NoRSAProof); ClassicTumblerParameters.ServerKey = tumlerKeyData.Item2; ClassicTumblerParameters.VoucherKey = voucherKeyData.Item2; TumblerKey = tumlerKeyData.Item1; VoucherKey = voucherKeyData.Item1; if (!conf.TorMandatory) { // Construct a valid 16 character long onion address which will be used as a reference (it is not meant to be a valid IP address or hostname) string dummyOnionAddress = Environment.MachineName; if (dummyOnionAddress.Length < 16) { dummyOnionAddress = dummyOnionAddress.PadRight(16, '-'); } TumblerUrlBuilder httpUri; //Set the Tor URI only if the Tor address has not been already set if (TorUri == null) { //Add onion style address, this is just a display address used when running MasterNode without Tor httpUri = new TumblerUrlBuilder() { Host = $"{dummyOnionAddress}.dummy", Port = conf.Listen.Port }; TumblerUris.Add(httpUri); TorUri = httpUri.GetRoutableUri(false); //Add IP address of the network card with Internet connection httpUri = new TumblerUrlBuilder() { Host = LocalEndpoint.Address.ToString(), Port = LocalEndpoint.Port }; TumblerUris.Add(httpUri); if (String.IsNullOrEmpty(ClassicTumblerParameters.ExpectedAddress)) { ClassicTumblerParameters.ExpectedAddress = httpUri.GetRoutableUri(false).AbsoluteUri; } } else { if (String.IsNullOrEmpty(ClassicTumblerParameters.ExpectedAddress)) { ClassicTumblerParameters.ExpectedAddress = TorUri.AbsoluteUri; } } } ClassicTumblerParametersHash = ClassicTumblerParameters.GetHash(); var configurationHash = ClassicTumblerParameters.GetHash(); foreach (var uri in TumblerUris) { uri.ConfigurationHash = configurationHash; } Logs.Configuration.LogInformation(""); Logs.Configuration.LogInformation($"--------------------------------"); Logs.Configuration.LogInformation($"Shareable URIs of the running tumbler are:"); foreach (var uri in TumblerUris) { Logs.Configuration.LogInformation(uri.ToString()); } Logs.Configuration.LogInformation($"--------------------------------"); Logs.Configuration.LogInformation(""); Repository = conf.DBreezeRepository; _Resources.Add(Repository); Tracker = conf.Tracker; Services = conf.Services; }
/// <summary>Invokes the interaction synchronously.</summary> /// <param name="interaction">The interaction.</param> public void InvokeInteraction(ClientInteraction interaction) { this.ClientSession.InvokeInteraction(interaction); }
async Task ConfigureAsyncCore(TumblerConfiguration conf, ClientInteraction interaction) { Cooperative = conf.Cooperative; ClassicTumblerParameters = conf.ClassicTumblerParameters.Clone(); Network = conf.Network; RPCClient rpcClient = null; try { rpcClient = conf.RPC.ConfigureRPCClient(conf.Network); } catch { throw new ConfigException("Please, fix rpc settings in " + conf.ConfigurationFile); } bool torConfigured = false; if (conf.TorSettings != null) { Exception error = null; try { _Resources.Add(await conf.TorSettings.SetupAsync(interaction, conf.TorPath).ConfigureAwait(false)); Logs.Configuration.LogInformation("Successfully authenticated to Tor"); var torRSA = Path.Combine(conf.DataDir, "Tor.rsa"); string privateKey = null; if (File.Exists(torRSA)) { privateKey = File.ReadAllText(torRSA, Encoding.UTF8); } IPEndPoint routable = GetLocalEndpoint(conf); TorConnection = conf.TorSettings.CreateTorClient2(); _Resources.Add(TorConnection); await TorConnection.ConnectAsync().ConfigureAwait(false); await TorConnection.AuthenticateAsync().ConfigureAwait(false); var result = await TorConnection.RegisterHiddenServiceAsync(routable, conf.TorSettings.VirtualPort, privateKey).ConfigureAwait(false); if (privateKey == null) { File.WriteAllText(torRSA, result.PrivateKey, Encoding.UTF8); Logs.Configuration.LogWarning($"Tor RSA private key generated to {torRSA}"); } TorUri = result.HiddenServiceUri; Logs.Configuration.LogInformation($"Tor configured on {TorUri.AbsoluteUri}"); torConfigured = true; } catch (ConfigException ex) { error = ex; } catch (TorException ex) { error = ex; } catch (ClientInteractionException) { } if (error != null) { Logs.Configuration.LogWarning("Error while configuring Tor hidden service: " + error.Message); } } if (!torConfigured) { Logs.Configuration.LogWarning("The tumbler is not configured as a Tor Hidden service"); } var rsaFile = Path.Combine(conf.DataDir, "Tumbler.pem"); if (!File.Exists(rsaFile)) { Logs.Configuration.LogWarning("RSA private key not found, please backup it. Creating..."); TumblerKey = new RsaKey(); File.WriteAllBytes(rsaFile, TumblerKey.ToBytes()); Logs.Configuration.LogInformation("RSA key saved (" + rsaFile + ")"); } else { Logs.Configuration.LogInformation("RSA private key found (" + rsaFile + ")"); TumblerKey = new RsaKey(File.ReadAllBytes(rsaFile)); } var voucherFile = Path.Combine(conf.DataDir, "Voucher.pem"); if (!File.Exists(voucherFile)) { Logs.Configuration.LogWarning("Creation of Voucher Key"); VoucherKey = new RsaKey(); File.WriteAllBytes(voucherFile, VoucherKey.ToBytes()); Logs.Configuration.LogInformation("RSA key saved (" + voucherFile + ")"); } else { Logs.Configuration.LogInformation("Voucher key found (" + voucherFile + ")"); VoucherKey = new RsaKey(File.ReadAllBytes(voucherFile)); } ClassicTumblerParameters.ServerKey = TumblerKey.PubKey; ClassicTumblerParameters.VoucherKey = VoucherKey.PubKey; ClassicTumblerParametersHash = ClassicTumblerParameters.GetHash(); if (TorUri != null) { TumblerUris.Add(CreateTumblerUri(TorUri)); } foreach (var url in conf.GetUrls()) { TumblerUris.Add(CreateTumblerUri(new Uri(url, UriKind.Absolute))); } Logs.Configuration.LogInformation(""); Logs.Configuration.LogInformation($"--------------------------------"); var uris = String.Join(Environment.NewLine, TumblerUris.ToArray().Select(u => u.AbsoluteUri).ToArray()); Logs.Configuration.LogInformation($"Shareable URIs of the running tumbler are:"); foreach (var uri in TumblerUris) { Logs.Configuration.LogInformation(uri.AbsoluteUri); } Logs.Configuration.LogInformation($"--------------------------------"); Logs.Configuration.LogInformation(""); var dbreeze = new DBreezeRepository(Path.Combine(conf.DataDir, "db2")); Repository = dbreeze; _Resources.Add(dbreeze); Tracker = new Tracker(dbreeze, Network); Services = ExternalServices.CreateFromRPCClient(rpcClient, dbreeze, Tracker); }