Esempio n. 1
0
        public async Task WaitForAvailableBidirectionStreamsAsyncWorks()
        {
            using QuicListener listener           = CreateQuicListener(maxBidirectionalStreams: 1);
            using QuicConnection clientConnection = CreateQuicConnection(listener.ListenEndPoint);

            Task <QuicConnection> serverTask = listener.AcceptConnectionAsync().AsTask();
            await TaskTimeoutExtensions.WhenAllOrAnyFailed(clientConnection.ConnectAsync().AsTask(), serverTask, PassingTestTimeoutMilliseconds);

            using QuicConnection serverConnection = serverTask.Result;

            // No stream opened yet, should return immediately.
            Assert.True(clientConnection.WaitForAvailableBidirectionalStreamsAsync().IsCompletedSuccessfully);

            // Open one stream, should wait till it closes.
            QuicStream stream   = clientConnection.OpenBidirectionalStream();
            ValueTask  waitTask = clientConnection.WaitForAvailableBidirectionalStreamsAsync();

            Assert.False(waitTask.IsCompleted);
            Assert.Throws <QuicException>(() => clientConnection.OpenBidirectionalStream());

            // Close the streams, the waitTask should finish as a result.
            stream.Dispose();
            QuicStream newStream = await serverConnection.AcceptStreamAsync();

            newStream.Dispose();
            await waitTask.AsTask().WaitAsync(TimeSpan.FromSeconds(10));
        }
Esempio n. 2
0
        public async Task SslStream_ClientSendsSNIServerReceives_Ok(string hostName)
        {
            X509Certificate serverCert = Configuration.Certificates.GetSelfSignedServerCertificate();

            await WithVirtualConnection(async (server, client) =>
            {
                Task clientJob = Task.Run(() => {
                    client.AuthenticateAsClient(hostName);
                });

                SslServerAuthenticationOptions options = DefaultServerOptions();

                int timesCallbackCalled = 0;
                options.ServerCertificateSelectionCallback = (sender, actualHostName) =>
                {
                    timesCallbackCalled++;
                    Assert.Equal(hostName, actualHostName);
                    return(serverCert);
                };

                await TaskTimeoutExtensions.WhenAllOrAnyFailed(new[] { clientJob, server.AuthenticateAsServerAsync(options, CancellationToken.None) });

                Assert.Equal(1, timesCallbackCalled);
            },
                                        (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) =>
            {
                Assert.Equal(serverCert, certificate);
                return(true);
            }
                                        );
        }
Esempio n. 3
0
        public async Task ConnectWithCertificateChain()
        {
            (X509Certificate2 certificate, X509Certificate2Collection chain) = System.Net.Security.Tests.TestHelper.GenerateCertificates("localhost", longChain: true);
            X509Certificate2 rootCA = chain[chain.Count - 1];

            var quicOptions = new QuicListenerOptions();

            quicOptions.ListenEndPoint = new IPEndPoint(IPAddress.Loopback, 0);
            quicOptions.ServerAuthenticationOptions = GetSslServerAuthenticationOptions();
            quicOptions.ServerAuthenticationOptions.ServerCertificateContext = SslStreamCertificateContext.Create(certificate, chain);
            quicOptions.ServerAuthenticationOptions.ServerCertificate        = null;

            using QuicListener listener = new QuicListener(QuicImplementationProviders.MsQuic, quicOptions);

            QuicClientConnectionOptions options = new QuicClientConnectionOptions()
            {
                RemoteEndPoint = listener.ListenEndPoint,
                ClientAuthenticationOptions = GetSslClientAuthenticationOptions(),
            };

            options.ClientAuthenticationOptions.RemoteCertificateValidationCallback = (sender, cert, chain, errors) =>
            {
                Assert.Equal(certificate.Subject, cert.Subject);
                Assert.Equal(certificate.Issuer, cert.Issuer);
                // We should get full chain without root CA.
                // With trusted root, we should be able to build chain.
                chain.ChainPolicy.CustomTrustStore.Add(rootCA);
                chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;
                bool ret = chain.Build(certificate);
                if (!ret)
                {
                    _output.WriteLine("Chain build failed with {0} elements", chain.ChainElements);
                    foreach (X509ChainElement element in chain.ChainElements)
                    {
                        _output.WriteLine("Element subject {0} and issuer {1}", element.Certificate.Subject, element.Certificate.Issuer);
                        _output.WriteLine("Element status len {0}", element.ChainElementStatus.Length);
                        foreach (X509ChainStatus status in element.ChainElementStatus)
                        {
                            _output.WriteLine($"Status:  {status.Status}: {status.StatusInformation}");
                        }
                    }
                }

                return(ret);
            };

            using QuicConnection clientConnection = new QuicConnection(QuicImplementationProviders.MsQuic, options);
            Task <QuicConnection> serverTask = listener.AcceptConnectionAsync().AsTask();
            await TaskTimeoutExtensions.WhenAllOrAnyFailed(clientConnection.ConnectAsync().AsTask(), serverTask, PassingTestTimeoutMilliseconds);

            using QuicConnection serverConnection = serverTask.Result;
            Assert.Equal(certificate, clientConnection.RemoteCertificate);
            Assert.Null(serverConnection.RemoteCertificate);
        }
