示例#1
0
        public static void DkimSign(MimeMessage message)
        {
            var headers = new HeaderId[] { HeaderId.From, HeaderId.Subject, HeaderId.Date };
            var signer  = new DkimSigner("privatekey.pem", "example.com", "brisbane", DkimSignatureAlgorithm.RsaSha256)
            {
                HeaderCanonicalizationAlgorithm = DkimCanonicalizationAlgorithm.Simple,
                BodyCanonicalizationAlgorithm   = DkimCanonicalizationAlgorithm.Simple,
                AgentOrUserIdentifier           = "@eng.example.com",
                QueryMethod = "dns/txt",
            };

            // Prepare the message body to be sent over a 7bit transport (such as older versions of SMTP).
            // Note: If the SMTP server you will be sending the message over supports the 8BITMIME extension,
            // then you can use `EncodingConstraint.EightBit` instead.
            message.Prepare(EncodingConstraint.SevenBit);

            signer.Sign(message, headers);
        }
示例#2
0
        public void TestSignRfc8463Example()
        {
            var message = MimeMessage.Load(Path.Combine(TestHelper.ProjectDir, "TestData", "dkim", "rfc8463-example.msg"));
            var signer  = new DkimSigner(Ed25519PrivateKey, "football.example.com", "brisbane", DkimSignatureAlgorithm.Ed25519Sha256)
            {
                HeaderCanonicalizationAlgorithm = DkimCanonicalizationAlgorithm.Relaxed,
                BodyCanonicalizationAlgorithm   = DkimCanonicalizationAlgorithm.Relaxed,
                AgentOrUserIdentifier           = "@football.example.com"
            };
            var headers = new string[] { "from", "to", "subject", "date", "message-id", "from", "subject", "date" };

            signer.Sign(message, headers);

            int index    = message.Headers.IndexOf(HeaderId.DkimSignature);
            var locator  = new DkimPublicKeyLocator();
            var verifier = new DkimVerifier(locator);
            var dkim     = message.Headers[index];

            locator.Add("brisbane._domainkey.football.example.com", "v=DKIM1; k=ed25519; p=11qYAYKxCrfVS/7TyWQHOg7hcvPapiMlrwIaaPcHURo=");
            locator.Add("test._domainkey.football.example.com", "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDkHlOQoBTzWRiGs5V6NpP3idY6Wk08a5qhdR6wy5bdOKb2jLQiY/J16JYi0Qvx/byYzCNb3W91y3FutACDfzwQ/BC/e/8uBsCR+yz1Lxj+PL6lHvqMKrM3rG4hstT5QjvHO9PzoxZyVYLzBfO2EeC3Ip3G+2kryOTIKT+l/K4w3QIDAQAB");

            Assert.IsTrue(verifier.Verify(message, message.Headers[index]), "Failed to verify ed25519-sha256");
        }
