예제 #1
0
 internal AzureActiveDirectoryTokenProvider(AuthenticationCallback authenticationCallback, string authority, object state)
 {
     this.clientId          = Guid.NewGuid().ToString();
     this.authority         = authority;
     this.AuthCallback      = authenticationCallback;
     this.authCallbackState = state;
 }
예제 #2
0
        public FingerprintService(
            FragmentActivity fragmentActivity,
            Context applicationContext,
            IObservable <Unit> applicationActivated,
            CoreDispatcher dispatcher,
            IScheduler backgroundScheduler,
            FuncAsync <BiometricPrompt.PromptInfo> promptInfoBuilder)
        {
            fragmentActivity.Validation().NotNull(nameof(fragmentActivity));
            applicationActivated.Validation().NotNull(nameof(applicationActivated));
            backgroundScheduler.Validation().NotNull(nameof(backgroundScheduler));
            _dispatcher        = dispatcher ?? throw new ArgumentNullException(nameof(dispatcher));
            _promptInfoBuilder = promptInfoBuilder ?? throw new ArgumentNullException(nameof(promptInfoBuilder));

            var executor = ContextCompat.GetMainExecutor(applicationContext);
            var callback = new AuthenticationCallback(OnAuthenticationSucceeded, OnAuthenticationFailed, OnAuthenticationError);

            _BiometricPrompt  = new BiometricPrompt(fragmentActivity, executor, callback);
            _BiometricManager = BiometricManager.From(Application.Context);

            _keyStore = KeyStore.GetInstance(ANDROID_KEYSTORE);
            _keyStore.Load(null);

            _canAuthenticate =
                applicationActivated
                .ObserveOn(backgroundScheduler)
                .StartWith(backgroundScheduler, Unit.Default)
                .Select(_ => _BiometricManager.CanAuthenticate())
                .Replay(1, backgroundScheduler)
                .RefCount();
        }
예제 #3
0
        private async Task AuthenticateAsync()
        {
            AuthenticationCallback.Invoke(this, new AuthenticationEventArgs()
            {
                isAuthenticated = true
            });

            //using (var scope = SharedAppInitializer.SharedInstance.Container.BeginLifetimeScope())
            //{


            //    var authenticator = scope.ResolveOptional<IAuthenticator>();
            //    var accessToken = await authenticator.AuthenticateAsync();
            //    Console.WriteLine(accessToken);

            //    var eventArgs = new AuthenticationEventArgs()
            //    {

            //        isAuthenticated = !(string.IsNullOrEmpty(accessToken))
            //    };

            //    AuthenticationCallback.Invoke(this, eventArgs);

            //}
        }
        public void EnableBiometrics(Action <bool> callback)
        {
            var passwordStorage = new PasswordStorageManager(this);
            var executor        = ContextCompat.GetMainExecutor(this);
            var authCallback    = new AuthenticationCallback();

            authCallback.Success += async(_, result) =>
            {
                try
                {
                    var password = await SecureStorageWrapper.GetDatabasePassword();

                    passwordStorage.Store(password, result.CryptoObject.Cipher);
                }
                catch (Exception e)
                {
                    Logger.Error(e);
                    callback(false);
                    return;
                }

                callback(true);
            };

            authCallback.Failed += delegate
            {
                callback(false);
            };

            authCallback.Error += delegate
            {
                // Do something, probably
                callback(false);
            };

            var prompt = new BiometricPrompt(this, executor, authCallback);

            var promptInfo = new BiometricPrompt.PromptInfo.Builder()
                             .SetTitle(GetString(Resource.String.setupBiometricUnlock))
                             .SetNegativeButtonText(GetString(Resource.String.cancel))
                             .SetConfirmationRequired(false)
                             .SetAllowedAuthenticators(BiometricManager.Authenticators.BiometricStrong)
                             .Build();

            Cipher cipher;

            try
            {
                cipher = passwordStorage.GetEncryptionCipher();
            }
            catch (Exception e)
            {
                Logger.Error(e);
                passwordStorage.Clear();
                callback(false);
                return;
            }

            prompt.Authenticate(promptInfo, new BiometricPrompt.CryptoObject(cipher));
        }
