public void TestBase64Encode() { using (var original = new MemoryStream()) { using (var file = File.OpenRead("../../TestData/encoders/photo.b64")) { using (var filtered = new FilteredStream(original)) { filtered.Add(new Dos2UnixFilter()); file.CopyTo(filtered, 4096); filtered.Flush(); } } using (var encoded = new MemoryStream()) { using (var filtered = new FilteredStream(encoded)) { filtered.Add(EncoderFilter.Create(ContentEncoding.Base64)); using (var file = File.OpenRead("../../TestData/encoders/photo.jpg")) file.CopyTo(filtered, 4096); filtered.Flush(); } var buf0 = original.GetBuffer(); var buf1 = encoded.GetBuffer(); int n = (int)original.Length; Assert.AreEqual(original.Length, encoded.Length, "Encoded length is incorrect."); for (int i = 0; i < n; i++) { Assert.AreEqual(buf0[i], buf1[i], "The byte at offset {0} does not match.", i); } } } }
void TestDecoder(ContentEncoding encoding, byte[] rawData, string encodedFile, int bufferSize) { int n; using (var original = new MemoryStream(rawData, false)) { using (var decoded = new MemoryStream()) { using (var filtered = new FilteredStream(decoded)) { filtered.Add(DecoderFilter.Create(encoding)); using (var file = File.OpenRead(Path.Combine(dataDir, encodedFile))) { var buffer = new byte[bufferSize]; while ((n = file.Read(buffer, 0, bufferSize)) > 0) { filtered.Write(buffer, 0, n); } } filtered.Flush(); } var buf = decoded.GetBuffer(); n = rawData.Length; Assert.AreEqual(rawData.Length, decoded.Length, "Decoded length is incorrect."); for (int i = 0; i < n; i++) { Assert.AreEqual(rawData[i], buf[i], "The byte at offset {0} does not match.", i); } } } }
public void TestArmoredFromFilter() { const string text = "This text is meant to test that the filter will armor lines beginning with\nFrom (like mbox). And let's add another\nFrom line for good measure, shall we?\n"; const string expected = "This text is meant to test that the filter will armor lines beginning with\n=46rom (like mbox). And let's add another\n=46rom line for good measure, shall we?\n"; var filter = new ArmoredFromFilter(); TestArgumentExceptions(filter); using (var stream = new MemoryStream()) { using (var filtered = new FilteredStream(stream)) { int fromIndex = text.IndexOf("\nFrom ", StringComparison.Ordinal); var buffer = Encoding.UTF8.GetBytes(text); filtered.Add(filter); // write out a buffer where the end boundary falls in the middle of "From " int endIndex = fromIndex + 3; filtered.Write(buffer, 0, endIndex); // write out the rest filtered.Write(buffer, endIndex, buffer.Length - endIndex); filtered.Flush(); var actual = Encoding.UTF8.GetString(stream.GetBuffer(), 0, (int)stream.Length); Assert.AreEqual(expected, actual, "From armoring failed when end boundary falls in the middle of From."); } } }
/// <summary> /// Gets the decoded text content using the provided charset to override /// the charset specified in the Content-Type parameters. /// </summary> /// <remarks> /// Uses the provided charset encoding to convert the raw text content /// into a unicode string, overriding any charset specified in the /// Content-Type header. /// </remarks> /// <returns>The decoded text.</returns> /// <param name="charset">The charset encoding to use.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="charset"/> is <c>null</c>. /// </exception> public string GetText(Encoding charset) { if (charset == null) { throw new ArgumentNullException("charset"); } using (var memory = new MemoryStream()) { using (var filtered = new FilteredStream(memory)) { filtered.Add(new CharsetFilter(charset, Encoding.UTF8)); ContentObject.DecodeTo(filtered); filtered.Flush(); #if PORTABLE var buffer = memory.ToArray(); int length = buffer.Length; #else var buffer = memory.GetBuffer(); int length = (int)memory.Length; #endif return(Encoding.UTF8.GetString(buffer, 0, length)); } } }
static EncoderTests() { using (var memory = new MemoryStream()) { using (var filtered = new FilteredStream(memory)) { filtered.Add(new Dos2UnixFilter()); using (var file = File.OpenRead(Path.Combine(dataDir, "wikipedia.txt"))) file.CopyTo(filtered, 4096); filtered.Flush(); } wikipedia_unix = memory.ToArray(); } using (var memory = new MemoryStream()) { using (var filtered = new FilteredStream(memory)) { filtered.Add(new Unix2DosFilter()); using (var file = File.OpenRead(Path.Combine(dataDir, "wikipedia.txt"))) file.CopyTo(filtered, 4096); filtered.Flush(); } wikipedia_dos = memory.ToArray(); } photo = File.ReadAllBytes(Path.Combine(dataDir, "photo.jpg")); }
public ImapReplayCommand(Encoding encoding, string tag, string command, string resource, bool compressed = false) { CommandBuffer = encoding.GetBytes(command); Compressed = compressed; Encoding = encoding; Command = command; using (var stream = GetType().Assembly.GetManifestResourceStream("UnitTests.Net.Imap.Resources." + resource)) { using (var memory = new MemoryBlockStream()) { using (Stream compress = new CompressedStream(memory)) { using (var filtered = new FilteredStream(compressed ? compress : memory)) { filtered.Add(new ImapReplayFilter("A########", tag)); filtered.Add(new Unix2DosFilter()); stream.CopyTo(filtered, 4096); filtered.Flush(); } Response = memory.ToArray(); } } } if (compressed) { using (var memory = new MemoryStream()) { using (var compress = new CompressedStream(memory)) { compress.Write(CommandBuffer, 0, CommandBuffer.Length); compress.Flush(); CommandBuffer = memory.ToArray(); } } } }
/// <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); } }
static void AssertJwzMboxResults(string actual, Stream output) { var summary = File.ReadAllText(Path.Combine(MboxDataDir, "jwz-summary.txt")).Replace("\r\n", "\n"); var original = new MemoryBlockStream(); var expected = new byte[4096]; var buffer = new byte[4096]; int nx, n; // WORKAROUND: Mono's iso-2022-jp decoder breaks on this input in versions <= 3.2.3 but is fixed in 3.2.4+ string iso2022jp = Encoding.GetEncoding("iso-2022-jp").GetString(Convert.FromBase64String("GyRAOjRGI0stGyhK")); if (iso2022jp != "佐藤豊") { actual = actual.Replace(iso2022jp, "佐藤豊"); } Assert.AreEqual(summary, actual, "Summaries do not match for jwz.mbox"); using (var stream = File.OpenRead(Path.Combine(MboxDataDir, "jwz.mbox.txt"))) { using (var filtered = new FilteredStream(original)) { filtered.Add(new Dos2UnixFilter()); stream.CopyTo(filtered); filtered.Flush(); } } original.Position = 0; output.Position = 0; Assert.AreEqual(original.Length, output.Length, "The length of the mbox did not match."); do { var position = original.Position; nx = original.Read(expected, 0, expected.Length); n = output.Read(buffer, 0, buffer.Length); if (nx == 0) { break; } for (int i = 0; i < nx; i++) { if (buffer[i] == expected[i]) { continue; } var strExpected = CharsetUtils.Latin1.GetString(expected, 0, nx); var strActual = CharsetUtils.Latin1.GetString(buffer, 0, n); Assert.AreEqual(strExpected, strActual, "The mbox differs at position {0}", position + i); } } while (true); }
/// <summary> /// Writes the <see cref="MimeKit.MimePart"/> to the specified output stream. /// </summary> /// <param name="options">The formatting options.</param> /// <param name="stream">The output stream.</param> /// <param name="cancellationToken">A cancellation token.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="options"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="stream"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> public override void WriteTo(FormatOptions options, Stream stream, CancellationToken cancellationToken) { base.WriteTo(options, stream, cancellationToken); if (ContentObject == null) { return; } if (ContentObject.Encoding != encoding) { if (encoding == ContentEncoding.UUEncode) { cancellationToken.ThrowIfCancellationRequested(); var begin = string.Format("begin 0644 {0}", FileName ?? "unknown"); var buffer = Encoding.UTF8.GetBytes(begin); stream.Write(buffer, 0, buffer.Length); stream.Write(options.NewLineBytes, 0, options.NewLineBytes.Length); } // transcode the content into the desired Content-Transfer-Encoding using (var filtered = new FilteredStream(stream)) { filtered.Add(EncoderFilter.Create(encoding)); if (encoding != ContentEncoding.Binary) { filtered.Add(options.CreateNewLineFilter()); } ContentObject.DecodeTo(filtered, cancellationToken); filtered.Flush(); } if (encoding == ContentEncoding.UUEncode) { cancellationToken.ThrowIfCancellationRequested(); var buffer = Encoding.ASCII.GetBytes("end"); stream.Write(buffer, 0, buffer.Length); stream.Write(options.NewLineBytes, 0, options.NewLineBytes.Length); } } else if (encoding != ContentEncoding.Binary) { using (var filtered = new FilteredStream(stream)) { filtered.Add(options.CreateNewLineFilter()); ContentObject.WriteTo(filtered, cancellationToken); filtered.Flush(); } } else { ContentObject.WriteTo(stream, cancellationToken); } }
async Task <bool> VerifyArcSealAsync(FormatOptions options, ArcHeaderSet[] sets, int i, bool doAsync, CancellationToken cancellationToken) { DkimSignatureAlgorithm algorithm; AsymmetricKeyParameter key; string d, s, q, b; ValidateArcSealParameters(sets[i].ArcSealParameters, out algorithm, out d, out s, out q, out b); if (!IsEnabled(algorithm)) { return(false); } if (doAsync) { key = await PublicKeyLocator.LocatePublicKeyAsync(q, d, s, cancellationToken).ConfigureAwait(false); } else { key = PublicKeyLocator.LocatePublicKey(q, d, s, cancellationToken); } if ((key is RsaKeyParameters rsa) && rsa.Modulus.BitLength < MinimumRsaKeyLength) { return(false); } options = options.Clone(); options.NewLineFormat = NewLineFormat.Dos; using (var stream = new DkimSignatureStream(CreateVerifyContext(algorithm, key))) { using (var filtered = new FilteredStream(stream)) { filtered.Add(options.CreateNewLineFilter()); for (int j = 0; j < i; j++) { WriteHeaderRelaxed(options, filtered, sets[j].ArcAuthenticationResult, false); WriteHeaderRelaxed(options, filtered, sets[j].ArcMessageSignature, false); WriteHeaderRelaxed(options, filtered, sets[j].ArcSeal, false); } WriteHeaderRelaxed(options, filtered, sets[i].ArcAuthenticationResult, false); WriteHeaderRelaxed(options, filtered, sets[i].ArcMessageSignature, false); // now include the ARC-Seal header that we are verifying, // but only after removing the "b=" signature value. var seal = GetSignedSignatureHeader(sets[i].ArcSeal); WriteHeaderRelaxed(options, filtered, seal, true); filtered.Flush(); } return(stream.VerifySignature(b)); } }
void TestEncoder(ContentEncoding encoding, byte[] rawData, string encodedFile, int bufferSize) { int n; using (var original = new MemoryStream()) { using (var file = File.OpenRead(Path.Combine(dataDir, encodedFile))) { using (var filtered = new FilteredStream(original)) { filtered.Add(new Dos2UnixFilter()); file.CopyTo(filtered, 4096); filtered.Flush(); } } using (var encoded = new MemoryStream()) { if (encoding == ContentEncoding.UUEncode) { var begin = Encoding.ASCII.GetBytes("begin 644 photo.jpg\n"); encoded.Write(begin, 0, begin.Length); } using (var filtered = new FilteredStream(encoded)) { filtered.Add(EncoderFilter.Create(encoding)); using (var memory = new MemoryStream(rawData, false)) { var buffer = new byte[bufferSize]; while ((n = memory.Read(buffer, 0, bufferSize)) > 0) { filtered.Write(buffer, 0, n); } } filtered.Flush(); } if (encoding == ContentEncoding.UUEncode) { var end = Encoding.ASCII.GetBytes("end\n"); encoded.Write(end, 0, end.Length); } var buf0 = original.GetBuffer(); var buf1 = encoded.GetBuffer(); n = (int)original.Length; Assert.AreEqual(original.Length, encoded.Length, "Encoded length is incorrect."); for (int i = 0; i < n; i++) { Assert.AreEqual(buf0[i], buf1[i], "The byte at offset {0} does not match.", i); } } } }
Header GenerateArcMessageSignature(FormatOptions options, MimeMessage message, int instance, TimeSpan t, IList <string> headers) { if (message.MimeVersion == null && message.Body != null && message.Body.Headers.Count > 0) { message.MimeVersion = new Version(1, 0); } var value = CreateArcHeaderBuilder(instance); byte[] signature, hash; Header ams; value.AppendFormat("; d={0}; s={1}", Domain, Selector); value.AppendFormat("; c={0}/{1}", HeaderCanonicalizationAlgorithm.ToString().ToLowerInvariant(), BodyCanonicalizationAlgorithm.ToString().ToLowerInvariant()); value.AppendFormat("; t={0}", (long)t.TotalSeconds); using (var stream = new DkimSignatureStream(CreateSigningContext())) { using (var filtered = new FilteredStream(stream)) { filtered.Add(options.CreateNewLineFilter()); // write the specified message headers DkimVerifierBase.WriteHeaders(options, message, headers, HeaderCanonicalizationAlgorithm, filtered); value.AppendFormat("; h={0}", string.Join(":", headers.ToArray())); hash = message.HashBody(options, SignatureAlgorithm, BodyCanonicalizationAlgorithm, -1); value.AppendFormat("; bh={0}", Convert.ToBase64String(hash)); value.Append("; b="); ams = new Header(HeaderId.ArcMessageSignature, value.ToString()); switch (HeaderCanonicalizationAlgorithm) { case DkimCanonicalizationAlgorithm.Relaxed: DkimVerifierBase.WriteHeaderRelaxed(options, filtered, ams, true); break; default: DkimVerifierBase.WriteHeaderSimple(options, filtered, ams, true); break; } filtered.Flush(); } signature = stream.GenerateSignature(); ams.Value += Convert.ToBase64String(signature); return(ams); } }
/// <summary> /// Writes the message to the specified stream. /// </summary> /// <param name="options">The formatting options.</param> /// <param name="stream">The stream.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="options"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="stream"/> is <c>null</c>.</para> /// </exception> public void WriteTo(FormatOptions options, Stream stream) { if (options == null) { throw new ArgumentNullException("options"); } if (stream == null) { throw new ArgumentNullException("stream"); } if (!Headers.Contains("Date")) { Date = DateTimeOffset.Now; } if (messageId == null) { MessageId = MimeUtils.GenerateMessageId(); } if (version == null && Body != null && Body.Headers.Count > 0) { MimeVersion = new Version(1, 0); } if (Body == null) { Headers.WriteTo(stream); stream.Write(options.NewLineBytes, 0, options.NewLineBytes.Length); } else { using (var filtered = new FilteredStream(stream)) { filtered.Add(options.CreateNewLineFilter()); foreach (var header in MergeHeaders()) { var name = Encoding.ASCII.GetBytes(header.Field); filtered.Write(name, 0, name.Length); filtered.WriteByte((byte)':'); filtered.Write(header.RawValue, 0, header.RawValue.Length); } filtered.Flush(); } options.WriteHeaders = false; Body.WriteTo(options, stream); } }
/// <summary> /// Decodes the content stream into another stream. /// </summary> /// <remarks> /// Uses the <see cref="Encoding"/> to decode the content stream to the output stream. /// </remarks> /// <param name="stream">The output stream.</param> /// <param name="cancellationToken">A cancellation token.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="stream"/> is <c>null</c>. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> public void DecodeTo(Stream stream, CancellationToken cancellationToken = default(CancellationToken)) { if (stream == null) { throw new ArgumentNullException("stream"); } using (var filtered = new FilteredStream(stream)) { filtered.Add(DecoderFilter.Create(Encoding)); WriteTo(filtered, cancellationToken); filtered.Flush(cancellationToken); } }
/// <summary> /// Decodes the content stream into another stream. /// </summary> /// <param name="stream">The output stream.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="stream"/> is <c>null</c>. /// </exception> public void DecodeTo(Stream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } using (var filtered = new FilteredStream(stream)) { filtered.Add(DecoderFilter.Create(Encoding)); WriteTo(filtered); filtered.Flush(); } }
public static void SaveToPickupDirectory (MimeMessage message, string pickupDirectory) { do { // Generate a random file name to save the message to. var path = Path.Combine (pickupDirectory, Guid.NewGuid ().ToString () + ".eml"); Stream stream; try { // Attempt to create the new file. stream = File.Open (path, FileMode.CreateNew); } catch (IOException) { // If the file already exists, try again with a new Guid. if (File.Exists (path)) continue; // Otherwise, fail immediately since it probably means that there is // no graceful way to recover from this error. throw; } try { using (stream) { // IIS pickup directories expect the message to be "byte-stuffed" // which means that lines beginning with "." need to be escaped // by adding an extra "." to the beginning of the line. // // Use an SmtpDataFilter "byte-stuff" the message as it is written // to the file stream. This is the same process that an SmtpClient // would use when sending the message in a `DATA` command. using (var filtered = new FilteredStream (stream)) { filtered.Add (new SmtpDataFilter ()); // Make sure to write the message in DOS (<CR><LF>) format. var options = FormatOptions.Default.Clone (); options.NewLineFormat = NewLineFormat.Dos; message.WriteTo (options, filtered); filtered.Flush (); return; } } } catch { // An exception here probably means that the disk is full. // // Delete the file that was created above so that incomplete files are not // left behind for IIS to send accidentally. File.Delete (path); throw; } } while (true); }
static byte[] ReadAllBytes(Stream stream, bool text) { using (var memory = new MemoryStream()) { using (var filtered = new FilteredStream(memory)) { if (text) { filtered.Add(new Dos2UnixFilter(true)); } stream.CopyTo(filtered, 4096); filtered.Flush(); return(memory.ToArray()); } } }
public void TestYDecodeStateTransitions() { using (var file = File.OpenRead(Path.Combine(DataDir, "state-changes.ntx"))) { using (var decoded = new MemoryStream()) { var ydec = new YDecoder(); using (var filtered = new FilteredStream(decoded)) { filtered.Add(new DecoderFilter(ydec)); file.CopyTo(filtered, 1); filtered.Flush(); } Assert.AreEqual(584, decoded.Length, "The decoded size does not match."); Assert.AreEqual(0xded29f4f, ydec.Checksum ^ 0xffffffff, "The decoded checksum does not match."); } } }
public ImapReplayCommand(string tag, string command, string resource) { Command = command; using (var stream = GetType().Assembly.GetManifestResourceStream("UnitTests.Net.Imap.Resources." + resource)) { using (var memory = new MemoryBlockStream()) { using (var filtered = new FilteredStream(memory)) { filtered.Add(new ImapReplayFilter("A########", tag)); filtered.Add(new Unix2DosFilter()); stream.CopyTo(filtered, 4096); filtered.Flush(); } Response = memory.ToArray(); } } }
/// <summary> /// Gets the decoded text content using the provided charset to override /// the charset specified in the Content-Type parameters. /// </summary> /// <returns>The decoded text.</returns> /// <param name="charset">The charset encoding to use.</param> /// <exception cref="System.ArgumentNullException"> /// <paramref name="charset"/> is <c>null</c>. /// </exception> public string GetText(Encoding charset) { if (charset == null) { throw new ArgumentNullException("charset"); } using (var memory = new MemoryStream()) { using (var filtered = new FilteredStream(memory)) { filtered.Add(new CharsetFilter(charset, Encoding.UTF8)); ContentObject.DecodeTo(filtered); filtered.Flush(); return(Encoding.UTF8.GetString(memory.GetBuffer(), 0, (int)memory.Length)); } } }
/// <summary> /// Converts the contents of <paramref name="source"/> from the <see cref="InputFormat"/> to the /// <see cref="OutputFormat"/> and writes the resulting text to <paramref name="destination"/>. /// </summary> /// <remarks> /// Converts the contents of <paramref name="source"/> from the <see cref="InputFormat"/> to the /// <see cref="OutputFormat"/> and writes the resulting text to <paramref name="destination"/>. /// </remarks> /// <param name="source">The source stream.</param> /// <param name="destination">The destination stream.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="source"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="destination"/> is <c>null</c>.</para> /// </exception> public void Convert(Stream source, Stream destination) { if (source == null) { throw new ArgumentNullException("source"); } if (destination == null) { throw new ArgumentNullException("destination"); } using (var filtered = new FilteredStream(destination)) { filtered.Add(this); source.CopyTo(filtered, 4096); filtered.Flush(); } }
public ImapReplayCommand(string command, string resource, bool compressed = false) { string tag = null; CommandBuffer = Latin1.GetBytes(command); Compressed = compressed; Command = command; if (command.StartsWith("A00000", StringComparison.Ordinal)) { tag = command.Substring(0, 9); } using (var stream = GetType().Assembly.GetManifestResourceStream("UnitTests.Net.Imap.Resources." + resource)) { using (var memory = new MemoryBlockStream()) { using (Stream compress = new CompressedStream(memory)) { using (var filtered = new FilteredStream(compressed ? compress : memory)) { if (tag != null) { filtered.Add(new ImapReplayFilter("A########", tag)); } filtered.Add(new Unix2DosFilter()); stream.CopyTo(filtered, 4096); filtered.Flush(); } Response = memory.ToArray(); } } } if (compressed) { using (var memory = new MemoryStream()) { using (var compress = new CompressedStream(memory)) { compress.Write(CommandBuffer, 0, CommandBuffer.Length); compress.Flush(); CommandBuffer = memory.ToArray(); } } } }
/// <summary> /// Calculates the most efficient content encoding given the specified constraint. /// </summary> /// <remarks> /// If no <see cref="ContentObject"/> is set, <see cref="ContentEncoding.SevenBit"/> will be returned. /// </remarks> /// <returns>The most efficient content encoding.</returns> /// <param name="constraint">The encoding constraint.</param> /// <param name="maxLineLength">The maximum allowable length for a line (not counting the CRLF). Must be between <c>72</c> and <c>998</c> (inclusive).</param> /// <param name="cancellationToken">A cancellation token.</param> /// <exception cref="System.ArgumentOutOfRangeException"> /// <para><paramref name="maxLineLength"/> is not between <c>72</c> and <c>998</c> (inclusive).</para> /// <para>-or-</para> /// <para><paramref name="constraint"/> is not a valid value.</para> /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> public ContentEncoding GetBestEncoding(EncodingConstraint constraint, int maxLineLength, CancellationToken cancellationToken = default(CancellationToken)) { if (ContentObject == null) { return(ContentEncoding.SevenBit); } using (var measure = new MeasuringStream()) { using (var filtered = new FilteredStream(measure)) { var filter = new BestEncodingFilter(); filtered.Add(filter); ContentObject.DecodeTo(filtered, cancellationToken); filtered.Flush(); return(filter.GetBestEncoding(constraint, maxLineLength)); } } }
Header GenerateArcSeal(FormatOptions options, int instance, TimeSpan t, ArcHeaderSet[] sets, int count, Header aar, Header ams) { var value = CreateArcHeaderBuilder(instance); byte[] signature; Header seal; // FIXME: where should this value come from? value.Append("; cv=pass"); value.AppendFormat("; d={0}; s={1}", Domain, Selector); value.AppendFormat("; t={0}", (long)t.TotalSeconds); using (var stream = new DkimSignatureStream(CreateSigningContext())) { using (var filtered = new FilteredStream(stream)) { filtered.Add(options.CreateNewLineFilter()); for (int i = 0; i < count; i++) { DkimVerifierBase.WriteHeaderRelaxed(options, filtered, sets[i].ArcAuthenticationResult, false); DkimVerifierBase.WriteHeaderRelaxed(options, filtered, sets[i].ArcMessageSignature, false); DkimVerifierBase.WriteHeaderRelaxed(options, filtered, sets[i].ArcSeal, false); } DkimVerifierBase.WriteHeaderRelaxed(options, filtered, aar, false); DkimVerifierBase.WriteHeaderRelaxed(options, filtered, ams, false); value.Append("; b="); seal = new Header(HeaderId.ArcSeal, value.ToString()); DkimVerifierBase.WriteHeaderRelaxed(options, filtered, seal, true); filtered.Flush(); } signature = stream.GenerateSignature(); seal.Value += Convert.ToBase64String(signature); return(seal); } }
public void TestUUEncode() { using (var original = new MemoryStream()) { using (var file = File.OpenRead("../../TestData/encoders/photo.uu")) { using (var filtered = new FilteredStream(original)) { filtered.Add(new Dos2UnixFilter()); file.CopyTo(filtered, 4096); filtered.Flush(); } } using (var encoded = new MemoryStream()) { var begin = Encoding.ASCII.GetBytes("begin 644 photo.jpg\n"); var end = Encoding.ASCII.GetBytes("end\n"); encoded.Write(begin, 0, begin.Length); using (var filtered = new FilteredStream(encoded)) { filtered.Add(EncoderFilter.Create(ContentEncoding.UUEncode)); using (var file = File.OpenRead("../../TestData/encoders/photo.jpg")) file.CopyTo(filtered, 4096); filtered.Flush(); } encoded.Write(end, 0, end.Length); var buf0 = original.GetBuffer(); var buf1 = encoded.GetBuffer(); int n = (int)original.Length; Assert.AreEqual(original.Length, encoded.Length, "Encoded length is incorrect."); for (int i = 0; i < n; i++) { Assert.AreEqual(buf0[i], buf1[i], "The byte at offset {0} does not match.", i); } } } }
/// <summary> /// Writes the <see cref="MimeKit.HeaderList"/> to the specified output stream. /// </summary> /// <remarks> /// Writes all of the headers to the output stream. /// </remarks> /// <param name="options">The formatting options.</param> /// <param name="stream">The output stream.</param> /// <param name="cancellationToken">A cancellation token.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="options"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="stream"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> public void WriteTo(FormatOptions options, Stream stream, CancellationToken cancellationToken = default(CancellationToken)) { if (options == null) { throw new ArgumentNullException("options"); } if (stream == null) { throw new ArgumentNullException("stream"); } using (var filtered = new FilteredStream(stream)) { if (options.NewLineFormat != FormatOptions.Default.NewLineFormat) { filtered.Add(options.CreateNewLineFilter()); } foreach (var header in headers) { var name = Encoding.ASCII.GetBytes(header.Field); byte[] rawValue; filtered.Write(name, 0, name.Length, cancellationToken); filtered.Write(new [] { (byte)':' }, 0, 1, cancellationToken); if (options.International) { rawValue = header.GetRawValue(options, Encoding.UTF8); } else { rawValue = header.RawValue; } filtered.Write(rawValue, 0, rawValue.Length, cancellationToken); } filtered.Flush(cancellationToken); } }
/// <summary> /// Creates a new <see cref="MultipartEncrypted"/>. /// </summary> /// <remarks> /// Encrypts the entity to the specified recipients, encapsulating the result in a /// new multipart/encrypted part. /// </remarks> /// <returns>A new <see cref="MimeKit.Cryptography.MultipartEncrypted"/> instance containing /// the encrypted version of the specified entity.</returns> /// <param name="ctx">The OpenPGP cryptography context to use for encrypting.</param> /// <param name="recipients">The recipients for the encrypted entity.</param> /// <param name="entity">The entity to sign and encrypt.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="ctx"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="recipients"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="entity"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.ArgumentException"> /// One or more of the recipient keys cannot be used for encrypting. /// </exception> public static MultipartEncrypted Create(OpenPgpContext ctx, IEnumerable <PgpPublicKey> recipients, MimeEntity entity) { if (ctx == null) { throw new ArgumentNullException("ctx"); } if (recipients == null) { throw new ArgumentNullException("recipients"); } if (entity == null) { throw new ArgumentNullException("entity"); } using (var memory = new MemoryBlockStream()) { using (var filtered = new FilteredStream(memory)) { filtered.Add(new Unix2DosFilter()); PrepareEntityForEncrypting(entity); entity.WriteTo(filtered); filtered.Flush(); } memory.Position = 0; var encrypted = new MultipartEncrypted(); encrypted.ContentType.Parameters["protocol"] = ctx.EncryptionProtocol; // add the protocol version part encrypted.Add(new ApplicationPgpEncrypted()); // add the encrypted entity as the second part encrypted.Add(ctx.Encrypt(recipients, memory)); return(encrypted); } }
public void TestYDecodeMultiPart() { var expected = File.ReadAllBytes(Path.Combine(DataDir, "joystick.jpg")); using (var decoded = new MemoryStream()) { using (var file = File.OpenRead(Path.Combine(DataDir, "00000020.ntx"))) { var ydec = new YDecoder(); using (var filtered = new FilteredStream(decoded)) { filtered.Add(new DecoderFilter(ydec)); file.CopyTo(filtered, 1); filtered.Flush(); } Assert.AreEqual(11250, decoded.Length, "The decoded size does not match (part 1)."); Assert.AreEqual(0xbfae5c0b, ydec.Checksum ^ 0xffffffff, "The decoded checksum does not match (part 1)."); } using (var file = File.OpenRead(Path.Combine(DataDir, "00000021.ntx"))) { var ydec = new YDecoder(); using (var filtered = new FilteredStream(decoded)) { filtered.Add(new DecoderFilter(ydec)); file.CopyTo(filtered, 1); filtered.Flush(); } Assert.AreEqual(19338, decoded.Length, "The decoded size does not match (part 2)."); Assert.AreEqual(0xaca76043, ydec.Checksum ^ 0xffffffff, "The decoded checksum does not match (part 2)."); } var actual = decoded.GetBuffer(); for (int i = 0; i < expected.Length; i++) { Assert.AreEqual(expected[i], actual[i], "different content at index {0}", i); } } }
void Data(MimeMessage message, CancellationToken cancellationToken) { var response = SendCommand("DATA", cancellationToken); if (response.StatusCode != SmtpStatusCode.StartMailInput) { throw new SmtpCommandException(SmtpErrorCode.UnexpectedStatusCode, response.StatusCode, response.Response); } var options = FormatOptions.Default.Clone(); options.NewLineFormat = NewLineFormat.Dos; options.HiddenHeaders.Add(HeaderId.ContentLength); options.HiddenHeaders.Add(HeaderId.ResentBcc); options.HiddenHeaders.Add(HeaderId.Bcc); using (var filtered = new FilteredStream(stream)) { filtered.Add(new SmtpDataFilter()); message.WriteTo(options, filtered, cancellationToken); filtered.Flush(); } stream.Write(EndData, 0, EndData.Length); response = ReadResponse(cancellationToken); switch (response.StatusCode) { default: throw new SmtpCommandException(SmtpErrorCode.MessageNotAccepted, response.StatusCode, response.Response); case SmtpStatusCode.AuthenticationRequired: throw new UnauthorizedAccessException(response.Response); case SmtpStatusCode.Ok: break; } }
Stream GetResponseStream(ImapReplayCommand command) { MemoryStream memory; if (testUnixFormat) { memory = new MemoryStream(); using (var filtered = new FilteredStream(memory)) { filtered.Add(new Dos2UnixFilter()); filtered.Write(command.Response, 0, command.Response.Length); filtered.Flush(); } memory.Position = 0; } else { memory = new MemoryStream(command.Response, false); } return(memory); }