/// <summary>
        /// Call the plugin credential provider application to acquire credentials.
        /// The request will be passed to the plugin on standard input as a json serialized
        /// PluginCredentialRequest.
        /// The plugin will return credentials as a json serialized PluginCredentialResponse.
        /// Valid credentials will be returned, or null if the provide cannot provide credentials
        /// for the given request.  If the plugin returns an Abort message, an exception will be thrown to
        /// fail the current request.
        /// </summary>
        /// <param name="uri">The uri of a web resource for which credentials are needed.</param>
        /// <param name="proxy">Ignored.  Proxy information will not be passed to plugins.</param>
        /// <param name="type">
        /// The type of credential request that is being made. Note that this implementation of
        /// <see cref="ICredentialProvider"/> does not support providing proxy credenitials and treats
        /// all other types the same.
        /// </param>
        /// <param name="isRetry">If true, credentials were previously supplied by this
        /// provider for the same uri.</param>
        /// <param name="message">A message provided by NuGet to show to the user when prompting.</param>
        /// <param name="nonInteractive">If true, the plugin must not prompt for credentials.</param>
        /// <param name="cancellationToken">A cancellation token.</param>
        /// <returns>A credential object.  If </returns>
        public Task <CredentialResponse> GetAsync(
            Uri uri,
            IWebProxy proxy,
            CredentialRequestType type,
            string message,
            bool isRetry,
            bool nonInteractive,
            CancellationToken cancellationToken)
        {
            CredentialResponse taskResponse;

            if (type == CredentialRequestType.Proxy)
            {
                taskResponse = new CredentialResponse(CredentialStatus.ProviderNotApplicable);
                return(Task.FromResult(taskResponse));
            }

            try
            {
                var request = new PluginCredentialRequest
                {
                    Uri            = uri.ToString(),
                    IsRetry        = isRetry,
                    NonInteractive = nonInteractive
                };

                // TODO: Extend the plug protocol to pass in the credential request type.
                var response = Execute(request, cancellationToken);

                if (response.IsValid)
                {
                    ICredentials result = new NetworkCredential(response.Username, response.Password);
                    if (response.AuthTypes != null)
                    {
                        result = new AuthTypeFilteredCredentials(result, response.AuthTypes);
                    }

                    taskResponse = new CredentialResponse(result);
                }
                else
                {
                    taskResponse = new CredentialResponse(CredentialStatus.ProviderNotApplicable);
                }
            }
            catch (OperationCanceledException)
            {
                throw;
            }
            catch (PluginException)
            {
                throw;
            }
            catch (Exception e)
            {
                throw PluginException.Create(Path, e);
            }

            return(Task.FromResult(taskResponse));
        }
        /// <param name="uri">The uri of a web resource for which credentials are needed.</param>
        /// <param name="proxy">Ignored.  Proxy information will not be passed to plugins.</param>
        /// <param name="type">
        /// The type of credential request that is being made. Note that this implementation of
        /// <see cref="ICredentialProvider"/> does not support providing proxy credenitials and treats
        /// all other types the same.
        /// </param>
        /// <param name="isRetry">If true, credentials were previously supplied by this
        /// provider for the same uri.</param>
        /// <param name="message">A message provided by NuGet to show to the user when prompting.</param>
        /// <param name="nonInteractive">If true, the plugin must not prompt for credentials.</param>
        /// <param name="cancellationToken">A cancellation token.</param>
        /// <returns>A credential object.</returns>
        public async Task <CredentialResponse> GetAsync(Uri uri, IWebProxy proxy, CredentialRequestType type, string message, bool isRetry, bool nonInteractive, CancellationToken cancellationToken)
        {
            CredentialResponse taskResponse = null;

            if (type == CredentialRequestType.Proxy || !_isAnAuthenticationPlugin)
            {
                taskResponse = new CredentialResponse(CredentialStatus.ProviderNotApplicable);
                return(taskResponse);
            }

            var plugin = await _pluginManager.CreateSourceAgnosticPluginAsync(_discoveredPlugin, cancellationToken);

            if (!string.IsNullOrEmpty(plugin.Message))
            {
                // There is a potential here for double logging as the CredentialService itself catches the exceptions and tries to log it.
                // In reality the logger in the Credential Service will be null because the first request always comes from a resource provider (ServiceIndex provider)
                _logger.LogError(plugin.Message);
                throw new PluginException(plugin.Message); // Throwing here will block authentication and ensure that the complete operation fails
            }

            _isAnAuthenticationPlugin = plugin.Claims.Contains(OperationClaim.Authentication);

            if (_isAnAuthenticationPlugin)
            {
                AddOrUpdateLogger(plugin.Plugin);
                await SetPluginLogLevelAsync(plugin, _logger, cancellationToken);

                if (proxy != null)
                {
                    await SetProxyCredentialsToPlugin(uri, proxy, plugin, cancellationToken);
                }

                var request            = new GetAuthenticationCredentialsRequest(uri, isRetry, nonInteractive);
                var credentialResponse = await plugin.Plugin.Connection.SendRequestAndReceiveResponseAsync <GetAuthenticationCredentialsRequest, GetAuthenticationCredentialsResponse>(
                    MessageMethod.GetAuthenticationCredentials,
                    request,
                    cancellationToken);

                if (credentialResponse.ResponseCode == MessageResponseCode.NotFound && nonInteractive)
                {
                    _logger.LogWarning(
                        string.Format(
                            CultureInfo.CurrentCulture,
                            Resources.SecurePluginWarning_UseInteractiveOption)
                        );
                }

                taskResponse = GetAuthenticationCredentialsResponseToCredentialResponse(credentialResponse);
            }
            else
            {
                taskResponse = new CredentialResponse(CredentialStatus.ProviderNotApplicable);
            }

            return(taskResponse);
        }