예제 #5
0
        public void ConfigureServices(IServiceCollection services)
        {
            services
            .AddEntityFrameworkSqlServer()
            .AddDbContext <MovieDb>(options =>
            {
                var connection = Configuration["Data:DefaultConnection:ConnectionString"];
                options.UseSqlServer(connection);
            });

            services
            .AddMvc();

            //services.AddSingleton(sp =>
            //{
            //    var tokenProvider = new AzureServiceTokenProvider();
            //    var callback = new AuthenticationCallback(tokenProvider.KeyVaultTokenCallback);
            //    return new KeyVaultClient(callback);
            //});
            services.AddSingleton <IKeyVaultCrypto>(sp =>
            {
                AuthenticationCallback callback = async(authority, resource, scope) =>
                {
                    var appId       = Configuration["AppId"];
                    var appSecret   = Configuration["AppSecret"];
                    var authContext = new AuthenticationContext(authority);
                    var credential  = new ClientCredential(appId, appSecret);
                    var authResult  = await authContext.AcquireTokenAsync(resource, credential);
                    return(authResult.AccessToken);
                };

                var client = new KeyVaultClient(callback);
                return(new KeyVaultCrypto(client, Configuration["KeyId"]));
            });
        }
        public async Task <ActionResult> ExternalLoginCallback(AuthenticationCallback model)
        {
            // authenticate the user with the custom scheme
            var result = await HttpContext.AuthenticateAsync(Constants.SignInScheme);

            //// Get claims
            //var claims = result.Principal.Claims;

            //// singin localy with claims
            //await HttpContext.SignInAsync(Constants.SignInScheme, new ClaimsPrincipal(new ClaimsIdentity(claims)));

            // Get user from claims
            var user = _userService.GetFromClaims(result.Principal);

            if (user == null)
            {
                return(View(model.RemoteError));
            }

            // Set user in session to use later
            _userService.Set(user);

            // Test new user, to edit profile
            if (user.Id == 0)
            {
                return(RedirectToAction("Edit", "Account"));
            }

            //if (String.IsNullOrWhiteSpace(model.ReturnUrl))
            //{
            //    Redirect("~/");
            //}
            // Redirection
            return(Redirect(model.ReturnUrl));
        }
예제 #7
0
        private void ShowBiometricPrompt()
        {
            var executor        = ContextCompat.GetMainExecutor(this);
            var passwordStorage = new PasswordStorageManager(this);
            var callback        = new AuthenticationCallback();

            callback.Success += async(_, result) =>
            {
                string password;

                try
                {
                    password = passwordStorage.Fetch(result.CryptoObject.Cipher);
                }
                catch
                {
                    Toast.MakeText(this, Resource.String.genericError, ToastLength.Short);
                    return;
                }

                await AttemptUnlock(password);
            };

            callback.Failed += delegate
            {
                FocusPasswordText();
            };

            callback.Error += (_, result) =>
            {
                Toast.MakeText(this, result.Message, ToastLength.Short).Show();
                FocusPasswordText();
            };

            _prompt = new BiometricPrompt(this, executor, callback);

            var promptInfo = new BiometricPrompt.PromptInfo.Builder()
                             .SetTitle(GetString(Resource.String.unlock))
                             .SetSubtitle(GetString(Resource.String.unlockBiometricsMessage))
                             .SetNegativeButtonText(GetString(Resource.String.cancel))
                             .SetConfirmationRequired(false)
                             .SetAllowedAuthenticators(BiometricManager.Authenticators.BiometricStrong)
                             .Build();

            Cipher cipher;

            try
            {
                cipher = passwordStorage.GetDecryptionCipher();
            }
            catch
            {
                _canUseBiometrics            = false;
                _useBiometricsButton.Enabled = false;
                return;
            }

            _prompt.Authenticate(promptInfo, new BiometricPrompt.CryptoObject(cipher));
        }
