Exemplo n.º 1
0
        public void TestParseMethodWithMultipleProperties()
        {
            const string          input  = "example.com; spf=pass ptype1.prop1=value1 ptype2.prop2=value2";
            var                   buffer = Encoding.ASCII.GetBytes(input);
            AuthenticationResults authres;

            Assert.IsTrue(AuthenticationResults.TryParse(buffer, 0, buffer.Length, out authres));
            Assert.AreEqual("example.com", authres.AuthenticationServiceIdentifier, "authserv-id");
            Assert.AreEqual(1, authres.Results.Count, "methods");
            Assert.AreEqual("spf", authres.Results[0].Method);
            Assert.AreEqual("pass", authres.Results[0].Result);
            Assert.AreEqual(2, authres.Results[0].Properties.Count, "properties");
            Assert.AreEqual("ptype1", authres.Results[0].Properties[0].PropertyType);
            Assert.AreEqual("prop1", authres.Results[0].Properties[0].Property);
            Assert.AreEqual("value1", authres.Results[0].Properties[0].Value);
            Assert.AreEqual("ptype2", authres.Results[0].Properties[1].PropertyType);
            Assert.AreEqual("prop2", authres.Results[0].Properties[1].Property);
            Assert.AreEqual("value2", authres.Results[0].Properties[1].Value);

            Assert.AreEqual(input, authres.ToString());

            const string expected = " example.com;\n\tspf=pass ptype1.prop1=value1 ptype2.prop2=value2\n";
            var          encoded  = new StringBuilder();
            var          options  = FormatOptions.Default.Clone();

            options.NewLineFormat = NewLineFormat.Unix;

            authres.Encode(options, encoded, "Authentication-Results:".Length);

            Assert.AreEqual(expected, encoded.ToString());
        }
Exemplo n.º 2
0
        public void TestParseHeavilyCommentedExample()
        {
            var buffer = Encoding.ASCII.GetBytes("foo.example.net (foobar) 1 (baz); dkim (Because I like it) / 1 (One yay) = (wait for it) fail policy (A dot can go here) . (like that) expired (this surprised me) = (as I wasn't expecting it) 1362471462");
            AuthenticationResults authres;

            Assert.IsTrue(AuthenticationResults.TryParse(buffer, 0, buffer.Length, out authres));
            Assert.AreEqual("foo.example.net", authres.AuthenticationServiceIdentifier, "authserv-id");
            Assert.AreEqual(1, authres.Version.Value, "authres-version");
            Assert.AreEqual(1, authres.Results.Count, "methods");
            Assert.AreEqual("dkim", authres.Results[0].Method);
            Assert.AreEqual(1, authres.Results[0].Version.Value, "method-version");
            Assert.AreEqual("fail", authres.Results[0].Result);
            Assert.AreEqual(1, authres.Results[0].Properties.Count, "dkim properties");
            Assert.AreEqual("policy", authres.Results[0].Properties[0].PropertyType);
            Assert.AreEqual("expired", authres.Results[0].Properties[0].Property);
            Assert.AreEqual("1362471462", authres.Results[0].Properties[0].Value);

            Assert.AreEqual("foo.example.net 1; dkim/1=fail policy.expired=1362471462", authres.ToString());

            const string expected = " foo.example.net 1;\n\tdkim/1=fail policy.expired=1362471462\n";
            var          encoded  = new StringBuilder();
            var          options  = FormatOptions.Default.Clone();

            options.NewLineFormat = NewLineFormat.Unix;

            authres.Encode(options, encoded, "Authentication-Results:".Length);

            Assert.AreEqual(expected, encoded.ToString());
        }
Exemplo n.º 3
0
        public void TestParseSimpleWithProperty3()
        {
            const string          input  = "example.com; spf=pass [email protected]";
            var                   buffer = Encoding.ASCII.GetBytes(input);
            AuthenticationResults authres;

            Assert.IsTrue(AuthenticationResults.TryParse(buffer, 0, buffer.Length, out authres));
            Assert.AreEqual("example.com", authres.AuthenticationServiceIdentifier, "authserv-id");
            Assert.AreEqual(1, authres.Results.Count, "methods");
            Assert.AreEqual("spf", authres.Results[0].Method);
            Assert.AreEqual("pass", authres.Results[0].Result);
            Assert.AreEqual(1, authres.Results[0].Properties.Count, "properties");
            Assert.AreEqual("smtp", authres.Results[0].Properties[0].PropertyType);
            Assert.AreEqual("mailfrom", authres.Results[0].Properties[0].Property);
            Assert.AreEqual("*****@*****.**", authres.Results[0].Properties[0].Value);

            Assert.AreEqual(input, authres.ToString());

            const string expected = " example.com;\n\tspf=pass [email protected]\n";
            var          encoded  = new StringBuilder();
            var          options  = FormatOptions.Default.Clone();

            options.NewLineFormat = NewLineFormat.Unix;

            authres.Encode(options, encoded, "Authentication-Results:".Length);

            Assert.AreEqual(expected, encoded.ToString());
        }
