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