예제 #8
0
 /// <summary>Creates an Azure Active Directory token provider.</summary>
 /// <param name="authCallback">A user supplied handler that would be invoked to obtain the AAD access token string.</param>
 /// <param name="authority">Address of the authority to issue the AAD token. For example, https://login.microsoftonline.com/{TenantId}</param>
 /// <param name="state">State to be delivered to callback.</param>
 /// <returns>The <see cref="Microsoft.Azure.Relay.TokenProvider" /> for returning Json web token.</returns>
 public static TokenProvider CreateAzureActiveDirectoryTokenProvider(
     AuthenticationCallback authCallback,
     string authority,
     object state = null)
 {
     Fx.Assert(authCallback != null, $"{nameof(authCallback)} cannot be null.");
     Fx.Assert(authority != null, $"{nameof(authority)} cannot be null.");
     return(new AzureActiveDirectoryTokenProvider(authCallback, authority, state));
 }
        public ColumnEncryptionAzureKeyVaultProvider(AuthenticationCallback authenticationCallback, string[] trustedEndPoints)
        {
            ValidateNotNull(authenticationCallback, nameof(authenticationCallback));
            ValidateNotNull(trustedEndPoints, nameof(trustedEndPoints));
            ValidateNotEmpty(trustedEndPoints, nameof(trustedEndPoints));
            ValidateNotNullOrWhitespaceForEach(trustedEndPoints, nameof(trustedEndPoints));

            KeyCryptographer = new KeyCryptographer(authenticationCallback);
            TrustedEndPoints = trustedEndPoints;
        }
예제 #10
0
        public AzureKeyVaultProviderTokenCredential(AuthenticationCallback authenticationCallback, string masterKeyPath)
        {
            Callback = authenticationCallback;
            HttpClient          httpClient = new HttpClient();
            HttpResponseMessage response   = httpClient.GetAsync(masterKeyPath).GetAwaiter().GetResult();
            string challenge        = response?.Headers.WwwAuthenticate.FirstOrDefault()?.ToString();
            string trimmedChallenge = ValidateChallenge(challenge);

            string[] pairs = trimmedChallenge.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);

            Authority = pairs[0].Split('=')[1].Trim().Trim(new char[] { '\"' });
            Resource  = pairs[1].Split('=')[1].Trim().Trim(new char[] { '\"' });
        }
예제 #11
0
        public IIoTKeyVaultClient(
            AuthenticationCallback authenticationCallback,
            VaultInner keyVault
            )
        {
            var kvAuthenticationCallback = new KeyVaultClient.AuthenticationCallback(
                async(authority, resource, scope) => {
                return(await authenticationCallback(authority, resource, scope));
            }
                );

            _keyVaultClient = new KeyVaultClient(kvAuthenticationCallback);
            _keyVault       = keyVault;
        }
예제 #12
0
        // localhost:port/api/home
        public async Task <IHttpActionResult> Get()
        {
            AuthenticationCallback keyVaultCallback = new AuthenticationCallback(GetAccessTokenAsync);
            KeyVaultClient         keyVaultClient   = new KeyVaultClient(keyVaultCallback);

            string usernameSecretId = WebConfigurationManager.AppSettings["UsernameSecretIdentifier"];
            string passwordSecretId = WebConfigurationManager.AppSettings["PasswordSecretIdentifier"];

            SecretBundle keyValueDbPassphraseSecret = await keyVaultClient.GetSecretAsync(usernameSecretId);

            SecretBundle keyValueAdminPasswordSecret = await keyVaultClient.GetSecretAsync(passwordSecretId);

            return(Ok(new {
                DbPassphrase = keyValueDbPassphraseSecret.Value,
                AdminPassword = keyValueAdminPasswordSecret.Value
            }));
        }