Exemplo n.º 4
0
        public void TestParseSimpleWithQuotedReasonSemiColon()
        {
            const string          input  = "example.com; spf=pass reason=\"good stuff\"";
            var                   buffer = Encoding.ASCII.GetBytes(input + "; ");
            AuthenticationResults authres;

            Assert.IsTrue(AuthenticationResults.TryParse(buffer, 0, buffer.Length, out authres));
            Assert.AreEqual("example.com", authres.AuthenticationServiceIdentifier, "authserv-id");
            Assert.AreEqual(1, authres.Results.Count, "methods");
            Assert.AreEqual("spf", authres.Results[0].Method);
            Assert.AreEqual("pass", authres.Results[0].Result);
            Assert.AreEqual("good stuff", authres.Results[0].Reason);
            Assert.AreEqual(0, authres.Results[0].Properties.Count, "properties");

            Assert.AreEqual(input, authres.ToString());

            const string expected = " example.com; spf=pass reason=\"good stuff\"\n";
            var          encoded  = new StringBuilder();
            var          options  = FormatOptions.Default.Clone();

            options.NewLineFormat = NewLineFormat.Unix;

            authres.Encode(options, encoded, "Authentication-Results:".Length);

            Assert.AreEqual(expected, encoded.ToString());
        }
Exemplo n.º 5
0
        public void TestArgumentExceptions()
        {
            AuthenticationResults authres;
            var buffer = new byte[16];

            Assert.Throws <ArgumentNullException> (() => new AuthenticationResults(null));

            Assert.Throws <ArgumentNullException> (() => new AuthenticationMethodResult(null));
            Assert.Throws <ArgumentNullException> (() => new AuthenticationMethodResult(null, "result"));
            Assert.Throws <ArgumentNullException> (() => new AuthenticationMethodResult("method", null));

            Assert.Throws <ArgumentNullException> (() => new AuthenticationMethodProperty(null, "property", "value"));
            Assert.Throws <ArgumentNullException> (() => new AuthenticationMethodProperty("ptype", null, "value"));
            Assert.Throws <ArgumentNullException> (() => new AuthenticationMethodProperty("ptype", "Property", null));

            Assert.Throws <ArgumentNullException> (() => AuthenticationResults.Parse(null));
            Assert.Throws <ArgumentNullException> (() => AuthenticationResults.Parse(null, 0, 0));
            Assert.Throws <ArgumentOutOfRangeException> (() => AuthenticationResults.Parse(buffer, -1, 0));
            Assert.Throws <ArgumentOutOfRangeException> (() => AuthenticationResults.Parse(buffer, 0, -1));

            Assert.Throws <ArgumentNullException> (() => AuthenticationResults.TryParse(null, out authres));
            Assert.Throws <ArgumentNullException> (() => AuthenticationResults.TryParse(null, 0, 0, out authres));
            Assert.Throws <ArgumentOutOfRangeException> (() => AuthenticationResults.TryParse(buffer, -1, 0, out authres));
            Assert.Throws <ArgumentOutOfRangeException> (() => AuthenticationResults.TryParse(buffer, 0, -1, out authres));
        }
Exemplo n.º 6
0
        public void TestParseSimpleWithComment()
        {
            const string          input  = "example.com; foo=pass (2 of 3 tests OK)";
            var                   buffer = Encoding.ASCII.GetBytes(input);
            AuthenticationResults authres;

            Assert.IsTrue(AuthenticationResults.TryParse(buffer, 0, buffer.Length, out authres));
            Assert.AreEqual("example.com", authres.AuthenticationServiceIdentifier, "authserv-id");
            Assert.AreEqual(1, authres.Results.Count, "methods");
            Assert.AreEqual("foo", authres.Results[0].Method);
            Assert.AreEqual("pass", authres.Results[0].Result);
            Assert.AreEqual("2 of 3 tests OK", authres.Results[0].ResultComment);

            Assert.AreEqual(input, authres.ToString());

            const string expected = " example.com; foo=pass (2 of 3 tests OK)\n";
            var          encoded  = new StringBuilder();
            var          options  = FormatOptions.Default.Clone();

            options.NewLineFormat = NewLineFormat.Unix;

            authres.Encode(options, encoded, "Authentication-Results:".Length);

            Assert.AreEqual(expected, encoded.ToString());
        }