Exemple #3
0
        bool TryFromCredentialCache(Uri uri, CredentialRequestType type, bool isRetry, ICredentialProvider provider,
                                    out CredentialResponse credentials)
        {
            credentials = null;

            var key = CredentialCacheKey(uri, type, provider);

            if (isRetry)
            {
                CredentialResponse removed;
                _providerCredentialCache.TryRemove(key, out removed);
                return(false);
            }

            return(_providerCredentialCache.TryGetValue(key, out credentials));
        }
        /// <summary>
        /// Convert from Plugin CredentialResponse to the CredentialResponse model used by the ICredentialService
        /// </summary>
        /// <param name="credentialResponse"></param>
        /// <returns>credential response</returns>
        private static CredentialResponse GetAuthenticationCredentialsResponseToCredentialResponse(GetAuthenticationCredentialsResponse credentialResponse)
        {
            CredentialResponse taskResponse;

            if (credentialResponse.IsValid())
            {
                ICredentials result = new AuthTypeFilteredCredentials(
                    new NetworkCredential(credentialResponse.Username, credentialResponse.Password),
                    credentialResponse.AuthenticationTypes ?? Enumerable.Empty <string>());

                taskResponse = new CredentialResponse(result);
            }
            else
            {
                taskResponse = new CredentialResponse(CredentialStatus.ProviderNotApplicable);
            }

            return(taskResponse);
        }
Exemple #5
0
        /// <summary>
        /// Convert from Plugin CredentialResponse to the CredentialResponse model used by the ICredentialService
        /// </summary>
        /// <param name="credentialResponse"></param>
        /// <returns>credential response</returns>
        private static CredentialResponse GetAuthenticationCredentialsResponseToCredentialResponse(GetAuthenticationCredentialsResponse credentialResponse)
        {
            CredentialResponse taskResponse;

            if (credentialResponse.IsValid())
            {
                ICredentials result = new NetworkCredential(credentialResponse.Username, credentialResponse.Password);
                if (credentialResponse.AuthenticationTypes != null)
                {
                    result = new AuthTypeFilteredCredentials(result, credentialResponse.AuthenticationTypes);
                }

                taskResponse = new CredentialResponse(result);
            }
            else
            {
                taskResponse = new CredentialResponse(CredentialStatus.ProviderNotApplicable);
            }

            return(taskResponse);
        }