示例#3
0
        public static void SendEmail(string smtpHost, Int32 smtpPort, string from, SecureString password, string to, string subject, string bodyEmail, bool isDkimEmail, string txtDKIMPath)
        {
            SmtpClient smtpClient = new SmtpClient();   //inicjalizacja klienta smtp z przestrzeni nazw MailKit.Net.Smtp

            try
            {
                smtpClient.Connect(smtpHost, smtpPort, SecureSocketOptions.StartTls); //łączymy się
            }
            catch (SmtpCommandException ex)                                           //obsługa wyjątku
            {
                Console.WriteLine("~~Cannot connect with client (SMTP Command Exception): {0}~~", ex.ToString());
                Environment.Exit(1);
            }
            catch (SmtpProtocolException ex)    //obsługa wyjątku
            {
                Console.WriteLine("~~Cannot connect with client (SMTP Protocol Exception): {0}~~", ex.ToString());
                Environment.Exit(1);
            }

            try
            {
                smtpClient.Authenticate(from, new NetworkCredential(string.Empty, password).Password);
            }
            catch (AuthenticationException ex)  //obsługa wyjątku
            {
                Console.WriteLine("~~Authentication error (Authentication Exception): {0}~~", ex.ToString());
                Environment.Exit(1);
            }
            catch (SmtpCommandException ex) //obsługa wyjątku
            {
                Console.WriteLine("~~Authentication error (SMTP Command Exception): {0}~~", ex.ToString());
                Environment.Exit(1);
            }
            catch (SmtpProtocolException ex)    //obsługa wyjątku
            {
                Console.WriteLine("~~Authentication error (SMTP Protocol Exception): {0}~~", ex.ToString());
                Environment.Exit(1);
            }


            smtpClient.SslProtocols = System.Security.Authentication.SslProtocols.Tls12;
            MimeMessage mimeMessage = new MimeMessage();    //inicjalizujemy obiekt mailMessage

            if (isDkimEmail)
            {
                string domain = from.Split("@")[1];

                HeaderId[] headers = new HeaderId[] { HeaderId.From, HeaderId.Subject, HeaderId.Date };
                DkimSigner signer  = new DkimSigner(txtDKIMPath, domain, "mail", DkimSignatureAlgorithm.RsaSha256)
                {
                    HeaderCanonicalizationAlgorithm = DkimCanonicalizationAlgorithm.Relaxed,
                    BodyCanonicalizationAlgorithm   = DkimCanonicalizationAlgorithm.Relaxed,
                    AgentOrUserIdentifier           = "@" + domain,
                    QueryMethod = "dns/txt",
                };

                //message.Prepare(EncodingConstraint.SevenBit);
                //message.Prepare(EncodingConstraint.EightBit);

                signer.Sign(mimeMessage, headers);
            }

            mimeMessage.From.Add(new MailboxAddress(from));     //od kogo e-mail
            mimeMessage.To.Add(new MailboxAddress(from));       //do kogo
            mimeMessage.Subject = subject;                      //temat
            BodyBuilder bodyBuilder = new BodyBuilder();        //bodyBuilder do tworzenia treści e-maila

            bodyBuilder.TextBody = bodyEmail;                   //tekst treści
            mimeMessage.Body     = bodyBuilder.ToMessageBody(); //wrzucenie tekstu bodyBuildera do treści e-maila
            try
            {
                smtpClient.Send(mimeMessage); //wysyłanie e-maila
            }
            catch (SmtpCommandException ex)   //obsługa wyjątku
            {
                Console.WriteLine("~~E-mail has not been sent (SMTP Command Exception): {0}", ex.Message);
                Environment.Exit(1);
            }
            catch (SmtpProtocolException ex)    //obsługa wyjątku
            {
                Console.WriteLine("~~E-mail has not been sent (SMTP Protocol Exception): {0}", ex.Message);
                Environment.Exit(1);
            }
            Console.WriteLine("~~E-mail sent~~");
            smtpClient.Disconnect(true);
        }
