diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 61e40c54..06fb5234 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -10,14 +10,22 @@ jobs: - uses: actions/checkout@v2 with: submodules: recursive - - name: Setup .NET Core SDK 3.1.x + - name: Setup .NET SDK 6.0.x uses: actions/setup-dotnet@v1.7.2 with: - dotnet-version: '3.1.x' + dotnet-version: '6.0.x' - name: Install dependencies run: dotnet restore - name: Build run: dotnet build --configuration Release --no-restore + # Please keep in mind that NOnion DOES NOT require tor client to function + # tor client is only installed here for testing purposes. + - name: Install Tor and wait for startup + run: | + sudo apt install tor + echo -e "SOCKSPort 127.0.0.1:9050" | sudo tee -a /etc/tor/torrc + sudo systemctl restart tor + sleep 2m - name: Test run: dotnet test --no-restore --verbosity normal @@ -31,10 +39,10 @@ jobs: submodules: recursive # needed because of commit-lint, see https://github.com/conventional-changelog/commitlint/issues/3376 fetch-depth: 0 - - name: Setup .NET SDK 5.0.x + - name: Setup .NET SDK 6.0.x uses: actions/setup-dotnet@v1.7.2 with: - dotnet-version: '5.0.x' + dotnet-version: '6.0.x' - name: Install dependencies run: dotnet restore - name: Build @@ -84,10 +92,10 @@ jobs: - uses: actions/checkout@v2 with: submodules: recursive - - name: Setup .NET Core SDK 3.1.x + - name: Setup .NET SDK 6.0.x uses: actions/setup-dotnet@v1.7.2 with: - dotnet-version: '3.1.x' + dotnet-version: '6.0.x' - name: Install dependencies run: dotnet restore - name: Build diff --git a/NOnion.Tests/HiddenServicesTests.cs b/NOnion.Tests/HiddenServicesTests.cs index eb5a6055..f7c97dc2 100644 --- a/NOnion.Tests/HiddenServicesTests.cs +++ b/NOnion.Tests/HiddenServicesTests.cs @@ -2,7 +2,10 @@ using System; using System.IO; using System.Linq; +using System.Net; +using System.Net.Http; using System.Security.Cryptography; +using System.Text; using System.Threading.Tasks; using NUnit.Framework; @@ -162,6 +165,78 @@ public void CanEstablishAndCommunicateOverHSConnectionOnionStyle() { Assert.DoesNotThrowAsync(EstablishAndCommunicateOverHSConnectionOnionStyle); } + + [Test] + [Retry(TestsRetryCount)] + public void CanConnectToHiddenServiceUsingTorClient() + { + Assert.DoesNotThrowAsync(ConnectToHiddenServiceUsingTorClient); + } + + private async Task ConnectToHiddenServiceUsingTorClient() + { + int descriptorUploadRetryLimit = 2; + + TorDirectory directory = await TorDirectory.BootstrapAsync(FallbackDirectorySelector.GetRandomFallbackDirectory(), new DirectoryInfo(Path.GetTempPath())); + + TorLogger.Log("Finished bootstraping"); + + SecureRandom random = new SecureRandom(); + Ed25519KeyPairGenerator kpGen = new Ed25519KeyPairGenerator(); + kpGen.Init(new Ed25519KeyGenerationParameters(random)); + Ed25519PrivateKeyParameters masterPrivateKey = (Ed25519PrivateKeyParameters)kpGen.GenerateKeyPair().Private; + + TorServiceHost host = new TorServiceHost(directory, descriptorUploadRetryLimit, TestsRetryCount, FSharpOption.Some(masterPrivateKey)); + await host.StartAsync(); + + TorLogger.Log("Finished starting HS host"); + + var stringToSendAndReceive = + "We are using tor!"; + + var serverSide = + Task.Run(async () => { + var stream = await host.AcceptClientAsync(); + + var httpResponse = + "HTTP/1.1 200 OK\r\n" + + "Server: NOnion\r\n" + + $"Content-Length: {stringToSendAndReceive.Length}\r\n" + + "Connection: close\r\n" + + "Content-Type: text/plain" + + "\r\n" + + "\r\n" + + stringToSendAndReceive + + "\r\n"; + + await stream.SendDataAsync(Encoding.ASCII.GetBytes(httpResponse)); + await stream.EndAsync(); + }); + + var clientSide = + Task.Run(async () => { + var handler = new HttpClientHandler + { + Proxy = new WebProxy(new Uri("socks5://localhost:9050")) + }; + + TestContext.Progress.WriteLine("Trying to connect to hidden service..."); + using (handler) + using (var httpClient = new HttpClient(handler)) + { + // Sometimes tor client takes a while to bootstrap and stalls + // the request. + httpClient.Timeout = TimeSpan.FromMinutes(20); + var result = await httpClient.GetStringAsync("http://" + host.ExportUrl()); + Assert.AreEqual(result, stringToSendAndReceive); + } + } + ); + + await TaskUtils.WhenAllFailFast(serverSide, clientSide); + + ((IDisposable)host).Dispose(); + } } } diff --git a/NOnion.Tests/NOnion.Tests.csproj b/NOnion.Tests/NOnion.Tests.csproj index e9a8683d..29e1c10d 100644 --- a/NOnion.Tests/NOnion.Tests.csproj +++ b/NOnion.Tests/NOnion.Tests.csproj @@ -1,7 +1,7 @@  - netcoreapp3.1 + net6.0 false