Esempio n. 4
0
        public async Task UnidirectionalAndBidirectionalStreamCountsWork()
        {
            using QuicListener listener           = CreateQuicListener();
            using QuicConnection clientConnection = CreateQuicConnection(listener.ListenEndPoint);
            Task <QuicConnection> serverTask = listener.AcceptConnectionAsync().AsTask();
            await TaskTimeoutExtensions.WhenAllOrAnyFailed(clientConnection.ConnectAsync().AsTask(), serverTask, PassingTestTimeoutMilliseconds);

            using QuicConnection serverConnection = serverTask.Result;

            Assert.Equal(100, serverConnection.GetRemoteAvailableBidirectionalStreamCount());
            Assert.Equal(100, serverConnection.GetRemoteAvailableUnidirectionalStreamCount());
        }
        public async Task GetAsync_SetAutomaticDecompression_AcceptEncodingHeaderSentWithNoDuplicates(
            DecompressionMethods methods,
            string encodings,
            string manualAcceptEncodingHeaderValues)
        {
            if (IsCurlHandler)
            {
                // Skip these tests on CurlHandler, dotnet/corefx #29905.
                return;
            }

            if (!UseSocketsHttpHandler &&
                (encodings.Contains("br") || manualAcceptEncodingHeaderValues.Contains("br")))
            {
                // Brotli encoding only supported on SocketsHttpHandler.
                return;
            }

            await LoopbackServer.CreateServerAsync(async (server, url) =>
            {
                HttpClientHandler handler      = CreateHttpClientHandler();
                handler.AutomaticDecompression = methods;

                using (HttpClient client = CreateHttpClient(handler))
                {
                    if (!string.IsNullOrEmpty(manualAcceptEncodingHeaderValues))
                    {
                        client.DefaultRequestHeaders.Add("Accept-Encoding", manualAcceptEncodingHeaderValues);
                    }

                    Task <HttpResponseMessage> clientTask = client.GetAsync(url);
                    Task <List <string> > serverTask      = server.AcceptConnectionSendResponseAndCloseAsync();
                    await TaskTimeoutExtensions.WhenAllOrAnyFailed(new Task[] { clientTask, serverTask });

                    List <string> requestLines = await serverTask;
                    string requestLinesString  = string.Join("\r\n", requestLines);
                    _output.WriteLine(requestLinesString);

                    Assert.InRange(Regex.Matches(requestLinesString, "Accept-Encoding").Count, 1, 1);
                    Assert.InRange(Regex.Matches(requestLinesString, encodings).Count, 1, 1);
                    if (!string.IsNullOrEmpty(manualAcceptEncodingHeaderValues))
                    {
                        Assert.InRange(Regex.Matches(requestLinesString, manualAcceptEncodingHeaderValues).Count, 1, 1);
                    }

                    using (HttpResponseMessage response = await clientTask)
                    {
                        Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                    }
                }
            });
        }