Exemple #6
0
        /// <param name="uri">The uri of a web resource for which credentials are needed.</param>
        /// <param name="proxy">Ignored.  Proxy information will not be passed to plugins.</param>
        /// <param name="type">
        /// The type of credential request that is being made. Note that this implementation of
        /// <see cref="ICredentialProvider"/> does not support providing proxy credenitials and treats
        /// all other types the same.
        /// </param>
        /// <param name="isRetry">If true, credentials were previously supplied by this
        /// provider for the same uri.</param>
        /// <param name="message">A message provided by NuGet to show to the user when prompting.</param>
        /// <param name="nonInteractive">If true, the plugin must not prompt for credentials.</param>
        /// <param name="cancellationToken">A cancellation token.</param>
        /// <returns>A credential object.</returns>
        public async Task <CredentialResponse> GetAsync(Uri uri, IWebProxy proxy, CredentialRequestType type, string message, bool isRetry, bool nonInteractive, CancellationToken cancellationToken)
        {
            CredentialResponse taskResponse = null;

            if (type == CredentialRequestType.Proxy || !_isAnAuthenticationPlugin)
            {
                taskResponse = new CredentialResponse(CredentialStatus.ProviderNotApplicable);
                return(taskResponse);
            }

            var plugin = await _pluginManager.CreateSourceAgnosticPluginAsync(_discoveredPlugin, cancellationToken);

            _isAnAuthenticationPlugin = plugin.Claims.Contains(OperationClaim.Authentication);

            if (_isAnAuthenticationPlugin)
            {
                AddOrUpdateLogger(plugin.Plugin);

                if (proxy != null)
                {
                    await SetProxyCredentialsToPlugin(uri, proxy, plugin, cancellationToken);
                }

                var request = new GetAuthenticationCredentialsRequest(uri, isRetry, nonInteractive);

                var credentialResponse = await plugin.Plugin.Connection.SendRequestAndReceiveResponseAsync <GetAuthenticationCredentialsRequest, GetAuthenticationCredentialsResponse>(
                    MessageMethod.GetAuthenticationCredentials,
                    request,
                    cancellationToken);

                taskResponse = GetAuthenticationCredentialsResponseToCredentialResponse(credentialResponse);
            }
            else
            {
                taskResponse = new CredentialResponse(CredentialStatus.ProviderNotApplicable);
            }

            return(taskResponse);
        }