예제 #13
0
        private static async Task <string> Encrypt(string value)
        {
            AuthenticationCallback callback = async(authority, resource, scope) =>
            {
                var appId     = "";
                var appSecret = "";

                System.Console.WriteLine($"Authority {authority}");
                System.Console.WriteLine($"resource {resource}");
                System.Console.WriteLine($"scope {scope}");

                var authContext = new AuthenticationContext(authority);

                var credential = new ClientCredential(appId, appSecret);
                var authResult = await authContext.AcquireTokenAsync(resource, credential);

                return(authResult.AccessToken);
            };

            System.Console.WriteLine($"Setting up client");
            var client = new KeyVaultClient(callback);

            var key = await client.GetKeyAsync("https://wickedvault.vault.azure.net", "masterKey");


            using (var rsa = new RSACryptoServiceProvider())
            {
                var parameters = new RSAParameters()
                {
                    Modulus  = key.Key.N,
                    Exponent = key.Key.E
                };

                rsa.ImportParameters(parameters);
                var byteData      = Encoding.Unicode.GetBytes(value);
                var encryptedText = rsa.Encrypt(byteData, fOAEP: true);

                var encodedText = Convert.ToBase64String(encryptedText);

                System.Console.WriteLine($"rsa encrypted text {encryptedText}");
                System.Console.WriteLine($"encoded text {encodedText}");

                return(encodedText);
            }
        }
예제 #14
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="authenticationCallback"> the authentication callback </param>
        /// <param name="sendRequestCallback"> the send request callback to log request that is sent </param>
        /// <param name="receiveResponseCallback"> the receive response callback to log response that is received </param>
        /// <param name="httpClient"> customized http client </param>
        /// <param name="setRequestUriCallback"> the callback to replace requst URI with a different URI </param>
        public KeyVaultClient(
            AuthenticationCallback authenticationCallback,
            SendRequestCallback sendRequestCallback         = null,
            ReceiveResponseCallback receiveResponseCallback = null,
            HttpClient httpClient = null,
            SetRequestUriCallback setRequestUriCallback = null)
            : this(httpClient)
        {
            if (authenticationCallback == null)
            {
                throw new ArgumentNullException("authenticationCallback");
            }

            OnAuthenticate    = authenticationCallback;
            OnSendRequest     = sendRequestCallback;
            OnReceiveResponse = receiveResponseCallback;
            OnSetRequestUri   = setRequestUriCallback;
        }
예제 #15
0
        // See https://docs.microsoft.com/en-us/azure/key-vault/key-vault-use-from-web-application
        private static string GetKeyVaultSecret(ClientCredential credential, string secretUri)
        {
            AuthenticationCallback callback = async(string authority, string resource, string scope) =>
            {
                var authContext             = new AuthenticationContext(authority);
                AuthenticationResult result = await authContext.AcquireTokenAsync(resource, credential);

                if (result == null)
                {
                    throw new InvalidOperationException("Failed to obtain the JWT token");
                }
                return(result.AccessToken);
            };

            var kv = new KeyVaultClient(callback);

            return(kv.GetSecretAsync(secretUri).Result.Value);
        }
예제 #16
0
 public void AuthenticateUser(
     string userName,
     string password,
     RegistrationCallback registrationCallback,
     AuthenticationCallback authenticationCallback)
 {
     new RegistrationRequest().
     SetUserName(userName).
     SetPassword(password).
     SetDisplayName(userName).
     Send((registrationResposnse) =>
     {
         if (!registrationResposnse.HasErrors)
         {
             Debug.Log("Registration Successful");
             registrationCallback(registrationResposnse);
         }
         else
         {
             if (registrationResposnse.NewPlayer == false)
             {
                 new AuthenticationRequest().SetUserName(userName).SetPassword(password).Send(
                     (authenticationResponse) =>
                 {
                     if (!authenticationResponse.HasErrors)
                     {
                         Debug.Log("Authentication Successful");
                         authenticationCallback(authenticationResponse);
                     }
                     else
                     {
                         Debug.Log("Authentication Error " +
                                   authenticationResponse.Errors.JSON);
                     }
                 });
             }
             else
             {
                 Debug.Log("Authentication Error " +
                           registrationResposnse.Errors.JSON);
             }
         }
     });
 }
