private static void SendChallengeMessage(HttpContext context, NtlmNegotiateMessage negotiateMessage,
                                                 Action <string> log)
        {
            if (negotiateMessage == null)
            {
                throw new ArgumentNullException(nameof(negotiateMessage));
            }

            if (log != null)
            {
                log($"Message 1 Flags: {negotiateMessage.Flags}");
                log($"Message 1 Domain: {negotiateMessage.Domain}");
                log($"Message 1 Host: {negotiateMessage.Host}");
            }

            var messageStruct = new ChallengeMessageStruct
            {
                Signature = Constants.NtlmsspBytes,
                Type      = MessageType.Challenge,
                Flags     = SupportedMessageFlag & negotiateMessage.Flags,
                Challenge = Challenge,
                Context   = ZeroBytes
            };

            var message2 = new NtlmChallengeMessage(messageStruct, "DOMAIN");

            message2.TargetInfoList.Add(new NtlmTargetInfo(TargetInfoType.DomainName, "DOMAIN", Encoding.Unicode));
            message2.TargetInfoList.Add(new NtlmTargetInfo(TargetInfoType.ServerName, "SERVER", Encoding.Unicode));
            message2.TargetInfoList.Add(new NtlmTargetInfo(TargetInfoType.DnsDomainName, "domain.com", Encoding.Unicode));
            message2.TargetInfoList.Add(new NtlmTargetInfo(TargetInfoType.FQDN, "server.domain.com", Encoding.Unicode));
            message2.TargetInfoList.Add(new NtlmTargetInfo(TargetInfoType.Terminator));
            message2.Rectify();

            if (log != null)
            {
                log($"Message 2 Flags: {message2.Flags}");
                log($"Message 2 TargetName: {message2.TargetName}");
            }

            SendUnauthorized(context, message2.ToBytes());
        }
        public static void CheckNtlmAuth(this HttpContext context, string userName, string password, Action <string> log)
        {
            MakeIdentity(context);

            if (CheckLogon(context))
            {
                return;
            }

            var auth = context.Request.Headers["Authorization"];

            if (string.IsNullOrWhiteSpace(auth) || !auth.StartsWith("NTLM"))
            {
                SendUnauthorized(context);
            }
            else
            {
                var base64 = auth.Substring(5); //skip "NTLM "
                var token  = Convert.FromBase64String(base64);
                var header = token.ToStruct <MessageHeaderStruct>();

                switch (header.Type)
                {
                case MessageType.Negotiation:
                    var message1 = NtlmNegotiateMessage.Parse(token);
                    SendChallengeMessage(context, message1, log);
                    break;

                case MessageType.Authentication:
                    var message3 = new NtlmAuthenticationMessage(token);
                    ValidateAuthMessage(context, userName, password, message3, log);
                    break;

                default:
                    SendUnauthorized(context);
                    break;
                }
            }
        }