Unless overridden, all textual parts parsed by the MimeParser, such as text/plain or text/html, will be represented by a TextPart.
For more information about text media types, see section 4.1 of http://www.ietf.org/rfc/rfc2046.txt
public static void TestSendMailDemo() { var message = new MimeKit.MimeMessage(); message.From.Add(new MailboxAddress("Joey Tribbiani", "*****@*****.**")); message.To.Add(new MailboxAddress("Mrs. Chanandler Bong", "*****@*****.**")); message.Subject = "This is a Test Mail"; var plain = new MimeKit.TextPart("plain") { Text = @"不好意思,我在测试程序,Sorry!" }; // now create the multipart/mixed container to hold the message text and the // image attachment using (var client = new MailKit.Net.Smtp.SmtpClient()) { client.Connect("smtp.live.com", 587, false); // Note: since we don't have an OAuth2 token, disable // the XOAUTH2 authentication mechanism. client.AuthenticationMechanisms.Remove("XOAUTH2"); // Note: only needed if the SMTP server requires authentication var mailFromAccount = "*****@*****.**"; var mailPassword = "******"; client.Authenticate(mailFromAccount, mailPassword); client.Send(message); client.Disconnect(true); } }
public void TestArgumentExceptions () { var multipart = new Multipart (); Assert.Throws<ArgumentNullException> (() => new Multipart ((MimeEntityConstructorArgs) null)); Assert.Throws<ArgumentNullException> (() => new Multipart ((string) null)); Assert.Throws<ArgumentNullException> (() => new Multipart ("mixed", null)); Assert.Throws<ArgumentException> (() => new Multipart ("mixed", 5)); Assert.Throws<ArgumentNullException> (() => multipart.Boundary = null); Assert.Throws<ArgumentNullException> (() => multipart.Add (null)); Assert.Throws<ArgumentOutOfRangeException> (() => multipart.Insert (-1, new TextPart ("plain"))); Assert.Throws<ArgumentNullException> (() => multipart.Insert (0, null)); Assert.Throws<ArgumentNullException> (() => multipart.Remove (null)); Assert.Throws<ArgumentOutOfRangeException> (() => multipart.RemoveAt (-1)); Assert.Throws<ArgumentNullException> (() => multipart.Contains (null)); Assert.Throws<ArgumentNullException> (() => multipart.IndexOf (null)); Assert.Throws<ArgumentOutOfRangeException> (() => multipart[0] = new TextPart ("plain")); Assert.Throws<ArgumentNullException> (() => multipart[0] = null); Assert.Throws<ArgumentNullException> (() => multipart.Accept (null)); Assert.Throws<ArgumentOutOfRangeException> (() => multipart.CopyTo (new MimeEntity[0], -1)); Assert.Throws<ArgumentNullException> (() => multipart.CopyTo (null, 0)); Assert.Throws<ArgumentOutOfRangeException> (() => multipart.Prepare (EncodingConstraint.SevenBit, 1)); }
void RenderText (TextPart text) { string html; if (text.IsHtml) { // the text content is already in HTML format html = text.Text; } else if (text.IsFlowed) { var converter = new FlowedToHtml (); string delsp; // the delsp parameter specifies whether or not to delete spaces at the end of flowed lines if (!text.ContentType.Parameters.TryGetValue ("delsp", out delsp)) delsp = "no"; if (string.Compare (delsp, "yes", StringComparison.OrdinalIgnoreCase) == 0) converter.DeleteSpace = true; html = converter.Convert (text.Text); } else { html = new TextToHtml ().Convert (text.Text); } webView.LoadData (html, "text/html", "utf-8"); }
public void TestPgpMimeSigning () { var self = new MailboxAddress ("MimeKit UnitTests", "*****@*****.**"); var cleartext = new TextPart ("plain"); cleartext.Text = "This is some cleartext that we'll end up signing..."; using (var ctx = new DummyOpenPgpContext ()) { var multipart = MultipartSigned.Create (ctx, self, DigestAlgorithm.Sha1, cleartext); Assert.AreEqual (2, multipart.Count, "The multipart/signed has an unexpected number of children."); var protocol = multipart.ContentType.Parameters["protocol"]; Assert.AreEqual (ctx.SignatureProtocol, protocol, "The multipart/signed protocol does not match."); Assert.IsInstanceOfType (typeof (TextPart), multipart[0], "The first child is not a text part."); Assert.IsInstanceOfType (typeof (ApplicationPgpSignature), multipart[1], "The second child is not a detached signature."); var signatures = multipart.Verify (ctx); Assert.AreEqual (1, signatures.Count, "Verify returned an unexpected number of signatures."); foreach (var signature in signatures) { try { bool valid = signature.Verify (); Assert.IsTrue (valid, "Bad signature from {0}", signature.SignerCertificate.Email); } catch (DigitalSignatureVerifyException ex) { Assert.Fail ("Failed to verify signature: {0}", ex); } } } }
public void TestFormat () { TextPart text; text = new TextPart (TextFormat.Html); Assert.IsTrue (text.IsHtml, "IsHtml"); Assert.IsFalse (text.IsPlain, "IsPlain"); Assert.IsFalse (text.IsFlowed, "IsFlowed"); Assert.IsFalse (text.IsRichText, "IsRichText"); text = new TextPart (TextFormat.Plain); Assert.IsFalse (text.IsHtml, "IsHtml"); Assert.IsTrue (text.IsPlain, "IsPlain"); Assert.IsFalse (text.IsFlowed, "IsFlowed"); Assert.IsFalse (text.IsRichText, "IsRichText"); text = new TextPart (TextFormat.Flowed); Assert.IsFalse (text.IsHtml, "IsHtml"); Assert.IsTrue (text.IsPlain, "IsPlain"); Assert.IsTrue (text.IsFlowed, "IsFlowed"); Assert.IsFalse (text.IsRichText, "IsRichText"); text = new TextPart (TextFormat.RichText); Assert.IsFalse (text.IsHtml, "IsHtml"); Assert.IsFalse (text.IsPlain, "IsPlain"); Assert.IsFalse (text.IsFlowed, "IsFlowed"); Assert.IsTrue (text.IsRichText, "IsRichText"); }
static async void SendMailAsync(string FromAddress, string Password, string Contain, string Title, string ToAddress) { var message = new MimeKit.MimeMessage(); message.From.Add(new MimeKit.MailboxAddress(FromAddress, FromAddress)); message.To.Add(new MimeKit.MailboxAddress(ToAddress, ToAddress)); message.Subject = Title; var textPart = new MimeKit.TextPart(MimeKit.Text.TextFormat.Plain); textPart.Text = @Contain; message.Body = textPart; using (var client = new MailKit.Net.Smtp.SmtpClient()) { try { await client.ConnectAsync("smtp.gmail.com", 587); await client.AuthenticateAsync(FromAddress, Password); await client.SendAsync(message); await client.DisconnectAsync(true); } catch (Exception ex) { Form2 form2 = new Form2(); form2.text(ex.ToString()); form2.ShowDialog(); } } }
static void Main(string[] args) { var host = "smtp.gmail.com"; var port = 465; var fromAdd = "*****@*****.**"; //送信元アドレス var fromAddPass = "******"; //送信元アドレスパスワード var toAdd = "*****@*****.**"; //送信先アドレス var mailSubject = "エラー通知テスト"; //メールタイトル var mailText = "お疲れ様です。\r\nエラー通知のテストメールを送信いたしまします。"; //メール本文 using (var smtp = new MailKit.Net.Smtp.SmtpClient()) { try { //開発用のSMTPサーバが暗号化に対応していないときは、次の行をコメントアウト //smtp.ServerCertificateValidationCallback = (s, c, h, e) => true; smtp.Connect(host, port, MailKit.Security.SecureSocketOptions.Auto); //認証設定 smtp.Authenticate(fromAdd, fromAddPass); //送信するメールを作成する var mail = new MimeKit.MimeMessage(); var builder = new MimeKit.BodyBuilder(); mail.From.Add(new MimeKit.MailboxAddress("", fromAdd)); mail.To.Add(new MimeKit.MailboxAddress("", toAdd)); //メールタイトル mail.Subject = mailSubject; //メール本文 MimeKit.TextPart textPart = new MimeKit.TextPart("Plain"); textPart.Text = mailText; var multipart = new MimeKit.Multipart("mixed"); multipart.Add(textPart); mail.Body = multipart; //メールを送信する smtp.Send(mail); } catch (Exception exception) { Console.WriteLine(exception.Message); } finally { //SMTPサーバから切断する smtp.Disconnect(true); } } }
public void TestSecureMimeCompression () { var original = new TextPart ("plain"); original.Text = "This is some text that we'll end up compressing..."; using (var ctx = CreateContext ()) { var compressed = ApplicationPkcs7Mime.Compress (ctx, original); Assert.AreEqual (SecureMimeType.CompressedData, compressed.SecureMimeType, "S/MIME type did not match."); var decompressed = compressed.Decompress (ctx); Assert.IsInstanceOfType (typeof (TextPart), decompressed, "Decompressed part is not the expected type."); Assert.AreEqual (original.Text, ((TextPart) decompressed).Text, "Decompressed content is not the same as the original."); } }
/* * returns true if email address can sign email */ public static bool CanSign(string email) { try { MailboxAddress signer = new MailboxAddress("", email); TextPart entity = new TextPart("text"); using (WindowsSecureMimeContext ctx = new WindowsSecureMimeContext(sys.StoreLocation.CurrentUser)) { MultipartSigned.Create(ctx, signer, DigestAlgorithm.Sha1, entity); return true; } } catch { return false; } }
void Render (TextPart text) { string html; if (!text.ContentType.Matches ("text", "html")) { var builder = new StringBuilder ("<html><body><p>"); var plain = text.Text; for (int i = 0; i < plain.Length; i++) { switch (plain[i]) { case ' ': builder.Append (" "); break; case '"': builder.Append ("""); break; case '&': builder.Append ("&"); break; case '<': builder.Append ("<"); break; case '>': builder.Append (">"); break; case '\r': break; case '\n': builder.Append ("<p>"); break; case '\t': for (int j = 0; j < 8; j++) builder.Append (" "); break; default: if (char.IsControl (plain[i]) || plain[i] > 127) { int unichar; if (i + 1 < plain.Length && char.IsSurrogatePair (plain[i], plain[i + 1])) unichar = char.ConvertToUtf32 (plain[i], plain[i + 1]); else unichar = plain[i]; builder.AppendFormat ("&#{0};", unichar); } else { builder.Append (plain[i]); } break; } } builder.Append ("</body></html>"); html = builder.ToString (); } else { html = text.Text; } webView.LoadData (html, "text/html", "utf-8"); }
public void TestArgumentExceptions () { var body = new TextPart ("plain") { Text = "This is the body..." }; var message = new MimeMessage (); Assert.Throws<ArgumentNullException> (() => new MimeMessage ((object[]) null)); Assert.Throws<ArgumentException> (() => new MimeMessage (body, null, body)); Assert.Throws<ArgumentException> (() => new MimeMessage (5)); Assert.Throws<ArgumentNullException> (() => new MessagePart ("rfc822", (object[]) null)); Assert.Throws<ArgumentException> (() => new MessagePart ("rfc822", message, null, message)); Assert.Throws<ArgumentException> (() => new MessagePart ("rfc822", 5)); Assert.Throws<ArgumentNullException> (() => new MimePart ("text", "plain", (object[]) null)); Assert.Throws<ArgumentException> (() => new MimePart ("text", "plain", body.ContentObject, body.ContentObject.Stream)); Assert.Throws<ArgumentException> (() => new MimePart ("text", "plain", body.ContentObject.Stream, body.ContentObject)); Assert.Throws<ArgumentException> (() => new MimePart ("text", "plain", null, 5)); }
public void TestArgumentExceptions () { var text = new TextPart (TextFormat.Plain); Assert.Throws<ArgumentNullException> (() => new TextPart ("plain", (object[]) null)); Assert.Throws<ArgumentException> (() => new TextPart ("plain", Encoding.UTF8, "blah blah blah", Encoding.UTF8)); Assert.Throws<ArgumentException> (() => new TextPart ("plain", Encoding.UTF8, "blah blah blah", "blah blah")); Assert.Throws<ArgumentException> (() => new TextPart ("plain", 5)); Assert.Throws<ArgumentOutOfRangeException> (() => new TextPart ((TextFormat) 500)); Assert.Throws<ArgumentNullException> (() => text.Accept (null)); Assert.Throws<ArgumentNullException> (() => text.GetText ((string) null)); Assert.Throws<ArgumentNullException> (() => text.GetText ((Encoding) null)); Assert.Throws<ArgumentNullException> (() => text.SetText ((string) null, "text")); Assert.Throws<ArgumentNullException> (() => text.SetText ((Encoding) null, "text")); Assert.Throws<ArgumentNullException> (() => text.SetText ("iso-8859-1", null)); Assert.Throws<ArgumentNullException> (() => text.SetText (Encoding.UTF8, null)); }
public void TestBasicFunctionality () { var multipart = new Multipart (); Assert.IsNotNullOrEmpty (multipart.Boundary, "Boundary"); Assert.IsFalse (multipart.IsReadOnly, "IsReadOnly"); multipart.Boundary = "__Next_Part_123"; Assert.AreEqual ("__Next_Part_123", multipart.Boundary); var generic = new MimePart ("application", "octet-stream") { ContentObject = new ContentObject (new MemoryStream ()), IsAttachment = true }; var plain = new TextPart ("plain") { Text = "This is some plain text." }; multipart.Add (generic); multipart.Insert (0, plain); Assert.AreEqual (2, multipart.Count, "Count"); Assert.IsTrue (multipart.Contains (generic), "Contains"); Assert.AreEqual (0, multipart.IndexOf (plain), "IndexOf"); Assert.IsTrue (multipart.Remove (generic), "Remove"); Assert.IsFalse (multipart.Remove (generic), "Remove 2nd time"); multipart.RemoveAt (0); Assert.AreEqual (0, multipart.Count, "Count"); multipart.Add (generic); multipart.Add (plain); Assert.AreEqual (generic, multipart[0]); Assert.AreEqual (plain, multipart[1]); multipart[0] = plain; multipart[1] = generic; Assert.AreEqual (plain, multipart[0]); Assert.AreEqual (generic, multipart[1]); multipart.Clear (); Assert.AreEqual (0, multipart.Count, "Count"); }
/* * returns true if email can be encrypted */ public static string CanEncrypt(Node emails) { if (emails.Count == 0) return "there are no recipients"; try { List<MailboxAddress> list = new List<MailboxAddress>(); foreach (Node idx in emails) list.Add(new MailboxAddress("", idx.Get<string>())); TextPart entity = new TextPart("text"); using (WindowsSecureMimeContext ctx = new WindowsSecureMimeContext(sys.StoreLocation.CurrentUser)) { ApplicationPkcs7Mime.Encrypt(ctx, list, entity); } return null; } catch(Exception err) { return err.Message; } }
public void TestDocumentRoot () { var gif = new MimePart ("image", "gif") { ContentDisposition = new ContentDisposition (ContentDisposition.Inline) { FileName = "empty.gif" }, ContentId = MimeUtils.GenerateMessageId () }; var jpg = new MimePart ("image", "jpg") { ContentDisposition = new ContentDisposition (ContentDisposition.Inline) { FileName = "empty.jpg" }, ContentId = MimeUtils.GenerateMessageId () }; var html = new TextPart ("html") { Text = "This is the html body...", ContentId = MimeUtils.GenerateMessageId () }; var related = new MultipartRelated (gif, jpg, html); string start; related.ContentType.Parameters["type"] = "text/html"; related.ContentType.Parameters["start"] = "<" + html.ContentId + ">"; Assert.AreEqual (3, related.Count, "Initial Count"); Assert.AreEqual (html, related.Root, "Initial Root"); Assert.AreEqual (html, related[2], "Initial Root should be the 3rd item."); var root = new TextPart ("html") { Text = "This is the replacement root document..." }; related.Root = root; Assert.AreEqual (3, related.Count, "Count"); Assert.AreEqual (root, related.Root, "Root"); Assert.AreEqual (root, related[2], "Root should be the 3rd item."); Assert.IsNotNullOrEmpty (root.ContentId, "Root's Content-Id should not be null."); start = "<" + root.ContentId + ">"; Assert.AreEqual (start, related.ContentType.Parameters["start"], "The start parameter does not match."); related.Clear (); related.Add (gif); related.Add (jpg); related.Root = html; Assert.AreEqual (3, related.Count, "Count"); Assert.AreEqual (html, related.Root, "Root"); Assert.AreEqual (html, related[0], "Root should be the 1st item."); // Note: MimeKit no longer sets the "start" parameter if the root is the first MIME part due to a bug in Thunderbird. Assert.IsNull (related.ContentType.Parameters["start"], "The start parameter should be null."); }
public void TestPgpMimeEncryption() { var self = new MailboxAddress ("MimeKit UnitTests", "*****@*****.**"); var recipients = new List<MailboxAddress> (); // encrypt to ourselves... recipients.Add (self); var cleartext = new TextPart ("plain"); cleartext.Text = "This is some cleartext that we'll end up encrypting..."; using (var ctx = new DummyOpenPgpContext ()) { var encrypted = MultipartEncrypted.Create (ctx, recipients, cleartext); //using (var file = File.Create ("pgp-encrypted.asc")) // encrypted.WriteTo (file); var decrypted = encrypted.Decrypt (ctx); Assert.IsInstanceOfType (typeof (TextPart), decrypted, "Decrypted part is not the expected type."); Assert.AreEqual (cleartext.Text, ((TextPart) decrypted).Text, "Decrypted content is not the same as the original."); } }
public void TestMimeMessageSign () { var body = new TextPart ("plain") { Text = "This is some cleartext that we'll end up signing..." }; var self = new MailboxAddress ("MimeKit UnitTests", "*****@*****.**"); var message = new MimeMessage { Subject = "Test of signing with OpenPGP" }; message.From.Add (self); message.Body = body; using (var ctx = new DummyOpenPgpContext ()) { message.Sign (ctx); Assert.IsInstanceOf<MultipartSigned> (message.Body); var multipart = (MultipartSigned) message.Body; Assert.AreEqual (2, multipart.Count, "The multipart/signed has an unexpected number of children."); var protocol = multipart.ContentType.Parameters["protocol"]; Assert.AreEqual (ctx.SignatureProtocol, protocol, "The multipart/signed protocol does not match."); Assert.IsInstanceOf<TextPart> (multipart[0], "The first child is not a text part."); Assert.IsInstanceOf<ApplicationPgpSignature> (multipart[1], "The second child is not a detached signature."); var signatures = multipart.Verify (ctx); Assert.AreEqual (1, signatures.Count, "Verify returned an unexpected number of signatures."); foreach (var signature in signatures) { try { bool valid = signature.Verify (); Assert.IsTrue (valid, "Bad signature from {0}", signature.SignerCertificate.Email); } catch (DigitalSignatureVerifyException ex) { Assert.Fail ("Failed to verify signature: {0}", ex); } } } }
public void TestSecureMimeEncapsulatedSigning () { var self = new MailboxAddress ("MimeKit UnitTests", "*****@*****.**"); var cleartext = new TextPart ("plain"); cleartext.Text = "This is some text that we'll end up signing..."; using (var ctx = CreateContext ()) { var signed = ApplicationPkcs7Mime.Sign (ctx, self, DigestAlgorithm.Sha1, cleartext); MimeEntity extracted; Assert.AreEqual (SecureMimeType.SignedData, signed.SecureMimeType, "S/MIME type did not match."); var signatures = signed.Verify (ctx, out extracted); Assert.IsInstanceOfType (typeof (TextPart), extracted, "Extracted part is not the expected type."); Assert.AreEqual (cleartext.Text, ((TextPart) extracted).Text, "Extracted content is not the same as the original."); Assert.AreEqual (1, signatures.Count, "Verify returned an unexpected number of signatures."); foreach (var signature in signatures) { try { bool valid = signature.Verify (); Assert.IsTrue (valid, "Bad signature from {0}", signature.SignerCertificate.Email); } catch (DigitalSignatureVerifyException ex) { Assert.Fail ("Failed to verify signature: {0}", ex); } var algorithms = ((SecureMimeDigitalSignature) signature).EncryptionAlgorithms; Assert.AreEqual (EncryptionAlgorithm.Camellia256, algorithms[0], "Expected Camellia-256 capability"); Assert.AreEqual (EncryptionAlgorithm.Aes256, algorithms[1], "Expected AES-256 capability"); Assert.AreEqual (EncryptionAlgorithm.Camellia192, algorithms[2], "Expected Camellia-192 capability"); Assert.AreEqual (EncryptionAlgorithm.Aes192, algorithms[3], "Expected AES-192 capability"); Assert.AreEqual (EncryptionAlgorithm.Camellia128, algorithms[4], "Expected Camellia-128 capability"); Assert.AreEqual (EncryptionAlgorithm.Aes128, algorithms[5], "Expected AES-128 capability"); Assert.AreEqual (EncryptionAlgorithm.Idea, algorithms[6], "Expected IDEA capability"); Assert.AreEqual (EncryptionAlgorithm.Cast5, algorithms[7], "Expected Cast5 capability"); Assert.AreEqual (EncryptionAlgorithm.TripleDes, algorithms[8], "Expected Triple-DES capability"); //Assert.AreEqual (EncryptionAlgorithm.RC2128, algorithms[9], "Expected RC2-128 capability"); //Assert.AreEqual (EncryptionAlgorithm.RC264, algorithms[10], "Expected RC2-64 capability"); //Assert.AreEqual (EncryptionAlgorithm.Des, algorithms[11], "Expected DES capability"); //Assert.AreEqual (EncryptionAlgorithm.RC240, algorithms[12], "Expected RC2-40 capability"); } } }
protected override void VisitTextPart (TextPart entity) { TextConverter converter; if (body != null) { // since we've already found the body, treat this as an attachment attachments.Add (entity); return; } if (entity.IsHtml) { converter = new HtmlToHtml { HtmlTagCallback = HtmlTagCallback }; } else if (entity.IsFlowed) { var flowed = new FlowedToHtml (); string delsp; if (entity.ContentType.Parameters.TryGetValue ("delsp", out delsp)) flowed.DeleteSpace = delsp.ToLowerInvariant () == "yes"; converter = flowed; } else { converter = new TextToHtml (); } body = converter.Convert (entity.Text); }
/// <summary> /// Constructs the message body based on the text-based bodies, the linked resources, and the attachments. /// </summary> /// <remarks> /// Combines the <see cref="Attachments"/>, <see cref="LinkedResources"/>, <see cref="TextBody"/>, /// and <see cref="HtmlBody"/> into the proper MIME structure suitable for display in many common /// mail clients. /// </remarks> /// <returns>The message body.</returns> public MimeEntity ToMessageBody() { Multipart alternative = null; MimeEntity body = null; if (!string.IsNullOrEmpty(TextBody)) { var text = new TextPart("plain"); text.Text = TextBody; if (!string.IsNullOrEmpty(HtmlBody)) { alternative = new Multipart("alternative"); alternative.Add(text); body = alternative; } else { body = text; } } if (!string.IsNullOrEmpty(HtmlBody)) { var text = new TextPart("html"); MimeEntity html; text.ContentId = MimeUtils.GenerateMessageId(); text.Text = HtmlBody; if (LinkedResources.Count > 0) { var related = new MultipartRelated { Root = text }; foreach (var resource in LinkedResources) { related.Add(resource); } html = related; } else { html = text; } if (alternative != null) { alternative.Add(html); } else { body = html; } } if (Attachments.Count > 0) { var mixed = new Multipart("mixed"); if (body != null) { mixed.Add(body); } foreach (var attachment in Attachments) { mixed.Add(attachment); } body = mixed; } return(body ?? new TextPart("plain")); }
public void TestMultipartEncryptedSignAndEncryptALgorithmUsingKeys () { var body = new TextPart ("plain") { Text = "This is some cleartext that we'll end up signing and encrypting..." }; var self = new SecureMailboxAddress ("MimeKit UnitTests", "*****@*****.**", "AB0821A2"); DigitalSignatureCollection signatures; IList<PgpPublicKey> recipients; PgpSecretKey signer; using (var ctx = new DummyOpenPgpContext ()) { recipients = ctx.GetPublicKeys (new [] { self }); signer = ctx.GetSigningKey (self); } var encrypted = MultipartEncrypted.SignAndEncrypt (signer, DigestAlgorithm.Sha1, EncryptionAlgorithm.Cast5, recipients, body); //using (var file = File.Create ("pgp-signed-encrypted.asc")) // encrypted.WriteTo (file); var decrypted = encrypted.Decrypt (out signatures); Assert.IsInstanceOf<TextPart> (decrypted, "Decrypted part is not the expected type."); Assert.AreEqual (body.Text, ((TextPart) decrypted).Text, "Decrypted content is not the same as the original."); Assert.AreEqual (1, signatures.Count, "Verify returned an unexpected number of signatures."); foreach (var signature in signatures) { try { bool valid = signature.Verify (); Assert.IsTrue (valid, "Bad signature from {0}", signature.SignerCertificate.Email); } catch (DigitalSignatureVerifyException ex) { Assert.Fail ("Failed to verify signature: {0}", ex); } } }
public void TestPgpMimeSignAndEncrypt() { var self = new MailboxAddress ("MimeKit UnitTests", "*****@*****.**"); var recipients = new List<MailboxAddress> (); // encrypt to ourselves... recipients.Add (self); var cleartext = new TextPart ("plain"); cleartext.Text = "This is some cleartext that we'll end up encrypting..."; using (var ctx = new DummyOpenPgpContext ()) { var encrypted = MultipartEncrypted.Create (ctx, self, DigestAlgorithm.Sha1, recipients, cleartext); //using (var file = File.Create ("pgp-signed-encrypted.asc")) // encrypted.WriteTo (file); DigitalSignatureCollection signatures; var decrypted = encrypted.Decrypt (ctx, out signatures); Assert.IsInstanceOfType (typeof (TextPart), decrypted, "Decrypted part is not the expected type."); Assert.AreEqual (cleartext.Text, ((TextPart) decrypted).Text, "Decrypted content is not the same as the original."); Assert.AreEqual (1, signatures.Count, "Verify returned an unexpected number of signatures."); foreach (var signature in signatures) { try { bool valid = signature.Verify (); Assert.IsTrue (valid, "Bad signature from {0}", signature.SignerCertificate.Email); } catch (DigitalSignatureVerifyException ex) { Assert.Fail ("Failed to verify signature: {0}", ex); } } } }
/// <summary> /// Constructs the message body based on the text-based bodies, the linked resources, and the attachments. /// </summary> /// <remarks> /// Combines the <see cref="Attachments"/>, <see cref="LinkedResources"/>, <see cref="TextBody"/>, /// and <see cref="HtmlBody"/> into the proper MIME structure suitable for display in many common /// mail clients. /// </remarks> /// <returns>The message body.</returns> public MimeEntity ToMessageBody () { Multipart alternative = null; MimeEntity body = null; if (!string.IsNullOrEmpty (TextBody)) { var text = new TextPart ("plain"); text.Text = TextBody; if (!string.IsNullOrEmpty (HtmlBody)) { alternative = new Multipart ("alternative"); alternative.Add (text); body = alternative; } else { body = text; } } if (!string.IsNullOrEmpty (HtmlBody)) { var text = new TextPart ("html"); MimeEntity html; text.ContentId = MimeUtils.GenerateMessageId (); text.Text = HtmlBody; if (LinkedResources.Count > 0) { var related = new MultipartRelated { Root = text }; foreach (var resource in LinkedResources) related.Add (resource); html = related; } else { html = text; } if (alternative != null) alternative.Add (html); else body = html; } if (Attachments.Count > 0) { var mixed = new Multipart ("mixed"); if (body != null) mixed.Add (body); foreach (var attachment in Attachments) mixed.Add (attachment); body = mixed; } return body ?? new TextPart ("plain") { Text = string.Empty }; }
public void TestMultipartEncryptedEncrypt () { var body = new TextPart ("plain") { Text = "This is some cleartext that we'll end up encrypting..." }; var self = new MailboxAddress ("MimeKit UnitTests", "*****@*****.**"); var encrypted = MultipartEncrypted.Encrypt (new [] { self }, body); //using (var file = File.Create ("pgp-encrypted.asc")) // encrypted.WriteTo (file); var decrypted = encrypted.Decrypt (); Assert.IsInstanceOf<TextPart> (decrypted, "Decrypted part is not the expected type."); Assert.AreEqual (body.Text, ((TextPart) decrypted).Text, "Decrypted content is not the same as the original."); }
public void TestMimeMessageEncrypt () { var body = new TextPart ("plain") { Text = "This is some cleartext that we'll end up encrypting..." }; var self = new SecureMailboxAddress ("MimeKit UnitTests", "*****@*****.**", "44CD48EEC90D8849961F36BA50DCD107AB0821A2"); var message = new MimeMessage { Subject = "Test of signing with OpenPGP" }; message.From.Add (self); message.To.Add (self); message.Body = body; using (var ctx = new DummyOpenPgpContext ()) { message.Encrypt (ctx); Assert.IsInstanceOf<MultipartEncrypted> (message.Body); var encrypted = (MultipartEncrypted) message.Body; //using (var file = File.Create ("pgp-encrypted.asc")) // encrypted.WriteTo (file); var decrypted = encrypted.Decrypt (ctx); Assert.IsInstanceOf<TextPart> (decrypted, "Decrypted part is not the expected type."); Assert.AreEqual (body.Text, ((TextPart) decrypted).Text, "Decrypted content is not the same as the original."); } }
public void TestMultipartSignedSignUsingKeys () { var body = new TextPart ("plain") { Text = "This is some cleartext that we'll end up signing..." }; var self = new SecureMailboxAddress ("MimeKit UnitTests", "*****@*****.**", "44CD48EEC90D8849961F36BA50DCD107AB0821A2"); PgpSecretKey signer; using (var ctx = new DummyOpenPgpContext ()) { signer = ctx.GetSigningKey (self); foreach (DigestAlgorithm digest in Enum.GetValues (typeof (DigestAlgorithm))) { if (digest == DigestAlgorithm.None || digest == DigestAlgorithm.DoubleSha || digest == DigestAlgorithm.Tiger192 || digest == DigestAlgorithm.Haval5160 || digest == DigestAlgorithm.MD4) continue; var multipart = MultipartSigned.Create (signer, digest, body); Assert.AreEqual (2, multipart.Count, "The multipart/signed has an unexpected number of children."); var protocol = multipart.ContentType.Parameters["protocol"]; Assert.AreEqual ("application/pgp-signature", protocol, "The multipart/signed protocol does not match."); var micalg = multipart.ContentType.Parameters["micalg"]; var algorithm = ctx.GetDigestAlgorithm (micalg); Assert.AreEqual (digest, algorithm, "The multipart/signed micalg does not match."); Assert.IsInstanceOf<TextPart> (multipart[0], "The first child is not a text part."); Assert.IsInstanceOf<ApplicationPgpSignature> (multipart[1], "The second child is not a detached signature."); var signatures = multipart.Verify (); Assert.AreEqual (1, signatures.Count, "Verify returned an unexpected number of signatures."); foreach (var signature in signatures) { try { bool valid = signature.Verify (); Assert.IsTrue (valid, "Bad signature from {0}", signature.SignerCertificate.Email); } catch (DigitalSignatureVerifyException ex) { Assert.Fail ("Failed to verify signature: {0}", ex); } } } } }
/// <summary> /// Visit the text-based MIME part entity. /// </summary> /// <remarks> /// Visits the text-based MIME part entity. /// </remarks> /// <example> /// <code language="c#" source="Examples\MimeVisitorExamples.cs" region="HtmlPreviewVisitor" /> /// </example> /// <param name="entity">The text-based MIME part entity.</param> protected internal virtual void VisitTextPart(TextPart entity) { VisitMimePart(entity); }
protected override void VisitTextPart(TextPart entity) { TextConverter converter; string header, footer; if (_body != null) { // since we've already found the body, treat this as an attachment _attachments.Add(entity); return; } GetHeaderFooter(out header, out footer); if (entity.IsHtml) { converter = new HtmlToHtml { Header = UIStrings.MarkOfTheWeb + Environment.NewLine, HeaderFormat = HeaderFooterFormat.Html, HtmlTagCallback = HtmlTagCallback }; } else if (entity.IsFlowed) { var flowed = new FlowedToHtml { Header = UIStrings.MarkOfTheWeb + Environment.NewLine + header, HeaderFormat = HeaderFooterFormat.Html, Footer = footer, FooterFormat = HeaderFooterFormat.Html }; string delsp; if (entity.ContentType.Parameters.TryGetValue("delsp", out delsp)) flowed.DeleteSpace = delsp.ToLowerInvariant() == "yes"; converter = flowed; } else { converter = new TextToHtml { Header = UIStrings.MarkOfTheWeb + Environment.NewLine + header, HeaderFormat = HeaderFooterFormat.Html, Footer = footer, FooterFormat = HeaderFooterFormat.Html }; } string text = entity.Text; _body = converter.Convert(entity.Text); }
public void TestSecureMimeSignAndEncrypt () { var self = new MailboxAddress ("MimeKit UnitTests", "*****@*****.**"); var recipients = new List<MailboxAddress> (); // encrypt to ourselves... recipients.Add (self); var cleartext = new TextPart ("plain"); cleartext.Text = "This is some cleartext that we'll end up encrypting..."; ApplicationPkcs7Mime encrypted; using (var ctx = CreateContext ()) { encrypted = ApplicationPkcs7Mime.SignAndEncrypt (ctx, self, DigestAlgorithm.Sha1, recipients, cleartext); Assert.AreEqual (SecureMimeType.EnvelopedData, encrypted.SecureMimeType, "S/MIME type did not match."); } using (var ctx = CreateContext ()) { var decrypted = encrypted.Decrypt (ctx); // The decrypted part should be a multipart/signed Assert.IsInstanceOfType (typeof (MultipartSigned), decrypted, "Expected the decrypted part to be a multipart/signed."); var signed = (MultipartSigned) decrypted; Assert.IsInstanceOfType (typeof (TextPart), signed[0], "Expected the first part of the multipart/signed to be a multipart."); Assert.IsInstanceOfType (typeof (ApplicationPkcs7Signature), signed[1], "Expected second part of the multipart/signed to be a pkcs7-signature."); var extracted = (TextPart) signed[0]; Assert.AreEqual (cleartext.Text, extracted.Text, "The decrypted text part's text does not match the original."); var signatures = signed.Verify (ctx); Assert.AreEqual (1, signatures.Count, "Verify returned an unexpected number of signatures."); foreach (var signature in signatures) { try { bool valid = signature.Verify (); Assert.IsTrue (valid, "Bad signature from {0}", signature.SignerCertificate.Email); } catch (DigitalSignatureVerifyException ex) { Assert.Fail ("Failed to verify signature: {0}", ex); } var algorithms = ((SecureMimeDigitalSignature) signature).EncryptionAlgorithms; Assert.AreEqual (EncryptionAlgorithm.Camellia256, algorithms[0], "Expected Camellia-256 capability"); Assert.AreEqual (EncryptionAlgorithm.Aes256, algorithms[1], "Expected AES-256 capability"); Assert.AreEqual (EncryptionAlgorithm.Camellia192, algorithms[2], "Expected Camellia-192 capability"); Assert.AreEqual (EncryptionAlgorithm.Aes192, algorithms[3], "Expected AES-192 capability"); Assert.AreEqual (EncryptionAlgorithm.Camellia128, algorithms[4], "Expected Camellia-128 capability"); Assert.AreEqual (EncryptionAlgorithm.Aes128, algorithms[5], "Expected AES-128 capability"); Assert.AreEqual (EncryptionAlgorithm.Idea, algorithms[6], "Expected IDEA capability"); Assert.AreEqual (EncryptionAlgorithm.Cast5, algorithms[7], "Expected Cast5 capability"); Assert.AreEqual (EncryptionAlgorithm.TripleDes, algorithms[8], "Expected Triple-DES capability"); //Assert.AreEqual (EncryptionAlgorithm.RC2128, algorithms[9], "Expected RC2-128 capability"); //Assert.AreEqual (EncryptionAlgorithm.RC264, algorithms[10], "Expected RC2-64 capability"); //Assert.AreEqual (EncryptionAlgorithm.Des, algorithms[11], "Expected DES capability"); //Assert.AreEqual (EncryptionAlgorithm.RC240, algorithms[12], "Expected RC2-40 capability"); } } }
public MailPostMan() { this.MimeMessage = new MimeMessage(); this.TextPart = new TextPart(); }
public void TestMultipartEncryptedEncryptAlgorithmUsingKeys () { var body = new TextPart ("plain") { Text = "This is some cleartext that we'll end up encrypting..." }; var self = new MailboxAddress ("MimeKit UnitTests", "*****@*****.**"); IList<PgpPublicKey> recipients; using (var ctx = new DummyOpenPgpContext ()) { recipients = ctx.GetPublicKeys (new [] { self }); } foreach (EncryptionAlgorithm algorithm in Enum.GetValues (typeof (EncryptionAlgorithm))) { if (algorithm == EncryptionAlgorithm.RC240 || algorithm == EncryptionAlgorithm.RC264 || algorithm == EncryptionAlgorithm.RC2128) continue; var encrypted = MultipartEncrypted.Encrypt (algorithm, recipients, body); //using (var file = File.Create ("pgp-encrypted.asc")) // encrypted.WriteTo (file); var decrypted = encrypted.Decrypt (); Assert.IsInstanceOf<TextPart> (decrypted, "Decrypted part is not the expected type."); Assert.AreEqual (body.Text, ((TextPart) decrypted).Text, "Decrypted content is not the same as the original."); } }
public void TestMimeMessageSignAndEncrypt () { var body = new TextPart ("plain") { Text = "This is some cleartext that we'll end up signing and encrypting..." }; var self = new SecureMailboxAddress ("MimeKit UnitTests", "*****@*****.**", "AB0821A2"); var message = new MimeMessage { Subject = "Test of signing with OpenPGP" }; DigitalSignatureCollection signatures; message.From.Add (self); message.To.Add (self); message.Body = body; using (var ctx = new DummyOpenPgpContext ()) { message.SignAndEncrypt (ctx); Assert.IsInstanceOf<MultipartEncrypted> (message.Body); var encrypted = (MultipartEncrypted) message.Body; //using (var file = File.Create ("pgp-signed-encrypted.asc")) // encrypted.WriteTo (file); var decrypted = encrypted.Decrypt (ctx, out signatures); Assert.IsInstanceOf<TextPart> (decrypted, "Decrypted part is not the expected type."); Assert.AreEqual (body.Text, ((TextPart) decrypted).Text, "Decrypted content is not the same as the original."); Assert.AreEqual (1, signatures.Count, "Verify returned an unexpected number of signatures."); foreach (var signature in signatures) { try { bool valid = signature.Verify (); Assert.IsTrue (valid, "Bad signature from {0}", signature.SignerCertificate.Email); } catch (DigitalSignatureVerifyException ex) { Assert.Fail ("Failed to verify signature: {0}", ex); } } } }
internal static string GetText (TextPart text) { if (text.IsFlowed) { var converter = new FlowedToText (); string delsp; if (text.ContentType.Parameters.TryGetValue ("delsp", out delsp)) converter.DeleteSpace = delsp.ToLowerInvariant () == "yes"; return converter.Convert (text.Text); } return text.Text; }
/// <summary> /// Creates a new <see cref="MimeMessage"/> from a <see cref="System.Net.Mail.MailMessage"/>. /// </summary> /// <remarks> /// Creates a new <see cref="MimeMessage"/> from a <see cref="System.Net.Mail.MailMessage"/>. /// </remarks> /// <returns>The equivalent <see cref="MimeMessage"/>.</returns> /// <param name="message">The message.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="message"/> is <c>null</c>. /// </exception> public static MimeMessage CreateFromMailMessage (MailMessage message) { if (message == null) throw new ArgumentNullException ("message"); var headers = new List<Header> (); foreach (var field in message.Headers.AllKeys) { foreach (var value in message.Headers.GetValues (field)) headers.Add (new Header (field, value)); } var msg = new MimeMessage (ParserOptions.Default, headers); MimeEntity body = null; // Note: If the user has already sent their MailMessage via System.Net.Mail.SmtpClient, // then the following MailMessage properties will have been merged into the Headers, so // check to make sure our MimeMessage properties are empty before adding them. if (msg.Sender == null && message.Sender != null) msg.Sender = (MailboxAddress) message.Sender; if (msg.From.Count == 0 && message.From != null) msg.From.Add ((MailboxAddress) message.From); #if NET_3_5 if (msg.ReplyTo.Count == 0 && message.ReplyTo != null) msg.ReplyTo.Add ((MailboxAddress) message.ReplyTo); #else if (msg.ReplyTo.Count == 0 && message.ReplyToList.Count > 0) msg.ReplyTo.AddRange ((InternetAddressList) message.ReplyToList); #endif if (msg.To.Count == 0 && message.To.Count > 0) msg.To.AddRange ((InternetAddressList) message.To); if (msg.Cc.Count == 0 && message.CC.Count > 0) msg.Cc.AddRange ((InternetAddressList) message.CC); if (msg.Bcc.Count == 0 && message.Bcc.Count > 0) msg.Bcc.AddRange ((InternetAddressList) message.Bcc); if (string.IsNullOrEmpty (msg.Subject)) msg.Subject = message.Subject ?? string.Empty; switch (message.Priority) { case MailPriority.High: msg.Headers.Replace (HeaderId.Priority, "urgent"); msg.Headers.Replace (HeaderId.Importance, "high"); msg.Headers.Replace ("X-Priority", "1"); break; case MailPriority.Low: msg.Headers.Replace (HeaderId.Priority, "non-urgent"); msg.Headers.Replace (HeaderId.Importance, "low"); msg.Headers.Replace ("X-Priority", "5"); break; } if (!string.IsNullOrEmpty (message.Body)) { var text = new TextPart (message.IsBodyHtml ? "html" : "plain"); text.SetText (message.BodyEncoding ?? Encoding.UTF8, message.Body); body = text; } if (message.AlternateViews.Count > 0) { var alternative = new Multipart ("alternative"); if (body != null) alternative.Add (body); foreach (var view in message.AlternateViews) { var part = GetMimePart (view); if (view.BaseUri != null) part.ContentLocation = view.BaseUri; if (view.LinkedResources.Count > 0) { var type = part.ContentType.MediaType + "/" + part.ContentType.MediaSubtype; var related = new Multipart ("related"); related.ContentType.Parameters.Add ("type", type); if (view.BaseUri != null) related.ContentLocation = view.BaseUri; related.Add (part); foreach (var resource in view.LinkedResources) { part = GetMimePart (resource); if (resource.ContentLink != null) part.ContentLocation = resource.ContentLink; related.Add (part); } alternative.Add (related); } else { alternative.Add (part); } } body = alternative; } if (body == null) body = new TextPart (message.IsBodyHtml ? "html" : "plain"); if (message.Attachments.Count > 0) { var mixed = new Multipart ("mixed"); if (body != null) mixed.Add (body); foreach (var attachment in message.Attachments) mixed.Add (GetMimePart (attachment)); body = mixed; } msg.Body = body; return msg; }
static void ExtractMapiProperties(TnefReader reader, MimeMessage message, BodyBuilder builder) { var prop = reader.TnefPropertyReader; while (prop.ReadNextProperty ()) { switch (prop.PropertyTag.Id) { case TnefPropertyId.InternetMessageId: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode) { message.MessageId = prop.ReadValueAsString (); Console.WriteLine ("Message Property: {0} = {1}", prop.PropertyTag.Id, message.MessageId); } else { Assert.Fail ("Unknown property type for Message-Id: {0}", prop.PropertyTag.ValueTnefType); } break; case TnefPropertyId.Subject: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode) { message.Subject = prop.ReadValueAsString (); Console.WriteLine ("Message Property: {0} = {1}", prop.PropertyTag.Id, message.Subject); } else { Assert.Fail ("Unknown property type for Subject: {0}", prop.PropertyTag.ValueTnefType); } break; case TnefPropertyId.RtfCompressed: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) { var rtf = new TextPart ("rtf"); rtf.ContentType.Name = "body.rtf"; var converter = new RtfCompressedToRtf (); var content = new MemoryStream (); using (var filtered = new FilteredStream (content)) { filtered.Add (converter); using (var compressed = prop.GetRawValueReadStream ()) { compressed.CopyTo (filtered, 4096); filtered.Flush (); } } rtf.ContentObject = new ContentObject (content); content.Position = 0; builder.Attachments.Add (rtf); Console.WriteLine ("Message Property: {0} = <compressed rtf data>", prop.PropertyTag.Id); } else { Assert.Fail ("Unknown property type for {0}: {1}", prop.PropertyTag.Id, prop.PropertyTag.ValueTnefType); } break; case TnefPropertyId.BodyHtml: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) { var html = new TextPart ("html"); html.ContentType.Name = "body.html"; html.Text = prop.ReadValueAsString (); builder.Attachments.Add (html); Console.WriteLine ("Message Property: {0} = {1}", prop.PropertyTag.Id, html.Text); } else { Assert.Fail ("Unknown property type for {0}: {1}", prop.PropertyTag.Id, prop.PropertyTag.ValueTnefType); } break; case TnefPropertyId.Body: if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 || prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode || prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary) { var plain = new TextPart ("plain"); plain.ContentType.Name = "body.txt"; plain.Text = prop.ReadValueAsString (); builder.Attachments.Add (plain); Console.WriteLine ("Message Property: {0} = {1}", prop.PropertyTag.Id, plain.Text); } else { Assert.Fail ("Unknown property type for {0}: {1}", prop.PropertyTag.Id, prop.PropertyTag.ValueTnefType); } break; default: Console.WriteLine ("Message Property (unhandled): {0} = {1}", prop.PropertyTag.Id, prop.ReadValue ()); break; } } }
/// <summary> /// Visit the text-based MIME part entity. /// </summary> /// <remarks> /// Visits the text-based MIME part entity. /// </remarks> /// <example> /// <code language="c#" source="Examples\MimeVisitorExamples.cs" region="HtmlPreviewVisitor" /> /// </example> /// <param name="entity">The text-based MIME part entity.</param> protected internal virtual void VisitTextPart (TextPart entity) { VisitMimePart (entity); }
/// <summary> /// Construct the message body based on the text-based bodies, the linked resources, and the attachments. /// </summary> /// <remarks> /// Combines the <see cref="Attachments"/>, <see cref="LinkedResources"/>, <see cref="TextBody"/>, /// and <see cref="HtmlBody"/> into the proper MIME structure suitable for display in many common /// mail clients. /// </remarks> /// <example> /// <code language="c#" source="Examples\BodyBuilder.cs" region="Complex" /> /// </example> /// <returns>The message body.</returns> public MimeEntity ToMessageBody() { MultipartAlternative alternative = null; MimeEntity body = null; if (TextBody != null) { var text = new TextPart("plain"); text.Text = TextBody; if (HtmlBody != null) { alternative = new MultipartAlternative(); alternative.Add(text); body = alternative; } else { body = text; } } if (HtmlBody != null) { var text = new TextPart("html"); MimeEntity html; text.Text = HtmlBody; if (LinkedResources.Count > 0) { var related = new MultipartRelated { Root = text }; foreach (var resource in LinkedResources) { related.Add(resource); } html = related; } else { html = text; } if (alternative != null) { alternative.Add(html); } else { body = html; } } if (Attachments.Count > 0) { if (body == null && Attachments.Count == 1) { return(Attachments[0]); } var mixed = new Multipart("mixed"); if (body != null) { mixed.Add(body); } foreach (var attachment in Attachments) { mixed.Add(attachment); } body = mixed; } return(body ?? new TextPart("plain") { Text = string.Empty }); }