private async Task HandleResponseStateAsync(AuthSession session, string message)
        {
            Dictionary <string, string> values = AuthUtil.ParseDigestValues(message);

            if (null == values || 0 == values.Count)
            {
                await session.ErrorAsync("Invalid challenge!").ConfigureAwait(false);

                return;
            }

            try {
                string rspauth = values["rspauth"].Trim('"');
                if (session.RspAuth != rspauth)
                {
                    await session.ErrorAsync($"rspauth mismatch, expected: '{session.RspAuth}', got: '{rspauth}'").ConfigureAwait(false);

                    return;
                }

                await session.AuthFinalizeAsync().ConfigureAwait(false);
            } catch (KeyNotFoundException e) {
                await session.ErrorAsync($"Invalid challenge: {e.Message}").ConfigureAwait(false);
            }
        }
        private async Task HandleChallengeStateAsync(AuthSession session, string message)
        {
            Dictionary <string, string> values = AuthUtil.ParseDigestValues(message);

            if (null == values || 0 == values.Count)
            {
                await session.ErrorAsync("Invalid challenge!").ConfigureAwait(false);

                return;
            }

            try {
                string charset = values["charset"].Trim('"');
                if (!"utf-8".Equals(charset, StringComparison.InvariantCultureIgnoreCase))
                {
                    await session.ErrorAsync("Invalid charset!").ConfigureAwait(false);

                    return;
                }

                string realm     = values["realm"].Trim('"');
                Nonce  cnonce    = new Nonce(realm, -1);
                string nc        = "00000001";
                string digestUri = $"{realm}/{ConfigurationManager.AppSettings["authHost"]}";

                Logger.Debug($"Authenticating {App.Instance.UserAccount.AccountName}:{realm}:****");
                string passwordHash = await new SHA512().DigestPasswordAsync(
                    App.Instance.UserAccount.AccountName,
                    realm,
                    App.Instance.UserAccount.Password).ConfigureAwait(false);
                Logger.Debug($"passwordHash={passwordHash}");

                string nonce = values["nonce"].Trim('"');
                string qop   = values["qop"].Trim('"');
                string rsp   = await AuthUtil.DigestClientResponseAsync(new SHA512(), passwordHash, nonce, nc, qop, cnonce.NonceHash, digestUri).ConfigureAwait(false);

                string msg = $"username=\"{App.Instance.UserAccount.AccountName}\",realm={realm},"
                             + $"nonce={nonce},cnonce=\"{cnonce.NonceHash}\",nc={nc},"
                             + $"qop={qop},digest-uri=\"{digestUri}\",response={rsp},charset={charset}";
                Logger.Debug($"Generated response: {msg}");

                string rspAuth = await AuthUtil.DigestServerResponseAsync(new SHA512(), passwordHash, nonce, nc, qop, cnonce.NonceHash, digestUri).ConfigureAwait(false);

                await session.AuthResponseAsync(Convert.ToBase64String(Encoding.UTF8.GetBytes(msg)), rspAuth).ConfigureAwait(false);
            } catch (KeyNotFoundException e) {
                await session.ErrorAsync($"Invalid challenge: {e.Message}").ConfigureAwait(false);
            }
        }
Exemple #3
0
        protected async override Task OnHandleMessageAsync(Message message, NetworkSession session)
        {
            AuthSession authSession = (AuthSession)session;

            if (authSession.Authenticated)
            {
                await CompleteAuthenticationAsync(authSession).ConfigureAwait(false);

                return;
            }

            if (!authSession.Authenticating)
            {
                await authSession.FailureAsync("Not Authenticating").ConfigureAwait(false);

                return;
            }

            if (authSession.AuthNonce.Expired)
            {
                await authSession.FailureAsync("Session Expired").ConfigureAwait(false);

                return;
            }

            ResponseMessage responseMessage = (ResponseMessage)message;

            string decoded = Encoding.UTF8.GetString(Convert.FromBase64String(responseMessage.Response));

            Logger.Debug($"Decoded response: {decoded}");

            Dictionary <string, string> values = AuthUtil.ParseDigestValues(decoded);

            if (null == values || 0 == values.Count)
            {
                await authSession.FailureAsync("Invalid Response").ConfigureAwait(false);

                return;
            }

            try {
                string username = values["username"].Trim('"');
                await EventLogger.Instance.BeginEventAsync(authSession.RemoteEndPoint, username).ConfigureAwait(false);

                string charset = values["charset"].Trim('"');
                if (!"utf-8".Equals(charset, StringComparison.InvariantCultureIgnoreCase))
                {
                    await authSession.FailureAsync("Invalid Response").ConfigureAwait(false);

                    return;
                }

                string qop = values["qop"].Trim('"');
                if (!"auth".Equals(qop, StringComparison.InvariantCultureIgnoreCase))
                {
                    await authSession.FailureAsync("Invalid Response").ConfigureAwait(false);

                    return;
                }

                string realm = values["realm"].Trim('"');
                if (!ConfigurationManager.AppSettings["authRealm"].Equals(realm, StringComparison.InvariantCultureIgnoreCase))
                {
                    await authSession.FailureAsync("Invalid Response").ConfigureAwait(false);

                    return;
                }

                string nonce = values["nonce"].Trim('"');
                if (!authSession.AuthNonce.NonceHash.Equals(nonce))
                {
                    await authSession.FailureAsync("Invalid Response").ConfigureAwait(false);

                    return;
                }

                string digestUri = values["digest-uri"].Trim('"');
                //// TODO: validate the digest-uri

                string cnonce = values["cnonce"].Trim('"');
                string nc     = values["nc"].Trim('"');
                string rsp    = values["response"].Trim('"');

                await AuthenticateAsync(authSession, username, nonce, cnonce, nc, qop, digestUri, rsp).ConfigureAwait(false);
            } catch (KeyNotFoundException) {
                await authSession.FailureAsync("Invalid response!").ConfigureAwait(false);
            }
        }