Esempio n. 6
0
        public async Task ProxyAuth_Digest_Succeeds()
        {
            if (IsCurlHandler)
            {
                // Issue #27870 CurlHandler can only do basic auth to proxy.
                return;
            }

            const string expectedUsername = "******";
            // [SuppressMessage("Microsoft.Security", "CS002:SecretInNextLine", Justification="This is adding a testpassword as part of an auth header test and verifying it later in the test. ")]
            const string expectedPassword = "******";
            const string authHeader       = "Proxy-Authenticate: Digest realm=\"NetCore\", nonce=\"PwOnWgAAAAAAjnbW438AAJSQi1kAAAAA\", qop=\"auth\", stale=false\r\n";

            LoopbackServer.Options options = new LoopbackServer.Options {
                IsProxy = true, Username = expectedUsername, Password = expectedPassword
            };
            var proxyCreds = new NetworkCredential(expectedUsername, expectedPassword);

            await LoopbackServer.CreateServerAsync(async (proxyServer, proxyUrl) =>
            {
                using (HttpClientHandler handler = CreateHttpClientHandler())
                    using (var client = new HttpClient(handler))
                    {
                        handler.Proxy = new WebProxy(proxyUrl)
                        {
                            Credentials = proxyCreds
                        };

                        // URL does not matter. We will get response from "proxy" code below.
                        Task <HttpResponseMessage> clientTask = client.GetAsync($"http://notarealserver.com/");

                        //  Send Digest challenge.
                        Task <List <string> > serverTask = proxyServer.AcceptConnectionSendResponseAndCloseAsync(HttpStatusCode.ProxyAuthenticationRequired, authHeader);
                        if (clientTask == await Task.WhenAny(clientTask, serverTask).TimeoutAfter(TestHelper.PassingTestTimeoutMilliseconds))
                        {
                            // Client task shouldn't have completed successfully; propagate failure.
                            Assert.NotEqual(TaskStatus.RanToCompletion, clientTask.Status);
                            await clientTask;
                        }

                        // Verify user & password.
                        serverTask = proxyServer.AcceptConnectionPerformAuthenticationAndCloseAsync("");
                        await TaskTimeoutExtensions.WhenAllOrAnyFailed(new Task[] { clientTask, serverTask }, TestHelper.PassingTestTimeoutMilliseconds);

                        Assert.Equal(HttpStatusCode.OK, clientTask.Result.StatusCode);
                    }
            }, options);
        }
        public async Task GetAsync_SetAutomaticDecompression_AcceptEncodingHeaderSentWithQualityWeightingsNoDuplicates(
            DecompressionMethods methods,
            string manualAcceptEncodingHeaderValues,
            string expectedHandlerAddedAcceptEncodingHeaderValues)
        {
            if (IsWinHttpHandler)
            {
                return;
            }

            await LoopbackServer.CreateServerAsync(async (server, url) =>
            {
                HttpClientHandler handler      = CreateHttpClientHandler();
                handler.AutomaticDecompression = methods;

                using (HttpClient client = CreateHttpClient(handler))
                {
                    client.DefaultRequestHeaders.Add("Accept-Encoding", manualAcceptEncodingHeaderValues);

                    Task <HttpResponseMessage> clientTask = client.SendAsync(TestAsync, CreateRequest(HttpMethod.Get, url, UseVersion));
                    Task <List <string> > serverTask      = server.AcceptConnectionSendResponseAndCloseAsync();
                    await TaskTimeoutExtensions.WhenAllOrAnyFailed(new Task[] { clientTask, serverTask });

                    List <string> requestLines = await serverTask;
                    string requestLinesString  = string.Join("\r\n", requestLines);
                    _output.WriteLine(requestLinesString);

                    bool acceptEncodingValid = false;
                    foreach (string requestLine in requestLines)
                    {
                        if (requestLine.StartsWith("Accept-Encoding", StringComparison.OrdinalIgnoreCase))
                        {
                            acceptEncodingValid = requestLine.Equals($"Accept-Encoding: {manualAcceptEncodingHeaderValues}{(string.IsNullOrEmpty(expectedHandlerAddedAcceptEncodingHeaderValues) ? string.Empty : ", " + expectedHandlerAddedAcceptEncodingHeaderValues)}", StringComparison.OrdinalIgnoreCase);
                            break;
                        }
                    }

                    Assert.True(acceptEncodingValid, "Accept-Encoding missing or invalid");

                    using (HttpResponseMessage response = await clientTask)
                    {
                        Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                    }
                }
            });
        }