Exemplo n.º 7
0
        /// <summary>
        /// Generate the ARC-Authentication-Results header.
        /// </summary>
        /// <remarks>
        /// The ARC-Authentication-Results header contains information detailing the results of
        /// authenticating/verifying the message via ARC, DKIM, SPF, etc.
        ///
        /// In the following implementation, we assume that all of these authentication results
        /// have already been determined by other mail software that has added some Authentication-Results
        /// headers containing this information.
        ///
        /// Note: This method is used when ArcSigner.Sign() is called instead of ArcSigner.SignAsync().
        /// </remarks>
        protected override AuthenticationResults GenerateArcAuthenticationResults(FormatOptions options, MimeMessage message, CancellationToken cancellationToken)
        {
            var results = new AuthenticationResults(AuthenticationServiceIdentifier);

            for (int i = 0; i < message.Headers.Count; i++)
            {
                var header = message.Headers[i];

                if (header.Id != HeaderId.AuthenticationResults)
                {
                    continue;
                }

                if (!AuthenticationResults.TryParse(header.RawValue, out AuthenticationResults authres))
                {
                    continue;
                }

                if (authres.AuthenticationServiceIdentifier != AuthenticationServiceIdentifier)
                {
                    continue;
                }

                foreach (var result in authres.Results)
                {
                    if (!results.Results.Any(r => r.Method == result.Method))
                    {
                        results.Results.Add(result);
                    }
                }
            }

            return(results);
        }
Exemplo n.º 8
0
        public void TestParseNoAuthServId()
        {
            var buffer = Encoding.ASCII.GetBytes("spf=fail (sender IP is 1.1.1.1) smtp.mailfrom=eu-west-1.amazonses.com; recevingdomain.com; dkim=pass (signature was verified) header.d=domain.com;domain1.com; dmarc=bestguesspass action=none header.from=domain.com;");
            AuthenticationResults authres;

            Assert.IsTrue(AuthenticationResults.TryParse(buffer, 0, buffer.Length, out authres));
            Assert.IsNull(authres.AuthenticationServiceIdentifier, "authserv-id");

            Assert.AreEqual("spf=fail (sender IP is 1.1.1.1) smtp.mailfrom=eu-west-1.amazonses.com; recevingdomain.com; dkim=pass (signature was verified) header.d=domain.com;domain1.com; dmarc=bestguesspass action=\"none\" header.from=domain.com", authres.ToString());

            const string expected = " spf=fail (sender IP is 1.1.1.1)\n\tsmtp.mailfrom=eu-west-1.amazonses.com; recevingdomain.com;\n\tdkim=pass (signature was verified) header.d=domain.com;domain1.com;\n\tdmarc=bestguesspass action=\"none\" header.from=domain.com\n";
            var          encoded  = new StringBuilder();
            var          options  = FormatOptions.Default.Clone();

            options.NewLineFormat = NewLineFormat.Unix;

            authres.Encode(options, encoded, "Authentication-Results:".Length);

            Assert.AreEqual(expected, encoded.ToString());
        }
Exemplo n.º 9
0
        public void TestParseAuthServIdSemicolon()
        {
            var buffer = Encoding.ASCII.GetBytes("example.org;");
            AuthenticationResults authres;

            Assert.IsTrue(AuthenticationResults.TryParse(buffer, 0, buffer.Length, out authres));
            Assert.AreEqual("example.org", authres.AuthenticationServiceIdentifier, "authserv-id");

            Assert.AreEqual("example.org; none", authres.ToString());

            const string expected = " example.org; none\n";
            var          encoded  = new StringBuilder();
            var          options  = FormatOptions.Default.Clone();

            options.NewLineFormat = NewLineFormat.Unix;

            authres.Encode(options, encoded, "Authentication-Results:".Length);

            Assert.AreEqual(expected, encoded.ToString());
        }
