예제 #1
0
        private async Task AuthenticateAsync(AuthSession session, string accountName, string nonce, string cnonce, string nc, string qop, string digestUri, string response)
        {
            using (AccountsDatabaseContext context = new AccountsDatabaseContext()) {
                var accounts = from a in context.Accounts where a.AccountName == accountName select a;
                if (!accounts.Any())
                {
                    await session.FailureAsync("Bad Username or Password").ConfigureAwait(false);

                    return;
                }

                AccountInfo account = accounts.First();
                if (!account.IsActive)
                {
                    await session.FailureAsync("Account Inactive").ConfigureAwait(false);

                    return;
                }

                string expected, rspauth;
                switch (session.AuthType)
                {
                case AuthType.DigestMD5:
                    /*Logger.Debug("Handling MD5 response...");
                     * ////Logger.Debug($"passwordHash={account.PasswordMD5}");
                     * expected = await AuthUtil.DigestClientResponse(new MD5(), account.PasswordMD5, nonce, nc, qop, cnonce, digestURI).ConfigureAwait(false);
                     * rspauth = await AuthUtil.DigestServerResponse(new MD5(), account.PasswordMD5, nonce, nc, qop, cnonce, digestURI).ConfigureAwait(false);
                     * break;*/
                    await session.FailureAsync("MD5 auth type not supported!").ConfigureAwait(false);

                    return;

                case AuthType.DigestSHA512:
                    Logger.Debug("Handling SHA512 response...");
                    ////Logger.Debug($"passwordHash={account.PasswordSHA512}");
                    expected = await AuthUtil.DigestClientResponseAsync(new SHA512(), account.PasswordSHA512, nonce, nc, qop, cnonce, digestUri).ConfigureAwait(false);

                    rspauth = await AuthUtil.DigestServerResponseAsync(new SHA512(), account.PasswordSHA512, nonce, nc, qop, cnonce, digestUri).ConfigureAwait(false);

                    break;

                default:
                    await session.FailureAsync("Unsupported auth type!").ConfigureAwait(false);

                    return;
                }

                if (!expected.Equals(response))
                {
                    await session.FailureAsync("Bad Username or Password").ConfigureAwait(false);

                    return;
                }

                Logger.Info($"Session {session.Id} authenticated account '{accountName}', sending response: {rspauth}");
                await session.ChallengeAsync($"rspauth={rspauth}", account).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);
            }
        }