예제 #17
0
        /// <summary>
        ///     Initializes a new instance of the <see cref="BiometryService" /> class.
        /// </summary>
        /// <param name="fragmentActivity"></param>
        /// <param name="dispatcher"></param>
        /// <param name="promptInfoBuilder"></param>
        /// <param name="authenticators"></param>
        public BiometryService(
            FragmentActivity fragmentActivity,
            CoreDispatcher dispatcher,
            FuncAsync <BiometricPrompt.PromptInfo> promptInfoBuilder)
        {
            fragmentActivity.Validation().NotNull(nameof(fragmentActivity));
            _dispatcher        = dispatcher ?? throw new ArgumentNullException(nameof(dispatcher));
            _promptInfoBuilder = promptInfoBuilder ?? throw new ArgumentNullException(nameof(promptInfoBuilder));

            _applicationContext = Application.Context;
            var executor = ContextCompat.GetMainExecutor(_applicationContext);
            var callback = new AuthenticationCallback(OnAuthenticationSucceeded, OnAuthenticationFailed, OnAuthenticationError);

            _biometricPrompt  = new BiometricPrompt(fragmentActivity, executor, callback);
            _biometricManager = BiometricManager.From(_applicationContext);

            _keyStore = KeyStore.GetInstance(ANDROID_KEYSTORE);
            _keyStore.Load(null);
        }
예제 #18
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ManagedKeyVaultSecurityKey"/> class.
        /// </summary>
        /// <param name="keyIdentifier">The key identifier.</param>
        /// <param name="clientId">Identifier of the client.</param>
        /// <param name="clientSecret">Secret of the client identity.</param>
        /// <exception cref="ArgumentNullException">if <paramref name="keyIdentifier"/> is null or empty.</exception>
        /// <exception cref="ArgumentNullException">if <paramref name="clientId"/>is null or empty.</exception>
        /// <exception cref="ArgumentNullException">if <paramref name="clientSecret"/>is null or clientSecret.</exception>
        public ManagedKeyVaultSecurityKey(string keyIdentifier, string clientId, string clientSecret)
        {
            if (string.IsNullOrEmpty(keyIdentifier))
            {
                throw LogHelper.LogArgumentNullException(nameof(keyIdentifier));
            }

            if (string.IsNullOrEmpty(clientId))
            {
                throw LogHelper.LogArgumentNullException(nameof(clientId));
            }

            if (string.IsNullOrEmpty(clientSecret))
            {
                throw LogHelper.LogArgumentNullException(nameof(clientSecret));
            }

            KeyId    = keyIdentifier;
            Callback = new AuthenticationCallback(async(string authority, string resource, string scope) =>
                                                  (await(new AuthenticationContext(authority, TokenCache.DefaultShared)).AcquireTokenAsync(resource, new ClientCredential(clientId, clientSecret)).ConfigureAwait(false)).AccessToken);
        }
예제 #19
0
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            SetContentView(Resource.Layout.activityLogin);

            var executor = ContextCompat.GetMainExecutor(this);
            var callback = new AuthenticationCallback();

            callback.Success += OnSuccess;
            callback.Error   += OnError;

            var prompt = new BiometricPrompt(this, executor, callback);

            var promptInfo = new BiometricPrompt.PromptInfo.Builder()
                             .SetTitle(GetString(Resource.String.login))
                             .SetSubtitle(GetString(Resource.String.loginMessage))
                             .SetDeviceCredentialAllowed(true)
                             .Build();

            prompt.Authenticate(promptInfo);
        }
