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); } }