示例#4
0
        public void TestArgumentExceptions()
        {
            var        locator    = new DummyPublicKeyLocator(DkimKeys.Public);
            var        verifier   = new DkimVerifier(locator);
            var        dkimHeader = new Header(HeaderId.DkimSignature, "value");
            var        arcHeader  = new Header(HeaderId.ArcMessageSignature, "value");
            var        options    = FormatOptions.Default;
            var        message    = new MimeMessage();
            DkimSigner signer;

            Assert.Throws <ArgumentNullException> (() => new DkimSigner((AsymmetricKeyParameter)null, "domain", "selector"));
            Assert.Throws <ArgumentException> (() => new DkimSigner(DkimKeys.Public, "domain", "selector"));
            Assert.Throws <ArgumentNullException> (() => new DkimSigner(DkimKeys.Private, null, "selector"));
            Assert.Throws <ArgumentNullException> (() => new DkimSigner(DkimKeys.Private, "domain", null));
            Assert.Throws <ArgumentNullException> (() => new DkimSigner((string)null, "domain", "selector"));
            Assert.Throws <ArgumentNullException> (() => new DkimSigner("fileName", null, "selector"));
            Assert.Throws <ArgumentNullException> (() => new DkimSigner("fileName", "domain", null));
            Assert.Throws <ArgumentException> (() => new DkimSigner(string.Empty, "domain", "selector"));
            Assert.Throws <ArgumentNullException> (() => new DkimSigner((Stream)null, "domain", "selector"));
            using (var stream = File.OpenRead(Path.Combine(TestHelper.ProjectDir, "TestData", "dkim", "example.pem"))) {
                Assert.Throws <ArgumentNullException> (() => new DkimSigner(stream, null, "selector"));
                Assert.Throws <ArgumentNullException> (() => new DkimSigner(stream, "domain", null));

                signer = new DkimSigner(stream, "example.com", "1433868189.example")
                {
                    SignatureAlgorithm    = DkimSignatureAlgorithm.RsaSha1,
                    AgentOrUserIdentifier = "@eng.example.com",
                    QueryMethod           = "dns/txt",
                };
            }

            Assert.Throws <ArgumentNullException> (() => signer.Sign(null, new HeaderId[] { HeaderId.From }));
            Assert.Throws <ArgumentNullException> (() => signer.Sign(message, (IList <HeaderId>)null));
            Assert.Throws <ArgumentException> (() => signer.Sign(message, new HeaderId[] { HeaderId.Unknown, HeaderId.From }));
            Assert.Throws <ArgumentException> (() => signer.Sign(message, new HeaderId[] { HeaderId.Received, HeaderId.From }));
            Assert.Throws <ArgumentException> (() => signer.Sign(message, new HeaderId[] { HeaderId.ContentType }));
            Assert.Throws <ArgumentNullException> (() => signer.Sign(null, new string[] { "From" }));
            Assert.Throws <ArgumentNullException> (() => signer.Sign(message, (IList <string>)null));
            Assert.Throws <ArgumentException> (() => signer.Sign(message, new string[] { "", "From" }));
            Assert.Throws <ArgumentException> (() => signer.Sign(message, new string[] { null, "From" }));
            Assert.Throws <ArgumentException> (() => signer.Sign(message, new string[] { "Received", "From" }));
            Assert.Throws <ArgumentException> (() => signer.Sign(message, new string[] { "Content-Type" }));

            Assert.Throws <ArgumentNullException> (() => signer.Sign(null, message, new HeaderId[] { HeaderId.From }));
            Assert.Throws <ArgumentNullException> (() => signer.Sign(options, null, new HeaderId[] { HeaderId.From }));
            Assert.Throws <ArgumentException> (() => signer.Sign(options, message, new HeaderId[] { HeaderId.From, HeaderId.Unknown }));
            Assert.Throws <ArgumentNullException> (() => signer.Sign(options, message, (IList <HeaderId>)null));

            Assert.Throws <ArgumentNullException> (() => signer.Sign(null, message, new string[] { "From" }));
            Assert.Throws <ArgumentNullException> (() => signer.Sign(options, null, new string[] { "From" }));
            Assert.Throws <ArgumentException> (() => signer.Sign(options, message, new string[] { "From", null }));
            Assert.Throws <ArgumentNullException> (() => signer.Sign(options, message, (IList <string>)null));

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

            Assert.Throws <ArgumentNullException> (() => verifier.Verify(null, dkimHeader));
            Assert.Throws <ArgumentNullException> (() => verifier.Verify(message, null));
            Assert.Throws <ArgumentNullException> (() => verifier.Verify(null, message, dkimHeader));
            Assert.Throws <ArgumentNullException> (() => verifier.Verify(FormatOptions.Default, null, dkimHeader));
            Assert.Throws <ArgumentNullException> (() => verifier.Verify(FormatOptions.Default, message, null));
            Assert.Throws <ArgumentException> (() => verifier.Verify(FormatOptions.Default, message, arcHeader));

            Assert.ThrowsAsync <ArgumentNullException> (async() => await verifier.VerifyAsync(null, dkimHeader));
            Assert.ThrowsAsync <ArgumentNullException> (async() => await verifier.VerifyAsync(message, null));
            Assert.ThrowsAsync <ArgumentNullException> (async() => await verifier.VerifyAsync(null, message, dkimHeader));
            Assert.ThrowsAsync <ArgumentNullException> (async() => await verifier.VerifyAsync(FormatOptions.Default, null, dkimHeader));
            Assert.ThrowsAsync <ArgumentNullException> (async() => await verifier.VerifyAsync(FormatOptions.Default, message, null));
            Assert.ThrowsAsync <ArgumentException> (async() => await verifier.VerifyAsync(FormatOptions.Default, message, arcHeader));

            Assert.Throws <ArgumentNullException> (() => message.Sign(null, new HeaderId[] { HeaderId.From }));
            Assert.Throws <ArgumentNullException> (() => message.Sign(signer, (IList <HeaderId>)null));
            Assert.Throws <ArgumentException> (() => message.Sign(signer, new HeaderId[] { HeaderId.Unknown, HeaderId.From }));
            Assert.Throws <ArgumentException> (() => message.Sign(signer, new HeaderId[] { HeaderId.Received, HeaderId.From }));
            Assert.Throws <ArgumentException> (() => message.Sign(signer, new HeaderId[] { HeaderId.ContentType }));
            Assert.Throws <ArgumentNullException> (() => message.Sign(null, new string[] { "From" }));
            Assert.Throws <ArgumentNullException> (() => message.Sign(signer, (IList <string>)null));
            Assert.Throws <ArgumentException> (() => message.Sign(signer, new string[] { "", "From" }));
            Assert.Throws <ArgumentException> (() => message.Sign(signer, new string[] { null, "From" }));
            Assert.Throws <ArgumentException> (() => message.Sign(signer, new string[] { "Received", "From" }));
            Assert.Throws <ArgumentException> (() => message.Sign(signer, new string[] { "Content-Type" }));

            Assert.Throws <ArgumentNullException> (() => message.Sign(null, signer, new HeaderId[] { HeaderId.From }));
            Assert.Throws <ArgumentNullException> (() => message.Sign(options, null, new HeaderId[] { HeaderId.From }));
            Assert.Throws <ArgumentException> (() => message.Sign(options, signer, new HeaderId[] { HeaderId.From, HeaderId.Unknown }));
            Assert.Throws <ArgumentNullException> (() => message.Sign(options, signer, (IList <HeaderId>)null));

            Assert.Throws <ArgumentNullException> (() => message.Sign(null, signer, new string[] { "From" }));
            Assert.Throws <ArgumentNullException> (() => message.Sign(options, null, new string[] { "From" }));
            Assert.Throws <ArgumentException> (() => message.Sign(options, signer, new string[] { "From", null }));
            Assert.Throws <ArgumentNullException> (() => message.Sign(options, signer, (IList <string>)null));

            Assert.Throws <ArgumentNullException> (() => message.Verify(null, locator));
            Assert.Throws <ArgumentNullException> (() => message.Verify(dkimHeader, null));
            Assert.Throws <ArgumentNullException> (() => message.Verify(null, dkimHeader, locator));
            Assert.Throws <ArgumentNullException> (() => message.Verify(FormatOptions.Default, null, locator));
            Assert.Throws <ArgumentNullException> (() => message.Verify(FormatOptions.Default, dkimHeader, null));
            Assert.Throws <ArgumentException> (() => message.Verify(FormatOptions.Default, arcHeader, locator));

            Assert.ThrowsAsync <ArgumentNullException> (async() => await message.VerifyAsync(null, locator));
            Assert.ThrowsAsync <ArgumentNullException> (async() => await message.VerifyAsync(dkimHeader, null));
            Assert.ThrowsAsync <ArgumentNullException> (async() => await message.VerifyAsync(null, dkimHeader, locator));
            Assert.ThrowsAsync <ArgumentNullException> (async() => await message.VerifyAsync(FormatOptions.Default, null, locator));
            Assert.ThrowsAsync <ArgumentNullException> (async() => await message.VerifyAsync(FormatOptions.Default, dkimHeader, null));
            Assert.ThrowsAsync <ArgumentException> (async() => await message.VerifyAsync(FormatOptions.Default, arcHeader, locator));
        }
