public void TestDkimSignVerifyJwzMbox() { using (var stream = File.OpenRead("../../TestData/mbox/jwz.mbox.txt")) { var parser = new MimeParser(stream, MimeFormat.Mbox); while (!parser.IsEndOfStream) { var message = parser.ParseMessage(); TestDkimSignVerify(message, DkimSignatureAlgorithm.RsaSha1, DkimCanonicalizationAlgorithm.Relaxed, DkimCanonicalizationAlgorithm.Relaxed); TestDkimSignVerify(message, DkimSignatureAlgorithm.RsaSha256, DkimCanonicalizationAlgorithm.Relaxed, DkimCanonicalizationAlgorithm.Simple); TestDkimSignVerify(message, DkimSignatureAlgorithm.RsaSha1, DkimCanonicalizationAlgorithm.Simple, DkimCanonicalizationAlgorithm.Relaxed); TestDkimSignVerify(message, DkimSignatureAlgorithm.RsaSha256, DkimCanonicalizationAlgorithm.Simple, DkimCanonicalizationAlgorithm.Simple); } } }
public async void TestUnmungedFromLinesAsync() { int count = 0; using (var stream = File.OpenRead(Path.Combine(MboxDataDir, "unmunged.mbox.txt"))) { var parser = new MimeParser(stream, MimeFormat.Mbox); while (!parser.IsEndOfStream) { await parser.ParseMessageAsync(); var marker = parser.MboxMarker; if ((count % 2) == 0) { Assert.AreEqual("From -", marker.TrimEnd(), "Message #{0}", count); } else { Assert.AreEqual("From Russia with love", marker.TrimEnd(), "Message #{0}", count); } count++; } } Assert.AreEqual(4, count, "Expected to find 4 messages."); }
/// <summary> /// Gets top lines of message. /// </summary> /// <param name="nr">Message number which top lines to get.</param> /// <param name="nLines">Number of lines to get.</param> public System.Net.Mail.MailMessage GetTopOfMessage(int nr, int nLines) { if (!m_Connected) { throw new Exception("You must connect first !"); } if (!m_Authenticated) { throw new Exception("You must authenticate first !"); } streamHelper.Write("TOP " + nr.ToString() + " " + nLines.ToString() + "\r\n"); // Read first line of reply, check if it's ok string line = streamHelper.ReadToEnd(); if (line.StartsWith("+OK")) { MimeParser parser = new MimeParser(Core.DoPeriodHandling(socketStream, false, false).ToArray()); return(parser.ToMailMessage()); } else { throw new Exception("Server returned:" + line); } }
public void TestBoundaryStart(string text, string boundary, bool isBoundary) { bool result = false; Assert.Null(Record.Exception(() => result = MimeParser.IsBoundary(new StringSegment(text), boundary))); Assert.True(result == isBoundary); }
public static string GetSubject(string path) { string res = ""; FileStream f = new FileStream(path, FileMode.Open, FileAccess.Read); try { MimeParser b = new MimeParser(f); var mime1 = b.ParseHeaders(); foreach (Header header in mime1) { if (HeaderId.Subject == header.Id) { res = header.Value; if (res == "" || res.Trim(' ') == "") { res = "* No subject"; } } } } catch { } finally { f.Close(); } return(res); }
public void TestBoundaryEnd(string text, bool isEnd) { bool result = false; Assert.DoesNotThrow(() => result = MimeParser.IsBoundaryEnd(new StringSegment(text))); Assert.True(result == isEnd); }
public Stream InlineEmbedImagesAndStripFromAttachments(Stream email) { var mimeParser = new MimeParser(email); var message = mimeParser.ParseMessage(); var entitiesToRemove = new List <MimeEntity>(); var textParts = message.BodyParts.OfType <TextPart>().ToArray(); EmbedImages(textParts, message, entitiesToRemove); if (message.Body is Multipart parts) { var multiparts = parts.OfType <Multipart>().ToArray(); foreach (var t in entitiesToRemove) { parts.Remove(t); // ReSharper disable once ReturnValueOfPureMethodIsNotUsed multiparts.Any(x => x.Remove(t)); } } var messageStream = new MemoryStream(); message.WriteTo(messageStream); messageStream.Seek(0, SeekOrigin.Begin); return(messageStream); }
static MimeEntity Prepare(MimeEntity entity, Stream memory) { entity.Prepare(EncodingConstraint.SevenBit, 78); using (var filtered = new FilteredStream(memory)) { // Note: see rfc3156, section 3 - second note filtered.Add(new ArmoredFromFilter()); // Note: see rfc3156, section 5.4 (this is the main difference between rfc2015 and rfc3156) filtered.Add(new TrailingWhitespaceFilter()); // Note: see rfc2015 or rfc3156, section 5.1 filtered.Add(new Unix2DosFilter()); entity.WriteTo(filtered); filtered.Flush(); } memory.Position = 0; // Note: we need to parse the modified entity structure to preserve any modifications var parser = new MimeParser(memory, MimeFormat.Entity); return(parser.ParseEntity()); }
/// <inheritdoc/> public bool HandleIncomingEmail() { MimeParser mimeParser = new MimeParser(_options.GetInputEmail(), !_options.StdIn); MimeMessage message = mimeParser.ParseMessage(); if (!message.Headers.Contains(OriginalToHeader)) { return(false); } string from = message.From[0].ToString(); string to = toCache.Get(message); if (IsFromRelay(from)) { // Not supported yet return(false); } else if (ShouldForward(to)) { ForwardEmail(message); } return(true); }
//[Ignore] public void TestDkimSignVerifyJwzMbox() { using (var stream = File.OpenRead(Path.Combine(TestHelper.ProjectDir, "TestData", "mbox", "jwz.mbox.txt"))) { var parser = new MimeParser(stream, MimeFormat.Mbox); int i = 0; while (!parser.IsEndOfStream && i < 10) { var message = parser.ParseMessage(); TestDkimSignVerify(message, DkimSignatureAlgorithm.RsaSha1, DkimCanonicalizationAlgorithm.Relaxed, DkimCanonicalizationAlgorithm.Relaxed); TestDkimSignVerify(message, DkimSignatureAlgorithm.RsaSha256, DkimCanonicalizationAlgorithm.Relaxed, DkimCanonicalizationAlgorithm.Simple); TestDkimSignVerify(message, DkimSignatureAlgorithm.RsaSha1, DkimCanonicalizationAlgorithm.Simple, DkimCanonicalizationAlgorithm.Relaxed); TestDkimSignVerify(message, DkimSignatureAlgorithm.RsaSha256, DkimCanonicalizationAlgorithm.Simple, DkimCanonicalizationAlgorithm.Simple); i++; } } }
public void TestBoundaryStart(string text, string boundary, bool isBoundary) { bool result = false; Assert.DoesNotThrow(() => result = MimeParser.IsBoundary(new StringSegment(text), boundary)); Assert.True(result == isBoundary); }
public void ToHeader(int addressCount, string source, string headerName) { DirectAddressCollection addresses = null; Assert.Null(Record.Exception(() => addresses = DirectAddressCollection.Parse(source))); Assert.True(addresses.Count == addressCount); Header header = null; Assert.Null(Record.Exception(() => header = addresses.ToHeader(headerName))); Assert.True(string.Equals(header.Name, headerName)); string foldedText = null; Assert.Null(Record.Exception(() => foldedText = header.SourceText.ToString())); Assert.True(!string.IsNullOrEmpty(foldedText)); string[] foldedParts = foldedText.Split(new string[] { MailStandard.CRLF }, StringSplitOptions.None); Assert.True(foldedParts.Length == addressCount); string entity = foldedText + MailStandard.CRLF; Header[] reparsedHeaders = null; Assert.Null(Record.Exception(() => reparsedHeaders = MimeParser.ReadHeaders(entity).ToArray())); Assert.True(reparsedHeaders.Length == 1); Assert.True(reparsedHeaders[0].Name == headerName); DirectAddressCollection reparsedAddresses = null; Assert.Null(Record.Exception(() => reparsedAddresses = DirectAddressCollection.Parse(reparsedHeaders[0].Value))); Assert.True(reparsedAddresses.Count == addressCount); }
static MimeMessage Load(string path) { using (var file = File.OpenRead(path)) { var parser = new MimeParser(file); return(parser.ParseMessage()); } }
static void AssertSimpleMbox(Stream stream) { var parser = new MimeParser(stream, MimeFormat.Mbox); while (!parser.IsEndOfStream) { var message = parser.ParseMessage(); Multipart multipart; MimeEntity entity; Assert.IsInstanceOf <Multipart> (message.Body); multipart = (Multipart)message.Body; Assert.AreEqual(1, multipart.Count); entity = multipart[0]; Assert.IsInstanceOf <Multipart> (entity); multipart = (Multipart)entity; Assert.AreEqual(1, multipart.Count); entity = multipart[0]; Assert.IsInstanceOf <Multipart> (entity); multipart = (Multipart)entity; Assert.AreEqual(1, multipart.Count); entity = multipart[0]; Assert.IsInstanceOf <TextPart> (entity); using (var memory = new MemoryStream()) { entity.WriteTo(UnixFormatOptions, memory); var text = Encoding.ASCII.GetString(memory.ToArray()); Assert.IsTrue(text.StartsWith("Content-Type: text/plain\n\n", StringComparison.Ordinal), "Headers are not properly terminated."); } } }
private void BtnParseMBox_Click(object sender, EventArgs e) { using (var stream = File.OpenRead(TxtPath.Text)) { // パーサを生成 var parser = new MimeParser(stream, MimeFormat.Mbox); while (!parser.IsEndOfStream) { // メッセージをパースする var message = parser.ParseMessage(); // メッセージを使って何かする Console.WriteLine("[From]"); Console.WriteLine(string.Join(Environment.NewLine, message.From.Select(a => a.ToString()))); Console.WriteLine("[To]"); Console.WriteLine(string.Join(Environment.NewLine, message.To.Select(a => a.ToString()))); Console.WriteLine("[Subject]"); Console.WriteLine(message.Subject); Console.WriteLine("[TextBody]"); Console.WriteLine(message.TextBody); Console.WriteLine("[HtmlBody]"); Console.WriteLine(message.HtmlBody); Console.WriteLine("[Attachments]"); Console.WriteLine(string.Join(Environment.NewLine, message.Attachments.Select(a => a.ContentDisposition))); Console.WriteLine(); } } }
public override void Parse() { var path = Path.Combine(rootFolder, "Mail"); var foldersName = Directory.GetFiles(path); foreach (var item in foldersName) { var mail = new GwsMail(); List <MimeMessage> messagesList = new List <MimeMessage>(); using (FileStream sr = File.OpenRead(item)) { var parser = new MimeParser(sr, MimeFormat.Mbox); while (!parser.IsEndOfStream) { messagesList.Add(parser.ParseMessage()); messagesCount++; } } var folder = item.Split(Path.DirectorySeparatorChar); mail.ParentFolder = folder[folder.Length - 1].Split('.')[0].ToLower() == "All mail Including Spam and Trash".ToLower()? "inbox" : folder[folder.Length - 1].Split('.')[0]; mail.Message = messagesList; mails.Add(mail); } throw new System.NotImplementedException(); }
public void TestParsingGarbage() { using (var stream = new MemoryStream()) { var line = Encoding.ASCII.GetBytes("This is just a standard test file... nothing to see here. No MIME anywhere to be found\r\n"); for (int i = 0; i < 200; i++) { stream.Write(line, 0, line.Length); } stream.Position = 0; var parser = new MimeParser(stream, MimeFormat.Mbox); Assert.Throws <FormatException> (() => parser.ParseMessage(), "Mbox"); stream.Position = 0; Assert.Throws <FormatException> (async() => await parser.ParseMessageAsync(), "MboxAsync"); stream.Position = 0; parser.SetStream(stream, MimeFormat.Entity); Assert.Throws <FormatException> (() => parser.ParseMessage(), "Entity"); stream.Position = 0; parser.SetStream(stream, MimeFormat.Entity); Assert.Throws <FormatException> (async() => await parser.ParseMessageAsync(), "EntityAsync"); } }
static void Main(string[] args) { Console.WriteLine("Provide path to the files folder. Or <enter> to use defaults."); var path = Console.ReadLine(); if (path.Length != 0) { if (!File.Exists(path)) { Console.WriteLine("Invalid path provided. Press any key to continue..."); Console.Read(); } } else { path = "C:/MailFiles"; } var files = from file in Directory.EnumerateFiles(path, "*.mbox") select file; Console.WriteLine("{0} files found to process", files.Count().ToString()); foreach (var f in files) { Console.WriteLine("Processing file {0}", f); List <MyMail> output = new List <MyMail>(); // Load every message from a Unix mbox using (FileStream stream = new FileStream(f, FileMode.Open)) { var parser = new MimeParser(stream, MimeFormat.Mbox); while (!parser.IsEndOfStream) { var message = parser.ParseMessage(); output.Add(new MyMail(message.From.ToString(), message.Date.ToString(), message.ReplyTo.ToString(), message.Subject, message.To.ToString(), MakeBody(message.TextBody, path + "/", false), MakeBody(message.HtmlBody, path + "/", true))); // do something with the message } } using (System.IO.TextWriter writer = File.CreateText(f + ".csv")) { var csv = new CsvWriter(writer, new CsvConfiguration() { QuoteAllFields = true, HasExcelSeparator = true }); csv.WriteRecords(output); } } Console.Read(); }
public void TestBoundaryEnd(string text, bool isEnd) { bool result = false; Assert.Null(Record.Exception(() => result = MimeParser.IsBoundaryEnd(new StringSegment(text)))); Assert.True(result == isEnd); }
public void TestSecureMimeVerifyThunderbird() { MimeMessage message; using (var file = File.OpenRead(Path.Combine("..", "..", "TestData", "smime", "thunderbird-signed.txt"))) { var parser = new MimeParser(file, MimeFormat.Default); message = parser.ParseMessage(); } using (var ctx = CreateContext()) { var multipart = (MultipartSigned)message.Body; var protocol = multipart.ContentType.Parameters["protocol"]; Assert.IsTrue(ctx.Supports(protocol), "The multipart/signed protocol is not supported."); Assert.IsInstanceOfType(typeof(ApplicationPkcs7Signature), 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); } } } }
/// <summary> /// Creates a new <see cref="MultipartSigned"/>. /// </summary> /// <remarks> /// Cryptographically signs the entity using the supplied signer in order /// to generate a detached signature and then adds the entity along with /// the detached signature data to a new multipart/signed part. /// </remarks> /// <returns>A new <see cref="MultipartSigned"/> instance.</returns> /// <param name="ctx">The S/MIME context to use for signing.</param> /// <param name="signer">The signer.</param> /// <param name="entity">The entity to sign.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="ctx"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="signer"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="entity"/> is <c>null</c>.</para> /// </exception> /// <exception cref="Org.BouncyCastle.Cms.CmsException"> /// An error occurred in the cryptographic message syntax subsystem. /// </exception> public static MultipartSigned Create(SecureMimeContext ctx, CmsSigner signer, MimeEntity entity) { if (ctx == null) { throw new ArgumentNullException("ctx"); } if (signer == null) { throw new ArgumentNullException("signer"); } if (entity == null) { throw new ArgumentNullException("entity"); } entity.Prepare(EncodingConstraint.SevenBit, 78); using (var memory = new MemoryBlockStream()) { using (var filtered = new FilteredStream(memory)) { // Note: see rfc3156, section 3 - second note filtered.Add(new ArmoredFromFilter()); // Note: see rfc3156, section 5.4 (this is the main difference between rfc2015 and rfc3156) filtered.Add(new TrailingWhitespaceFilter()); // Note: see rfc2015 or rfc3156, section 5.1 filtered.Add(new Unix2DosFilter()); entity.WriteTo(filtered); filtered.Flush(); } memory.Position = 0; // Note: we need to parse the modified entity structure to preserve any modifications var parser = new MimeParser(memory, MimeFormat.Entity); var parsed = parser.ParseEntity(); memory.Position = 0; // sign the cleartext content var micalg = ctx.GetDigestAlgorithmName(signer.DigestAlgorithm); var signature = ctx.Sign(signer, memory); var signed = new MultipartSigned(); // set the protocol and micalg Content-Type parameters signed.ContentType.Parameters["protocol"] = ctx.SignatureProtocol; signed.ContentType.Parameters["micalg"] = micalg; // add the modified/parsed entity as our first part signed.Add(parsed); // add the detached signature as the second part signed.Add(signature); return(signed); } }
private MailMessage GetMailMessage(String filePath) { MimeParser parser = new MimeParser(); using (var str = new FileStream(filePath, FileMode.Open)) { return(parser.ToMailMessage(str)); } }
public async Task TestReserializationEmptyParts() { string rawMessageText = @"Date: Fri, 22 Jan 2016 8:44:05 -0500 (EST) From: MimeKit Unit Tests <*****@*****.**> To: MimeKit Unit Tests <*****@*****.**> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary=""Interpart.Boundary.IeCBvV20M2YtEoUA0A"" Subject: Reserialization test of empty mime parts THIS IS A MESSAGE IN 'MIME' FORMAT. Your mail reader does not support MIME. Please read the first section, which is plain text, and ignore the rest. --Interpart.Boundary.IeCBvV20M2YtEoUA0A Content-type: text/plain; charset=US-ASCII This is the body. --Interpart.Boundary.IeCBvV20M2YtEoUA0A Content-type: text/plain; charset=US-ASCII; name=empty.txt Content-Description: this part contains no content --Interpart.Boundary.IeCBvV20M2YtEoUA0A Content-type: text/plain; charset=US-ASCII; name=blank-line.txt Content-Description: this part contains a single blank line --Interpart.Boundary.IeCBvV20M2YtEoUA0A-- ".Replace("\r\n", "\n"); using (var source = new MemoryStream(Encoding.UTF8.GetBytes(rawMessageText))) { var parser = new MimeParser(source, MimeFormat.Default); var message = parser.ParseMessage(); using (var serialized = new MemoryStream()) { var options = FormatOptions.Default.Clone(); options.NewLineFormat = NewLineFormat.Unix; message.WriteTo(options, serialized); var result = Encoding.UTF8.GetString(serialized.ToArray()); Assert.AreEqual(rawMessageText, result, "Reserialized message is not identical to the original."); } using (var serialized = new MemoryStream()) { var options = FormatOptions.Default.Clone(); options.NewLineFormat = NewLineFormat.Unix; await message.WriteToAsync(options, serialized); var result = Encoding.UTF8.GetString(serialized.ToArray()); Assert.AreEqual(rawMessageText, result, "Reserialized (async) message is not identical to the original."); } } }
static void debug_read_message_from_file(string path) { bd_util.log("fake email input:" + path, Serilog.Events.LogEventLevel.Warning); FileStream stream = File.OpenRead(path); var parser = new MimeParser(stream); MimeMessage message = parser.ParseMessage(); process_incoming_message(message); }
/// <summary> /// Returns requested mime entry data. /// </summary> /// <param name="parser"></param> /// <param name="mimeEntryNo"></param> /// <returns>Returns requested mime entry data or NULL if requested entri doesn't exist.</returns> public static byte[] ParseMimeEntry(MimeParser parser, int mimeEntryNo) { if (mimeEntryNo > 0 && mimeEntryNo <= parser.MimeEntries.Count) { return(((MimeEntry)parser.MimeEntries[mimeEntryNo - 1]).Data); } return(null); }
public void TestInvalidCRLN(string text) { MimeException error = null; error = AssertEx.Throws <MimeException>(() => { MimeParser.ReadLines(text).ToArray(); }); Assert.True(error.Error == MimeError.InvalidCRLF); }
public string InlineEmbedImagesAndReturnBodyOnly(Stream email) { var mimeParser = new MimeParser(email); var message = mimeParser.ParseMessage(); var entitiesToRemove = new List <MimeEntity>(); var textParts = message.BodyParts.OfType <TextPart>().ToArray(); EmbedImages(textParts, message, entitiesToRemove); return(message.HtmlBody); }
private static string ConstructMultiPart(MimeEntry ent, bool bodystructure) { string str = "("; str += ConstructPart(ent.MimeEntries, bodystructure); str += " "; // conentSubType if (ent.ContentType.Split('/').Length == 2) { str += "\"" + ent.ContentType.Split('/')[1].Replace(";", "") + "\""; } else { str += "NIL"; } // Need to add extended fields if (bodystructure) { str += " "; // conentTypeSubFields string longContentType = MimeParser.ParseHeaderField("Content-Type:", ent.Headers); if (longContentType.IndexOf(";") > -1) { str += "("; string[] fields = longContentType.Split(';'); for (int i = 1; i < fields.Length; i++) { string[] nameValue = fields[i].Replace("\"", "").Trim().Split(new char[] { '=' }, 2); str += "\"" + nameValue[0] + "\" \"" + nameValue[1] + "\""; if (i < fields.Length - 1) { str += " "; } } str += ") "; } // contentDisposition str += "NIL "; // contentLanguage str += "NIL"; } str += ")"; return(str); }
public void TestInvalidHeaders(string entity, MimeError expectedError) { MimeException error; error = AssertEx.Throws <MimeException>(() => { Header[] headers = MimeParser.ReadHeaders(entity).ToArray(); string value = headers[0].Value; }); Assert.True(error.Error == expectedError); }
public void TestValidCRLN(string text, string[] expectedLines) { StringSegment[] parsedLines = null; Assert.Null(Record.Exception(() => parsedLines = MimeParser.ReadLines(text).ToArray())); Assert.True(parsedLines[parsedLines.Length - 1].IsEmpty); Assert.True((parsedLines.Length - 1) == expectedLines.Length); for (int i = 0; i < expectedLines.Length; ++i) { Assert.Equal(parsedLines[i].ToString(), expectedLines[i]); } }
/// <summary> /// Creates a new <see cref="MultipartSigned"/>. /// </summary> /// <remarks> /// Cryptographically signs the entity using the supplied signer in order /// to generate a detached signature and then adds the entity along with /// the detached signature data to a new multipart/signed part. /// </remarks> /// <returns>A new <see cref="MultipartSigned"/> instance.</returns> /// <param name="ctx">The S/MIME context to use for signing.</param> /// <param name="signer">The signer.</param> /// <param name="entity">The entity to sign.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="ctx"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="signer"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="entity"/> is <c>null</c>.</para> /// </exception> /// <exception cref="Org.BouncyCastle.Cms.CmsException"> /// An error occurred in the cryptographic message syntax subsystem. /// </exception> public static MultipartSigned Create (SecureMimeContext ctx, CmsSigner signer, MimeEntity entity) { if (ctx == null) throw new ArgumentNullException ("ctx"); if (signer == null) throw new ArgumentNullException ("signer"); if (entity == null) throw new ArgumentNullException ("entity"); PrepareEntityForSigning (entity); using (var memory = new MemoryBlockStream ()) { using (var filtered = new FilteredStream (memory)) { // Note: see rfc3156, section 3 - second note filtered.Add (new ArmoredFromFilter ()); // Note: see rfc3156, section 5.4 (this is the main difference between rfc2015 and rfc3156) filtered.Add (new TrailingWhitespaceFilter ()); // Note: see rfc2015 or rfc3156, section 5.1 filtered.Add (new Unix2DosFilter ()); entity.WriteTo (filtered); filtered.Flush (); } memory.Position = 0; // Note: we need to parse the modified entity structure to preserve any modifications var parser = new MimeParser (memory, MimeFormat.Entity); var parsed = parser.ParseEntity (); memory.Position = 0; // sign the cleartext content var micalg = ctx.GetDigestAlgorithmName (signer.DigestAlgorithm); var signature = ctx.Sign (signer, memory); var signed = new MultipartSigned (); // set the protocol and micalg Content-Type parameters signed.ContentType.Parameters["protocol"] = ctx.SignatureProtocol; signed.ContentType.Parameters["micalg"] = micalg; // add the modified/parsed entity as our first part signed.Add (parsed); // add the detached signature as the second part signed.Add (signature); return signed; } }