Esempio n. 1
0
        private static async Task ProfileServiceOperationAsync(Func <IUserCredentials, ILogger, IUserProfileServiceResult> operation, string name, IUserProfileNamedPipeFactory pipeFactory, int serverTimeOutms = 0, int clientTimeOutms = 0, CancellationToken ct = default(CancellationToken), ILogger logger = null)
        {
            using (NamedPipeServerStream server = pipeFactory.CreatePipe(name)) {
                await server.WaitForConnectionAsync(ct);

                ManualResetEventSlim forceDisconnect = new ManualResetEventSlim(false);
                try {
                    if (serverTimeOutms + clientTimeOutms > 0)
                    {
                        Task.Run(() => {
                            // This handles Empty string input cases. This is usually the case were client is connected and writes a empty string.
                            // on the server side this blocks the ReadAsync indefinitely (even with the cancellation set). The code below protects
                            // the server from being indefinitely blocked by a malicious client.
                            forceDisconnect.Wait(serverTimeOutms + clientTimeOutms);
                            if (server.IsConnected)
                            {
                                server.Disconnect();
                                logger?.LogError(Resources.Error_ClientTimedOut);
                            }
                        }).DoNotWait();
                    }

                    using (var cts = CancellationTokenSource.CreateLinkedTokenSource(ct)) {
                        if (serverTimeOutms > 0)
                        {
                            cts.CancelAfter(serverTimeOutms);
                        }

                        byte[] requestRaw = new byte[1024];
                        int    bytesRead  = 0;

                        while (bytesRead == 0 && !cts.IsCancellationRequested)
                        {
                            bytesRead = await server.ReadAsync(requestRaw, 0, requestRaw.Length, cts.Token);
                        }

                        string json = Encoding.Unicode.GetString(requestRaw, 0, bytesRead);

                        var requestData = Json.DeserializeObject <RUserProfileServiceRequest>(json);

                        var result = operation?.Invoke(requestData, logger);

                        string jsonResp = JsonConvert.SerializeObject(result);
                        byte[] respData = Encoding.Unicode.GetBytes(jsonResp);

                        await server.WriteAsync(respData, 0, respData.Length, cts.Token);

                        await server.FlushAsync(cts.Token);
                    }

                    using (var cts = CancellationTokenSource.CreateLinkedTokenSource(ct)) {
                        if (clientTimeOutms > 0)
                        {
                            cts.CancelAfter(clientTimeOutms);
                        }

                        // Waiting here to allow client to finish reading client should disconnect after reading.
                        byte[] requestRaw = new byte[1024];
                        int    bytesRead  = 0;
                        while (bytesRead == 0 && !cts.Token.IsCancellationRequested)
                        {
                            bytesRead = await server.ReadAsync(requestRaw, 0, requestRaw.Length, cts.Token);
                        }

                        // if there was an attempt to write, disconnect.
                        server.Disconnect();
                    }
                } finally {
                    // server work is done.
                    forceDisconnect.Set();
                }
            }
        }
        private async Task CreateProfileFuzzTestRunnerAsync(IUserProfileServices creator, IUserProfileNamedPipeFactory pipeFactory, string input, int serverTimeOut, int clientTimeOut)
        {
            var task = Task.Run(async() => {
                try {
                    await RUserProfileServicesHelper.CreateProfileAsync(serverTimeOutms: serverTimeOut, clientTimeOutms: clientTimeOut, userProfileService: creator, pipeFactory: pipeFactory);
                } catch (JsonReaderException) {
                    // expecting JSON parsing to fail
                    // JSON parsing may fail due to randomly generated strings as input.
                }
            });

            using (var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(clientTimeOut))) {
                var result = await CreateProfileClientTestWorkerAsync(input, cts.Token);

                // fuzz test parsing succeeded, the creator always fails for this test.
                result?.Error.Should().Be(13);
            }

            await ParallelTools.When(task, serverTimeOut + clientTimeOut);
        }
Esempio n. 3
0
 public static async Task DeleteProfileAsync(int serverTimeOutms = 0, int clientTimeOutms = 0, IUserProfileServices userProfileService = null, IUserProfileNamedPipeFactory pipeFactory = null, CancellationToken ct = default(CancellationToken), ILogger logger = null)
 {
     userProfileService = userProfileService ?? new RUserProfileServices();
     pipeFactory        = pipeFactory ?? new NamedPipeServerStreamFactory();
     await ProfileServiceOperationAsync(userProfileService.DeleteUserProfile, NamedPipeServerStreamFactory.DeletorName, pipeFactory, serverTimeOutms, clientTimeOutms, ct, logger);
 }
        private async Task CreateProfileTestRunnerAsync(IUserProfileServices creator, IUserProfileNamedPipeFactory pipeFactory, string input, bool isValidParse, bool isValidAccount, bool isExistingAccount, int serverTimeOut, int clientTimeOut)
        {
            var testDone = new ManualResetEventSlim(false);

            Task.Run(async() => {
                try {
                    if (isValidParse)
                    {
                        Func <Task> f = async() => await RUserProfileServicesHelper.CreateProfileAsync(serverTimeOutms: serverTimeOut, clientTimeOutms: clientTimeOut, userProfileService: creator, pipeFactory: pipeFactory);
                        f.ShouldNotThrow();
                    }
                    else
                    {
                        Func <Task> f = () => RUserProfileServicesHelper.CreateProfileAsync(serverTimeOutms: serverTimeOut, clientTimeOutms: clientTimeOut, userProfileService: creator, pipeFactory: pipeFactory);
                        await f.ShouldThrowAsync <Exception>();
                    }
                } finally {
                    testDone.Set();
                }
            }).DoNotWait();

            using (var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(clientTimeOut))) {
                var result = await CreateProfileClientTestWorkerAsync(input, cts.Token);

                if (isValidParse)
                {
                    result.Error.Should().Be((uint)(isValidAccount ? 0 : 13));
                    result.ProfileExists.Should().Be(isExistingAccount);
                }
                else
                {
                    result.Should().BeNull();
                }
            }

            testDone.Wait(serverTimeOut + clientTimeOut);
        }