Example #1
0
        /// <summary>
        /// Handles the async reception of the public key from the authentication service.
        /// </summary>
        /// <param name="ar">The async result instance.</param>
        private void OnGetKey(IAsyncResult ar)
        {
            AuthAsyncResult arAuth = (AuthAsyncResult)ar.AsyncState;
            GetPublicKeyAck ack;
            AuthMsg         authMsg;

            using (TimedLock.Lock(this))
            {
                try
                {
                    if (!isOpen)
                    {
                        throw new AuthenticationException(NotOpenMsg);
                    }

                    ack       = (GetPublicKeyAck)router.EndQuery(ar);
                    publicKey = ack.PublicKey;

                    // Now that we have the public key, we're going to broadcast
                    // it to the authentication service instances so that they can
                    // perform a man-in-the-middle security check.

                    router.BroadcastTo(AbstractAuthServerEP, new AuthServerIDMsg(ack.PublicKey, ack.MachineName, ack.Address));

                    // Now initiate the authentication query.

                    arAuth.OpState = AuthOpState.AuthPending;
                    authMsg        = new AuthMsg(AuthMsg.EncryptCredentials(publicKey, arAuth.Realm, arAuth.Account, arAuth.Password, out arAuth.SymmetricKey));

                    router.BeginQuery(AbstractAuthServerEP, authMsg, onAuth, arAuth);
                }
                catch (System.TimeoutException)
                {
                    arAuth.Notify(new AuthenticationException("No authentication service instances responded."));
                }
                catch (Exception e)
                {
                    arAuth.Notify(e);
                }
            }
        }
Example #2
0
        /// <summary>
        /// Initiates an asynchronous account credential authentication.
        /// </summary>
        /// <param name="realm">The authentication realm.</param>
        /// <param name="account">The account.</param>
        /// <param name="password">The password.</param>
        /// <param name="callback">The delegate to be called when the operation completes (or <c>null</c>).</param>
        /// <param name="state">Application defined state (or <c>null</c>).</param>
        /// <returns>An <see cref="IAsyncResult" /> instance to be used to track the operation.</returns>
        /// <remarks>
        /// <note>
        /// Successful calls to this method must eventually be followed by a call
        /// to <see cref="EndAuthenticate" />.
        /// </note>
        /// </remarks>
        /// <exception cref="AuthenticationException">Thrown if the authenticator is not open.</exception>
        public IAsyncResult BeginAuthenticate(string realm, string account, string password, AsyncCallback callback, object state)
        {
            string               cacheKey = GetCacheKey(realm, account, password);
            AuthAsyncResult      arAuth;
            AuthenticationResult result;

            using (TimedLock.Lock(this))
            {
                if (!isOpen)
                {
                    throw new AuthenticationException(NotOpenMsg);
                }

                arAuth          = new AuthAsyncResult(this, callback, state);
                arAuth.Realm    = realm;
                arAuth.Account  = account;
                arAuth.Password = password;

                arAuth.Started();

                // First check to see if the answer is already cached

                if (cache != null && cache.TryGetValue(cacheKey, out result))
                {
                    arAuth.Result = result;
                    arAuth.Notify();

                    if (result.Status != AuthenticationStatus.Authenticated &&
                        result.Status != AuthenticationStatus.AccountLocked)
                    {
                        // If the authentication failed and the account is not locked
                        // then broadcast message to the authentication services so that
                        // they can increment their fail counts.

                        router.BroadcastTo(AbstractAuthServerEP, new AuthControlMsg("auth-failed", string.Format("realm={0};account={1};status={2}", realm, account, result.Status)));
                    }

                    return(arAuth);
                }

                // If we don't have the authentication service's public key yet then
                // initiate an async query to get it.

                if (publicKey == null)
                {
                    arAuth.OpState = AuthOpState.GetPublicKey;
                    router.BeginQuery(AbstractAuthServerEP, new GetPublicKeyMsg(), onGetKey, arAuth);
                    return(arAuth);
                }

                // Initiate an async authentication query, encrypting the credentials
                // using the authentication service's public key.

                AuthMsg authMsg;

                arAuth.OpState = AuthOpState.AuthPending;
                authMsg        = new AuthMsg(AuthMsg.EncryptCredentials(publicKey, realm, account, password, out arAuth.SymmetricKey));

                router.BeginQuery(AbstractAuthServerEP, authMsg, onAuth, arAuth);

                return(arAuth);
            }
        }