Esempio n. 8
0
        public async Task ConnectWithClientCertificate()
        {
            bool clientCertificateOK = false;

            var serverOptions = new QuicListenerOptions();

            serverOptions.ListenEndPoint = new IPEndPoint(IPAddress.Loopback, 0);
            serverOptions.ServerAuthenticationOptions = GetSslServerAuthenticationOptions();
            serverOptions.ServerAuthenticationOptions.ClientCertificateRequired           = true;
            serverOptions.ServerAuthenticationOptions.RemoteCertificateValidationCallback = (sender, cert, chain, errors) =>
            {
                _output.WriteLine("client certificate {0}", cert);
                Assert.NotNull(cert);
                Assert.Equal(ClientCertificate.Thumbprint, ((X509Certificate2)cert).Thumbprint);

                clientCertificateOK = true;
                return(true);
            };
            using QuicListener listener = new QuicListener(QuicImplementationProviders.MsQuic, serverOptions);

            QuicClientConnectionOptions clientOptions = new QuicClientConnectionOptions()
            {
                RemoteEndPoint = listener.ListenEndPoint,
                ClientAuthenticationOptions = GetSslClientAuthenticationOptions(),
            };

            clientOptions.ClientAuthenticationOptions.ClientCertificates = new X509CertificateCollection()
            {
                ClientCertificate
            };

            using QuicConnection clientConnection = new QuicConnection(QuicImplementationProviders.MsQuic, clientOptions);
            Task <QuicConnection> serverTask = listener.AcceptConnectionAsync().AsTask();
            await TaskTimeoutExtensions.WhenAllOrAnyFailed(clientConnection.ConnectAsync().AsTask(), serverTask, PassingTestTimeoutMilliseconds);

            using QuicConnection serverConnection = serverTask.Result;

            // Verify functionality of the connections.
            await PingPong(clientConnection, serverConnection);

            // check we completed the client certificate verification.
            Assert.True(clientCertificateOK);
            Assert.Equal(ClientCertificate, serverConnection.RemoteCertificate);

            await serverConnection.CloseAsync(0);
        }
Esempio n. 9
0
        public async Task ProxyAuth_Digest_Succeeds()
        {
            const string expectedUsername = "******";
            const string expectedPassword = "******";
            const string authHeader       = "Proxy-Authenticate: Digest realm=\"NetCore\", nonce=\"PwOnWgAAAAAAjnbW438AAJSQi1kAAAAA\", qop=\"auth\", stale=false\r\n";

            LoopbackServer.Options options = new LoopbackServer.Options {
                IsProxy = true, Username = expectedUsername, Password = expectedPassword
            };
            var proxyCreds = new NetworkCredential(expectedUsername, expectedPassword);

            await LoopbackServer.CreateServerAsync(async (proxyServer, proxyUrl) =>
            {
                using (HttpClientHandler handler = CreateHttpClientHandler())
                    using (HttpClient client = CreateHttpClient(handler))
                    {
                        handler.Proxy = new WebProxy(proxyUrl)
                        {
                            Credentials = proxyCreds
                        };

                        // URL does not matter. We will get response from "proxy" code below.
                        Task <HttpResponseMessage> clientTask = client.GetAsync($"http://notarealserver.com/");

                        //  Send Digest challenge.
                        Task <List <string> > serverTask = proxyServer.AcceptConnectionSendResponseAndCloseAsync(HttpStatusCode.ProxyAuthenticationRequired, authHeader);
                        if (clientTask == await Task.WhenAny(clientTask, serverTask).WaitAsync(TestHelper.PassingTestTimeout))
                        {
                            // Client task shouldn't have completed successfully; propagate failure.
                            Assert.NotEqual(TaskStatus.RanToCompletion, clientTask.Status);
                            await clientTask;
                        }

                        // Verify user & password.
                        serverTask = proxyServer.AcceptConnectionPerformAuthenticationAndCloseAsync("");
                        await TaskTimeoutExtensions.WhenAllOrAnyFailed(new Task[] { clientTask, serverTask }, TestHelper.PassingTestTimeoutMilliseconds);

                        Assert.Equal(HttpStatusCode.OK, clientTask.Result.StatusCode);
                    }
            }, options);
        }
Esempio n. 10
0
        public async Task SslStream_ServerCallbackNotSet_UsesLocalCertificateSelection(string hostName)
        {
            X509Certificate serverCert = Configuration.Certificates.GetSelfSignedServerCertificate();

            int timesCallbackCalled = 0;

            var selectionCallback = new LocalCertificateSelectionCallback((object sender, string targetHost, X509CertificateCollection localCertificates, X509Certificate remoteCertificate, string[] issuers) =>
            {
                Assert.Equal(string.Empty, targetHost);
                Assert.True(localCertificates.Contains(serverCert));
                timesCallbackCalled++;
                return(serverCert);
            });

            var validationCallback = new RemoteCertificateValidationCallback((object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) =>
            {
                Assert.Equal(serverCert, certificate);
                return(true);
            });

            VirtualNetwork vn = new VirtualNetwork();

            using (VirtualNetworkStream serverStream = new VirtualNetworkStream(vn, isServer: true),
                   clientStream = new VirtualNetworkStream(vn, isServer: false))
                using (SslStream server = new SslStream(serverStream, false, null, selectionCallback),
                       client = new SslStream(clientStream, leaveInnerStreamOpen: false, validationCallback))
                {
                    Task clientJob = Task.Run(() => {
                        client.AuthenticateAsClient(hostName);
                    });

                    SslServerAuthenticationOptions options = DefaultServerOptions();
                    options.ServerCertificate = serverCert;

                    await TaskTimeoutExtensions.WhenAllOrAnyFailed(new[] { clientJob, server.AuthenticateAsServerAsync(options, CancellationToken.None) });

                    Assert.Equal(1, timesCallbackCalled);
                }
        }