示例#5
0
        /// <summary>
        /// Create a MimMessage so MailKit can send it
        /// </summary>
        /// <returns>The mail message.</returns>
        /// <param name="email">Email data.</param>
        private MimeMessage CreateMailMessage(IFluentEmail email)
        {
            var data = email.Data;

            var message = new MimeMessage();

            // fixes https://github.com/lukencode/FluentEmail/issues/228
            // if for any reason, subject header is not added, add it else update it.
            if (!message.Headers.Contains(HeaderId.Subject))
            {
                message.Headers.Add(HeaderId.Subject, Encoding.UTF8, data.Subject ?? string.Empty);
            }
            else
            {
                message.Headers[HeaderId.Subject] = data.Subject ?? string.Empty;
            }

            message.Headers.Add(HeaderId.Encoding, Encoding.UTF8.EncodingName);

            message.From.Add(new MailboxAddress(data.FromAddress.Name, data.FromAddress.EmailAddress));

            var builder = new BodyBuilder();

            if (!string.IsNullOrEmpty(data.PlaintextAlternativeBody))
            {
                builder.TextBody = data.PlaintextAlternativeBody;
                builder.HtmlBody = data.Body;
            }
            else if (!data.IsHtml)
            {
                builder.TextBody = data.Body;
            }
            else
            {
                builder.HtmlBody = data.Body;
            }

            data.Attachments.ForEach(x =>
            {
                MimeEntity attachment;
                if (x.Data != null)
                {
                    attachment = builder.Attachments.Add(x.Filename, x.Data, ContentType.Parse(x.ContentType));
                }
                else
                {
                    attachment = builder.Attachments.Add(x.Filename, x.DataBuffer, ContentType.Parse(x.ContentType));
                }

                attachment.ContentId = x.ContentId;
            });


            message.Body = builder.ToMessageBody();

            foreach (var header in data.Headers)
            {
                message.Headers.Add(header.Key, header.Value);
            }

            data.ToAddresses.ForEach(x =>
            {
                message.To.Add(new MailboxAddress(x.Name, x.EmailAddress));
            });

            data.CcAddresses.ForEach(x =>
            {
                message.Cc.Add(new MailboxAddress(x.Name, x.EmailAddress));
            });

            data.BccAddresses.ForEach(x =>
            {
                message.Bcc.Add(new MailboxAddress(x.Name, x.EmailAddress));
            });

            data.ReplyToAddresses.ForEach(x =>
            {
                message.ReplyTo.Add(new MailboxAddress(x.Name, x.EmailAddress));
            });

            switch (data.Priority)
            {
            case Priority.Low:
                message.Priority = MessagePriority.NonUrgent;
                break;

            case Priority.Normal:
                message.Priority = MessagePriority.Normal;
                break;

            case Priority.High:
                message.Priority = MessagePriority.Urgent;
                break;
            }

            if (_smtpClientOptions.Dkim != null && _smtpClientOptions.Dkim.Sign)
            {
                HeaderId[] headersToSign = new HeaderId[] { HeaderId.From, HeaderId.Subject, HeaderId.Date };

                DkimSigner signer = new DkimSigner(_smtpClientOptions.Dkim.Key, _smtpClientOptions.Dkim.Domain, _smtpClientOptions.Dkim.Selector)
                {
                    SignatureAlgorithm = DkimSignatureAlgorithm.RsaSha256,
                    HeaderCanonicalizationAlgorithm = DkimCanonicalizationAlgorithm.Relaxed,
                    BodyCanonicalizationAlgorithm   = DkimCanonicalizationAlgorithm.Relaxed,
                    AgentOrUserIdentifier           = $"@{_smtpClientOptions.Dkim.Domain}",
                    QueryMethod = "dns/txt",
                };

                message.Prepare(EncodingConstraint.EightBit);
                signer.Sign(message, headersToSign);
            }

            return(message);
        }