예제 #1
0
        static void AssertNtlmv2(SaslMechanismNtlm sasl, string challenge1, string challenge2)
        {
            var challenge = sasl.Challenge(string.Empty);

            Assert.AreEqual(challenge1, challenge, "Initial challenge");
            Assert.IsFalse(sasl.IsAuthenticated, "IsAuthenticated");

            challenge = sasl.Challenge(challenge2);

            var token        = Convert.FromBase64String(challenge2);
            var type2        = new Type2Message(token, 0, token.Length);
            var type3        = new Type3Message(type2, null, sasl.Level, sasl.Credentials.UserName, sasl.Credentials.Password, sasl.Workstation);
            var ignoreLength = type2.EncodedTargetInfo.Length + 28 + 16;

            var actual          = Convert.FromBase64String(challenge);
            var expected        = type3.Encode();
            var ntlmBufferIndex = expected.Length - ignoreLength;
            var targetInfoIndex = ntlmBufferIndex + 16 /* md5 hash */ + 28;

            Assert.AreEqual(expected.Length, actual.Length, "Final challenge differs in length: {0} vs {1}", expected.Length, actual.Length);

            for (int i = 0; i < expected.Length - ignoreLength; i++)
            {
                Assert.AreEqual(expected[i], actual[i], "Final challenge differs at index {0}", i);
            }

            // now compare the TargetInfo blobs
            for (int i = targetInfoIndex; i < expected.Length; i++)
            {
                Assert.AreEqual(expected[i], actual[i], "Final challenge differs at index {0}", i);
            }

            Assert.IsTrue(sasl.IsAuthenticated, "IsAuthenticated");
        }
예제 #2
0
        static void AssertNtlm2Key(SaslMechanismNtlm sasl, string challenge1, string challenge2)
        {
            var challenge = sasl.Challenge(string.Empty);

            Assert.AreEqual(challenge1, challenge, "Initial challenge");
            Assert.IsFalse(sasl.IsAuthenticated, "IsAuthenticated");

            challenge = sasl.Challenge(challenge2);

            var token        = Convert.FromBase64String(challenge2);
            var type2        = new Type2Message(token, 0, token.Length);
            var type3        = new Type3Message(type2, null, sasl.Level, sasl.Credentials.UserName, sasl.Credentials.Password, sasl.Workstation);
            var ignoreLength = 48;

            var actual   = Convert.FromBase64String(challenge);
            var expected = type3.Encode();

            Assert.AreEqual(expected.Length, actual.Length, "Final challenge differs in length: {0} vs {1}", expected.Length, actual.Length);

            for (int i = 0; i < expected.Length - ignoreLength; i++)
            {
                Assert.AreEqual(expected[i], actual[i], "Final challenge differs at index {0}", i);
            }

            Assert.IsTrue(sasl.IsAuthenticated, "IsAuthenticated");
        }
예제 #3
0
        protected override void ConfigureClient(SmtpClient client)
        {
            var ntlm = new SaslMechanismNtlm(_appConfiguration["App:UsernameSasl"], _appConfiguration["App:PasswordSasl"]);

            client.Authenticate(ntlm);

            base.ConfigureClient(client);
        }
예제 #4
0
        static void AssertNtlm(SaslMechanismNtlm sasl, string challenge1, string challenge2, string challenge3)
        {
            var challenge = sasl.Challenge(string.Empty);

            Assert.AreEqual(challenge1, challenge, "Initial challenge");
            Assert.IsFalse(sasl.IsAuthenticated, "IsAuthenticated");

            challenge = sasl.Challenge(challenge2);

            Assert.AreEqual(challenge3, challenge, "Final challenge");
            Assert.IsTrue(sasl.IsAuthenticated, "IsAuthenticated");
        }