Esempio n. 11
0
        public async Task UnidirectionalAndBidirectionalChangeValues()
        {
            using QuicListener listener = CreateQuicListener();

            QuicClientConnectionOptions options = new QuicClientConnectionOptions()
            {
                MaxBidirectionalStreams     = 10,
                MaxUnidirectionalStreams    = 20,
                RemoteEndPoint              = listener.ListenEndPoint,
                ClientAuthenticationOptions = GetSslClientAuthenticationOptions()
            };

            using QuicConnection clientConnection = new QuicConnection(QuicImplementationProviders.MsQuic, options);
            Task <QuicConnection> serverTask = listener.AcceptConnectionAsync().AsTask();
            await TaskTimeoutExtensions.WhenAllOrAnyFailed(clientConnection.ConnectAsync().AsTask(), serverTask, PassingTestTimeoutMilliseconds);

            using QuicConnection serverConnection = serverTask.Result;

            Assert.Equal(100, clientConnection.GetRemoteAvailableBidirectionalStreamCount());
            Assert.Equal(100, clientConnection.GetRemoteAvailableUnidirectionalStreamCount());
            Assert.Equal(10, serverConnection.GetRemoteAvailableBidirectionalStreamCount());
            Assert.Equal(20, serverConnection.GetRemoteAvailableUnidirectionalStreamCount());
        }
Esempio n. 12
0
        public async Task SetListenerTimeoutWorksWithSmallTimeout()
        {
            var quicOptions = new QuicListenerOptions();

            quicOptions.IdleTimeout = TimeSpan.FromSeconds(1);
            quicOptions.ServerAuthenticationOptions = GetSslServerAuthenticationOptions();
            quicOptions.ListenEndPoint = new IPEndPoint(IPAddress.Loopback, 0);

            using QuicListener listener = new QuicListener(QuicImplementationProviders.MsQuic, quicOptions);

            QuicClientConnectionOptions options = new QuicClientConnectionOptions()
            {
                RemoteEndPoint = listener.ListenEndPoint,
                ClientAuthenticationOptions = GetSslClientAuthenticationOptions(),
            };

            using QuicConnection clientConnection = new QuicConnection(QuicImplementationProviders.MsQuic, options);
            Task <QuicConnection> serverTask = listener.AcceptConnectionAsync().AsTask();
            await TaskTimeoutExtensions.WhenAllOrAnyFailed(clientConnection.ConnectAsync().AsTask(), serverTask, PassingTestTimeoutMilliseconds);

            using QuicConnection serverConnection = serverTask.Result;

            await Assert.ThrowsAsync <QuicOperationAbortedException>(async() => await serverConnection.AcceptStreamAsync().AsTask().WaitAsync(TimeSpan.FromSeconds(100)));
        }
Esempio n. 13
0
 public static Task WhenAllCompletedOrAnyFailedWithTimeout(int timeoutInMilliseconds, params Task[] tasks)
 {
     return(TaskTimeoutExtensions.WhenAllOrAnyFailed(tasks, timeoutInMilliseconds));
 }
Esempio n. 14
0
 public static Task WhenAllCompletedOrAnyFailed(params Task[] tasks)
 {
     return(TaskTimeoutExtensions.WhenAllOrAnyFailed(tasks, PlatformDetection.IsArmProcess || PlatformDetection.IsArm64Process ? PassingTestTimeoutMilliseconds * 5 : PassingTestTimeoutMilliseconds));
 }
Esempio n. 15
0
 public static Task WhenAllCompletedOrAnyFailed(params Task[] tasks)
 {
     return(TaskTimeoutExtensions.WhenAllOrAnyFailed(tasks));
 }