예제 #20
0
        private static async Task <string> Decrypt(string encryptedText)
        {
            Console.WriteLine("Source value ################################");
            Console.WriteLine(encryptedText);
            Console.WriteLine("Source value ################################");

            var encryptedBytes = Convert.FromBase64String(encryptedText);

            System.Console.WriteLine("Decypting text");
            System.Console.WriteLine(encryptedBytes);


            AuthenticationCallback callback = async(authority, resource, scope) =>
            {
                var appId     = "";
                var appSecret = "";
                //resource = "/subscriptions/0d2be596-245f-4f2e-8f16-abdc53bf0042/resourceGroups/rgkv/providers/Microsoft.KeyVault/vaults/wickedvault";

                System.Console.WriteLine($"Authority {authority}");
                System.Console.WriteLine($"resource {resource}");
                System.Console.WriteLine($"scope {scope}");

                var authContext = new AuthenticationContext(authority);

                var credential = new ClientCredential(appId, appSecret);
                var authResult = await authContext.AcquireTokenAsync(resource, credential);

                return(authResult.AccessToken);
            };

            System.Console.WriteLine($"Setting up client");
            var client = new KeyVaultClient(callback);

            var decryptionResult = await client.DecryptAsync("https://wickedvault.vault.azure.net/keys/masterKey/4a43739e319941a889321e801d8534a4", JsonWebKeyEncryptionAlgorithm.RSAOAEP, encryptedBytes);

            var decryptedText = Encoding.Unicode.GetString(decryptionResult.Result);

            Console.WriteLine($"decrypted : {decryptedText}");
            return(decryptedText);
        }
예제 #21
0
        /// <summary>
        /// Constructor of IIoT-specific KeyVault client.
        /// </summary>
        /// <param name="authenticationCallback"></param>
        /// <param name="keyVault"></param>
        public IIoTKeyVaultClient(
            AuthenticationCallback authenticationCallback,
            VaultInner keyVault
            )
        {
            if (authenticationCallback is null)
            {
                throw new ArgumentNullException(nameof(authenticationCallback));
            }
            if (keyVault is null)
            {
                throw new ArgumentNullException(nameof(keyVault));
            }

            var kvAuthenticationCallback = new KeyVaultClient.AuthenticationCallback(
                async(authority, resource, scope) => {
                return(await authenticationCallback(authority, resource, scope));
            }
                );

            _keyVaultClient = new KeyVaultClient(kvAuthenticationCallback);
            _keyVault       = keyVault;
        }
예제 #22
0
 internal AzureActiveDirectoryTokenProvider(AuthenticationCallback authenticationCallback, string authority, object state)
 {
     this.authCallback      = authenticationCallback ?? throw new ArgumentNullException(nameof(authenticationCallback));
     this.authority         = authority;
     this.authCallbackState = state;
 }
예제 #23
0
 public AzureActiveDirectoryTokenProvider(AuthenticationCallback authenticationCallback, string authority, object state)
 {
     this.AuthCallback      = authenticationCallback ?? throw Fx.Exception.ArgumentNull(nameof(authenticationCallback));
     this.authority         = authority ?? throw Fx.Exception.ArgumentNull(nameof(authority));
     this.authCallbackState = state;
 }
예제 #24
0
 public KeyCryptographer(AuthenticationCallback authenticationCallback)
 {
     AuthenticationCallback      = authenticationCallback;
     isUsingLegacyAuthentication = true;
 }
 public ColumnEncryptionAzureKeyVaultProvider(AuthenticationCallback authenticationCallback, string trustedEndPoint) :
     this(authenticationCallback, new[] { trustedEndPoint })
 {
 }
예제 #26
0
 public KeyVaultClientEx(string vaultName, AuthenticationCallback authenticationCallback) : base(authenticationCallback)
 {
     Utils.GuardVaultName(vaultName);
     VaultName = vaultName;
     VaultUri  = string.Format(Consts.AzureVaultUriFormat, VaultName);
 }