예제 #5
0
        public void TestAuthenticationLmAndNtlmSessionNegotiateNtlm2KeyWithDomain()
        {
            const string challenge1  = "TlRMTVNTUAABAAAABxIAAAYABgAgAAAAAAAAACAAAABET01BSU4=";
            const string challenge2  = "TlRMTVNTUAACAAAADAAMADAAAAABAokAASNFZ4mrze8AAAAAAAAAAGIAYgA8AAAARABPAE0AQQBJAE4AAgAMAEQATwBNAEEASQBOAAEADABTAEUAUgBWAEUAUgAEABQAZABvAG0AYQBpAG4ALgBjAG8AbQADACIAcwBlAHIAdgBlAHIALgBkAG8AbQBhAGkAbgAuAGMAbwBtAAAAAAA=";
            var          credentials = new NetworkCredential("user", "password", "DOMAIN");
            var          sasl        = new SaslMechanismNtlm(credentials)
            {
                Level = NtlmAuthLevel.LM_and_NTLM_and_try_NTLMv2_Session
            };

            AssertNtlm2Key(sasl, challenge1, challenge2);
        }
예제 #6
0
        public void TestAuthenticationNtlmv2()
        {
            const string challenge1  = "TlRMTVNTUAABAAAABwIAAAAAAAAgAAAAAAAAACAAAAA=";
            const string challenge2  = "TlRMTVNTUAACAAAADAAMADAAAAABAoEAASNFZ4mrze8AAAAAAAAAAGIAYgA8AAAARABPAE0AQQBJAE4AAgAMAEQATwBNAEEASQBOAAEADABTAEUAUgBWAEUAUgAEABQAZABvAG0AYQBpAG4ALgBjAG8AbQADACIAcwBlAHIAdgBlAHIALgBkAG8AbQBhAGkAbgAuAGMAbwBtAAAAAAA=";
            var          credentials = new NetworkCredential("user", "password");
            var          sasl        = new SaslMechanismNtlm(credentials)
            {
                Level = NtlmAuthLevel.NTLMv2_only
            };

            AssertNtlmv2(sasl, challenge1, challenge2);
        }
예제 #7
0
        public void TestAuthenticationNtlmv2WithDomainAndWorkstation()
        {
            const string challenge1  = "TlRMTVNTUAABAAAABzIAAAYABgArAAAACwALACAAAABXT1JLU1RBVElPTkRPTUFJTg==";
            const string challenge2  = "TlRMTVNTUAACAAAADAAMADAAAAABAoEAASNFZ4mrze8AAAAAAAAAAGIAYgA8AAAARABPAE0AQQBJAE4AAgAMAEQATwBNAEEASQBOAAEADABTAEUAUgBWAEUAUgAEABQAZABvAG0AYQBpAG4ALgBjAG8AbQADACIAcwBlAHIAdgBlAHIALgBkAG8AbQBhAGkAbgAuAGMAbwBtAAAAAAA=";
            var          credentials = new NetworkCredential("user", "password", "DOMAIN");
            var          sasl        = new SaslMechanismNtlm(credentials)
            {
                Workstation = "WORKSTATION", Level = NtlmAuthLevel.NTLMv2_only
            };

            AssertNtlmv2(sasl, challenge1, challenge2);
        }
예제 #8
0
        public void TestAuthenticationNtlmWithDomainAndWorkstation()
        {
            const string challenge1  = "TlRMTVNTUAABAAAABzIAAAYABgArAAAACwALACAAAABXT1JLU1RBVElPTkRPTUFJTg==";
            const string challenge2  = "TlRMTVNTUAACAAAADAAMADAAAAABAoEAASNFZ4mrze8AAAAAAAAAAGIAYgA8AAAARABPAE0AQQBJAE4AAgAMAEQATwBNAEEASQBOAAEADABTAEUAUgBWAEUAUgAEABQAZABvAG0AYQBpAG4ALgBjAG8AbQADACIAcwBlAHIAdgBlAHIALgBkAG8AbQBhAGkAbgAuAGMAbwBtAAAAAAA=";
            const string challenge3  = "TlRMTVNTUAADAAAAAAAAAGoAAAAYABgAagAAAAwADABAAAAACAAIAEwAAAAWABYAVAAAAAAAAACCAAAAAQIAAEQATwBNAEEASQBOAHUAcwBlAHIAVwBPAFIASwBTAFQAQQBUAEkATwBOAN1UKLAehvTfyr6sOUlG29Q+6I95TdYyVQ==";
            var          credentials = new NetworkCredential("user", "password", "DOMAIN");
            var          sasl        = new SaslMechanismNtlm(credentials)
            {
                Workstation = "WORKSTATION", Level = NtlmAuthLevel.NTLM_only
            };

            AssertNtlm(sasl, challenge1, challenge2, challenge3);
        }
