async Task Authenticate(string username, NpgsqlTimeout timeout, bool async, CancellationToken cancellationToken)
        {
            Log.Trace("Authenticating...", Id);

            timeout.CheckAndApply(this);
            var msg = Expect <AuthenticationRequestMessage>(await ReadMessage(async), this);

            switch (msg.AuthRequestType)
            {
            case AuthenticationRequestType.AuthenticationOk:
                return;

            case AuthenticationRequestType.AuthenticationCleartextPassword:
                await AuthenticateCleartext(username, async, cancellationToken);

                return;

            case AuthenticationRequestType.AuthenticationMD5Password:
                await AuthenticateMD5(username, ((AuthenticationMD5PasswordMessage)msg).Salt, async, cancellationToken);

                return;

            case AuthenticationRequestType.AuthenticationSASL:
                AuthenticationSASLMessage authmsg = (AuthenticationSASLMessage)msg;
                await AuthenticateSha256(authmsg.Salt, authmsg.Token, authmsg.Iteration, username, async, cancellationToken);

                return;

            case AuthenticationRequestType.AuthenticationGSS:
            case AuthenticationRequestType.AuthenticationSSPI:
                await AuthenticateGSS(async);

                return;

            case AuthenticationRequestType.AuthenticationGSSContinue:
                throw new NpgsqlException("Can't start auth cycle with AuthenticationGSSContinue");

            default:
                throw new NotSupportedException($"Authentication method not supported (Received: {msg.AuthRequestType})");
            }
        }
コード例 #2
0
        internal static async Task Bind(NpgsqlConnector connector, NpgsqlTimeout timeout, bool async)
        {
            // Note that there's a chicken and egg problem here - PostgresDatabase.Load below needs a functional
            // connector to load the types, hence the strange initialization code here

            var mapper = new ConnectorTypeMapper(connector);

            connector.TypeMapper = mapper;

            // If we've connected to this specific database before, we have a PostgresDatabase instance
            // (containing all type information)
            var connString = connector.ConnectionString;

            if (!DatabaseInfo.Cache.TryGetValue(connString, out var database))
            {
                DatabaseInfo.Cache[connString] = database = await DatabaseInfo.Load(connector, timeout, async);
            }

            mapper.DatabaseInfo = database;
            mapper.BindTypes();
        }
コード例 #3
0
 public ClusterInfo(ClusterState state, NpgsqlTimeout timeout, DateTime timeStamp)
 => (State, Timeout, TimeStamp) = (state, timeout, timeStamp);
コード例 #4
0
 public Task <NpgsqlDatabaseInfo?> Load(NpgsqlConnector conn, NpgsqlTimeout timeout, bool async)
 => Task.FromResult(
     conn.Settings.ServerCompatibilityMode == ServerCompatibilityMode.NoTypeLoading
             ? (NpgsqlDatabaseInfo) new PostgresMinimalDatabaseInfo(conn)
             : null
     );
コード例 #5
0
    /// <summary>
    /// Executes a potentially non-cancellable <see cref="Task"/> while allowing to timeout and/or cancel awaiting for it.
    /// If the given task does not complete within <paramref name="timeout"/>, a <see cref="TimeoutException"/> is thrown.
    /// The executed <see cref="Task"/> may be left in an incomplete state after the <see cref="Task"/> that this method returns completes dues to timeout and/or cancellation request.
    /// The method guarantees that the abandoned, incomplete <see cref="Task"/> is not going to produce <see cref="TaskScheduler.UnobservedTaskException"/> event if it fails later.
    /// </summary>
    /// <param name="getTaskFunc">Gets the <see cref="Task"/> for execution with a combined <see cref="CancellationToken"/> that attempts to cancel the <see cref="Task"/> in an event of the timeout or external cancellation request.</param>
    /// <param name="timeout">The timeout after which the <see cref="Task"/> should be faulted with a <see cref="TimeoutException"/> if it hasn't otherwise completed.</param>
    /// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for a cancellation request.</param>
    /// <returns>The <see cref="Task"/> representing the asynchronous wait.</returns>
    internal static async Task ExecuteAsync(Func <CancellationToken, Task> getTaskFunc, NpgsqlTimeout timeout, CancellationToken cancellationToken)
    {
        using var combinedCts = timeout.IsSet ? CancellationTokenSource.CreateLinkedTokenSource(cancellationToken) : null;
        var task = getTaskFunc(combinedCts?.Token ?? cancellationToken);

        try
        {
            try
            {
                await task.WaitAsync(timeout.CheckAndGetTimeLeft(), cancellationToken);
            }
            catch (TimeoutException) when(!task !.IsCompleted)
            {
                // Attempt to stop the Task in progress.
                combinedCts?.Cancel();
                throw;
            }
        }
        catch
        {
            // Prevent unobserved Task notifications by observing the failed Task exception.
            // To test: comment the next line out and re-run TaskExtensionsTest.DelayedFaultedTaskCancellation.
            _ = task.ContinueWith(t => _ = t.Exception, CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, TaskScheduler.Current);
            throw;
        }
    }
}
コード例 #6
0
    /// <summary>
    /// Executes a potentially non-cancellable <see cref="Task{TResult}"/> while allowing to timeout and/or cancel awaiting for it.
    /// If the given task does not complete within <paramref name="timeout"/>, a <see cref="TimeoutException"/> is thrown.
    /// The executed <see cref="Task{TResult}"/> may be left in an incomplete state after the <see cref="Task{TResult}"/> that this method returns completes dues to timeout and/or cancellation request.
    /// The method guarantees that the abandoned, incomplete <see cref="Task{TResult}"/> is not going to produce <see cref="TaskScheduler.UnobservedTaskException"/> event if it fails later.
    /// </summary>
    /// <param name="getTaskFunc">Gets the <see cref="Task{TResult}"/> for execution with a combined <see cref="CancellationToken"/> that attempts to cancel the <see cref="Task{TResult}"/> in an event of the timeout or external cancellation request.</param>
    /// <param name="timeout">The timeout after which the <see cref="Task{TResult}"/> should be faulted with a <see cref="TimeoutException"/> if it hasn't otherwise completed.</param>
    /// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for a cancellation request.</param>
    /// <typeparam name="TResult">The result <see cref="Type"/>.</typeparam>
    /// <returns>The <see cref="Task{TResult}"/> representing the asynchronous wait.</returns>
    internal static async Task <TResult> ExecuteAsync <TResult>(Func <CancellationToken, Task <TResult> > getTaskFunc, NpgsqlTimeout timeout, CancellationToken cancellationToken)
    {
        Task <TResult>?task = default;

        await ExecuteAsync(ct => (Task)(task = getTaskFunc(ct)), timeout, cancellationToken);

        return(await task !);
    }