예제 #27
0
        public SshAuthenticatedSession Authenticate(
            string username,
            ISshKey key,
            AuthenticationCallback callback)
        {
            this.session.Handle.CheckCurrentThreadOwnsHandle();
            Utilities.ThrowIfNullOrEmpty(username, nameof(username));
            Utilities.ThrowIfNull(key, nameof(key));
            Utilities.ThrowIfNull(callback, nameof(callback));

            Exception interactiveCallbackException = null;

            //
            // NB. The callbacks are sparsely documented in the libssh2 sources
            // and docs. For sample usage, the Guacamole sources can be helpful, cf.
            // https://github.com/stuntbadger/GuacamoleServer/blob/a06ae0743b0609cde0ceccc7ed136b0d71009105/src/common-ssh/ssh.c#L335
            //

            int Sign(
                IntPtr session,
                out IntPtr signaturePtr,
                out IntPtr signatureLength,
                IntPtr dataPtr,
                IntPtr dataLength,
                IntPtr context)
            {
                Debug.Assert(context == IntPtr.Zero);
                Debug.Assert(session == this.session.Handle.DangerousGetHandle());

                //
                // Copy data to managed buffer and create signature.
                //
                var data = new byte[dataLength.ToInt32()];

                Marshal.Copy(dataPtr, data, 0, data.Length);

                var signature = key.SignData(data);

                //
                // Copy data back to a buffer that libssh2 can free using
                // the allocator specified in libssh2_session_init_ex.
                //

                signatureLength = new IntPtr(signature.Length);
                signaturePtr    = SshSession.Alloc(signatureLength, IntPtr.Zero);
                Marshal.Copy(signature, 0, signaturePtr, signature.Length);

                return((int)LIBSSH2_ERROR.NONE);
            }

            void InteractiveCallback(
                IntPtr namePtr,
                int nameLength,
                IntPtr instructionPtr,
                int instructionLength,
                int numPrompts,
                IntPtr promptsPtr,
                IntPtr responsesPtr,
                IntPtr context)
            {
                var name = UnsafeNativeMethods.PtrToString(
                    namePtr,
                    nameLength,
                    Encoding.UTF8);
                var instruction = UnsafeNativeMethods.PtrToString(
                    instructionPtr,
                    nameLength,
                    Encoding.UTF8);
                var prompts = UnsafeNativeMethods.PtrToStructureArray <
                    UnsafeNativeMethods.LIBSSH2_USERAUTH_KBDINT_PROMPT>(
                    promptsPtr,
                    numPrompts);

                //
                // NB. libssh2 allocates the responses structure for us, but frees
                // the embedded text strings using its allocator.
                //
                // NB. libssh2 assumes text to be encoded in UTF-8.
                //
                Debug.Assert(SshSession.Alloc != null);

                var responses = new UnsafeNativeMethods.LIBSSH2_USERAUTH_KBDINT_RESPONSE[prompts.Length];

                for (int i = 0; i < prompts.Length; i++)
                {
                    var promptText = UnsafeNativeMethods.PtrToString(
                        prompts[i].TextPtr,
                        prompts[i].TextLength,
                        Encoding.UTF8);

                    SshTraceSources.Default.TraceVerbose("Keyboard/interactive prompt: {0}", promptText);

                    //
                    // NB. Name and instruction aren't used by OS Login,
                    // so flatten the structure to a single level.
                    //
                    string responseText = null;
                    try
                    {
                        responseText = callback(
                            name,
                            instruction,
                            promptText,
                            prompts[i].Echo != 0);
                    }
                    catch (Exception e)
                    {
                        SshTraceSources.Default.TraceError(
                            "Authentication callback threw exception", e);

                        //
                        // Don't let the exception escape into unmanaged code,
                        // instead return null and let the enclosing method
                        // rethrow the exception once we're back on a managed
                        // callstack.
                        //
                        interactiveCallbackException = e;
                    }

                    responses[i] = new UnsafeNativeMethods.LIBSSH2_USERAUTH_KBDINT_RESPONSE();
                    if (responseText == null)
                    {
                        responses[i].TextLength = 0;
                        responses[i].TextPtr    = IntPtr.Zero;
                    }
                    else
                    {
                        var responseTextBytes = Encoding.UTF8.GetBytes(responseText);
                        responses[i].TextLength = responseTextBytes.Length;
                        responses[i].TextPtr    = SshSession.Alloc(
                            new IntPtr(responseTextBytes.Length),
                            IntPtr.Zero);
                        Marshal.Copy(
                            responseTextBytes,
                            0,
                            responses[i].TextPtr,
                            responseTextBytes.Length);
                    }
                }

                UnsafeNativeMethods.StructureArrayToPtr(
                    responsesPtr,
                    responses);
            }

            using (SshTraceSources.Default.TraceMethod().WithParameters(username))
            {
                //
                // NB. The public key must be passed in OpenSSH format, not PEM.
                // cf. https://tools.ietf.org/html/rfc4253#section-6.6
                //
                var publicKey = key.PublicKey;

                var result = (LIBSSH2_ERROR)UnsafeNativeMethods.libssh2_userauth_publickey(
                    this.session.Handle,
                    username,
                    key.PublicKey,
                    new IntPtr(publicKey.Length),
                    Sign,
                    IntPtr.Zero);

                if (result == LIBSSH2_ERROR.PUBLICKEY_UNVERIFIED)
                {
                    SshTraceSources.Default.TraceVerbose(
                        "Server responded that public key is unverified, " +
                        "trying keyboard/interactive auth for MFA challenges");

                    //
                    // Public key wasn't accepted - this might be because the
                    // key is not authorized, or because we need to respond to
                    // some more (MFA) challenges.
                    //
                    // NB. It's not worth checking GetAuthenticationMethods, it
                    // won't indicate whether additional challenges are expected
                    // or not.
                    //

                    //
                    // Temporarily change the timeout since we must give the
                    // user some time to react.
                    //
                    var originalTimeout = this.session.Timeout;
                    this.session.Timeout = this.session.KeyboardInteractivePromptTimeout;
                    try
                    {
                        //
                        // Retry to account for wrong user input.
                        //
                        for (int retry = 0; retry < KeyboardInteractiveRetries; retry++)
                        {
                            result = (LIBSSH2_ERROR)UnsafeNativeMethods.libssh2_userauth_keyboard_interactive_ex(
                                this.session.Handle,
                                username,
                                username.Length,
                                InteractiveCallback,
                                IntPtr.Zero);

                            if (result == LIBSSH2_ERROR.NONE)
                            {
                                break;
                            }
                            else if (interactiveCallbackException != null)
                            {
                                //
                                // Restore exception thrown in callback.
                                //
                                throw interactiveCallbackException;
                            }
                        }
                    }
                    finally
                    {
                        //
                        // Restore timeout.
                        //
                        this.session.Timeout = originalTimeout;
                    }
                }

                if (result != LIBSSH2_ERROR.NONE)
                {
                    throw this.session.CreateException(result);
                }
                else
                {
                    return(new SshAuthenticatedSession(this.session));
                }
            }
        }
예제 #28
0
 public CachedKeyVaultClient(AuthenticationCallback authenticationCallback, params System.Net.Http.DelegatingHandler[] handlers)
     : base(authenticationCallback, handlers)
 {
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="KeyVaultSecurityKey"/> class.
 /// </summary>
 /// <param name="keyIdentifier">The key identifier.</param>
 /// <param name="callback">The authentication callback.</param>
 /// <exception cref="ArgumentNullException">if <paramref name="keyIdentifier"/> is null or empty.</exception>
 /// <exception cref="ArgumentNullException">if <paramref name="callback"/>is null.</exception>
 public KeyVaultSecurityKey(string keyIdentifier, AuthenticationCallback callback)
 {
     Callback = callback ?? throw LogHelper.LogArgumentNullException(nameof(callback));
     KeyId    = keyIdentifier;
 }
예제 #30
0
 public CachedKeyVaultClient(AuthenticationCallback authenticationCallback, System.Net.Http.HttpClient httpClient)
     : base(authenticationCallback, httpClient)
 {
 }