예제 #9
0
        public void TestAuthenticationNtlmWithDomain()
        {
            const string challenge1  = "TlRMTVNTUAABAAAABxIAAAYABgAgAAAAAAAAACAAAABET01BSU4=";
            const string challenge2  = "TlRMTVNTUAACAAAADAAMADAAAAABAoEAASNFZ4mrze8AAAAAAAAAAGIAYgA8AAAARABPAE0AQQBJAE4AAgAMAEQATwBNAEEASQBOAAEADABTAEUAUgBWAEUAUgAEABQAZABvAG0AYQBpAG4ALgBjAG8AbQADACIAcwBlAHIAdgBlAHIALgBkAG8AbQBhAGkAbgAuAGMAbwBtAAAAAAA=";
            const string challenge3  = "TlRMTVNTUAADAAAAAAAAAFQAAAAYABgAVAAAAAwADABAAAAACAAIAEwAAAAAAAAAVAAAAAAAAABsAAAAAQIAAEQATwBNAEEASQBOAHUAcwBlAHIA3VQosB6G9N/Kvqw5SUbb1D7oj3lN1jJV";
            var          credentials = new NetworkCredential("user", "password", "DOMAIN");
            var          sasl        = new SaslMechanismNtlm(credentials)
            {
                Level = NtlmAuthLevel.NTLM_only
            };

            AssertNtlm(sasl, challenge1, challenge2, challenge3);
        }
예제 #10
0
        public void TestAuthenticationLmAndNtlmSessionFallbackWithDomainAndWorkstation()
        {
            // Note: this will fallback to LN_and_NTLM because the type2 message does not contain the NegotiateNtlm2Key flag
            const string challenge1  = "TlRMTVNTUAABAAAABzIAAAYABgArAAAACwALACAAAABXT1JLU1RBVElPTkRPTUFJTg==";
            const string challenge2  = "TlRMTVNTUAACAAAADAAMADAAAAABAoEAASNFZ4mrze8AAAAAAAAAAGIAYgA8AAAARABPAE0AQQBJAE4AAgAMAEQATwBNAEEASQBOAAEADABTAEUAUgBWAEUAUgAEABQAZABvAG0AYQBpAG4ALgBjAG8AbQADACIAcwBlAHIAdgBlAHIALgBkAG8AbQBhAGkAbgAuAGMAbwBtAAAAAAA=";
            const string challenge3  = "TlRMTVNTUAADAAAAGAAYAGoAAAAYABgAggAAAAwADABAAAAACAAIAEwAAAAWABYAVAAAAAAAAACaAAAAAQIAAEQATwBNAEEASQBOAHUAcwBlAHIAVwBPAFIASwBTAFQAQQBUAEkATwBOAJje97h/iKpdr+Lfd5aIoXLe8Rx9XM3vE91UKLAehvTfyr6sOUlG29Q+6I95TdYyVQ==";
            var          credentials = new NetworkCredential("user", "password", "DOMAIN");
            var          sasl        = new SaslMechanismNtlm(credentials)
            {
                Workstation = "WORKSTATION", Level = NtlmAuthLevel.LM_and_NTLM_and_try_NTLMv2_Session
            };

            AssertLmAndNtlm(sasl, challenge1, challenge2, challenge3);
        }