Exemplo n.º 10
0
        public void TestParseMultipleMethods()
        {
            const string          input  = "example.com; auth=pass (cram-md5) [email protected]; spf=pass smtp.mailfrom=example.net; sender-id=pass header.from=example.net";
            var                   buffer = Encoding.ASCII.GetBytes(input);
            AuthenticationResults authres;

            Assert.IsTrue(AuthenticationResults.TryParse(buffer, 0, buffer.Length, out authres));
            Assert.AreEqual("example.com", authres.AuthenticationServiceIdentifier, "authserv-id");
            Assert.AreEqual(3, authres.Results.Count, "methods");
            Assert.AreEqual("auth", authres.Results[0].Method);
            Assert.AreEqual("pass", authres.Results[0].Result);
            Assert.AreEqual("cram-md5", authres.Results[0].ResultComment);
            Assert.AreEqual(1, authres.Results[0].Properties.Count, "auth properties");
            Assert.AreEqual("smtp", authres.Results[0].Properties[0].PropertyType);
            Assert.AreEqual("auth", authres.Results[0].Properties[0].Property);
            Assert.AreEqual("*****@*****.**", authres.Results[0].Properties[0].Value);
            Assert.AreEqual("spf", authres.Results[1].Method);
            Assert.AreEqual("pass", authres.Results[1].Result);
            Assert.AreEqual(1, authres.Results[1].Properties.Count, "spf properties");
            Assert.AreEqual("smtp", authres.Results[1].Properties[0].PropertyType);
            Assert.AreEqual("mailfrom", authres.Results[1].Properties[0].Property);
            Assert.AreEqual("example.net", authres.Results[1].Properties[0].Value);
            Assert.AreEqual("sender-id", authres.Results[2].Method);
            Assert.AreEqual("pass", authres.Results[2].Result);
            Assert.AreEqual(1, authres.Results[2].Properties.Count, "sender-id properties");
            Assert.AreEqual("header", authres.Results[2].Properties[0].PropertyType);
            Assert.AreEqual("from", authres.Results[2].Properties[0].Property);
            Assert.AreEqual("example.net", authres.Results[2].Properties[0].Value);

            Assert.AreEqual(input, authres.ToString());

            const string expected = " example.com;\n\tauth=pass (cram-md5) [email protected];\n\tspf=pass smtp.mailfrom=example.net; sender-id=pass header.from=example.net\n";
            var          encoded  = new StringBuilder();
            var          options  = FormatOptions.Default.Clone();

            options.NewLineFormat = NewLineFormat.Unix;

            authres.Encode(options, encoded, "Authentication-Results:".Length);

            Assert.AreEqual(expected, encoded.ToString());
        }
Exemplo n.º 11
0
        static void AssertParseFailure(string input, int tokenIndex, int errorIndex)
        {
            var buffer = Encoding.ASCII.GetBytes(input);

            Assert.IsFalse(AuthenticationResults.TryParse(buffer, out AuthenticationResults authres));

            try {
                AuthenticationResults.Parse(buffer);
                Assert.Fail("Expected parse error.");
            } catch (ParseException ex) {
                Assert.AreEqual(tokenIndex, ex.TokenIndex, "TokenIndex");
                Assert.AreEqual(errorIndex, ex.ErrorIndex, "ErrorIndex");
            }

            try {
                AuthenticationResults.Parse(buffer, 0, buffer.Length);
                Assert.Fail("Expected parse error.");
            } catch (ParseException ex) {
                Assert.AreEqual(tokenIndex, ex.TokenIndex, "TokenIndex");
                Assert.AreEqual(errorIndex, ex.ErrorIndex, "ErrorIndex");
            }
        }
Exemplo n.º 12
0
        public void TestParseMultipleMethodsWithReasons()
        {
            const string          input  = "example.com; dkim=pass reason=\"good signature\" [email protected]; dkim=fail reason=\"bad signature\" [email protected]";
            var                   buffer = Encoding.ASCII.GetBytes(input);
            AuthenticationResults authres;

            Assert.IsTrue(AuthenticationResults.TryParse(buffer, 0, buffer.Length, out authres));
            Assert.AreEqual("example.com", authres.AuthenticationServiceIdentifier, "authserv-id");
            Assert.AreEqual(2, authres.Results.Count, "methods");
            Assert.AreEqual("dkim", authres.Results[0].Method);
            Assert.AreEqual("pass", authres.Results[0].Result);
            Assert.AreEqual("good signature", authres.Results[0].Reason);
            Assert.AreEqual(1, authres.Results[0].Properties.Count, "dkim properties");
            Assert.AreEqual("header", authres.Results[0].Properties[0].PropertyType);
            Assert.AreEqual("i", authres.Results[0].Properties[0].Property);
            Assert.AreEqual("@mail-router.example.net", authres.Results[0].Properties[0].Value);
            Assert.AreEqual("dkim", authres.Results[1].Method);
            Assert.AreEqual("fail", authres.Results[1].Result);
            Assert.AreEqual("bad signature", authres.Results[1].Reason);
            Assert.AreEqual(1, authres.Results[1].Properties.Count, "dkim properties");
            Assert.AreEqual("header", authres.Results[1].Properties[0].PropertyType);
            Assert.AreEqual("i", authres.Results[1].Properties[0].Property);
            Assert.AreEqual("@newyork.example.com", authres.Results[1].Properties[0].Value);

            Assert.AreEqual(input, authres.ToString());

            const string expected = " example.com;\n\tdkim=pass reason=\"good signature\" [email protected];\n\tdkim=fail reason=\"bad signature\" [email protected]\n";
            var          encoded  = new StringBuilder();
            var          options  = FormatOptions.Default.Clone();

            options.NewLineFormat = NewLineFormat.Unix;

            authres.Encode(options, encoded, "Authentication-Results:".Length);

            Assert.AreEqual(expected, encoded.ToString());
        }