Exemple #7
0
 void AddToCredentialCache(Uri uri, CredentialRequestType type, ICredentialProvider provider,
                           CredentialResponse credentials)
 {
     _providerCredentialCache [CredentialCacheKey(uri, type, provider)] = credentials;
 }
        /// <summary>
        /// Call the plugin credential provider application to acquire credentials.
        /// The request will be passed to the plugin on standard input as a json serialized
        /// PluginCredentialRequest.
        /// The plugin will return credentials as a json serialized PluginCredentialResponse.
        /// Valid credentials will be returned, or null if the provide cannot provide credentials
        /// for the given request.  If the plugin returns an Abort message, an exception will be thrown to
        /// fail the current request.
        /// </summary>
        /// <param name="uri">The uri of a web resource for which credentials are needed.</param>
        /// <param name="proxy">Ignored.  Proxy information will not be passed to plugins.</param>
        /// <param name="type">
        /// The type of credential request that is being made. Note that this implementation of
        /// <see cref="ICredentialProvider"/> does not support providing proxy credenitials and treats
        /// all other types the same.
        /// </param>
        /// <param name="isRetry">If true, credentials were previously supplied by this
        /// provider for the same uri.</param>
        /// <param name="message">A message provided by NuGet to show to the user when prompting.</param>
        /// <param name="nonInteractive">If true, the plugin must not prompt for credentials.</param>
        /// <param name="cancellationToken">A cancellation token.</param>
        /// <returns>A credential object.</returns>
        public Task <CredentialResponse> GetAsync(
            Uri uri,
            IWebProxy proxy,
            CredentialRequestType type,
            string message,
            bool isRetry,
            bool nonInteractive,
            CancellationToken cancellationToken)
        {
            CredentialResponse taskResponse;

            if (type == CredentialRequestType.Proxy)
            {
                taskResponse = new CredentialResponse(CredentialStatus.ProviderNotApplicable);
                return(Task.FromResult(taskResponse));
            }

            try
            {
                var request = new PluginCredentialRequest
                {
                    Uri            = uri.AbsoluteUri,
                    IsRetry        = isRetry,
                    NonInteractive = nonInteractive,
                    Verbosity      = _verbosity
                };
                PluginCredentialResponse response;
                if (Interlocked.CompareExchange(ref _deprecationMessageWarningLogged, 1, 0) == 0)
                {
                    _logger.LogWarning(string.Format(CultureInfo.CurrentCulture, Resources.PluginWarning_PluginIsBeingDeprecated, Path, CrossPlatformPluginLink));
                }

                try
                {
                    response = GetPluginResponse(request, cancellationToken);
                }
                catch (PluginUnexpectedStatusException) when(PassVerbosityFlag(request))
                {
                    // older providers may throw if the verbosity flag is sent,
                    // so retry without it
                    request.Verbosity = null;
                    response          = GetPluginResponse(request, cancellationToken);
                }

                if (response.IsValid)
                {
                    var result = new AuthTypeFilteredCredentials(
                        new NetworkCredential(response.Username, response.Password),
                        response.AuthTypes ?? Enumerable.Empty <string>());

                    taskResponse = new CredentialResponse(result);
                }
                else
                {
                    taskResponse = new CredentialResponse(CredentialStatus.ProviderNotApplicable);
                }
            }
            catch (OperationCanceledException)
            {
                throw;
            }
            catch (PluginException)
            {
                throw;
            }
            catch (Exception e)
            {
                throw PluginException.Create(Path, e);
            }

            return(Task.FromResult(taskResponse));
        }
        /// <summary>
        /// Call the plugin credential provider application to acquire credentials.
        /// The request will be passed to the plugin on standard input as a json serialized
        /// PluginCredentialRequest.
        /// The plugin will return credentials as a json serialized PluginCredentialResponse.
        /// Valid credentials will be returned, or null if the provide cannot provide credentials
        /// for the given request.  If the plugin returns an Abort message, an exception will be thrown to
        /// fail the current request.
        /// </summary>
        /// <param name="uri">The uri of a web resource for which credentials are needed.</param>
        /// <param name="proxy">Ignored.  Proxy information will not be passed to plugins.</param>
        /// <param name="type">
        /// The type of credential request that is being made. Note that this implementation of
        /// <see cref="ICredentialProvider"/> does not support providing proxy credenitials and treats
        /// all other types the same.
        /// </param>
        /// <param name="isRetry">If true, credentials were previously supplied by this
        /// provider for the same uri.</param>
        /// <param name="message">A message provided by NuGet to show to the user when prompting.</param>
        /// <param name="nonInteractive">If true, the plugin must not prompt for credentials.</param>
        /// <param name="cancellationToken">A cancellation token.</param>
        /// <returns>A credential object.  If </returns>
        public Task <CredentialResponse> GetAsync(
            Uri uri,
            IWebProxy proxy,
            CredentialRequestType type,
            string message,
            bool isRetry,
            bool nonInteractive,
            CancellationToken cancellationToken)
        {
            CredentialResponse taskResponse;

            if (type == CredentialRequestType.Proxy)
            {
                taskResponse = new CredentialResponse(CredentialStatus.ProviderNotApplicable);
                return(Task.FromResult(taskResponse));
            }

            try
            {
                var request = new PluginCredentialRequest
                {
                    Uri            = uri.AbsoluteUri,
                    IsRetry        = isRetry,
                    NonInteractive = nonInteractive,
                    Verbosity      = _verbosity
                };
                PluginCredentialResponse response;

                // TODO: Extend the plug protocol to pass in the credential request type.
                try
                {
                    response = GetPluginResponse(request, cancellationToken);
                }
                catch (PluginUnexpectedStatusException) when(PassVerbosityFlag(request))
                {
                    // older providers may throw if the verbosity flag is sent,
                    // so retry without it
                    request.Verbosity = null;
                    response          = GetPluginResponse(request, cancellationToken);
                }

                if (response.IsValid)
                {
                    ICredentials result = new NetworkCredential(response.Username, response.Password);
                    if (response.AuthTypes != null)
                    {
                        result = new AuthTypeFilteredCredentials(result, response.AuthTypes);
                    }

                    taskResponse = new CredentialResponse(result);
                }
                else
                {
                    taskResponse = new CredentialResponse(CredentialStatus.ProviderNotApplicable);
                }
            }
            catch (OperationCanceledException)
            {
                throw;
            }
            catch (PluginException)
            {
                throw;
            }
            catch (Exception e)
            {
                throw PluginException.Create(Path, e);
            }

            return(Task.FromResult(taskResponse));
        }