예제 #11
0
        public void TestAuthenticationLmAndNtlmSessionFallbackWithDomain()
        {
            // Note: this will fallback to LN_and_NTLM because the type2 message does not contain the NegotiateNtlm2Key flag
            const string challenge1  = "TlRMTVNTUAABAAAABxIAAAYABgAgAAAAAAAAACAAAABET01BSU4=";
            const string challenge2  = "TlRMTVNTUAACAAAADAAMADAAAAABAoEAASNFZ4mrze8AAAAAAAAAAGIAYgA8AAAARABPAE0AQQBJAE4AAgAMAEQATwBNAEEASQBOAAEADABTAEUAUgBWAEUAUgAEABQAZABvAG0AYQBpAG4ALgBjAG8AbQADACIAcwBlAHIAdgBlAHIALgBkAG8AbQBhAGkAbgAuAGMAbwBtAAAAAAA=";
            const string challenge3  = "TlRMTVNTUAADAAAAGAAYAFQAAAAYABgAbAAAAAwADABAAAAACAAIAEwAAAAAAAAAVAAAAAAAAACEAAAAAQIAAEQATwBNAEEASQBOAHUAcwBlAHIAmN73uH+Iql2v4t93loihct7xHH1cze8T3VQosB6G9N/Kvqw5SUbb1D7oj3lN1jJV";
            var          credentials = new NetworkCredential("user", "password", "DOMAIN");
            var          sasl        = new SaslMechanismNtlm(credentials)
            {
                Level = NtlmAuthLevel.LM_and_NTLM_and_try_NTLMv2_Session
            };

            AssertLmAndNtlm(sasl, challenge1, challenge2, challenge3);
        }
예제 #12
0
        public void TestAuthenticationLmAndNtlm()
        {
            const string challenge1 = "TlRMTVNTUAABAAAABwIAAAAAAAAgAAAAAAAAACAAAAA=";
            const string challenge2 = "TlRMTVNTUAACAAAADAAMADAAAAABAoEAASNFZ4mrze8AAAAAAAAAAGIAYgA8AAAARABPAE0AQQBJAE4AAgAMAEQATwBNAEEASQBOAAEADABTAEUAUgBWAEUAUgAEABQAZABvAG0AYQBpAG4ALgBjAG8AbQADACIAcwBlAHIAdgBlAHIALgBkAG8AbQBhAGkAbgAuAGMAbwBtAAAAAAA=";
            const string challenge3 = "TlRMTVNTUAADAAAAGAAYAFQAAAAYABgAbAAAAAwADABAAAAACAAIAEwAAAAAAAAAVAAAAAAAAACEAAAAAQIAAEQATwBNAEEASQBOAHUAcwBlAHIAmN73uH+Iql2v4t93loihct7xHH1cze8T3VQosB6G9N/Kvqw5SUbb1D7oj3lN1jJV";

            var credentials = new NetworkCredential("user", "password");
            var sasl        = new SaslMechanismNtlm(credentials)
            {
                Level = NtlmAuthLevel.LM_and_NTLM
            };

            AssertLmAndNtlm(sasl, challenge1, challenge2, challenge3);
        }
예제 #13
0
        public void TestArgumentExceptions()
        {
            var           credentials = new NetworkCredential("username", "password");
            var           uri         = new Uri("smtp://localhost");
            SaslMechanism sasl;

            Assert.Throws <ArgumentNullException> (() => new SaslException(null, SaslErrorCode.MissingChallenge, "message"));

            sasl = new SaslMechanismCramMd5(uri, credentials);
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismCramMd5(null, credentials));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismCramMd5(uri, null));
            Assert.Throws <NotSupportedException> (() => sasl.Challenge(null));

            sasl = new SaslMechanismDigestMd5(uri, credentials);
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismDigestMd5(null, credentials));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismDigestMd5(uri, null));
            Assert.Throws <NotSupportedException> (() => sasl.Challenge(null));

            sasl = new SaslMechanismLogin(uri, credentials);
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismLogin(uri, null, credentials));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismLogin(null, credentials));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismLogin(uri, null));
            Assert.Throws <NotSupportedException> (() => sasl.Challenge(null));

            sasl = new SaslMechanismNtlm(uri, credentials);
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismNtlm(null, credentials));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismNtlm(uri, null));
            Assert.DoesNotThrow(() => sasl.Challenge(null));

            sasl = new SaslMechanismOAuth2(uri, credentials);
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismOAuth2(null, credentials));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismOAuth2(uri, null));
            Assert.DoesNotThrow(() => sasl.Challenge(null));

            sasl = new SaslMechanismPlain(uri, credentials);
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismPlain(uri, null, credentials));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismPlain(null, credentials));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismPlain(uri, null));
            Assert.DoesNotThrow(() => sasl.Challenge(null));

            sasl = new SaslMechanismScramSha1(uri, credentials);
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismScramSha1(null, credentials));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismScramSha1(uri, null));
            Assert.DoesNotThrow(() => sasl.Challenge(null));

            sasl = new SaslMechanismScramSha256(uri, credentials);
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismScramSha256(null, credentials));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismScramSha256(uri, null));
            Assert.DoesNotThrow(() => sasl.Challenge(null));
        }
