Exemple #1
0
        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);
                    }
                }
            }
        }
Exemple #2
0
        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);
                    }
                }
            }
        }
Exemple #3
0
        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.");
                }
            }
        }
Exemple #4
0
        /// <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));
                }
            }
        }
Exemple #5
0
        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"));
        }
Exemple #6
0
        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);
            }
        }
Exemple #8
0
        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);
        }
Exemple #9
0
        /// <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);
            }
        }
Exemple #10
0
        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));
            }
        }
Exemple #11
0
        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);
                    }
                }
            }
        }
Exemple #12
0
        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);
            }
        }
Exemple #13
0
        /// <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);
            }
        }
Exemple #15
0
        /// <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();
            }
        }
Exemple #16
0
		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);
		}
Exemple #17
0
        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());
                }
            }
        }
Exemple #18
0
        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.");
                }
            }
        }
Exemple #19
0
        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();
                }
            }
        }
Exemple #20
0
        /// <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();
            }
        }
Exemple #22
0
        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();
                    }
                }
            }
        }
Exemple #23
0
        /// <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));
                }
            }
        }
Exemple #24
0
        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);
            }
        }
Exemple #25
0
        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);
                    }
                }
            }
        }
Exemple #26
0
        /// <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);
            }
        }
Exemple #28
0
        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);
                }
            }
        }
Exemple #29
0
        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;
            }
        }
Exemple #30
0
        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);
        }