예제 #14
0
        static void AssertNtlmAuthNoDomain(SaslMechanismNtlm sasl, string prefix)
        {
            string challenge;

            byte [] decoded;

            Assert.IsTrue(sasl.SupportsInitialResponse, "{0}: SupportsInitialResponse", prefix);

            challenge = sasl.Challenge(string.Empty);
            decoded   = Convert.FromBase64String(challenge);

            var type1 = new Type1Message(decoded, 0, decoded.Length);

            Assert.AreEqual(Type1Message.DefaultFlags, type1.Flags, "{0}: Expected initial NTLM client challenge flags do not match.", prefix);
            Assert.AreEqual(string.Empty, type1.Domain, "{0}: Expected initial NTLM client challenge domain does not match.", prefix);
            Assert.AreEqual(string.Empty, type1.Host, "{0}: Expected initial NTLM client challenge host does not match.", prefix);
            Assert.IsFalse(sasl.IsAuthenticated, "{0}: NTLM should not be authenticated.", prefix);
        }
예제 #15
0
        public void TestArgumentExceptions()
        {
            var credentials = new NetworkCredential("username", "password");
            var uri         = new Uri("smtp://localhost");

            var sasl = new SaslMechanismNtlm(credentials);

            Assert.DoesNotThrow(() => sasl.Challenge(null));

            Assert.Throws <ArgumentNullException> (() => new SaslMechanismNtlm((Uri)null, credentials));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismNtlm(uri, null));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismNtlm((Uri)null, "username", "password"));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismNtlm(uri, (string)null, "password"));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismNtlm(uri, "username", null));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismNtlm(null));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismNtlm(null, "password"));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismNtlm("username", null));
        }
예제 #16
0
        public void TestNtlmAuthNoDomain()
        {
            var    credentials = new NetworkCredential("username", "password");
            var    uri         = new Uri("imap://imap.gmail.com");
            var    sasl        = new SaslMechanismNtlm(uri, credentials);
            string challenge;

            byte[] decoded;

            challenge = sasl.Challenge(string.Empty);
            decoded   = Convert.FromBase64String(challenge);

            var type1 = new Type1Message(decoded, 0, decoded.Length);

            Assert.AreEqual(Type1Message.DefaultFlags, type1.Flags, "Expected initial NTLM client challenge flags do not match.");
            Assert.AreEqual(string.Empty, type1.Domain, "Expected initial NTLM client challenge domain does not match.");
            Assert.AreEqual(string.Empty, type1.Host, "Expected initial NTLM client challenge host does not match.");
            Assert.IsFalse(sasl.IsAuthenticated, "NTLM should not be authenticated.");
        }
예제 #17
0
        public void TestNtlmAuthWithDomain()
        {
            var credentials = new NetworkCredential("domain\\username", "password");
            var sasl        = new SaslMechanismNtlm(credentials);
            var uri         = new Uri("smtp://localhost");

            AssertNtlmAuthWithDomain(sasl, "NetworkCredential");

            sasl = new SaslMechanismNtlm("domain\\username", "password");

            AssertNtlmAuthWithDomain(sasl, "user/pass");

            sasl = new SaslMechanismNtlm(uri, credentials);

            AssertNtlmAuthWithDomain(sasl, "uri/credentials");

            sasl = new SaslMechanismNtlm(uri, "domain\\username", "password");

            AssertNtlmAuthWithDomain(sasl, "uri/user/pass");
        }
예제 #18
0
        public void TestNtlmAuthWithDomain()
        {
            const NtlmFlags initialFlags = NtlmFlags.NegotiateUnicode | NtlmFlags.NegotiateOem | NtlmFlags.NegotiateNtlm |
                                           NtlmFlags.NegotiateNtlm2Key | NtlmFlags.RequestTarget | NtlmFlags.NegotiateDomainSupplied;
            var    credentials = new NetworkCredential("domain\\username", "password");
            var    uri         = new Uri("imap://imap.gmail.com");
            var    sasl        = new SaslMechanismNtlm(uri, credentials);
            string challenge;

            byte[] decoded;

            challenge = sasl.Challenge(string.Empty);
            decoded   = Convert.FromBase64String(challenge);

            var type1 = new Type1Message(decoded, 0, decoded.Length);

            Assert.AreEqual(initialFlags, type1.Flags, "Expected initial NTLM client challenge flags do not match.");
            Assert.AreEqual("DOMAIN", type1.Domain, "Expected initial NTLM client challenge domain does not match.");
            Assert.AreEqual(string.Empty, type1.Host, "Expected initial NTLM client challenge host does not match.");
            Assert.IsFalse(sasl.IsAuthenticated, "NTLM should not be authenticated.");
        }
        public void TestArgumentExceptions()
        {
            var           credentials = new NetworkCredential("username", "password");
            var           uri         = new Uri("smtp://localhost");
            SaslMechanism sasl;

            Assert.Throws <ArgumentNullException> (() => new SaslException(null, SaslErrorCode.MissingChallenge, "message"));

            sasl = new SaslMechanismCramMd5(credentials);
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismCramMd5(null, credentials));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismCramMd5(uri, null));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismCramMd5(null, "username", "password"));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismCramMd5(uri, null, "password"));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismCramMd5(uri, "username", null));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismCramMd5(null));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismCramMd5(null, "password"));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismCramMd5("username", null));
            Assert.Throws <NotSupportedException> (() => sasl.Challenge(null));

            sasl = new SaslMechanismDigestMd5(credentials)
            {
                Uri = uri
            };
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismDigestMd5(null, credentials));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismDigestMd5(uri, null));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismDigestMd5(null, "username", "password"));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismDigestMd5(uri, (string)null, "password"));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismDigestMd5(uri, "username", null));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismDigestMd5(null));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismDigestMd5(null, "password"));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismDigestMd5("username", null));
            Assert.Throws <NotSupportedException> (() => sasl.Challenge(null));

            sasl = new SaslMechanismLogin(credentials);
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismLogin((Uri)null, Encoding.UTF8, credentials));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismLogin(uri, null, credentials));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismLogin(uri, Encoding.UTF8, null));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismLogin((Uri)null, credentials));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismLogin(uri, null));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismLogin((Uri)null, Encoding.UTF8, "username", "password"));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismLogin(uri, null, "username", "password"));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismLogin(uri, Encoding.UTF8, null, "password"));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismLogin(uri, Encoding.UTF8, "username", null));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismLogin((Uri)null, "username", "password"));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismLogin(uri, null, "password"));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismLogin(uri, "username", null));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismLogin(null, credentials));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismLogin(Encoding.UTF8, null));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismLogin(null));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismLogin((Encoding)null, "username", "password"));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismLogin(Encoding.UTF8, null, "password"));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismLogin(Encoding.UTF8, "username", null));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismLogin(null, "password"));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismLogin("username", null));
            Assert.Throws <NotSupportedException> (() => sasl.Challenge(null));

            sasl = new SaslMechanismNtlm(credentials);
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismNtlm((Uri)null, credentials));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismNtlm(uri, null));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismNtlm((Uri)null, "username", "password"));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismNtlm(uri, (string)null, "password"));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismNtlm(uri, "username", null));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismNtlm(null));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismNtlm(null, "password"));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismNtlm("username", null));
            Assert.DoesNotThrow(() => sasl.Challenge(null));

            sasl = new SaslMechanismOAuth2(credentials);
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismOAuth2((Uri)null, credentials));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismOAuth2(uri, null));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismOAuth2((Uri)null, "username", "password"));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismOAuth2(uri, (string)null, "password"));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismOAuth2(uri, "username", null));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismOAuth2(null));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismOAuth2(null, "password"));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismOAuth2("username", null));
            Assert.DoesNotThrow(() => sasl.Challenge(null));

            sasl = new SaslMechanismPlain(credentials);
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismPlain((Uri)null, Encoding.UTF8, credentials));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismPlain(uri, null, credentials));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismPlain(uri, Encoding.UTF8, null));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismPlain((Uri)null, credentials));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismPlain(uri, null));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismPlain((Uri)null, Encoding.UTF8, "username", "password"));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismPlain(uri, null, "username", "password"));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismPlain(uri, Encoding.UTF8, null, "password"));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismPlain(uri, Encoding.UTF8, "username", null));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismPlain((Uri)null, "username", "password"));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismPlain(uri, null, "password"));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismPlain(uri, "username", null));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismPlain(null, credentials));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismPlain(Encoding.UTF8, null));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismPlain(null));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismPlain((Encoding)null, "username", "password"));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismPlain(Encoding.UTF8, null, "password"));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismPlain(Encoding.UTF8, "username", null));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismPlain(null, "password"));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismPlain("username", null));
            Assert.DoesNotThrow(() => sasl.Challenge(null));

            sasl = new SaslMechanismScramSha1(credentials);
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismScramSha1(null, credentials));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismScramSha1(uri, null));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismScramSha1(null, "username", "password"));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismScramSha1(uri, (string)null, "password"));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismScramSha1(uri, "username", null));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismScramSha1(null));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismScramSha1((string)null, "password"));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismScramSha1("username", null));
            Assert.DoesNotThrow(() => sasl.Challenge(null));

            sasl = new SaslMechanismScramSha256(credentials);
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismScramSha256(null, credentials));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismScramSha256(uri, null));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismScramSha256(null, "username", "password"));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismScramSha256(uri, (string)null, "password"));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismScramSha256(uri, "username", null));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismScramSha256(null));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismScramSha256((string)null, "password"));
            Assert.Throws <ArgumentNullException> (() => new SaslMechanismScramSha256("username", null));
            Assert.DoesNotThrow(() => sasl.Challenge(null));

            Assert.Throws <ArgumentNullException> (() => SaslMechanism.Create(null, uri, Encoding.UTF8, credentials));
            Assert.Throws <ArgumentNullException> (() => SaslMechanism.Create("PLAIN", null, Encoding.UTF8, credentials));
            Assert.Throws <ArgumentNullException> (() => SaslMechanism.Create("PLAIN", uri, null, credentials));
            Assert.Throws <ArgumentNullException> (() => SaslMechanism.Create("PLAIN", uri, Encoding.UTF8, null));

            Assert.Throws <ArgumentNullException> (() => SaslMechanism.Create(null, uri, credentials));
            Assert.Throws <ArgumentNullException> (() => SaslMechanism.Create("PLAIN", null, credentials));
            Assert.Throws <ArgumentNullException> (() => SaslMechanism.Create("PLAIN", uri, null));

            Assert.Throws <ArgumentNullException> (() => SaslMechanism.SaslPrep(null));
        }